225 lines
5.6 KiB
Vue
225 lines
5.6 KiB
Vue
|
<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>
|