mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	synchronous events, updating title works fully
This commit is contained in:
		| @@ -29,6 +29,7 @@ import RunScriptButtonsWidget from "../widgets/run_script_buttons.js"; | |||||||
| import ProtectedNoteSwitchWidget from "../widgets/protected_note_switch.js"; | import ProtectedNoteSwitchWidget from "../widgets/protected_note_switch.js"; | ||||||
| import NoteTypeWidget from "../widgets/note_type.js"; | import NoteTypeWidget from "../widgets/note_type.js"; | ||||||
| import NoteActionsWidget from "../widgets/note_actions.js"; | import NoteActionsWidget from "../widgets/note_actions.js"; | ||||||
|  | import protectedSessionHolder from "./protected_session_holder.js"; | ||||||
|  |  | ||||||
| class AppContext { | class AppContext { | ||||||
|     constructor() { |     constructor() { | ||||||
| @@ -116,23 +117,23 @@ class AppContext { | |||||||
|         ]; |         ]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     trigger(name, data) { |     trigger(name, data, sync = false) { | ||||||
|         this.eventReceived(name, data); |         this.eventReceived(name, data); | ||||||
|  |  | ||||||
|         for (const tabContext of this.tabContexts) { |         for (const tabContext of this.tabContexts) { | ||||||
|             tabContext.eventReceived(name, data); |             tabContext.eventReceived(name, data, sync); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         for (const widget of this.widgets) { |         for (const widget of this.widgets) { | ||||||
|             widget.eventReceived(name, data); |             widget.eventReceived(name, data, sync); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     eventReceived(name, data) { |     async eventReceived(name, data, sync) { | ||||||
|         const fun = this[name + 'Listener']; |         const fun = this[name + 'Listener']; | ||||||
|  |  | ||||||
|         if (typeof fun === 'function') { |         if (typeof fun === 'function') { | ||||||
|             fun.call(this, data); |             await fun.call(this, data, sync); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -347,6 +348,18 @@ class AppContext { | |||||||
|     tabReorderListener() { |     tabReorderListener() { | ||||||
|         this.openTabsChanged(); |         this.openTabsChanged(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     noteChangesSavedListener() { | ||||||
|  |         const activeTabContext = this.getActiveTabContext(); | ||||||
|  |  | ||||||
|  |         if (!activeTabContext || !activeTabContext.note) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (activeTabContext.note.isProtected && protectedSessionHolder.isProtectedSessionAvailable()) { | ||||||
|  |             protectedSessionHolder.touchProtectedSession(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| const appContext = new AppContext(); | const appContext = new AppContext(); | ||||||
|   | |||||||
| @@ -36,6 +36,8 @@ class TabContext extends Component { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async setNote(notePath) { |     async setNote(notePath) { | ||||||
|  |         await this.trigger('beforeNoteSwitch', {tabId: this.tabId}, true); | ||||||
|  |  | ||||||
|         this.notePath = notePath; |         this.notePath = notePath; | ||||||
|         const noteId = treeUtils.getNoteIdFromNotePath(notePath); |         const noteId = treeUtils.getNoteIdFromNotePath(notePath); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ export default class Component { | |||||||
|         this.initialized = Promise.resolve(); |         this.initialized = Promise.resolve(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async eventReceived(name, data) { |     async eventReceived(name, data, sync = false) { | ||||||
|         await this.initialized; |         await this.initialized; | ||||||
|  |  | ||||||
| //        console.log(`Received ${name} to ${this.componentId}`); | //        console.log(`Received ${name} to ${this.componentId}`); | ||||||
| @@ -23,12 +23,16 @@ export default class Component { | |||||||
|  |  | ||||||
|         if (propagateToChildren) { |         if (propagateToChildren) { | ||||||
|             for (const child of this.children) { |             for (const child of this.children) { | ||||||
|                 child.eventReceived(name, data); |                 let promise = child.eventReceived(name, data, sync); | ||||||
|  |  | ||||||
|  |                 if (sync) { | ||||||
|  |                     await promise; | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     trigger(name, data) { |     trigger(name, data, sync = false) { | ||||||
|         this.appContext.trigger(name, data); |         this.appContext.trigger(name, data, sync); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -31,15 +31,13 @@ class NoteInfoWidget extends StandardWidget { | |||||||
|         this.$body.html(TPL); |         this.$body.html(TPL); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     refreshWithNote() { |     refreshWithNote(note) { | ||||||
|         const $noteId = this.$body.find(".note-info-note-id"); |         const $noteId = this.$body.find(".note-info-note-id"); | ||||||
|         const $dateCreated = this.$body.find(".note-info-date-created"); |         const $dateCreated = this.$body.find(".note-info-date-created"); | ||||||
|         const $dateModified = this.$body.find(".note-info-date-modified"); |         const $dateModified = this.$body.find(".note-info-date-modified"); | ||||||
|         const $type = this.$body.find(".note-info-type"); |         const $type = this.$body.find(".note-info-type"); | ||||||
|         const $mime = this.$body.find(".note-info-mime"); |         const $mime = this.$body.find(".note-info-mime"); | ||||||
|  |  | ||||||
|         const note = this.tabContext.note; |  | ||||||
|  |  | ||||||
|         $noteId.text(note.noteId); |         $noteId.text(note.noteId); | ||||||
|         $dateCreated |         $dateCreated | ||||||
|             .text(note.dateCreated) |             .text(note.dateCreated) | ||||||
| @@ -56,6 +54,15 @@ class NoteInfoWidget extends StandardWidget { | |||||||
|             .attr("title", note.mime); |             .attr("title", note.mime); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // this is interesting for this widget since dateModified had to change after update | ||||||
|  |     noteChangesSavedListener({noteId}) { | ||||||
|  |         const note = this.tabContext.note; | ||||||
|  |  | ||||||
|  |         if (note && note.noteId === noteId) { | ||||||
|  |             this.refreshWithNote(note); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     syncDataListener({data}) { |     syncDataListener({data}) { | ||||||
|         if (data.find(sd => sd.entityName === 'notes' && sd.entityId === this.tabContext.note.noteId)) { |         if (data.find(sd => sd.entityName === 'notes' && sd.entityId === this.tabContext.note.noteId)) { | ||||||
|             this.refresh(); |             this.refresh(); | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ import TabAwareWidget from "./tab_aware_widget.js"; | |||||||
| import utils from "../services/utils.js"; | import utils from "../services/utils.js"; | ||||||
| import protectedSessionHolder from "../services/protected_session_holder.js"; | import protectedSessionHolder from "../services/protected_session_holder.js"; | ||||||
| import treeCache from "../services/tree_cache.js"; | import treeCache from "../services/tree_cache.js"; | ||||||
|  | import server from "../services/server.js"; | ||||||
|  |  | ||||||
| const TPL = ` | const TPL = ` | ||||||
| <div class="note-title-container"> | <div class="note-title-container"> | ||||||
| @@ -23,7 +24,61 @@ const TPL = ` | |||||||
|     <input autocomplete="off" value="" class="note-title" tabindex="1"> |     <input autocomplete="off" value="" class="note-title" tabindex="1"> | ||||||
| </div>`; | </div>`; | ||||||
|  |  | ||||||
|  | class SpacedUpdate { | ||||||
|  |     constructor(updater, updateInterval = 1000) { | ||||||
|  |         this.updater = updater; | ||||||
|  |         this.lastUpdated = Date.now(); | ||||||
|  |         this.changed = false; | ||||||
|  |         this.updateInterval = updateInterval; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     scheduleUpdate() { | ||||||
|  |         this.changed = true; | ||||||
|  |         setTimeout(() => this.triggerUpdate()) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async updateNowIfNecessary() { | ||||||
|  |         if (this.changed) { | ||||||
|  |             this.changed = false; | ||||||
|  |             await this.updater(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     triggerUpdate() { | ||||||
|  |         if (!this.changed) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (Date.now() - this.lastUpdated > this.updateInterval) { | ||||||
|  |             this.updater(); | ||||||
|  |             this.lastUpdated = Date.now(); | ||||||
|  |             this.changed = false; | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             // update not triggered but changes are still pending so we need to schedule another check | ||||||
|  |             this.scheduleUpdate(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| export default class NoteTitleWidget extends TabAwareWidget { | export default class NoteTitleWidget extends TabAwareWidget { | ||||||
|  |     constructor(appContext) { | ||||||
|  |         super(appContext); | ||||||
|  |  | ||||||
|  |         this.spacedUpdate = new SpacedUpdate(async () => { | ||||||
|  |             const noteId = this.tabContext.note.noteId; | ||||||
|  |             const title = this.$noteTitle.val(); | ||||||
|  |  | ||||||
|  |             const resp = await server.put(`notes/${noteId}/change-title`, {title}); | ||||||
|  |  | ||||||
|  |             // FIXME: minor - does not propagate to other tab contexts with this note though | ||||||
|  |             this.tabContext.note.dateModified = resp.dateModified; | ||||||
|  |             this.tabContext.note.utcDateModified = resp.utcDateModified; | ||||||
|  |  | ||||||
|  |             this.trigger('noteChangesSaved', {noteId}) | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     doRender() { |     doRender() { | ||||||
|         this.$widget = $(TPL); |         this.$widget = $(TPL); | ||||||
|         this.$noteTitle = this.$widget.find(".note-title"); |         this.$noteTitle = this.$widget.find(".note-title"); | ||||||
| @@ -46,6 +101,8 @@ export default class NoteTitleWidget extends TabAwareWidget { | |||||||
|  |  | ||||||
|         note.title = this.$noteTitle.val(); |         note.title = this.$noteTitle.val(); | ||||||
|  |  | ||||||
|  |         this.spacedUpdate.scheduleUpdate(); | ||||||
|  |  | ||||||
|         const noteFromCache = await treeCache.getNote(note.noteId); |         const noteFromCache = await treeCache.getNote(note.noteId); | ||||||
|         noteFromCache.title = note.title; |         noteFromCache.title = note.title; | ||||||
|  |  | ||||||
| @@ -74,4 +131,10 @@ export default class NoteTitleWidget extends TabAwareWidget { | |||||||
|             this.$noteTitle.prop("readonly", true); |             this.$noteTitle.prop("readonly", true); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     async beforeNoteSwitch({tabId}) { | ||||||
|  |         if (this.isTab(tabId)) { | ||||||
|  |             await this.spacedUpdate.updateNowIfNecessary(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| @@ -450,8 +450,6 @@ export default class NoteTreeWidget extends TabAwareWidget { | |||||||
|  |  | ||||||
|     noteTitleChangedListener({noteId}) { |     noteTitleChangedListener({noteId}) { | ||||||
|         for (const node of this.getNodesByNoteId(noteId)) { |         for (const node of this.getNodesByNoteId(noteId)) { | ||||||
|             console.log("Setting to", node); |  | ||||||
|  |  | ||||||
|             treeService.setNodeTitleWithPrefix(node); |             treeService.setNodeTitleWithPrefix(node); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -8,8 +8,16 @@ export default class TabAwareWidget extends BasicWidget { | |||||||
|         this.noteSwitched(); |         this.noteSwitched(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     isTab(tabId) { | ||||||
|  |         return this.tabContext && this.tabContext.tabId === tabId; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     isNote(noteId) { | ||||||
|  |         return this.tabContext && this.tabContext.note && this.tabContext.note.noteId === noteId; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     tabNoteSwitchedListener({tabId}) { |     tabNoteSwitchedListener({tabId}) { | ||||||
|         if (this.tabContext && tabId === this.tabContext.tabId) { |         if (this.isTab(tabId)) { | ||||||
|             this.noteSwitched(); |             this.noteSwitched(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -170,6 +170,8 @@ async function changeTitle(req) { | |||||||
|     note.title = title; |     note.title = title; | ||||||
|  |  | ||||||
|     await note.save(); |     await note.save(); | ||||||
|  |  | ||||||
|  |     return note; | ||||||
| } | } | ||||||
|  |  | ||||||
| async function duplicateNote(req) { | async function duplicateNote(req) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user