This commit is contained in:
Mo Bitar
2020-02-09 12:07:18 -06:00
parent 046f6ca5b9
commit 1a87df0db8
18 changed files with 1151 additions and 1130 deletions

View File

@@ -1,13 +1,25 @@
export class PureCtrl { export class PureCtrl {
constructor( constructor(
$timeout $scope,
$timeout,
application,
appState
) { ) {
if(!$timeout) { if (!$scope || !$timeout || !application || !appState) {
throw 'Invalid PureCtrl construction.'; throw 'Invalid PureCtrl construction.';
} }
this.$scope = $scope;
this.$timeout = $timeout; this.$timeout = $timeout;
this.appState = appState;
this.application = application;
this.state = {}; this.state = {};
this.props = {}; this.props = {};
this.addAppStateObserver();
this.addAppEventObserver();
$scope.$on('$destroy', () => {
this.unsubApp();
this.unsubState();
});
} }
async setState(state) { async setState(state) {
@@ -25,4 +37,25 @@ export class PureCtrl {
} }
this.props = Object.freeze(Object.assign({}, this.props, props)); this.props = Object.freeze(Object.assign({}, this.props, props));
} }
addAppStateObserver() {
this.unsubState = this.appState.addObserver((eventName, data) => {
this.onAppStateEvent(eventName, data);
});
}
addAppEventObserver() {
this.unsubApp = this.application.addEventObserver((eventName) => {
this.onApplicationEvent(eventName);
});
}
onApplicationEvent(eventName) {
/** Optional override */
}
onAppStateEvent(eventName, data) {
/** Optional override */
}
} }

View File

