diff --git a/db/migrations/0136__update_recent_notes.sql b/db/migrations/0136__update_recent_notes.sql new file mode 100644 index 000000000..c3397597f --- /dev/null +++ b/db/migrations/0136__update_recent_notes.sql @@ -0,0 +1,12 @@ +drop table recent_notes; + +create table recent_notes +( + noteId TEXT not null primary key, + notePath TEXT not null, + hash TEXT default "" not null, + utcDateCreated TEXT not null, + isDeleted INT +); + +delete from sync where entityName = 'recent_notes'; \ No newline at end of file diff --git a/docs/backend_api/RecentNote.html b/docs/backend_api/RecentNote.html index 7e4fe023e..0e310241b 100644 --- a/docs/backend_api/RecentNote.html +++ b/docs/backend_api/RecentNote.html @@ -28,7 +28,7 @@
-

RecentNote(branchId, notePath, isDeleted, utcDateModified)

+

RecentNote(noteId, notePath, isDeleted, utcDateModified)

RecentNote represents recently visited note.
@@ -45,7 +45,7 @@ -

new RecentNote(branchId, notePath, isDeleted, utcDateModified)

+

new RecentNote(noteId, notePath, isDeleted, utcDateModified)

@@ -85,7 +85,7 @@ - branchId + noteId diff --git a/docs/backend_api/entities_recent_note.js.html b/docs/backend_api/entities_recent_note.js.html index b8e6177ad..79e160eb9 100644 --- a/docs/backend_api/entities_recent_note.js.html +++ b/docs/backend_api/entities_recent_note.js.html @@ -34,7 +34,7 @@ const dateUtils = require('../services/date_utils'); /** * RecentNote represents recently visited note. * - * @param {string} branchId + * @param {string} noteId * @param {string} notePath * @param {boolean} isDeleted * @param {string} utcDateModified @@ -43,8 +43,8 @@ const dateUtils = require('../services/date_utils'); */ class RecentNote extends Entity { static get entityName() { return "recent_notes"; } - static get primaryKeyName() { return "branchId"; } - static get hashedProperties() { return ["branchId", "notePath", "utcDateCreated", "isDeleted"]; } + static get primaryKeyName() { return "noteId"; } + static get hashedProperties() { return ["noteId", "notePath", "utcDateCreated", "isDeleted"]; } beforeSaving() { if (!this.isDeleted) { diff --git a/docs/frontend_api/FrontendScriptApi.html b/docs/frontend_api/FrontendScriptApi.html index 2ed05931c..a7a0842e8 100644 --- a/docs/frontend_api/FrontendScriptApi.html +++ b/docs/frontend_api/FrontendScriptApi.html @@ -461,6 +461,115 @@ + +

tabContext

+ + + + + + + + + + +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeDescription
+ + +TabContext +| + +null + + + + experimental!
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + @@ -573,7 +682,7 @@
Source:
@@ -726,7 +835,7 @@
Source:
@@ -879,7 +988,7 @@
Source:
@@ -1057,7 +1166,7 @@
Source:
@@ -1188,7 +1297,7 @@
Source:
@@ -1292,7 +1401,7 @@
Source:
@@ -1348,7 +1457,7 @@ -

getActiveNoteContent() → {string}

+

getActiveNotePath() → {Promise.<(string|null)>}

@@ -1396,7 +1505,7 @@
Source:
@@ -1423,7 +1532,7 @@
- content of active note (loaded into right pane) + returns note path of active note or null if there isn't active note
@@ -1434,111 +1543,7 @@
-string - - -
- - - - - - - - - - - - - - -

getActiveNotePath() → {Promise.<string>}

- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
Returns:
- - -
- returns note path of active note -
- - - -
-
- Type -
-
- -Promise.<string> +Promise.<(string|null)>
@@ -1604,7 +1609,7 @@
Source:
@@ -1761,7 +1766,7 @@
Source:
@@ -1861,7 +1866,7 @@
Source:
@@ -1970,7 +1975,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -2123,7 +2128,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -2277,7 +2282,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -2476,7 +2481,7 @@ otherwise (by e.g. createNoteLink())
Source:
@@ -2580,7 +2585,7 @@ otherwise (by e.g. createNoteLink())
Source:
@@ -2733,7 +2738,7 @@ otherwise (by e.g. createNoteLink())
Source:
@@ -2840,7 +2845,7 @@ note.
Source:
@@ -2993,7 +2998,7 @@ note.
Source:
@@ -3124,7 +3129,7 @@ note.
Source:
@@ -3228,7 +3233,7 @@ note.
Source:
@@ -3314,7 +3319,7 @@ note.
Source:
@@ -3463,7 +3468,7 @@ note.
Source:
@@ -3594,7 +3599,7 @@ note.
Source:
@@ -3753,7 +3758,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -3911,7 +3916,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -4065,7 +4070,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -4214,7 +4219,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -4345,7 +4350,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -4480,7 +4485,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
@@ -4615,7 +4620,7 @@ Internally this serializes the anonymous function into string and sends it to ba
Source:
diff --git a/docs/frontend_api/global.html b/docs/frontend_api/global.html index 104db4601..636c6101d 100644 --- a/docs/frontend_api/global.html +++ b/docs/frontend_api/global.html @@ -303,7 +303,7 @@
Source:
diff --git a/docs/frontend_api/services_frontend_script_api.js.html b/docs/frontend_api/services_frontend_script_api.js.html index be54b8405..62ff12f08 100644 --- a/docs/frontend_api/services_frontend_script_api.js.html +++ b/docs/frontend_api/services_frontend_script_api.js.html @@ -44,7 +44,7 @@ import dateNotesService from'./date_notes.js'; * @constructor * @hideconstructor */ -function FrontendScriptApi(startNote, currentNote, originEntity = null) { +function FrontendScriptApi(startNote, currentNote, originEntity = null, tabContext = null) { const $pluginButtons = $("#plugin-buttons"); /** @property {object} note where script started executing */ @@ -57,6 +57,9 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) { // to keep consistency with backend API this.dayjs = dayjs; + /** @property {TabContext|null} - experimental! */ + this.tabContext = tabContext; + /** * Activates note in the tree and in the note detail. * @@ -282,12 +285,6 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) { */ this.createNoteLink = linkService.createNoteLink; - /** - * @method - * @returns {string} content of active note (loaded into right pane) - */ - this.getActiveNoteContent = noteDetailService.getActiveNoteContent; - /** * @method * @returns {NoteFull} active note (loaded into right pane) @@ -296,9 +293,13 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) { /** * @method - * @returns {Promise<string>} returns note path of active note + * @returns {Promise<string|null>} returns note path of active note or null if there isn't active note */ - this.getActiveNotePath = treeService.getActiveNotePath; + this.getActiveNotePath = () => { + const activeTabContext = noteDetailService.getActiveTabContext(); + + return activeTabContext ? activeTabContext.notePath : null; + }; /** * This method checks whether user navigated away from the note from which the scripts has been started. diff --git a/src/entities/recent_note.js b/src/entities/recent_note.js index fd58894d4..eab6cb77a 100644 --- a/src/entities/recent_note.js +++ b/src/entities/recent_note.js @@ -6,7 +6,7 @@ const dateUtils = require('../services/date_utils'); /** * RecentNote represents recently visited note. * - * @param {string} branchId + * @param {string} noteId * @param {string} notePath * @param {boolean} isDeleted * @param {string} utcDateModified @@ -15,8 +15,8 @@ const dateUtils = require('../services/date_utils'); */ class RecentNote extends Entity { static get entityName() { return "recent_notes"; } - static get primaryKeyName() { return "branchId"; } - static get hashedProperties() { return ["branchId", "notePath", "utcDateCreated", "isDeleted"]; } + static get primaryKeyName() { return "noteId"; } + static get hashedProperties() { return ["noteId", "notePath", "utcDateCreated", "isDeleted"]; } beforeSaving() { if (!this.isDeleted) { diff --git a/src/public/javascripts/services/tab_context.js b/src/public/javascripts/services/tab_context.js index c751e246c..4a8f45b65 100644 --- a/src/public/javascripts/services/tab_context.js +++ b/src/public/javascripts/services/tab_context.js @@ -94,6 +94,7 @@ class TabContext { this.attributes.invalidateAttributes(); + this.$noteTitleRow.show(); // might be hidden from empty detail this.$tabContent.toggleClass("protected", this.note.isProtected); this.$protectButton.toggleClass("active", this.note.isProtected); this.$protectButton.prop("disabled", this.note.isProtected); @@ -106,8 +107,11 @@ class TabContext { setTimeout(async () => { // we include the note into recent list only if the user stayed on the note at least 5 seconds - if (notePath && notePath === await this.notePath) { - await server.post('recent-notes', { notePath }); + if (notePath && notePath === this.notePath) { + await server.post('recent-notes', { + noteId: this.noteId, + notePath: this.notePath + }); } }, 5000); diff --git a/src/routes/api/autocomplete.js b/src/routes/api/autocomplete.js index 5b7d326ae..4e9e4e5ba 100644 --- a/src/routes/api/autocomplete.js +++ b/src/routes/api/autocomplete.js @@ -43,11 +43,11 @@ async function getRecentNotes(activeNoteId) { recent_notes.* FROM recent_notes - JOIN branches USING(branchId) + JOIN notes USING(noteId) WHERE recent_notes.isDeleted = 0 - AND branches.isDeleted = 0 - AND branches.noteId != ? + AND notes.isDeleted = 0 + AND notes.noteId != ? ${extraCondition} ORDER BY utcDateCreated DESC diff --git a/src/routes/api/recent_notes.js b/src/routes/api/recent_notes.js index 280dadbad..436367964 100644 --- a/src/routes/api/recent_notes.js +++ b/src/routes/api/recent_notes.js @@ -3,12 +3,9 @@ const RecentNote = require('../../entities/recent_note'); async function addRecentNote(req) { - const branchId = req.body.branchId; - const notePath = req.body.notePath; - await new RecentNote({ - branchId: branchId, - notePath: notePath + noteId: req.body.noteId, + notePath: req.body.notePath }).save(); } diff --git a/src/routes/api/sync.js b/src/routes/api/sync.js index f77786548..48a4f1e5b 100644 --- a/src/routes/api/sync.js +++ b/src/routes/api/sync.js @@ -78,13 +78,14 @@ async function forceNoteSync(req) { for (const branchId of await sql.getColumn("SELECT branchId FROM branches WHERE isDeleted = 0 AND noteId = ?", [noteId])) { await syncTableService.addBranchSync(branchId); - await syncTableService.addRecentNoteSync(branchId); } for (const noteRevisionId of await sql.getColumn("SELECT noteRevisionId FROM note_revisions WHERE noteId = ?", [noteId])) { await syncTableService.addNoteRevisionSync(noteRevisionId); } + await syncTableService.addRecentNoteSync(noteId); + log.info("Forcing note sync for " + noteId); // not awaiting for the job to finish (will probably take a long time) diff --git a/src/services/app_info.js b/src/services/app_info.js index 3d4443583..2787ba67c 100644 --- a/src/services/app_info.js +++ b/src/services/app_info.js @@ -4,8 +4,8 @@ const build = require('./build'); const packageJson = require('../../package'); const {TRILIUM_DATA_DIR} = require('./data_dir'); -const APP_DB_VERSION = 135; -const SYNC_VERSION = 8; +const APP_DB_VERSION = 136; +const SYNC_VERSION = 9; module.exports = { appVersion: packageJson.version, diff --git a/src/services/consistency_checks.js b/src/services/consistency_checks.js index b09544d5e..e326264fa 100644 --- a/src/services/consistency_checks.js +++ b/src/services/consistency_checks.js @@ -396,7 +396,7 @@ async function findSyncRowsIssues() { await runSyncRowChecks("note_contents", "noteId"); await runSyncRowChecks("note_revisions", "noteRevisionId"); await runSyncRowChecks("branches", "branchId"); - await runSyncRowChecks("recent_notes", "branchId"); + await runSyncRowChecks("recent_notes", "noteId"); await runSyncRowChecks("attributes", "attributeId"); await runSyncRowChecks("api_tokens", "apiTokenId"); await runSyncRowChecks("options", "name"); diff --git a/src/services/sync.js b/src/services/sync.js index 14b950fa5..28cfdc3af 100644 --- a/src/services/sync.js +++ b/src/services/sync.js @@ -246,7 +246,7 @@ const primaryKeys = { "note_contents": "noteId", "branches": "branchId", "note_revisions": "noteRevisionId", - "recent_notes": "branchId", + "recent_notes": "noteId", "api_tokens": "apiTokenId", "options": "name", "attributes": "attributeId", diff --git a/src/services/sync_table.js b/src/services/sync_table.js index 050815111..4ac6b5972 100644 --- a/src/services/sync_table.js +++ b/src/services/sync_table.js @@ -28,8 +28,8 @@ async function addOptionsSync(name, sourceId) { await addEntitySync("options", name, sourceId); } -async function addRecentNoteSync(branchId, sourceId) { - await addEntitySync("recent_notes", branchId, sourceId); +async function addRecentNoteSync(noteId, sourceId) { + await addEntitySync("recent_notes", noteId, sourceId); } async function addLinkSync(linkId, sourceId) { @@ -91,7 +91,7 @@ async function fillAllSyncRows() { await fillSyncRows("note_contents", "noteId"); await fillSyncRows("branches", "branchId"); await fillSyncRows("note_revisions", "noteRevisionId"); - await fillSyncRows("recent_notes", "branchId"); + await fillSyncRows("recent_notes", "noteId"); await fillSyncRows("attributes", "attributeId"); await fillSyncRows("api_tokens", "apiTokenId"); await fillSyncRows("links", "linkId"); diff --git a/src/services/sync_update.js b/src/services/sync_update.js index 34a4659fc..548675357 100644 --- a/src/services/sync_update.js +++ b/src/services/sync_update.js @@ -148,13 +148,13 @@ async function updateOptions(entity, sourceId) { } async function updateRecentNotes(entity, sourceId) { - const orig = await sql.getRowOrNull("SELECT * FROM recent_notes WHERE branchId = ?", [entity.branchId]); + const orig = await sql.getRowOrNull("SELECT * FROM recent_notes WHERE noteId = ?", [entity.noteId]); if (orig === null || orig.utcDateCreated < entity.utcDateCreated) { await sql.transactional(async () => { await sql.replace('recent_notes', entity); - await syncTableService.addRecentNoteSync(entity.branchId, sourceId); + await syncTableService.addRecentNoteSync(entity.noteId, sourceId); }); } }