From 090e1b845fa50c9cb8fddf79a1c07558f3d64904 Mon Sep 17 00:00:00 2001 From: azivner Date: Sat, 20 Jan 2018 21:56:03 -0500 Subject: [PATCH] first experiments with code mirror --- migrations/0068__add_note_type.sql | 1 + public/javascripts/note_editor.js | 45 ++++++++++++++++++++++++++++-- routes/api/import.js | 3 +- routes/api/notes.js | 16 +++++++++++ services/app_info.js | 2 +- services/consistency_checks.js | 9 ++++++ services/content_hash.js | 1 + services/notes.js | 5 ++-- views/index.ejs | 6 ++++ 9 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 migrations/0068__add_note_type.sql diff --git a/migrations/0068__add_note_type.sql b/migrations/0068__add_note_type.sql new file mode 100644 index 000000000..2104b11dd --- /dev/null +++ b/migrations/0068__add_note_type.sql @@ -0,0 +1 @@ +ALTER TABLE notes ADD COLUMN type TEXT NOT NULL DEFAULT 'text'; \ No newline at end of file diff --git a/public/javascripts/note_editor.js b/public/javascripts/note_editor.js index 7209c1c62..0631f7971 100644 --- a/public/javascripts/note_editor.js +++ b/public/javascripts/note_editor.js @@ -3,12 +3,14 @@ const noteEditor = (function() { const noteTitleEl = $("#note-title"); const noteDetailEl = $('#note-detail'); + const noteDetailCodeEl = $('#note-detail-code'); const protectButton = $("#protect-button"); const unprotectButton = $("#unprotect-button"); const noteDetailWrapperEl = $("#note-detail-wrapper"); const noteIdDisplayEl = $("#note-id-display"); let editor = null; + let codeEditor = null; let currentNote = null; @@ -121,8 +123,24 @@ const noteEditor = (function() { noteTitleEl.val(currentNote.detail.note_title); - // temporary workaround for https://github.com/ckeditor/ckeditor5-enter/issues/49 - editor.setData(currentNote.detail.note_text ? currentNote.detail.note_text : "

"); + console.log("Type: " + currentNote.detail.type); + + if (currentNote.detail.type === 'text') { + // temporary workaround for https://github.com/ckeditor/ckeditor5-enter/issues/49 + editor.setData(currentNote.detail.note_text ? currentNote.detail.note_text : "

"); + + noteDetailEl.show(); + noteDetailCodeEl.hide(); + } + else if (currentNote.detail.type === 'code') { + codeEditor.setValue(currentNote.detail.note_text); + + noteDetailEl.hide(); + noteDetailCodeEl.show(); + } + else { + throwError("Unrecognized type " + currentNote.detail.type); + } noteChangeDisabled = false; @@ -162,10 +180,33 @@ const noteEditor = (function() { console.error(error); }); + codeEditor = CodeMirror($("#note-detail-code")[0], { + value: "", + mode: "javascript" + }); + + codeEditor.setOption("extraKeys", { + 'Ctrl-.': function(cm) { + noteTree.scrollToCurrentNote(); + } + }); + // so that tab jumps from note title (which has tabindex 1) noteDetailEl.attr("tabindex", 2); }); + $(document).bind('keydown', 'alt+q', async e => { + const note = getCurrentNote(); + const type = note.detail.type; + const newType = type === "text" ? "code" : "text"; + + await server.put('notes/' + note.detail.note_id + '/type/' + newType); + + await reload(); + + e.preventDefault(); + }); + setInterval(saveNoteIfChanged, 5000); return { diff --git a/routes/api/import.js b/routes/api/import.js index a8f011d0e..fed4db91e 100644 --- a/routes/api/import.js +++ b/routes/api/import.js @@ -77,7 +77,8 @@ async function importNotes(dir, parentNoteId) { note_position: notePos, is_expanded: 0, is_deleted: 0, - date_modified: now + date_modified: now, + type: 'text' }); await sync_table.addNoteTreeSync(noteTreeId); diff --git a/routes/api/notes.js b/routes/api/notes.js index fded5a9ff..c854d966d 100644 --- a/routes/api/notes.js +++ b/routes/api/notes.js @@ -10,6 +10,7 @@ const utils = require('../../services/utils'); const protected_session = require('../../services/protected_session'); const data_encryption = require('../../services/data_encryption'); const tree = require('../../services/tree'); +const sync_table = require('../../services/sync_table'); const wrap = require('express-promise-wrap').wrap; router.get('/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => { @@ -92,4 +93,19 @@ router.put('/:noteId/protect-sub-tree/:isProtected', auth.checkApiAuth, wrap(asy res.send({}); })); +router.put('/:noteId/type/:type', auth.checkApiAuth, wrap(async (req, res, next) => { + const noteId = req.params.noteId; + const type = req.params.type; + const sourceId = req.headers.source_id; + + await sql.doInTransaction(async () => { + await sql.execute("UPDATE notes SET type = ?, date_modified = ? WHERE note_id = ?", + [type, utils.nowDate(), noteId]); + + await sync_table.addNoteSync(noteId, sourceId); + }); + + res.send({}); +})); + module.exports = router; \ No newline at end of file diff --git a/services/app_info.js b/services/app_info.js index 1184212ca..c81511bf9 100644 --- a/services/app_info.js +++ b/services/app_info.js @@ -3,7 +3,7 @@ const build = require('./build'); const packageJson = require('../package'); -const APP_DB_VERSION = 67; +const APP_DB_VERSION = 68; module.exports = { app_version: packageJson.version, diff --git a/services/consistency_checks.js b/services/consistency_checks.js index 8be92d2e7..bf4ef4bb1 100644 --- a/services/consistency_checks.js +++ b/services/consistency_checks.js @@ -208,6 +208,15 @@ async function runAllChecks() { AND (note_title IS NULL OR note_text IS NULL)`, "Note has null title or text", errorList); + await runCheck(` + SELECT + note_id + FROM + notes + WHERE + type != 'text' AND type != 'code'`, + "Note has invalid type", errorList); + await runSyncRowChecks("notes", "note_id", errorList); await runSyncRowChecks("notes_history", "note_history_id", errorList); await runSyncRowChecks("notes_tree", "note_tree_id", errorList); diff --git a/services/content_hash.js b/services/content_hash.js index 424fe5e96..d5ef26fea 100644 --- a/services/content_hash.js +++ b/services/content_hash.js @@ -22,6 +22,7 @@ async function getHashes() { note_id, note_title, note_text, + type, date_modified, is_protected, is_deleted diff --git a/services/notes.js b/services/notes.js index 4e2ed933f..1c9091aa6 100644 --- a/services/notes.js +++ b/services/notes.js @@ -38,9 +38,10 @@ async function createNewNote(parentNoteId, note, sourceId) { note_id: noteId, note_title: note.note_title, note_text: note.note_text ? note.note_text : '', + is_protected: note.is_protected, + type: 'text', date_created: now, - date_modified: now, - is_protected: note.is_protected + date_modified: now }); await sync_table.addNoteSync(noteId, sourceId); diff --git a/views/index.ejs b/views/index.ejs index 0393add9c..559297018 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -113,6 +113,8 @@
+ +
@@ -423,6 +425,10 @@ + + + +