@@ -49,18 +49,17 @@ const Fonts = {
class EditorCtrl extends PureCtrl { class EditorCtrl extends PureCtrl {
/* @ngInject */ /* @ngInject */
constructor( constructor(
$scope,
$timeout, $timeout,
$rootScope, $rootScope,
appState,
application, application,
appState,
desktopManager, desktopManager,
keyboardManager, keyboardManager,
preferencesManager, preferencesManager,
) { ) {
super($timeout); super($scope, $timeout, application, appState);
this.$rootScope = $rootScope; this.$rootScope = $rootScope;
this.application = application;
this.appState = appState;
this.desktopManager = desktopManager; this.desktopManager = desktopManager;
this.keyboardManager = keyboardManager; this.keyboardManager = keyboardManager;
this.preferencesManager = preferencesManager; this.preferencesManager = preferencesManager;
@@ -77,13 +76,10 @@ class EditorCtrl extends PureCtrl {
this.leftResizeControl = {}; this.leftResizeControl = {};
this.rightResizeControl = {}; this.rightResizeControl = {};
this.addAppStateObserver();
this.addAppEventObserver();
this.addSyncStatusObserver(); this.addSyncStatusObserver();
this.registerKeyboardShortcuts(); this.registerKeyboardShortcuts();
application.onReady(() => { application.onUnlock(() => {
this.streamItems(); this.streamItems();
this.registerComponentHandler(); this.registerComponentHandler();
}); });
@@ -94,17 +90,50 @@ class EditorCtrl extends PureCtrl {
this.prefKeyMarginResizers = PrefKeys.EditorResizersEnabled; this.prefKeyMarginResizers = PrefKeys.EditorResizersEnabled;
} }
addAppStateObserver() { /** @override */
this.appState.addObserver((eventName, data) => { onAppStateEvent(eventName, data) {
if (eventName === AppStateEvents.NoteChanged) { if (eventName === AppStateEvents.NoteChanged) {
this.handleNoteSelectionChange( this.handleNoteSelectionChange(
this.appState.getSelectedNote(), this.appState.getSelectedNote(),
data.previousNote data.previousNote
); );
} else if (eventName === AppStateEvents.PreferencesChanged) { } else if (eventName === AppStateEvents.PreferencesChanged) {
this.loadPreferences(); this.loadPreferences();
}
}
/** @override */
onApplicationEvent(eventName) {
if (!this.state.note) {
return;
}
if (eventName === ApplicationEvents.HighLatencySync) {
this.setState({
syncTakingTooLong: true
});
} else if (eventName === ApplicationEvents.CompletedSync) {
this.setState({
syncTakingTooLong: false
});
if (this.state.note.dirty) {
/** if we're still dirty, don't change status, a sync is likely upcoming. */
} else {
const saved = this.state.note.updated_at > this.state.note.lastSyncBegan;
const isInErrorState = this.state.saveError;
if (isInErrorState || saved) {
this.showAllChangesSavedStatus();
}
} }
}); } else if (eventName === ApplicationEvents.FailedSync) {
/**
* Only show error status in editor if the note is dirty.
* Otherwise, it means the originating sync came from somewhere else
* and we don't want to display an error here.
*/
if (this.state.note.dirty) {
this.showErrorStatus();
}
}
} }
streamItems() { streamItems() {
@@ -176,42 +205,6 @@ class EditorCtrl extends PureCtrl {
}); });
} }
addAppEventObserver() {
this.application.addEventObserver((eventName) => {
if (!this.state.note) {
return;
}
if (eventName === ApplicationEvents.HighLatencySync) {
this.setState({
syncTakingTooLong: true
});
} else if (eventName === ApplicationEvents.CompletedSync) {
this.setState({
syncTakingTooLong: false
});
if (this.state.note.dirty) {
/** if we're still dirty, don't change status, a sync is likely upcoming. */
} else {
const saved = this.state.note.updated_at > this.state.note.lastSyncBegan;
const isInErrorState = this.state.saveError;
if (isInErrorState || saved) {
this.showAllChangesSavedStatus();
}
}
} else if (eventName === ApplicationEvents.FailedSync) {
/**
* Only show error status in editor if the note is dirty.
* Otherwise, it means the originating sync came from somewhere else
* and we don't want to display an error here.
*/
if (this.state.note.dirty) {
this.showErrorStatus();
}
}
});
}
async handleNoteSelectionChange(note, previousNote) { async handleNoteSelectionChange(note, previousNote) {
this.setState({ this.setState({
note: this.appState.getSelectedNote(), note: this.appState.getSelectedNote(),

View File

@@ -11,23 +11,23 @@ import {
STRING_GENERIC_SYNC_ERROR, STRING_GENERIC_SYNC_ERROR,
STRING_NEW_UPDATE_READY STRING_NEW_UPDATE_READY
} from '@/strings'; } from '@/strings';
import { PureCtrl } from '@Controllers';
class FooterCtrl { class FooterCtrl extends PureCtrl {
/* @ngInject */ /* @ngInject */
constructor( constructor(
$scope,
$rootScope, $rootScope,
$timeout, $timeout,
appState,
application, application,
appState,
nativeExtManager, nativeExtManager,
statusManager, statusManager,
godService godService
) { ) {
super($scope, $timeout, application, appState);
this.$rootScope = $rootScope; this.$rootScope = $rootScope;
this.$timeout = $timeout;
this.application = application;
this.appState = appState;
this.nativeExtManager = nativeExtManager; this.nativeExtManager = nativeExtManager;
this.statusManager = statusManager; this.statusManager = statusManager;
this.godService = godService; this.godService = godService;
@@ -36,7 +36,6 @@ class FooterCtrl {
this.themesWithIcons = []; this.themesWithIcons = [];
this.showSyncResolution = false; this.showSyncResolution = false;
this.addAppStateObserver();
this.addRootScopeListeners(); this.addRootScopeListeners();
this.statusManager.addStatusObserver((string) => { this.statusManager.addStatusObserver((string) => {
@@ -45,7 +44,7 @@ class FooterCtrl {
}); });
}); });
application.onReady(() => { application.onUnlock(() => {
this.application.hasPasscode().then((value) => { this.application.hasPasscode().then((value) => {
this.hasPasscode = value; this.hasPasscode = value;
}); });
@@ -76,55 +75,53 @@ class FooterCtrl {
}); });
} }
addAppStateObserver() { /** @override */
this.appState.addObserver((eventName, data) => { onAppStateEvent(eventName, data) {
if(eventName === AppStateEvents.EditorFocused) { if (eventName === AppStateEvents.EditorFocused) {
if (data.eventSource === EventSources.UserInteraction) { if (data.eventSource === EventSources.UserInteraction) {
this.closeAllRooms(); this.closeAllRooms();
this.closeAccountMenu(); this.closeAccountMenu();
}
} else if(eventName === AppStateEvents.BeganBackupDownload) {
this.backupStatus = this.statusManager.addStatusFromString(
"Saving local backup..."
);
} else if(eventName === AppStateEvents.EndedBackupDownload) {
if(data.success) {
this.backupStatus = this.statusManager.replaceStatusWithString(
this.backupStatus,
"Successfully saved backup."
);
} else {
this.backupStatus = this.statusManager.replaceStatusWithString(
this.backupStatus,
"Unable to save local backup."
);
}
this.$timeout(() => {
this.backupStatus = this.statusManager.removeStatus(this.backupStatus);
}, 2000);
} }
}); } else if (eventName === AppStateEvents.BeganBackupDownload) {
this.backupStatus = this.statusManager.addStatusFromString(
"Saving local backup..."
);
} else if (eventName === AppStateEvents.EndedBackupDownload) {
if (data.success) {
this.backupStatus = this.statusManager.replaceStatusWithString(
this.backupStatus,
"Successfully saved backup."
);
} else {
this.backupStatus = this.statusManager.replaceStatusWithString(
this.backupStatus,
"Unable to save local backup."
);
}
this.$timeout(() => {
this.backupStatus = this.statusManager.removeStatus(this.backupStatus);
}, 2000);
}
} }
addAppEventObserver() { /** @override */
this.application.addEventObserver((eventName) => { onApplicationEvent(eventName) {
if (eventName === ApplicationEvents.LoadedLocalData) { if (eventName === ApplicationEvents.LoadedLocalData) {
if(this.offline && this.application.getNoteCount() === 0) { if (this.offline && this.application.getNoteCount() === 0) {
this.showAccountMenu = true; this.showAccountMenu = true;
}
} else if (eventName === ApplicationEvents.EnteredOutOfSync) {
this.outOfSync = true;
} else if (eventName === ApplicationEvents.ExitedOutOfSync) {
this.outOfSync = false;
} else if (eventName === ApplicationEvents.CompletedSync) {
this.syncUpdated();
this.findErrors();
this.updateOfflineStatus();
} else if (eventName === ApplicationEvents.FailedSync) {
this.findErrors();
this.updateOfflineStatus();
} }
}); } else if (eventName === ApplicationEvents.EnteredOutOfSync) {
this.outOfSync = true;
} else if (eventName === ApplicationEvents.ExitedOutOfSync) {
this.outOfSync = false;
} else if (eventName === ApplicationEvents.CompletedSync) {
this.syncUpdated();
this.findErrors();
this.updateOfflineStatus();
} else if (eventName === ApplicationEvents.FailedSync) {
this.findErrors();
this.updateOfflineStatus();
}
} }
streamItems() { streamItems() {
@@ -136,7 +133,7 @@ class FooterCtrl {
}).filter((candidate) => { }).filter((candidate) => {
return candidate.area === 'rooms' && !candidate.deleted; return candidate.area === 'rooms' && !candidate.deleted;
}); });
if(this.queueExtReload) { if (this.queueExtReload) {
this.queueExtReload = false; this.queueExtReload = false;
this.reloadExtendedData(); this.reloadExtendedData();
} }
@@ -159,7 +156,7 @@ class FooterCtrl {
}); });
const differ = themes.length !== this.themesWithIcons.length; const differ = themes.length !== this.themesWithIcons.length;
this.themesWithIcons = themes; this.themesWithIcons = themes;
if(differ) { if (differ) {
this.reloadDockShortcuts(); this.reloadDockShortcuts();
} }
} }
@@ -170,14 +167,14 @@ class FooterCtrl {
this.application.componentManager.registerHandler({ this.application.componentManager.registerHandler({
identifier: "roomBar", identifier: "roomBar",
areas: ["rooms", "modal"], areas: ["rooms", "modal"],
activationHandler: (component) => {}, activationHandler: (component) => { },
actionHandler: (component, action, data) => { actionHandler: (component, action, data) => {
if(action === "set-size") { if (action === "set-size") {
component.setLastSize(data); component.setLastSize(data);
} }
}, },
focusHandler: (component, focused) => { focusHandler: (component, focused) => {
if(component.isEditor() && focused) { if (component.isEditor() && focused) {
this.closeAllRooms(); this.closeAllRooms();
this.closeAccountMenu(); this.closeAccountMenu();
} }
@@ -186,7 +183,7 @@ class FooterCtrl {
} }
reloadExtendedData() { reloadExtendedData() {
if(this.reloadInProgress) { if (this.reloadInProgress) {
return; return;
} }
this.reloadInProgress = true; this.reloadInProgress = true;
@@ -198,7 +195,7 @@ class FooterCtrl {
const extWindow = this.rooms.find((room) => { const extWindow = this.rooms.find((room) => {
return room.package_info.identifier === this.nativeExtManager.extManagerId; return room.package_info.identifier === this.nativeExtManager.extManagerId;
}); });
if(!extWindow) { if (!extWindow) {
this.queueExtReload = true; this.queueExtReload = true;
this.reloadInProgress = false; this.reloadInProgress = false;
return; return;
@@ -249,7 +246,7 @@ class FooterCtrl {
this.$timeout(() => { this.$timeout(() => {
this.isRefreshing = false; this.isRefreshing = false;
}, 200); }, 200);
if(response && response.error) { if (response && response.error) {
this.application.alertManager.alert({ this.application.alertManager.alert({
text: STRING_GENERIC_SYNC_ERROR text: STRING_GENERIC_SYNC_ERROR
}); });
@@ -276,10 +273,10 @@ class FooterCtrl {
reloadDockShortcuts() { reloadDockShortcuts() {
const shortcuts = []; const shortcuts = [];
for(const theme of this.themesWithIcons) { for (const theme of this.themesWithIcons) {
const name = theme.content.package_info.name; const name = theme.content.package_info.name;
const icon = theme.content.package_info.dock_icon; const icon = theme.content.package_info.dock_icon;
if(!icon) { if (!icon) {
continue; continue;
} }
shortcuts.push({ shortcuts.push({
@@ -293,11 +290,11 @@ class FooterCtrl {
/** Circles first, then images */ /** Circles first, then images */
const aType = a.icon.type; const aType = a.icon.type;
const bType = b.icon.type; const bType = b.icon.type;
if(aType === bType) { if (aType === bType) {
return 0; return 0;
} else if(aType === 'circle' && bType === 'svg') { } else if (aType === 'circle' && bType === 'svg') {
return -1; return -1;
} else if(bType === 'circle' && aType === 'svg') { } else if (bType === 'circle' && aType === 'svg') {
return 1; return 1;
} }
}); });
@@ -321,7 +318,7 @@ class FooterCtrl {
} }
closeAllRooms() { closeAllRooms() {
for(const room of this.rooms) { for (const room of this.rooms) {
room.showRoom = false; room.showRoom = false;
} }
} }
@@ -333,11 +330,11 @@ class FooterCtrl {
}); });
}; };
if(!room.showRoom) { if (!room.showRoom) {
const requiresPrivilege = await this.application.privilegesManager.actionRequiresPrivilege( const requiresPrivilege = await this.application.privilegesManager.actionRequiresPrivilege(
ProtectedActions.ManageExtensions ProtectedActions.ManageExtensions
); );
if(requiresPrivilege) { if (requiresPrivilege) {
this.godService.presentPrivilegesModal( this.godService.presentPrivilegesModal(
ProtectedActions.ManageExtensions, ProtectedActions.ManageExtensions,
run run
@@ -351,7 +348,7 @@ class FooterCtrl {
} }
clickOutsideAccountMenu() { clickOutsideAccountMenu() {
if(this.godService.authenticationInProgress()) { if (this.godService.authenticationInProgress()) {
return; return;
} }
this.showAccountMenu = false; this.showAccountMenu = false;

View File

@@ -1,21 +1,19 @@
import template from '%/lock-screen.pug'; import template from '%/lock-screen.pug';
import { AppStateEvents } from '@/state'; import { AppStateEvents } from '@/state';
import { PureCtrl } from './abstract/pure_ctrl';
const ELEMENT_ID_PASSCODE_INPUT = 'passcode-input'; const ELEMENT_ID_PASSCODE_INPUT = 'passcode-input';
class LockScreenCtrl { class LockScreenCtrl extends PureCtrl {
/* @ngInject */ /* @ngInject */
constructor( constructor(
$scope, $scope,
$timeout,
application, application,
appState appState
) { ) {
this.$scope = $scope; super($scope, $timeout, application, appState);
this.application = application;
this.appState = appState;
this.formData = {}; this.formData = {};
this.addVisibilityObserver();
this.addDestroyHandler();
} }
$onInit() { $onInit() {
@@ -30,25 +28,18 @@ class LockScreenCtrl {
); );
} }
addDestroyHandler() { /** @override */
this.$scope.$on('$destroy', () => { async onAppStateEvent(eventName, data) {
this.unregisterObserver(); if (eventName === AppStateEvents.WindowDidFocus) {
}); const input = this.passcodeInput;
} if (input) {
input.focus();
addVisibilityObserver() {
this.unregisterObserver = this.appState.addObserver((eventName, data) => {
if (eventName === AppStateEvents.WindowDidFocus) {
const input = this.passcodeInput;
if(input) {
input.focus();
}
} }
}); }
} }
async submitPasscodeForm($event) { async submitPasscodeForm($event) {
if( if (
!this.formData.passcode || !this.formData.passcode ||
this.formData.passcode.length === 0 this.formData.passcode.length === 0
) { ) {

View File

@@ -32,6 +32,7 @@ class NotesCtrl extends PureCtrl {
/* @ngInject */ /* @ngInject */
constructor( constructor(
$scope,
$timeout, $timeout,
$rootScope, $rootScope,
application, application,
@@ -40,7 +41,7 @@ class NotesCtrl extends PureCtrl {
keyboardManager, keyboardManager,
preferencesManager, preferencesManager,
) { ) {
super($timeout); super($scope, $timeout, application, appState);
this.$rootScope = $rootScope; this.$rootScope = $rootScope;
this.application = application; this.application = application;
this.appState = appState; this.appState = appState;
@@ -68,58 +69,53 @@ class NotesCtrl extends PureCtrl {
keepCurrentIfLarger: true keepCurrentIfLarger: true
}); });
}; };
this.addAppStateObserver();
this.addAppEventObserver();
this.resetPagination(); this.resetPagination();
this.registerKeyboardShortcuts(); this.registerKeyboardShortcuts();
angular.element(document).ready(() => { angular.element(document).ready(() => {
this.reloadPreferences(); this.reloadPreferences();
}); });
application.onReady(() => { application.onUnlock(() => {
this.streamNotesAndTags(); this.streamNotesAndTags();
this.reloadPreferences(); this.reloadPreferences();
}); });
} }
addAppStateObserver() { /** @override */
this.appState.addObserver((eventName, data) => { onAppStateEvent(eventName, data) {
if (eventName === AppStateEvents.TagChanged) { if (eventName === AppStateEvents.TagChanged) {
this.handleTagChange(this.appState.getSelectedTag(), data.previousTag); this.handleTagChange(this.appState.getSelectedTag(), data.previousTag);
} else if (eventName === AppStateEvents.NoteChanged) { } else if (eventName === AppStateEvents.NoteChanged) {
this.handleNoteSelection(this.appState.getSelectedNote()); this.handleNoteSelection(this.appState.getSelectedNote());
} else if (eventName === AppStateEvents.PreferencesChanged) { } else if (eventName === AppStateEvents.PreferencesChanged) {
this.reloadPreferences(); this.reloadPreferences();
this.reloadNotes(); this.reloadNotes();
} else if (eventName === AppStateEvents.EditorFocused) { } else if (eventName === AppStateEvents.EditorFocused) {
this.setShowMenuFalse(); this.setShowMenuFalse();
} }
});
} }
addAppEventObserver() { /** @override */
this.application.addEventObserver((eventName) => { onApplicationEvent(eventName) {
if (eventName === ApplicationEvents.SignedIn) { if (eventName === ApplicationEvents.SignedIn) {
/** Delete dummy note if applicable */ /** Delete dummy note if applicable */
if (this.state.selectedNote && this.state.selectedNote.dummy) { if (this.state.selectedNote && this.state.selectedNote.dummy) {
this.application.deleteItemLocally({ item: this.state.selectedNote }); this.application.deleteItemLocally({ item: this.state.selectedNote });
this.selectNote(null).then(() => { this.selectNote(null).then(() => {
this.reloadNotes(); this.reloadNotes();
}); });
/** /**
* We want to see if the user will download any items from the server. * We want to see if the user will download any items from the server.
* If the next sync completes and our notes are still 0, * If the next sync completes and our notes are still 0,
* we need to create a dummy. * we need to create a dummy.
*/ */
this.createDummyOnSynCompletionIfNoNotes = true; this.createDummyOnSynCompletionIfNoNotes = true;
}
} else if (eventName === ApplicationEvents.CompletedSync) {
if (this.createDummyOnSynCompletionIfNoNotes && this.state.notes.length === 0) {
this.createDummyOnSynCompletionIfNoNotes = false;
this.createNewNote();
}
} }
}); } else if (eventName === ApplicationEvents.CompletedSync) {
if (this.createDummyOnSynCompletionIfNoNotes && this.state.notes.length === 0) {
this.createDummyOnSynCompletionIfNoNotes = false;
this.createNewNote();
}
}
} }
streamNotesAndTags() { streamNotesAndTags() {
@@ -157,11 +153,9 @@ class NotesCtrl extends PureCtrl {
} }
await this.selectNote(null); await this.selectNote(null);
} }
await this.setState({ await this.setState({
tag: tag tag: tag
}); });
this.resetScrollPosition(); this.resetScrollPosition();
this.setShowMenuFalse(); this.setShowMenuFalse();
this.setNoteFilterText(''); this.setNoteFilterText('');
@@ -348,7 +342,7 @@ class NotesCtrl extends PureCtrl {
resetPagination({ keepCurrentIfLarger } = {}) { resetPagination({ keepCurrentIfLarger } = {}) {
const clientHeight = document.documentElement.clientHeight; const clientHeight = document.documentElement.clientHeight;
this.pageSize = clientHeight / MIN_NOTE_CELL_HEIGHT; this.pageSize = Math.ceil(clientHeight / MIN_NOTE_CELL_HEIGHT);
if (this.pageSize === 0) { if (this.pageSize === 0) {
this.pageSize = DEFAULT_LIST_NUM_NOTES; this.pageSize = DEFAULT_LIST_NUM_NOTES;
} }

View File

@@ -17,41 +17,36 @@ class RootCtrl extends PureCtrl {
/* @ngInject */ /* @ngInject */
constructor( constructor(
$location, $location,
$scope,
$rootScope, $rootScope,
$timeout, $timeout,
application, application,
appState, appState,
desktopManager, desktopManager,
lockManager, lockManager,
preferencesManager, preferencesManager /** Unused below, required to load globally */,
themeManager /** Unused below, required to load globally */, themeManager,
statusManager, statusManager,
) { ) {
super($timeout); super($scope, $timeout, application, appState);
this.$location = $location; this.$location = $location;
this.$rootScope = $rootScope; this.$rootScope = $rootScope;
this.$timeout = $timeout;
this.application = application;
this.appState = appState;
this.desktopManager = desktopManager; this.desktopManager = desktopManager;
this.lockManager = lockManager; this.lockManager = lockManager;
this.preferencesManager = preferencesManager;
this.statusManager = statusManager; this.statusManager = statusManager;
this.themeManager = themeManager;
this.platformString = getPlatformString(); this.platformString = getPlatformString();
this.state = { this.state = {
needsUnlock: false, needsUnlock: true,
appClass: '' appClass: ''
}; };
this.loadApplication(); this.loadApplication();
this.addAppStateObserver();
this.addDragDropHandlers(); this.addDragDropHandlers();
application.onUnlock(() => {
application.onReady(() => {
this.handleAutoSignInFromParams(); this.handleAutoSignInFromParams();
}); });
this.lockScreenPuppet = { this.lockScreenPuppet = {
focusInput: () => {} focusInput: () => { }
}; };
} }
@@ -77,8 +72,8 @@ class RootCtrl extends PureCtrl {
return this.watchLockscreenValue(); return this.watchLockscreenValue();
}, },
handleChallengeFailures: (responses) => { handleChallengeFailures: (responses) => {
for(const response of responses) { for (const response of responses) {
if(response.challenge === Challenges.LocalPasscode) { if (response.challenge === Challenges.LocalPasscode) {
this.application.alertManager.alert({ this.application.alertManager.alert({
text: "Invalid passcode. Please try again.", text: "Invalid passcode. Please try again.",
onClose: () => { onClose: () => {
@@ -87,16 +82,13 @@ class RootCtrl extends PureCtrl {
}); });
} }
} }
},
onReady: async () => {
await this.appState.setApplicationReady();
} }
} }
}); });
await this.application.launch(); await this.application.launch();
this.setState({ needsUnlock: false }); this.setState({ needsUnlock: false });
this.application.componentManager.setDesktopManager(this.desktopManager); this.application.componentManager.setDesktopManager(this.desktopManager);
this.preferencesManager.initialize(); this.application.registerService(this.themeManager);
// this.addSyncStatusObserver(); // this.addSyncStatusObserver();
// this.addSyncEventHandler(); // this.addSyncEventHandler();
} }
@@ -105,25 +97,24 @@ class RootCtrl extends PureCtrl {
this.$rootScope.$broadcast('new-update-available'); this.$rootScope.$broadcast('new-update-available');
}; };
addAppStateObserver() { /** @override */
this.appState.addObserver(async (eventName, data) => { async onAppStateEvent(eventName, data) {
if (eventName === AppStateEvents.PanelResized) { if (eventName === AppStateEvents.PanelResized) {
if (data.panel === PANEL_NAME_NOTES) { if (data.panel === PANEL_NAME_NOTES) {
this.notesCollapsed = data.collapsed; this.notesCollapsed = data.collapsed;
}
if (data.panel === PANEL_NAME_TAGS) {
this.tagsCollapsed = data.collapsed;
}
let appClass = "";
if (this.notesCollapsed) { appClass += "collapsed-notes"; }
if (this.tagsCollapsed) { appClass += " collapsed-tags"; }
this.setState({ appClass });
} else if (eventName === AppStateEvents.WindowDidFocus) {
if (!(await this.application.isPasscodeLocked())) {
this.application.sync();
}
} }
}); if (data.panel === PANEL_NAME_TAGS) {
this.tagsCollapsed = data.collapsed;
}
let appClass = "";
if (this.notesCollapsed) { appClass += "collapsed-notes"; }
if (this.tagsCollapsed) { appClass += " collapsed-tags"; }
this.setState({ appClass });
} else if (eventName === AppStateEvents.WindowDidFocus) {
if (!(await this.application.isPasscodeLocked())) {
this.application.sync();
}
}
} }
// addSyncStatusObserver() { // addSyncStatusObserver() {

View File

@@ -9,26 +9,24 @@ import { PureCtrl } from '@Controllers';
class TagsPanelCtrl extends PureCtrl { class TagsPanelCtrl extends PureCtrl {
/* @ngInject */ /* @ngInject */
constructor( constructor(
$scope,
$rootScope, $rootScope,
$timeout, $timeout,
application, application,
appState, appState,
preferencesManager preferencesManager
) { ) {
super($timeout); super($scope, $timeout, application, appState);
this.$rootScope = $rootScope; this.$rootScope = $rootScope;
this.application = application;
this.appState = appState;
this.preferencesManager = preferencesManager; this.preferencesManager = preferencesManager;
this.panelController = {}; this.panelController = {};
this.addAppStateObserver();
this.loadPreferences(); this.loadPreferences();
this.registerComponentHandler(); this.registerComponentHandler();
this.state = { this.state = {
smartTags: [], smartTags: [],
noteCounts: {} noteCounts: {}
}; };
application.onReady(() => { application.onUnlock(() => {
this.beginStreamingItems(); this.beginStreamingItems();
const smartTags = this.application.getSmartTags(); const smartTags = this.application.getSmartTags();
this.setState({ this.setState({
@@ -64,16 +62,15 @@ class TagsPanelCtrl extends PureCtrl {
}); });
} }
addAppStateObserver() { /** @override */
this.appState.addObserver((eventName, data) => { onAppStateEvent(eventName, data) {
if (eventName === AppStateEvents.PreferencesChanged) { if (eventName === AppStateEvents.PreferencesChanged) {
this.loadPreferences(); this.loadPreferences();
} else if (eventName === AppStateEvents.TagChanged) { } else if (eventName === AppStateEvents.TagChanged) {
this.setState({ this.setState({
selectedTag: this.appState.getSelectedTag() selectedTag: this.appState.getSelectedTag()
}); });
} }
});
} }
reloadNoteCounts() { reloadNoteCounts() {

View File

@@ -40,10 +40,8 @@ class AccountMenuCtrl extends PureCtrl {
godService, godService,
lockManager, lockManager,
) { ) {
super($timeout); super($scope, $timeout, application, appState);
this.$scope = $scope;
this.$rootScope = $rootScope; this.$rootScope = $rootScope;
this.$timeout = $timeout;
this.appState = appState; this.appState = appState;
this.application = application; this.application = application;
this.archiveManager = archiveManager; this.archiveManager = archiveManager;
@@ -59,7 +57,7 @@ class AccountMenuCtrl extends PureCtrl {
}, },
mutable: {} mutable: {}
}; };
application.onReady(async () => { application.onUnlock(async () => {
this.setState(await this.refreshedCredentialState()); this.setState(await this.refreshedCredentialState());
this.loadHost(); this.loadHost();
this.checkForSecurityUpdate(); this.checkForSecurityUpdate();

View File

@@ -4,13 +4,13 @@ import { PureCtrl } from '@Controllers';
class ActionsMenuCtrl extends PureCtrl { class ActionsMenuCtrl extends PureCtrl {
/* @ngInject */ /* @ngInject */
constructor( constructor(
$scope,
$timeout, $timeout,
application, application,
appState,
godService godService
) { ) {
super($timeout); super($scope, $timeout, application, appState);
this.$timeout = $timeout;
this.application = application;
this.godService = godService; this.godService = godService;
} }

View File

@@ -5,11 +5,12 @@ import { PureCtrl } from '@Controllers';
class EditorMenuCtrl extends PureCtrl { class EditorMenuCtrl extends PureCtrl {
/* @ngInject */ /* @ngInject */
constructor( constructor(
$scope,
$timeout, $timeout,
application application,
appState
) { ) {
super($timeout); super($scope, $timeout, application, appState);
this.application = application;
this.state = { this.state = {
isDesktop: isDesktopApplication() isDesktop: isDesktopApplication()
}; };

View File

@@ -11,7 +11,7 @@ class PrivilegesManagementModalCtrl {
this.$element = $element; this.$element = $element;
this.$timeout = $timeout; this.$timeout = $timeout;
this.application = application; this.application = application;
application.onReady(() => { application.onUnlock(() => {
this.hasPasscode = application.hasPasscode(); this.hasPasscode = application.hasPasscode();
this.hasAccount = !application.noAccount(); this.hasAccount = !application.noAccount();
this.reloadPrivileges(); this.reloadPrivileges();

View File

@@ -15,8 +15,9 @@ export class NativeExtManager {
this.resolveExtensionsManager(); this.resolveExtensionsManager();
this.resolveBatchManager(); this.resolveBatchManager();
application.onReady(() => { application.onUnlock(() => {
this.initialize(); this.resolveExtensionsManager();
this.resolveBatchManager();
}); });
} }
@@ -24,11 +25,6 @@ export class NativeExtManager {
return this.systemExtensions.includes(extension.uuid); return this.systemExtensions.includes(extension.uuid);
} }
async initialize() {
this.resolveExtensionsManager();
this.resolveBatchManager();
}
extensionsManagerTemplatePayload() { extensionsManagerTemplatePayload() {
const url = window._extensions_manager_location; const url = window._extensions_manager_location;
if (!url) { if (!url) {

View File

@@ -1,5 +1,4 @@
import { SFPredicate, CreateMaxPayloadFromAnyObject } from 'snjs'; import { SFPredicate, CreateMaxPayloadFromAnyObject } from 'snjs';
import { AppStateEvents } from '../state';
export const PrefKeys = { export const PrefKeys = {
TagsPanelWidth: 'tagsPanelWidth', TagsPanelWidth: 'tagsPanelWidth',
@@ -26,16 +25,12 @@ export class PreferencesManager {
) { ) {
this.application = application; this.application = application;
this.appState = appState; this.appState = appState;
application.onReady(() => { application.onUnlock(() => {
this.initialize(); this.streamPreferences();
this.loadSingleton();
}); });
} }
async initialize() {
this.streamPreferences();
await this.loadSingleton();
}
streamPreferences() { streamPreferences() {
this.application.streamItems({ this.application.streamItems({
contentType: 'SN|UserPreferences', contentType: 'SN|UserPreferences',

View File

@@ -1,33 +1,40 @@
import _ from 'lodash'; import _ from 'lodash';
import { ContentTypes, StorageValueModes, EncryptionIntents } from 'snjs'; import { ContentTypes, StorageValueModes, EncryptionIntents, PureService } from 'snjs';
import { AppStateEvents } from '@/state'; import { AppStateEvents } from '@/state';
const CACHED_THEMES_KEY = 'cachedThemes'; const CACHED_THEMES_KEY = 'cachedThemes';
export class ThemeManager { export class ThemeManager extends PureService {
/* @ngInject */ /* @ngInject */
constructor( constructor(
application, application,
appState, appState,
desktopManager, desktopManager,
) { ) {
super();
this.application = application; this.application = application;
this.appState = appState; this.appState = appState;
this.desktopManager = desktopManager; this.desktopManager = desktopManager;
this.activeThemes = []; this.activeThemes = [];
this.registerObservers(); this.registerObservers();
application.onReady(() => { application.onStart(() => {
if (!desktopManager.isDesktop) { if (!desktopManager.isDesktop) {
this.activateCachedThemes(); this.activateCachedThemes();
} }
}); });
appState.addObserver((eventName, data) => { this.unsubState = appState.addObserver((eventName, data) => {
if (eventName === AppStateEvents.DesktopExtsReady) { if (eventName === AppStateEvents.DesktopExtsReady) {
this.activateCachedThemes(); this.activateCachedThemes();
} }
}); });
} }
/** @override */
async deinit() {
super.deinit();
this.unsubState();
}
async activateCachedThemes() { async activateCachedThemes() {
const cachedThemes = await this.getCachedThemes(); const cachedThemes = await this.getCachedThemes();
const writeToCache = false; const writeToCache = false;

View File

@@ -13,8 +13,6 @@ export const AppStateEvents = {
DesktopExtsReady: 8, DesktopExtsReady: 8,
WindowDidFocus: 9, WindowDidFocus: 9,
WindowDidBlur: 10, WindowDidBlur: 10,
/** Register observers and streamers on this event */
ApplicationReady: 11
}; };
export const EventSources = { export const EventSources = {
@@ -80,11 +78,6 @@ export class AppState {
}); });
} }
async setApplicationReady() {
this.applicationReady = true;
await this.notifyEvent(AppStateEvents.ApplicationReady);
}
setSelectedTag(tag) { setSelectedTag(tag) {
if (this.selectedTag === tag) { if (this.selectedTag === tag) {
return; return;
@@ -93,7 +86,10 @@ export class AppState {
this.selectedTag = tag; this.selectedTag = tag;
this.notifyEvent( this.notifyEvent(
AppStateEvents.TagChanged, AppStateEvents.TagChanged,
{ previousTag: previousTag } {
tag: tag,
previousTag: previousTag
}
); );
} }

View File

@@ -109,9 +109,9 @@
threshold='200' threshold='200'
) )
.note( .note(
ng-class="{'selected' : self.state.selectedNote == note}",
ng-click='self.selectNote(note, true)',
ng-repeat='note in self.state.renderedNotes track by note.uuid' ng-repeat='note in self.state.renderedNotes track by note.uuid'
ng-class="{'selected' : self.state.selectedNote == note}"
ng-click='self.selectNote(note, true)'
) )
.note-flags(ng-show='note.flags.length > 0') .note-flags(ng-show='note.flags.length > 0')
.flag(ng-class='flag.class', ng-repeat='flag in note.flags') .flag(ng-class='flag.class', ng-repeat='flag in note.flags')

1722
dist/javascripts/app.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long