From 212a65f4632b549f76f97df8810c74c47095871e Mon Sep 17 00:00:00 2001 From: Baptiste Grob <60621355+baptiste-grob@users.noreply.github.com> Date: Tue, 29 Sep 2020 12:08:19 +0200 Subject: [PATCH] refactor: move status functions to footer view --- .../javascripts/services/statusManager.ts | 46 ++--- .../javascripts/ui_models/application.ts | 6 +- .../ui_models/application_group.ts | 2 +- .../views/application/application_view.ts | 111 +---------- .../javascripts/views/footer/footer_view.ts | 183 ++++++++++++------ package-lock.json | 4 +- package.json | 2 +- 7 files changed, 155 insertions(+), 199 deletions(-) diff --git a/app/assets/javascripts/services/statusManager.ts b/app/assets/javascripts/services/statusManager.ts index d46ea1667..fed54e1c0 100644 --- a/app/assets/javascripts/services/statusManager.ts +++ b/app/assets/javascripts/services/statusManager.ts @@ -1,54 +1,30 @@ import { removeFromArray } from 'snjs'; -import { FooterStatus } from '@/types'; -type StatusCallback = (string: string) => void +type StatusCallback = (string: string) => void; export class StatusManager { + private _message = ''; + private observers: StatusCallback[] = []; - private statuses: FooterStatus[] = [] - private observers: StatusCallback[] = [] - - replaceStatusWithString(status: FooterStatus, string: string) { - this.removeStatus(status); - return this.addStatusFromString(string); + get message(): string { + return this._message; } - addStatusFromString(string: string) { - const status = { string }; - this.statuses.push(status); + setMessage(message: string) { + this._message = message; this.notifyObservers(); - return status; } - removeStatus(status: FooterStatus) { - removeFromArray(this.statuses, status); - this.notifyObservers(); - return undefined; - } - - addStatusObserver(callback: StatusCallback) { + onStatusChange(callback: StatusCallback) { this.observers.push(callback); return () => { removeFromArray(this.observers, callback); - } + }; } private notifyObservers() { - for(const observer of this.observers) { - observer(this.getStatusString()); + for (const observer of this.observers) { + observer(this._message); } } - - private getStatusString() { - let result = ''; - this.statuses.forEach((status, index) => { - if(index > 0) { - result += ' '; - } - result += status.string; - }); - - return result; - } - } diff --git a/app/assets/javascripts/ui_models/application.ts b/app/assets/javascripts/ui_models/application.ts index d02324070..56d3b953a 100644 --- a/app/assets/javascripts/ui_models/application.ts +++ b/app/assets/javascripts/ui_models/application.ts @@ -36,7 +36,7 @@ type WebServices = { autolockService: AutolockService archiveService: ArchiveManager nativeExtService: NativeExtManager - statusService: StatusManager + statusManager: StatusManager themeService: ThemeManager prefsService: PreferencesManager keyboardService: KeyboardManager @@ -135,8 +135,8 @@ export class WebApplication extends SNApplication { return this.webServices.nativeExtService; } - public getStatusService() { - return this.webServices.statusService; + getStatusManager() { + return this.webServices.statusManager; } public getThemeService() { diff --git a/app/assets/javascripts/ui_models/application_group.ts b/app/assets/javascripts/ui_models/application_group.ts index 34f8ec82d..f29ed8d34 100644 --- a/app/assets/javascripts/ui_models/application_group.ts +++ b/app/assets/javascripts/ui_models/application_group.ts @@ -96,7 +96,7 @@ export class ApplicationGroup extends SNApplicationGroup { autolockService, nativeExtService, prefsService, - statusService, + statusManager: statusService, themeService }); return application; diff --git a/app/assets/javascripts/views/application/application_view.ts b/app/assets/javascripts/views/application/application_view.ts index a60986dac..28229819f 100644 --- a/app/assets/javascripts/views/application/application_view.ts +++ b/app/assets/javascripts/views/application/application_view.ts @@ -12,17 +12,14 @@ import { STRING_DEFAULT_FILE_ERROR } from '@/strings'; import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl'; +import { alertDialog } from '@/services/alertService'; class ApplicationViewCtrl extends PureViewCtrl { private $location?: ng.ILocationService private $rootScope?: ng.IRootScopeService public platformString: string - private completedInitialSync = false - private syncStatus: any private notesCollapsed = false private tagsCollapsed = false - private showingDownloadStatus = false - private uploadSyncStatus: any /* @ngInject */ constructor( @@ -89,35 +86,14 @@ class ApplicationViewCtrl extends PureViewCtrl { /** @override */ async onAppEvent(eventName: ApplicationEvent) { super.onAppEvent(eventName); - if (eventName === ApplicationEvent.LocalDataIncrementalLoad) { - this.updateLocalDataStatus(); - } else if ( - eventName === ApplicationEvent.SyncStatusChanged || - eventName === ApplicationEvent.FailedSync - ) { - this.updateSyncStatus(); - } else if (eventName === ApplicationEvent.LocalDataLoaded) { - this.updateLocalDataStatus(); - } else if (eventName === ApplicationEvent.WillSync) { - if (!this.completedInitialSync) { - this.syncStatus = this.application!.getStatusService().replaceStatusWithString( - this.syncStatus, - "Syncing…" - ); - } - } else if (eventName === ApplicationEvent.CompletedFullSync) { - if (!this.completedInitialSync) { - this.syncStatus = this.application!.getStatusService().removeStatus(this.syncStatus); - this.completedInitialSync = true; - } - } else if (eventName === ApplicationEvent.LocalDatabaseReadError) { - this.application!.alertService!.alert( - 'Unable to load local database. Please restart the app and try again.' - ); + if (eventName === ApplicationEvent.LocalDatabaseReadError) { + alertDialog({ + text: 'Unable to load local database. Please restart the app and try again.' + }); } else if (eventName === ApplicationEvent.LocalDatabaseWriteError) { - this.application!.alertService!.alert( - 'Unable to write to local database. Please restart the app and try again.' - ); + alertDialog({ + text: 'Unable to write to local database. Please restart the app and try again.' + }); } } @@ -141,77 +117,6 @@ class ApplicationViewCtrl extends PureViewCtrl { } } - updateLocalDataStatus() { - const syncStatus = this.application!.getSyncStatus(); - const stats = syncStatus.getStats(); - const encryption = this.application!.isEncryptionAvailable(); - if (stats.localDataDone) { - this.syncStatus = this.application!.getStatusService().removeStatus(this.syncStatus); - return; - } - const notesString = `${stats.localDataCurrent}/${stats.localDataTotal} items...`; - const loadingStatus = encryption - ? `Decrypting ${notesString}` - : `Loading ${notesString}`; - this.syncStatus = this.application!.getStatusService().replaceStatusWithString( - this.syncStatus, - loadingStatus - ); - } - - updateSyncStatus() { - const syncStatus = this.application!.getSyncStatus(); - const stats = syncStatus.getStats(); - if (syncStatus.hasError()) { - this.syncStatus = this.application!.getStatusService().replaceStatusWithString( - this.syncStatus, - 'Unable to Sync' - ); - } else if (stats.downloadCount > 20) { - const text = `Downloading ${stats.downloadCount} items. Keep app open.`; - this.syncStatus = this.application!.getStatusService().replaceStatusWithString( - this.syncStatus, - text - ); - this.showingDownloadStatus = true; - } else if (this.showingDownloadStatus) { - this.showingDownloadStatus = false; - const text = "Download Complete."; - this.syncStatus = this.application!.getStatusService().replaceStatusWithString( - this.syncStatus, - text - ); - setTimeout(() => { - this.syncStatus = this.application!.getStatusService().removeStatus(this.syncStatus); - }, 2000); - } else if (stats.uploadTotalCount > 20) { - const completionPercentage = stats.uploadCompletionCount === 0 - ? 0 - : stats.uploadCompletionCount / stats.uploadTotalCount; - - const stringPercentage = completionPercentage.toLocaleString( - undefined, - { style: 'percent' } - ); - - this.uploadSyncStatus = this.application!.getStatusService().replaceStatusWithString( - this.uploadSyncStatus, - `Syncing ${stats.uploadTotalCount} items (${stringPercentage} complete)`, - ); - } else { - if (this.syncStatus) { - this.syncStatus = this.application!.getStatusService().removeStatus( - this.syncStatus - ); - } - if (this.uploadSyncStatus) { - this.uploadSyncStatus = this.application!.getStatusService().removeStatus( - this.uploadSyncStatus - ); - } - } - } - addDragDropHandlers() { /** * Disable dragging and dropping of files (but allow text) into main SN interface. diff --git a/app/assets/javascripts/views/footer/footer_view.ts b/app/assets/javascripts/views/footer/footer_view.ts index 4dc8b3984..75c5bd397 100644 --- a/app/assets/javascripts/views/footer/footer_view.ts +++ b/app/assets/javascripts/views/footer/footer_view.ts @@ -62,7 +62,6 @@ class FooterViewCtrl extends PureViewCtrl<{}, { private rootScopeListener2: any public arbitraryStatusMessage?: string public user?: any - private backupStatus?: FooterStatus private offline = true private showAccountMenu = false private didCheckForOffline = false @@ -75,6 +74,8 @@ class FooterViewCtrl extends PureViewCtrl<{}, { public dockShortcuts: DockShortcut[] = [] public roomShowState: Partial> = {} private observerRemovers: Array<() => void> = []; + private completedInitialSync = false; + private showingDownloadStatus = false; /* @ngInject */ constructor( @@ -107,9 +108,9 @@ class FooterViewCtrl extends PureViewCtrl<{}, { $onInit() { super.$onInit(); - this.application.getStatusService().addStatusObserver((string: string) => { + this.application.getStatusManager().onStatusChange((message) => { this.$timeout(() => { - this.arbitraryStatusMessage = string; + this.arbitraryStatusMessage = message; }); }); this.loadAccountSwitcherState(); @@ -184,30 +185,32 @@ class FooterViewCtrl extends PureViewCtrl<{}, { /** @override */ onAppStateEvent(eventName: AppStateEvent, data: any) { - if (eventName === AppStateEvent.EditorFocused) { - if (data.eventSource === EventSource.UserInteraction) { - this.closeAllRooms(); - this.closeAccountMenu(); - } - } else if (eventName === AppStateEvent.BeganBackupDownload) { - this.backupStatus = this.application.getStatusService().addStatusFromString( - "Saving local backup..." - ); - } else if (eventName === AppStateEvent.EndedBackupDownload) { - if (data.success) { - this.backupStatus = this.application.getStatusService().replaceStatusWithString( - this.backupStatus!, - "Successfully saved backup." - ); - } else { - this.backupStatus = this.application.getStatusService().replaceStatusWithString( - this.backupStatus!, - "Unable to save local backup." - ); - } - this.$timeout(() => { - this.backupStatus = this.application.getStatusService().removeStatus(this.backupStatus!); - }, 2000); + const statusService = this.application.getStatusManager(); + switch (eventName) { + case AppStateEvent.EditorFocused: + if (data.eventSource === EventSource.UserInteraction) { + this.closeAllRooms(); + this.closeAccountMenu(); + } + break; + case AppStateEvent.BeganBackupDownload: + statusService.setMessage("Saving local backup…"); + break; + case AppStateEvent.EndedBackupDownload: + const successMessage = "Successfully saved backup."; + const errorMessage = "Unable to save local backup." + statusService.setMessage(data.success ? successMessage : errorMessage); + + const twoSeconds = 2000; + this.$timeout(() => { + if ( + statusService.message === successMessage || + statusService.message === errorMessage + ) { + statusService.setMessage(''); + } + }, twoSeconds); + break; } } @@ -219,34 +222,56 @@ class FooterViewCtrl extends PureViewCtrl<{}, { /** @override */ onAppEvent(eventName: ApplicationEvent) { - if (eventName === ApplicationEvent.KeyStatusChanged) { - this.reloadUpgradeStatus(); - } else if (eventName === ApplicationEvent.EnteredOutOfSync) { - this.setState({ - outOfSync: true - }); - } else if (eventName === ApplicationEvent.ExitedOutOfSync) { - this.setState({ - outOfSync: false - }); - } else if (eventName === ApplicationEvent.CompletedFullSync) { - if (!this.didCheckForOffline) { - this.didCheckForOffline = true; - if (this.offline && this.application.getNoteCount() === 0) { - this.showAccountMenu = true; + switch (eventName) { + case ApplicationEvent.KeyStatusChanged: + this.reloadUpgradeStatus(); + break; + case ApplicationEvent.EnteredOutOfSync: + this.setState({ + outOfSync: true + }); + break; + case ApplicationEvent.ExitedOutOfSync: + this.setState({ + outOfSync: false + }); + break; + case ApplicationEvent.CompletedFullSync: + if (!this.completedInitialSync) { + this.application.getStatusManager().setMessage(''); + this.completedInitialSync = true; } - } - this.syncUpdated(); - this.findErrors(); - this.updateOfflineStatus(); - } else if (eventName === ApplicationEvent.FailedSync) { - this.findErrors(); - this.updateOfflineStatus(); - } else if ( - eventName === ApplicationEvent.SignedIn || - eventName === ApplicationEvent.SignedOut - ) { - this.reloadUser(); + if (!this.didCheckForOffline) { + this.didCheckForOffline = true; + if (this.offline && this.application.getNoteCount() === 0) { + this.showAccountMenu = true; + } + } + this.syncUpdated(); + this.findErrors(); + this.updateOfflineStatus(); + break; + case ApplicationEvent.SyncStatusChanged: + this.updateSyncStatus(); + break; + case ApplicationEvent.FailedSync: + this.updateSyncStatus(); + this.findErrors(); + this.updateOfflineStatus(); + break; + case ApplicationEvent.LocalDataIncrementalLoad: + case ApplicationEvent.LocalDataLoaded: + this.updateLocalDataStatus(); + break; + case ApplicationEvent.SignedIn: + case ApplicationEvent.SignedOut: + this.reloadUser(); + break; + case ApplicationEvent.WillSync: + if (!this.completedInitialSync) { + this.application.getStatusManager().setMessage('Syncing…'); + } + break; } } @@ -310,6 +335,56 @@ class FooterViewCtrl extends PureViewCtrl<{}, { }); } + updateSyncStatus() { + const statusManager = this.application.getStatusManager(); + const syncStatus = this.application!.getSyncStatus(); + const stats = syncStatus.getStats(); + if (syncStatus.hasError()) { + statusManager.setMessage('Unable to Sync'); + } else if (stats.downloadCount > 20) { + const text = `Downloading ${stats.downloadCount} items. Keep app open.`; + statusManager.setMessage(text); + this.showingDownloadStatus = true; + } else if (this.showingDownloadStatus) { + this.showingDownloadStatus = false; + statusManager.setMessage('Download Complete.'); + setTimeout(() => { + statusManager.setMessage(''); + }, 2000); + } else if (stats.uploadTotalCount > 20) { + const completionPercentage = stats.uploadCompletionCount === 0 + ? 0 + : stats.uploadCompletionCount / stats.uploadTotalCount; + + const stringPercentage = completionPercentage.toLocaleString( + undefined, + { style: 'percent' } + ); + + statusManager.setMessage( + `Syncing ${stats.uploadTotalCount} items (${stringPercentage} complete)`, + ); + } else { + statusManager.setMessage(''); + } + } + + updateLocalDataStatus() { + const statusManager = this.application.getStatusManager(); + const syncStatus = this.application!.getSyncStatus(); + const stats = syncStatus.getStats(); + const encryption = this.application!.isEncryptionAvailable(); + if (stats.localDataDone) { + statusManager.setMessage(''); + return; + } + const notesString = `${stats.localDataCurrent}/${stats.localDataTotal} items...`; + const loadingStatus = encryption + ? `Decrypting ${notesString}` + : `Loading ${notesString}`; + statusManager.setMessage(loadingStatus); + } + reloadExtendedData() { if (this.reloadInProgress) { return; diff --git a/package-lock.json b/package-lock.json index 9063b140f..13b89348d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10956,8 +10956,8 @@ "from": "github:standardnotes/sncrypto#8794c88daa967eaae493cd5fdec7506d52b257ad" }, "snjs": { - "version": "github:standardnotes/snjs#403dd0ccd860c42889601446540a9e17b8f7440f", - "from": "github:standardnotes/snjs#403dd0ccd860c42889601446540a9e17b8f7440f" + "version": "github:standardnotes/snjs#3ed1e58670cf1e5b554e18a88f0ea9a28668a376", + "from": "github:standardnotes/snjs#3ed1e58670cf1e5b554e18a88f0ea9a28668a376" }, "sockjs": { "version": "0.3.20", diff --git a/package.json b/package.json index 6ee25268a..43eb53b95 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,6 @@ }, "dependencies": { "sncrypto": "github:standardnotes/sncrypto#8794c88daa967eaae493cd5fdec7506d52b257ad", - "snjs": "github:standardnotes/snjs#403dd0ccd860c42889601446540a9e17b8f7440f" + "snjs": "github:standardnotes/snjs#3ed1e58670cf1e5b554e18a88f0ea9a28668a376" } }