client/src/components/SlateEditor.js
changeset 159 a4705c2b4544
parent 157 5c3af4f10e92
child 161 a642639dbc07
--- a/client/src/components/SlateEditor.js	Mon Oct 01 00:17:45 2018 +0200
+++ b/client/src/components/SlateEditor.js	Mon Oct 08 03:24:47 2018 +0200
@@ -7,6 +7,7 @@
 import HtmlSerializer from '../HtmlSerializer'
 import AnnotationPlugin from '../AnnotationPlugin'
 import CategoriesTooltip from './CategoriesTooltip'
+// import './SlateEditor.css';
 import { now } from '../utils';
 import { defaultAnnotationsCategories } from '../constants';
 
@@ -26,6 +27,7 @@
 // TODO Check if we can move this to the plugin using the schema option
 // https://docs.slatejs.org/reference/plugins/plugin.html#schema
 const schema = {
+
   nodes: {
     'bulleted-list': props => <ul {...props.attributes}>{props.children}</ul>,
     'list-item': props => <li {...props.attributes}>{props.children}</li>,
@@ -46,6 +48,7 @@
       textDecoration: 'underlined'
     }
   }
+
 }
 
 const initialValue = Value.fromJSON({
@@ -90,7 +93,7 @@
         this.setState({
           currentSelectionText: text,
           currentSelectionStart: start,
-          currentSelectionEnd: end
+          currentSelectionEnd: end,
         });
       }
     });
@@ -99,7 +102,7 @@
 
 
     this.state = {
-      value: props.note ? initialValue : Plain.deserialize(''),
+      value: props.note ? Value.fromJSON(initialValue) : Plain.deserialize(''),
       startedAt: null,
       finishedAt: null,
       currentSelectionText: '',
@@ -109,6 +112,7 @@
       isPortalOpen: false,
       categories: Immutable.List([]),
       isCheckboxChecked: false,
+      enterKeyValue: 0,
     };
   }
 
@@ -212,52 +216,6 @@
     this.refs.editor.focus();
   }
 
-  /**
-   * On key down, if it's a formatting command toggle a mark.
-   *
-   * @param {Event} e
-   * @param {Object} data
-   * @param {Change} change
-   * @return {Change}
-   */
-
-  onKeyDown = (e, change) => {
-    //   if (data.key === 'enter' && this.props.isChecked && typeof this.props.onEnterKeyDown === 'function') {
-
-    //   e.preventDefault();
-    //   this.props.onEnterKeyDown();
-
-    //   return change;
-    // }
-
-    // if (!data.isMod) return
-    if (!e.ctrlKey) return
-        // Decide what to do based on the key code...
-        switch (e.key) {
-          // When "B" is pressed, add a "bold" mark to the text.
-          case 'b': {
-            e.preventDefault()
-            change.toggleMark('bold')
-
-            return true
-          }
-          case 'i': {
-            // When "U" is pressed, add an "italic" mark to the text.
-            e.preventDefault()
-            change.toggleMark('italic')
-
-            return true
-          }
-          case 'u': {
-            // When "U" is pressed, add an "underline" mark to the text.
-            e.preventDefault()
-            change.toggleMark('underlined')
-
-            return true
-          }
-        }
-    }
-
       /**
    * When a mark button is clicked, toggle the current mark.
    *
@@ -267,7 +225,7 @@
 
   onClickMark = (e, type) => {
 
-      e.preventDefault()
+    e.preventDefault()
     const { value } = this.state
     let { categories } = this.state
 
@@ -398,7 +356,6 @@
         key: category.key
       }
     })
-    this.onChange(change)
 
     Object.assign(category, {
       text: currentSelectionText,
@@ -409,8 +366,9 @@
     });
     categories = categories.push(category);
 
+    this.onChange(change)
+
     this.setState({
-      value: value,
       isPortalOpen: false,
       categories: categories
     });
@@ -429,6 +387,94 @@
   }
 
   /**
+   * On key down, if it's a formatting command toggle a mark.
+   *
+   * @param {Event} e
+   * @param {Change} change
+   * @return {Change}
+   */
+
+  onKeyDown = (e, change) => {
+
+    const {value} = this.state;
+
+    // if (e.key === 'Enter' && value.document.text === '') {
+    //   change.removeChild()
+    // }
+
+    if (e.key === 'Enter' && value.document.text !== '') {
+      this.setState({enterKeyValue: 1})
+    }
+
+    if (e.key !== 'Enter') {
+      this.setState({
+        enterKeyValue: 0,
+      })
+
+    }
+
+    if (e.key === 'Enter' && !this.props.isChecked && this.state.enterKeyValue === 1 && typeof this.props.onEnterKeyDown === 'function') {
+      e.preventDefault();
+      this.props.onEnterKeyDown();
+      this.setState({
+        enterKeyValue: 0,
+      })
+
+
+      return change
+    }
+
+    else if (e.key === 'Enter' && value.document.text !== '' && this.props.isChecked && typeof this.props.onEnterKeyDown === 'function') {
+
+      e.preventDefault();
+      this.props.onEnterKeyDown();
+
+      return change
+    }
+
+    if (!e.ctrlKey) return
+        // Decide what to do based on the key code...
+        switch (e.key) {
+          default: {
+            break;
+          }
+          // When "B" is pressed, add a "bold" mark to the text.
+          case 'b': {
+            e.preventDefault()
+            change.toggleMark('bold')
+
+            return true
+          }
+          case 'i': {
+            // When "U" is pressed, add an "italic" mark to the text.
+            e.preventDefault()
+            change.toggleMark('italic')
+
+            return true
+          }
+          case 'u': {
+            // When "U" is pressed, add an "underline" mark to the text.
+            e.preventDefault()
+            change.toggleMark('underlined')
+
+            return true
+          }
+          case 'Enter': {
+            // When "ENTER" is pressed, autosubmit the note.
+            if (value.document.text !== '' && typeof this.props.onEnterKeyDown === 'function') {
+              e.preventDefault()
+              this.props.onEnterKeyDown();
+              this.setState({
+                enterKeyValue: 0,
+              })
+
+              return true
+            }
+        }
+      }
+  }
+
+  /**
    * Render.
    *
    * @return {Element}
@@ -453,7 +499,7 @@
 
   renderToolbar = () => {
     return (
-      <div className="menu toolbar-menu d-flex bg-secondary">
+      <div className="menu toolbar-menu d-flex sticky-top bg-secondary">
           {this.renderMarkButton('bold', 'format_bold')}
           {this.renderMarkButton('italic', 'format_italic')}
           {this.renderMarkButton('underlined', 'format_underlined')}
@@ -478,12 +524,20 @@
     )
   }
 
+  renderSaveButton = () => {
+    if (this.props.note) {
+      return <button type="button" id="btn-editor" className="btn btn-primary btn-sm text-secondary font-weight-bold mr-2" disabled={this.props.isButtonDisabled} onClick={this.onButtonClick}>
+      Sauvegarder</button>
+    }
+  }
+
   renderToolbarButtons = () => {
     return (
       <div>
-        <button type="button" className="btn btn-primary btn-sm text-secondary float-right mr-5" disabled={this.props.isButtonDisabled} onClick={this.onButtonClick}>
-          { this.props.note ? 'Save note' : 'Ajouter' }
-        </button>
+        {/* <button type="button" id="btn-editor" className="btn btn-primary btn-sm text-secondary font-weight-bold float-right" disabled={this.props.isButtonDisabled} onClick={this.onButtonClick}> */}
+          {/* { this.props.note ? 'Sauvegarder' : 'Ajouter' } */}
+          {this.renderSaveButton()}
+        {/* </button> */}
         { !this.props.note && this.renderToolbarCheckbox() }
       </div>
     );
