mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
saving note detail
This commit is contained in:
parent
562c729ed6
commit
423a70d102
@ -27,8 +27,6 @@ async function openInTab(notePath, activate) {
|
||||
}
|
||||
|
||||
async function switchToNote(notePath) {
|
||||
await saveNotesIfChanged();
|
||||
|
||||
await loadNoteDetail(notePath);
|
||||
|
||||
appContext.openTabsChanged();
|
||||
@ -38,15 +36,6 @@ function onNoteChange(func) {
|
||||
return appContext.getActiveTabContext().getComponent().onNoteChange(func);
|
||||
}
|
||||
|
||||
async function saveNotesIfChanged() {
|
||||
for (const ctx of appContext.getTabContexts()) {
|
||||
await ctx.saveNoteIfChanged();
|
||||
}
|
||||
|
||||
// make sure indicator is visible in a case there was some race condition.
|
||||
$savedIndicator.fadeIn();
|
||||
}
|
||||
|
||||
function getActiveEditor() {
|
||||
const activeTabContext = appContext.getActiveTabContext();
|
||||
|
||||
@ -210,10 +199,9 @@ function noteChanged() {
|
||||
|
||||
// this makes sure that when user e.g. reloads the page or navigates away from the page, the note's content is saved
|
||||
// this sends the request asynchronously and doesn't wait for result
|
||||
// FIXME
|
||||
$(window).on('beforeunload', () => { saveNotesIfChanged(); }); // don't convert to short form, handler doesn't like returned promise
|
||||
|
||||
setInterval(saveNotesIfChanged, 3000);
|
||||
|
||||
export default {
|
||||
reload,
|
||||
openInTab,
|
||||
@ -222,7 +210,6 @@ export default {
|
||||
loadNoteDetail,
|
||||
focusOnTitle,
|
||||
focusAndSelectTitle,
|
||||
saveNotesIfChanged,
|
||||
onNoteChange,
|
||||
addDetailLoadedListener,
|
||||
getActiveEditor,
|
||||
|
36
src/public/javascripts/services/spaced_update.js
Normal file
36
src/public/javascripts/services/spaced_update.js
Normal file
@ -0,0 +1,36 @@
|
||||
export default 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();
|
||||
}
|
||||
}
|
||||
}
|
@ -26,7 +26,6 @@ class TabContext extends Component {
|
||||
|
||||
this.tabRow = tabRow;
|
||||
this.tabId = state.tabId || utils.randomString(4);
|
||||
this.$tab = $(this.tabRow.addTab(this.tabId));
|
||||
this.state = state;
|
||||
|
||||
this.attributes = new Attributes(this.appContext, this);
|
||||
|
@ -374,6 +374,7 @@ async function createNote(node, parentNoteId, target, extraOptions = {}) {
|
||||
window.cutToNote.removeSelection();
|
||||
}
|
||||
|
||||
// FIXME
|
||||
await noteDetailService.saveNotesIfChanged();
|
||||
|
||||
noteDetailService.addDetailLoadedListener(note.noteId, noteDetailService.focusAndSelectTitle);
|
||||
|
@ -2,6 +2,8 @@ import TabAwareWidget from "./tab_aware_widget.js";
|
||||
import utils from "../services/utils.js";
|
||||
import protectedSessionHolder from "../services/protected_session_holder.js";
|
||||
import appContext from "../services/app_context.js";
|
||||
import SpacedUpdate from "../services/spaced_update.js";
|
||||
import server from "../services/server.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="note-detail">
|
||||
@ -32,6 +34,19 @@ export default class NoteDetailWidget extends TabAwareWidget {
|
||||
|
||||
this.typeWidgets = {};
|
||||
this.typeWidgetPromises = {};
|
||||
|
||||
this.spacedUpdate = new SpacedUpdate(async () => {
|
||||
const note = this.tabContext.note;
|
||||
note.content = this.getTypeWidget().getContent();
|
||||
|
||||
const resp = await server.put('notes/' + note.noteId, note.dto);
|
||||
|
||||
// FIXME: minor - does not propagate to other tab contexts with this note though
|
||||
note.dateModified = resp.dateModified;
|
||||
note.utcDateModified = resp.utcDateModified;
|
||||
|
||||
this.trigger('noteChangesSaved', {noteId: note.noteId})
|
||||
});
|
||||
}
|
||||
|
||||
doRender() {
|
||||
@ -114,12 +129,14 @@ export default class NoteDetailWidget extends TabAwareWidget {
|
||||
async initWidgetType(type) {
|
||||
const clazz = await import(typeWidgetClasses[type]);
|
||||
|
||||
this.typeWidgets[this.type] = new clazz.default(this.appContext);
|
||||
this.children.push(this.typeWidgets[this.type]);
|
||||
const typeWidget = this.typeWidgets[this.type] = new clazz.default(this.appContext);
|
||||
this.children.push(typeWidget);
|
||||
|
||||
this.$widget.append(this.typeWidgets[this.type].render());
|
||||
this.$widget.append(typeWidget.render());
|
||||
|
||||
this.typeWidgets[this.type].eventReceived('setTabContext', {tabContext: this.tabContext});
|
||||
typeWidget.onNoteChange(() => this.spacedUpdate.scheduleUpdate());
|
||||
|
||||
typeWidget.eventReceived('setTabContext', {tabContext: this.tabContext});
|
||||
}
|
||||
|
||||
getWidgetType(disableAutoBook) {
|
||||
@ -153,4 +170,16 @@ export default class NoteDetailWidget extends TabAwareWidget {
|
||||
widget.focus();
|
||||
}
|
||||
}
|
||||
|
||||
async beforeNoteSwitchListener({tabId}) {
|
||||
if (this.isTab(tabId)) {
|
||||
await this.spacedUpdate.updateNowIfNecessary();
|
||||
}
|
||||
}
|
||||
|
||||
async beforeTabRemoveListener({tabId}) {
|
||||
if (this.isTab(tabId)) {
|
||||
await this.spacedUpdate.updateNowIfNecessary();
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ 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";
|
||||
import SpacedUpdate from "../services/spaced_update.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="note-title-container">
|
||||
@ -24,43 +25,6 @@ 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);
|
||||
|
@ -109,6 +109,7 @@ class CodeTypeWidget extends TypeWidget {
|
||||
}
|
||||
|
||||
// make sure note is saved so we load latest changes
|
||||
// FIXME
|
||||
await noteDetailService.saveNotesIfChanged();
|
||||
|
||||
if (this.tabContext.note.mime.endsWith("env=frontend")) {
|
||||
@ -122,7 +123,9 @@ class CodeTypeWidget extends TypeWidget {
|
||||
toastService.showMessage("Note executed");
|
||||
}
|
||||
|
||||
onNoteChange(func) {
|
||||
async onNoteChange(func) {
|
||||
await this.initialized;
|
||||
|
||||
this.codeEditor.on('change', func);
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ class NoteDetailSearch {
|
||||
this.$refreshButton = ctx.$tabContent.find('.note-detail-search-refresh-results-button');
|
||||
|
||||
this.$refreshButton.on('click', async () => {
|
||||
// FIXME
|
||||
await noteDetailService.saveNotesIfChanged();
|
||||
|
||||
await searchNotesService.refreshSearch();
|
||||
|
@ -174,7 +174,9 @@ class TextTypeWidget extends TypeWidget {
|
||||
return this.textEditor;
|
||||
}
|
||||
|
||||
onNoteChange(func) {
|
||||
async onNoteChange(func) {
|
||||
await this.initialized;
|
||||
|
||||
this.textEditor.model.document.on('change:data', func);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user