mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +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 NoteTypeWidget from "../widgets/note_type.js"; | ||||
| import NoteActionsWidget from "../widgets/note_actions.js"; | ||||
| import protectedSessionHolder from "./protected_session_holder.js"; | ||||
|  | ||||
| class AppContext { | ||||
|     constructor() { | ||||
| @@ -116,23 +117,23 @@ class AppContext { | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     trigger(name, data) { | ||||
|     trigger(name, data, sync = false) { | ||||
|         this.eventReceived(name, data); | ||||
|  | ||||
|         for (const tabContext of this.tabContexts) { | ||||
|             tabContext.eventReceived(name, data); | ||||
|             tabContext.eventReceived(name, data, sync); | ||||
|         } | ||||
|  | ||||
|         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']; | ||||
|  | ||||
|         if (typeof fun === 'function') { | ||||
|             fun.call(this, data); | ||||
|             await fun.call(this, data, sync); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -347,6 +348,18 @@ class AppContext { | ||||
|     tabReorderListener() { | ||||
|         this.openTabsChanged(); | ||||
|     } | ||||
|  | ||||
|     noteChangesSavedListener() { | ||||
|         const activeTabContext = this.getActiveTabContext(); | ||||
|  | ||||
|         if (!activeTabContext || !activeTabContext.note) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (activeTabContext.note.isProtected && protectedSessionHolder.isProtectedSessionAvailable()) { | ||||
|             protectedSessionHolder.touchProtectedSession(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| const appContext = new AppContext(); | ||||
|   | ||||
| @@ -36,6 +36,8 @@ class TabContext extends Component { | ||||
|     } | ||||
|  | ||||
|     async setNote(notePath) { | ||||
|         await this.trigger('beforeNoteSwitch', {tabId: this.tabId}, true); | ||||
|  | ||||
|         this.notePath = notePath; | ||||
|         const noteId = treeUtils.getNoteIdFromNotePath(notePath); | ||||
|  | ||||
|   | ||||
| @@ -8,7 +8,7 @@ export default class Component { | ||||
|         this.initialized = Promise.resolve(); | ||||
|     } | ||||
|  | ||||
|     async eventReceived(name, data) { | ||||
|     async eventReceived(name, data, sync = false) { | ||||
|         await this.initialized; | ||||
|  | ||||
| //        console.log(`Received ${name} to ${this.componentId}`); | ||||
| @@ -23,12 +23,16 @@ export default class Component { | ||||
|  | ||||
|         if (propagateToChildren) { | ||||
|             for (const child of this.children) { | ||||
|                 child.eventReceived(name, data); | ||||
|                 let promise = child.eventReceived(name, data, sync); | ||||
|  | ||||
|                 if (sync) { | ||||
|                     await promise; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     trigger(name, data) { | ||||
|         this.appContext.trigger(name, data); | ||||
|     trigger(name, data, sync = false) { | ||||
|         this.appContext.trigger(name, data, sync); | ||||
|     } | ||||
| } | ||||
| @@ -31,15 +31,13 @@ class NoteInfoWidget extends StandardWidget { | ||||
|         this.$body.html(TPL); | ||||
|     } | ||||
|  | ||||
|     refreshWithNote() { | ||||
|     refreshWithNote(note) { | ||||
|         const $noteId = this.$body.find(".note-info-note-id"); | ||||
|         const $dateCreated = this.$body.find(".note-info-date-created"); | ||||
|         const $dateModified = this.$body.find(".note-info-date-modified"); | ||||
|         const $type = this.$body.find(".note-info-type"); | ||||
|         const $mime = this.$body.find(".note-info-mime"); | ||||
|  | ||||
|         const note = this.tabContext.note; | ||||
|  | ||||
|         $noteId.text(note.noteId); | ||||
|         $dateCreated | ||||
|             .text(note.dateCreated) | ||||
| @@ -56,6 +54,15 @@ class NoteInfoWidget extends StandardWidget { | ||||
|             .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}) { | ||||
|         if (data.find(sd => sd.entityName === 'notes' && sd.entityId === this.tabContext.note.noteId)) { | ||||
|             this.refresh(); | ||||
|   | ||||
| @@ -2,6 +2,7 @@ import TabAwareWidget from "./tab_aware_widget.js"; | ||||
| import utils from "../services/utils.js"; | ||||
| import protectedSessionHolder from "../services/protected_session_holder.js"; | ||||
| import treeCache from "../services/tree_cache.js"; | ||||
| import server from "../services/server.js"; | ||||
|  | ||||
| const TPL = ` | ||||
| <div class="note-title-container"> | ||||
| @@ -23,7 +24,61 @@ const TPL = ` | ||||
|     <input autocomplete="off" value="" class="note-title" tabindex="1"> | ||||
| </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 { | ||||
|     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() { | ||||
|         this.$widget = $(TPL); | ||||
|         this.$noteTitle = this.$widget.find(".note-title"); | ||||
| @@ -46,6 +101,8 @@ export default class NoteTitleWidget extends TabAwareWidget { | ||||
|  | ||||
|         note.title = this.$noteTitle.val(); | ||||
|  | ||||
|         this.spacedUpdate.scheduleUpdate(); | ||||
|  | ||||
|         const noteFromCache = await treeCache.getNote(note.noteId); | ||||
|         noteFromCache.title = note.title; | ||||
|  | ||||
| @@ -74,4 +131,10 @@ export default class NoteTitleWidget extends TabAwareWidget { | ||||
|             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}) { | ||||
|         for (const node of this.getNodesByNoteId(noteId)) { | ||||
|             console.log("Setting to", node); | ||||
|  | ||||
|             treeService.setNodeTitleWithPrefix(node); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -8,8 +8,16 @@ export default class TabAwareWidget extends BasicWidget { | ||||
|         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}) { | ||||
|         if (this.tabContext && tabId === this.tabContext.tabId) { | ||||
|         if (this.isTab(tabId)) { | ||||
|             this.noteSwitched(); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -170,6 +170,8 @@ async function changeTitle(req) { | ||||
|     note.title = title; | ||||
|  | ||||
|     await note.save(); | ||||
|  | ||||
|     return note; | ||||
| } | ||||
|  | ||||
| async function duplicateNote(req) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user