@@ -500,10 +554,12 @@
   renderMarkButton = (type, icon) => {
     const isActive = this.hasMark(type)
     const onMouseDown = e => this.onClickMark(e, type)
-
+    const markActivation = "button sticky-top" + ((!isActive)?" text-primary":" text-dark");
 
     return (
-      <span className="button text-primary" onMouseDown={onMouseDown} data-active={isActive}>
+      // <span className="button text-primary" onMouseDown={onMouseDown} data-active={isActive}>
+      <span className={markActivation} onMouseDown={onMouseDown} data-active={isActive}>
+
         <span className="material-icons">{icon}</span>
       </span>
     )
@@ -515,6 +571,9 @@
       const { children, mark, attributes } = props
 
       switch (mark.type) {
+        default: {
+          break;
+        }
         case 'bold':
           return <strong {...attributes}>{children}</strong>
         case 'code':
@@ -542,9 +601,10 @@
       isActive = this.hasBlock('list-item') && parent && parent.type === type
     }
     const onMouseDown = e => this.onClickBlock(e, type)
+    const blockActivation = "button sticky-top" + ((!isActive)?" text-primary":" text-dark");
 
     return (
-      <span className="button text-primary" onMouseDown={onMouseDown} data-active={isActive}>
+      <span className={blockActivation} onMouseDown={onMouseDown} data-active={isActive}>
         <span className="material-icons">{icon}</span>
       </span>
     )
@@ -554,6 +614,9 @@
     const { attributes, children, node } = props
 
     switch (node.type) {
+      default: {
+        break;
+      }
       case 'block-quote':
         return <blockquote {...attributes}>{children}</blockquote>
       case 'bulleted-list':
@@ -577,13 +640,11 @@
 
   renderEditor = () => {
     return (
-      <div className="editor-wrapper sticky-bottom p-2">
-      <div className="editor-slatejs">
+      <div className="editor-slatejs p-2">
         {this.renderHoveringMenu()}
         <Editor
           ref="editor"
           spellCheck
-          autoFocus
           placeholder={'Votre espace de prise de note...'}
           schema={schema}
           plugins={plugins}
@@ -594,7 +655,6 @@
           renderNode = {this.renderNode}
         />
       </div>
-      </div>
     )
   }