mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
prompt user when there are unsaved changes, #1692
This commit is contained in:
parent
02016ed031
commit
78e48095e6
@ -12,6 +12,7 @@ import keyboardActionsService from "./keyboard_actions.js";
|
||||
import MobileScreenSwitcherExecutor from "../widgets/mobile_widgets/mobile_screen_switcher.js";
|
||||
import MainTreeExecutors from "./main_tree_executors.js";
|
||||
import protectedSessionHolder from "./protected_session_holder.js";
|
||||
import toast from "./toast.js";
|
||||
|
||||
class AppContext extends Component {
|
||||
constructor(isMainWindow) {
|
||||
@ -19,6 +20,7 @@ class AppContext extends Component {
|
||||
|
||||
this.isMainWindow = isMainWindow;
|
||||
this.executors = [];
|
||||
this.beforeUnloadListeners = [];
|
||||
}
|
||||
|
||||
setLayout(layout) {
|
||||
@ -104,6 +106,15 @@ class AppContext extends Component {
|
||||
getComponentByEl(el) {
|
||||
return $(el).closest(".component").prop('component');
|
||||
}
|
||||
|
||||
addBeforeUnloadListener(obj) {
|
||||
if (typeof WeakRef !== "function") {
|
||||
// older browsers don't support WeakRef
|
||||
return;
|
||||
}
|
||||
|
||||
this.beforeUnloadListeners.push(new WeakRef(obj));
|
||||
}
|
||||
}
|
||||
|
||||
const appContext = new AppContext(window.glob.isMainWindow);
|
||||
@ -112,7 +123,29 @@ const appContext = new AppContext(window.glob.isMainWindow);
|
||||
$(window).on('beforeunload', () => {
|
||||
protectedSessionHolder.resetSessionCookie();
|
||||
|
||||
appContext.triggerEvent('beforeUnload');
|
||||
let allSaved = true;
|
||||
|
||||
appContext.beforeUnloadListeners = appContext.beforeUnloadListeners.filter(wr => !!wr.deref());
|
||||
|
||||
for (const weakRef of appContext.beforeUnloadListeners) {
|
||||
const component = weakRef.deref();
|
||||
|
||||
if (!component) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!component.beforeUnloadEvent()) {
|
||||
console.log(`Component ${component.componentId} is not finished saving its state.`);
|
||||
|
||||
toast.showMessage("Please wait for a couple of seconds for the save to finish, then you can try again.", 10000);
|
||||
|
||||
allSaved = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allSaved) {
|
||||
return "some string";
|
||||
}
|
||||
});
|
||||
|
||||
function isNotePathInAddress() {
|
||||
|
@ -15,11 +15,27 @@ export default class SpacedUpdate {
|
||||
|
||||
async updateNowIfNecessary() {
|
||||
if (this.changed) {
|
||||
this.changed = false;
|
||||
await this.updater();
|
||||
this.changed = false; // optimistic...k
|
||||
|
||||
try {
|
||||
await this.updater();
|
||||
}
|
||||
catch (e) {
|
||||
this.changed = true;
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isAllSavedAndTriggerUpdate() {
|
||||
const allSaved = !this.changed;
|
||||
|
||||
this.updateNowIfNecessary();
|
||||
|
||||
return allSaved;
|
||||
}
|
||||
|
||||
triggerUpdate() {
|
||||
if (!this.changed) {
|
||||
return;
|
||||
|
@ -27,6 +27,8 @@ export default class TabManager extends Component {
|
||||
openTabs: JSON.stringify(openTabs)
|
||||
});
|
||||
});
|
||||
|
||||
appContext.addBeforeUnloadListener(this);
|
||||
}
|
||||
|
||||
/** @type {TabContext[]} */
|
||||
@ -329,6 +331,8 @@ export default class TabManager extends Component {
|
||||
|
||||
beforeUnloadEvent() {
|
||||
this.tabsUpdate.updateNowIfNecessary();
|
||||
|
||||
return true; // don't block closing the tab, this metadata is not that important
|
||||
}
|
||||
|
||||
openNewTabCommand() {
|
||||
|
@ -54,8 +54,6 @@ export default class NoteDetailWidget extends TabAwareWidget {
|
||||
|
||||
this.typeWidgets = {};
|
||||
|
||||
const updateInterval = utils.isDesktop() ? 1000 : 5000;
|
||||
|
||||
this.spacedUpdate = new SpacedUpdate(async () => {
|
||||
const {note} = this.tabContext;
|
||||
const {noteId} = note;
|
||||
@ -66,7 +64,9 @@ export default class NoteDetailWidget extends TabAwareWidget {
|
||||
protectedSessionHolder.touchProtectedSessionIfNecessary(note);
|
||||
|
||||
await server.put('notes/' + noteId, dto, this.componentId);
|
||||
}, updateInterval);
|
||||
});
|
||||
|
||||
appContext.addBeforeUnloadListener(this);
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
@ -295,7 +295,7 @@ export default class NoteDetailWidget extends TabAwareWidget {
|
||||
}
|
||||
|
||||
beforeUnloadEvent() {
|
||||
this.spacedUpdate.updateNowIfNecessary();
|
||||
return this.spacedUpdate.isAllSavedAndTriggerUpdate();
|
||||
}
|
||||
|
||||
textPreviewDisabledEvent({tabContext}) {
|
||||
|
@ -3,6 +3,7 @@ import utils from "../services/utils.js";
|
||||
import protectedSessionHolder from "../services/protected_session_holder.js";
|
||||
import server from "../services/server.js";
|
||||
import SpacedUpdate from "../services/spaced_update.js";
|
||||
import appContext from "../services/app_context.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="note-title-container">
|
||||
@ -37,6 +38,8 @@ export default class NoteTitleWidget extends TabAwareWidget {
|
||||
|
||||
await server.put(`notes/${this.noteId}/change-title`, {title});
|
||||
});
|
||||
|
||||
appContext.addBeforeUnloadListener(this);
|
||||
}
|
||||
|
||||
doRender() {
|
||||
@ -101,6 +104,6 @@ export default class NoteTitleWidget extends TabAwareWidget {
|
||||
}
|
||||
|
||||
beforeUnloadEvent() {
|
||||
this.spacedUpdate.updateNowIfNecessary();
|
||||
return this.spacedUpdate.isAllSavedAndTriggerUpdate();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user