SolidScribe/client/src/components/InputNotes.vue

225 lines
5.6 KiB
Vue
Raw Normal View History

<template>
<div id="InputNotes" class="master-note-edit">
<ckeditor ref="main-edit"
:editor="editor" @ready="onReady" v-model="noteText" :config="editorConfig" v-on:blur="save"></ckeditor>
<div class="ui buttons">
<div class="ui green button">{{statusText}}</div>
<div class="ui button">Delete</div>
<div v-on:click="close" class="ui button">Close</div>
<div class="ui disabled button">{{lastNoteHash}}</div>
<div class="ui disabled button">Last Update: {{updated}}</div>
</div>
<div class="ui segment">
<note-tag-edit :noteId="noteid" :key="'tags-for-note-'+noteid"/>
</div>
<div class="ui segment" v-if="false">
Block formatting
The following block formatting options are available:
<p> Bulleted list Start a line with * or - followed by a space.</p>
<p> Numbered list Start a line with 1. or 1) followed by a space.</p>
<p> Headings Start a line with # or ## or ### followed by a space to create a heading 1, heading 2 or heading 3 (up to heading 6 if options defines more headings).</p>
<p> Block quote Start a line with > followed by a space.</p>
Inline formatting
The following inline formatting options are available:
Bold Type **text** or __text__,
Italic Type *text* or _text_,
Code Type `text`.
</div>
</div>
</template>
<script>
import axios from 'axios'
import DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document';
export default {
name: 'InputNotes',
props: [ 'noteid' ],
components:{
'note-tag-edit': require('./NoteTagEdit.vue').default
},
data(){
return {
currentNoteId: 0,
noteText: '',
statusText: 'Save',
lastNoteHash: null,
updated: 'Never',
editDebounce: null,
keyPressesCounter: 0,
editor: DecoupledEditor,
editorConfig: {
startupFocus: 'end',
toolbar: ["alignment", "fontSize", "removeHighlight", "highlight", "bold", "italic", "strikethrough", "underline", "blockQuote", "heading", "link", "numberedList", "bulletedList", "insertTable", "|", "undo", "redo"]
}
}
},
watch: {
noteid:function(newVal, oldVal){
if(newVal == this.currentNoteId){
return
}
if(newVal == oldVal){
return
}
this.currentNoteId = newVal
this.loadNote(this.currentNoteId)
}
},
beforeMount(){
},
beforeDestroy(){
},
mounted: function() {
this.loadNote(this.noteid)
},
methods: {
loadNote(noteId){
let vm = this
//Component is activated with NoteId in place, lookup text with associated ID
if(this.$store.getters.getLoggedIn){
axios.post('/api/notes/get', {'noteId': noteId})
.then(response => {
//Set up local data
vm.currentNoteId = noteId
vm.noteText = response.data.text
vm.updated = response.data.updated
vm.lastNoteHash = vm.hashString(response.data.text)
//Put focus on note, at the end of the note text
vm.$nextTick(() => {
// vm.$refs['custom-input'].focus()
})
})
} else {
console.log('Could not fetch note')
}
},
onReady(editor){
let vm = this
console.log(vm)
// Insert the toolbar before the editable area.
editor.ui.getEditableElement().parentElement.insertBefore(
editor.ui.view.toolbar.element,
editor.ui.getEditableElement()
);
editor.editing.view.focus()
// const editor = this.editor;
const view = editor.editing.view;
const viewDocument = view.document;
//Insert 5 spaces when tab is pressed
viewDocument.on( 'keyup', ( evt, data ) => {
//Each note, save after 5 seconds, focus lost or 30 characters typed.
clearTimeout(vm.editDebounce)
vm.editDebounce = setTimeout(() => {
vm.save()
}, 5000)
//Save after 20 keystrokes
vm.keyPressesCounter = (vm.keyPressesCounter + 1)
if(vm.keyPressesCounter > 30){
vm.save()
}
if( (data.keyCode == 9) && viewDocument.isFocused ){
//Insert 5 spaces to simulate tab
editor.execute( 'input', { text: " " } );
evt.stop(); // Prevent executing the default handler.
data.preventDefault();
view.scrollToTheSelection();
}
} );
},
save(){
console.log('Save, ', this.keyPressesCounter)
this.keyPressesCounter = 0
clearTimeout(this.editDebounce)
//Don't save note if its hash doesn't change
if(this.lastNoteHash == this.hashString(this.noteText)){
return
}
const postData = {
'noteId':this.currentNoteId,
'text': this.noteText
}
let vm = this
axios.post('/api/notes/update', postData).then( response => {
vm.statusText = 'Saved'
//Update last saved note hash
vm.lastNoteHash = vm.hashString(vm.noteText)
setTimeout(() => {
vm.statusText = 'Save'
}, 5000)
})
},
hashString(text){
var hash = 0;
if (text.length == 0) {
return hash;
}
for (let i = 0; i < text.length; i++) {
let char = text.charCodeAt(i);
hash = ((hash<<5)-hash)+char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
},
close(){
this.$bus.$emit('close_active_note')
}
}
}
</script>
<style type="text/css" scoped>
.master-note-edit {
position: fixed;
left: 10%;
right: 10%;
bottom: 0;
background: green;
height: 98vh;
border-top-right-radius: 4px;
border-top-left-radius: 4px;
box-shadow: 0px 0px 5px 2px rgba(140,140,140,1);
}
</style>