Draft implementation of note timing.
authorAlexandre Segura <mex.zktk@gmail.com>
Thu, 01 Jun 2017 17:32:07 +0200
changeset 16 e67cd18cc594
parent 15 4a8bbd314a46
child 17 877d8796b86d
Draft implementation of note timing.
client/src/actions/notesActions.js
client/src/components/Note.js
client/src/components/NoteInput.js
client/src/components/SlateEditor.js
client/src/store/noteRecord.js
--- a/client/src/actions/notesActions.js	Thu Jun 01 16:15:08 2017 +0200
+++ b/client/src/actions/notesActions.js	Thu Jun 01 17:32:07 2017 +0200
@@ -9,7 +9,9 @@
       id: uuidV1(),
       session: session.id,
       raw: data.raw,
-      plain: data.plain
+      plain: data.plain,
+      startedAt: data.startedAt,
+      finishedAt: data.finishedAt
     }
   };
 }
--- a/client/src/components/Note.js	Thu Jun 01 16:15:08 2017 +0200
+++ b/client/src/components/Note.js	Thu Jun 01 17:32:07 2017 +0200
@@ -4,7 +4,7 @@
 const Note = ({note}) => {
   return (
     <div id={"note-" + note.id}>
-      {note.plain}
+      {note.startedAt} ⇒ {note.finishedAt} {note.plain}
     </div>
   );
 };
--- a/client/src/components/NoteInput.js	Thu Jun 01 16:15:08 2017 +0200
+++ b/client/src/components/NoteInput.js	Thu Jun 01 17:32:07 2017 +0200
@@ -1,6 +1,6 @@
 import React, {Component} from 'react';
-import { Form, FormGroup, Button } from 'react-bootstrap';
-import { Plain } from 'slate';
+import { Form, FormGroup, Button, Label, Row, Col } from 'react-bootstrap';
+import moment from 'moment';
 
 import PropTypes from 'prop-types';
 import SlateEditor from './SlateEditor';
@@ -8,12 +8,18 @@
 class NoteInput extends Component {
 
   state = {
-    buttonDisabled: false
+    buttonDisabled: false,
+    time: moment().format('H:mm:ss'),
+    startedAt: null,
+    finishedAt: null,
   }
 
-  onChange = (state) => {
-    const text = Plain.serialize(state);
-    this.setState({ buttonDisabled: text.length === 0 });
+  onEditorChange = (e) => {
+    this.setState({
+      buttonDisabled: e.state.document.length === 0,
+      startedAt: e.startedAt,
+      finishedAt: e.finishedAt
+    });
   }
 
   onAddNoteClick = () => {
@@ -22,7 +28,9 @@
 
     this.props.addNote(this.props.session, {
       plain: plain,
-      raw: raw
+      raw: raw,
+      startedAt: this.state.startedAt,
+      finishedAt: moment().format('H:mm:ss')
     });
 
     this.refs.editor.clear();
@@ -32,14 +40,41 @@
   componentDidMount() {
     const text = this.refs.editor.asPlain();
     this.setState({ buttonDisabled: text.length === 0 });
+    setInterval(() => {
+      const time = moment().format('H:mm:ss');
+      this.setState({ time });
+    }, 1000);
+  }
+
+  renderTiming() {
+    if (this.state.startedAt && this.state.finishedAt) {
+      return (
+        <span>
+          <Label>{this.state.startedAt}</Label> ⇒ <Label>{this.state.finishedAt}</Label>
+        </span>
+      )
+    } else {
+      return (
+        <span>No timing</span>
+      )
+    }
   }
 
   render() {
     return (
       <Form>
+        <Row>
+          <Col md={6}>
+            { this.renderTiming() }
+          </Col>
+          <Col md={6} className="text-right">
+            <Label bsStyle="info">{ this.state.time }</Label>
+          </Col>
+        </Row>
+        <hr />
         <FormGroup>
           <div className="editor-wrapper">
-            <SlateEditor ref="editor" onChange={this.onChange} />
+            <SlateEditor ref="editor" onChange={this.onEditorChange} />
           </div>
         </FormGroup>
         <Button disabled={this.state.buttonDisabled} bsStyle="primary" type="button" onClick={this.onAddNoteClick}>Add Note</Button>
--- a/client/src/components/SlateEditor.js	Thu Jun 01 16:15:08 2017 +0200
+++ b/client/src/components/SlateEditor.js	Thu Jun 01 17:32:07 2017 +0200
@@ -1,5 +1,6 @@
 import { Editor, Plain, Raw } from 'slate'
 import React from 'react'
+import moment from 'moment';
 
 /**
  * Define the default node type.
@@ -57,7 +58,9 @@
   constructor(props) {
     super(props);
     this.state = {
-      state: Plain.deserialize('')
+      state: Plain.deserialize(''),
+      startedAt: null,
+      finishedAt: null
     };
   }
 
@@ -96,9 +99,33 @@
    */
 
   onChange = (state) => {
-    this.setState({ state })
+
+    let newState = {
+      state: state,
+      startedAt: this.state.startedAt
+    };
+
+    const isEmpty = state.document.length === 0;
+
+    // Reset timers when the text is empty
+    if (isEmpty) {
+      Object.assign(newState, {
+        startedAt: null,
+        finishedAt: null
+      });
+    } else {
+      Object.assign(newState, { finishedAt: moment().format('H:mm:ss') });
+    }
+
+    // Store start time once when the first character is typed
+    if (!isEmpty && this.state.startedAt === null) {
+      Object.assign(newState, { startedAt: moment().format('H:mm:ss') });
+    }
+
+    this.setState(newState)
+
     if (typeof this.props.onChange === 'function') {
-      this.props.onChange(state);
+      this.props.onChange(newState);
     }
   }
 
@@ -235,16 +262,6 @@
     this.setState({ state })
   }
 
-  // /**
-  //  *
-  //  * @param {*Cosntructor} props
-  //  */
-  // componentWillMount() {
-  //   const initialValue = Raw.deserialize(initialState, { terse: true });
-  //   this.state = { state: initialValue};
-  //   this.onChange(initialValue);
-  // }
-
   /**
    * Render.
    *
--- a/client/src/store/noteRecord.js	Thu Jun 01 16:15:08 2017 +0200
+++ b/client/src/store/noteRecord.js	Thu Jun 01 17:32:07 2017 +0200
@@ -4,5 +4,7 @@
   id: '',
   session: '',
   plain: '',
-  raw: {}
+  raw: {},
+  startedAt: '',
+  finishedAt: '',
 });