first experiments with code mirror

This commit is contained in:
azivner 2018-01-20 21:56:03 -05:00
parent 93b4cf6a05
commit 090e1b845f
9 changed files with 82 additions and 6 deletions

View File

@ -0,0 +1 @@
ALTER TABLE notes ADD COLUMN type TEXT NOT NULL DEFAULT 'text';

View File

@ -3,12 +3,14 @@
const noteEditor = (function() { const noteEditor = (function() {
const noteTitleEl = $("#note-title"); const noteTitleEl = $("#note-title");
const noteDetailEl = $('#note-detail'); const noteDetailEl = $('#note-detail');
const noteDetailCodeEl = $('#note-detail-code');
const protectButton = $("#protect-button"); const protectButton = $("#protect-button");
const unprotectButton = $("#unprotect-button"); const unprotectButton = $("#unprotect-button");
const noteDetailWrapperEl = $("#note-detail-wrapper"); const noteDetailWrapperEl = $("#note-detail-wrapper");
const noteIdDisplayEl = $("#note-id-display"); const noteIdDisplayEl = $("#note-id-display");
let editor = null; let editor = null;
let codeEditor = null;
let currentNote = null; let currentNote = null;
@ -121,9 +123,25 @@ const noteEditor = (function() {
noteTitleEl.val(currentNote.detail.note_title); noteTitleEl.val(currentNote.detail.note_title);
console.log("Type: " + currentNote.detail.type);
if (currentNote.detail.type === 'text') {
// temporary workaround for https://github.com/ckeditor/ckeditor5-enter/issues/49 // temporary workaround for https://github.com/ckeditor/ckeditor5-enter/issues/49
editor.setData(currentNote.detail.note_text ? currentNote.detail.note_text : "<p></p>"); editor.setData(currentNote.detail.note_text ? currentNote.detail.note_text : "<p></p>");
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; noteChangeDisabled = false;
setNoteBackgroundIfProtected(currentNote); setNoteBackgroundIfProtected(currentNote);
@ -162,10 +180,33 @@ const noteEditor = (function() {
console.error(error); 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) // so that tab jumps from note title (which has tabindex 1)
noteDetailEl.attr("tabindex", 2); 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); setInterval(saveNoteIfChanged, 5000);
return { return {

View File

@ -77,7 +77,8 @@ async function importNotes(dir, parentNoteId) {
note_position: notePos, note_position: notePos,
is_expanded: 0, is_expanded: 0,
is_deleted: 0, is_deleted: 0,
date_modified: now date_modified: now,
type: 'text'
}); });
await sync_table.addNoteTreeSync(noteTreeId); await sync_table.addNoteTreeSync(noteTreeId);

View File

@ -10,6 +10,7 @@ const utils = require('../../services/utils');
const protected_session = require('../../services/protected_session'); const protected_session = require('../../services/protected_session');
const data_encryption = require('../../services/data_encryption'); const data_encryption = require('../../services/data_encryption');
const tree = require('../../services/tree'); const tree = require('../../services/tree');
const sync_table = require('../../services/sync_table');
const wrap = require('express-promise-wrap').wrap; const wrap = require('express-promise-wrap').wrap;
router.get('/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => { 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({}); 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; module.exports = router;

View File

@ -3,7 +3,7 @@
const build = require('./build'); const build = require('./build');
const packageJson = require('../package'); const packageJson = require('../package');
const APP_DB_VERSION = 67; const APP_DB_VERSION = 68;
module.exports = { module.exports = {
app_version: packageJson.version, app_version: packageJson.version,

View File

@ -208,6 +208,15 @@ async function runAllChecks() {
AND (note_title IS NULL OR note_text IS NULL)`, AND (note_title IS NULL OR note_text IS NULL)`,
"Note has null title or text", errorList); "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", "note_id", errorList);
await runSyncRowChecks("notes_history", "note_history_id", errorList); await runSyncRowChecks("notes_history", "note_history_id", errorList);
await runSyncRowChecks("notes_tree", "note_tree_id", errorList); await runSyncRowChecks("notes_tree", "note_tree_id", errorList);

View File

@ -22,6 +22,7 @@ async function getHashes() {
note_id, note_id,
note_title, note_title,
note_text, note_text,
type,
date_modified, date_modified,
is_protected, is_protected,
is_deleted is_deleted

View File

@ -38,9 +38,10 @@ async function createNewNote(parentNoteId, note, sourceId) {
note_id: noteId, note_id: noteId,
note_title: note.note_title, note_title: note.note_title,
note_text: note.note_text ? note.note_text : '', note_text: note.note_text ? note.note_text : '',
is_protected: note.is_protected,
type: 'text',
date_created: now, date_created: now,
date_modified: now, date_modified: now
is_protected: note.is_protected
}); });
await sync_table.addNoteSync(noteId, sourceId); await sync_table.addNoteSync(noteId, sourceId);

View File

@ -113,6 +113,8 @@
<div style="overflow: auto; grid-area: note-content; padding-left: 10px; padding-top: 10px;" id="note-detail-wrapper"> <div style="overflow: auto; grid-area: note-content; padding-left: 10px; padding-top: 10px;" id="note-detail-wrapper">
<div id="note-detail"></div> <div id="note-detail"></div>
<div id="note-detail-code"></div>
</div> </div>
</div> </div>
@ -423,6 +425,10 @@
<script src="libraries/knockout.min.js"></script> <script src="libraries/knockout.min.js"></script>
<script src="libraries/codemirror/codemirror.js"></script>
<link rel="stylesheet" href="libraries/codemirror/codemirror.css">
<script src="libraries/codemirror/mode/javascript/javascript.js"></script>
<link href="stylesheets/style.css" rel="stylesheet"> <link href="stylesheets/style.css" rel="stylesheet">
<script src="javascripts/utils.js"></script> <script src="javascripts/utils.js"></script>