mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-29 03:23:25 +08: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,9 +15,25 @@ export default class SpacedUpdate { | ||||
| 
 | ||||
|     async updateNowIfNecessary() { | ||||
|         if (this.changed) { | ||||
|             this.changed = false; | ||||
|             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() { | ||||
|  | ||||
| @ -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
	 zadam
						zadam