feat: (wip) sessions management
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { isDesktopApplication } from '@/utils';
|
||||
import { isDesktopApplication, isDev } from '@/utils';
|
||||
import pull from 'lodash/pull';
|
||||
import {
|
||||
ProtectedAction,
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
PayloadSource,
|
||||
DeinitSource,
|
||||
UuidString,
|
||||
SyncOpStatus
|
||||
SyncOpStatus,
|
||||
} from '@standardnotes/snjs';
|
||||
import { WebApplication } from '@/ui_models/application';
|
||||
import { Editor } from '@/ui_models/editor';
|
||||
@@ -27,14 +27,14 @@ export enum AppStateEvent {
|
||||
EndedBackupDownload,
|
||||
WindowDidFocus,
|
||||
WindowDidBlur,
|
||||
};
|
||||
}
|
||||
|
||||
export enum EventSource {
|
||||
UserInteraction,
|
||||
Script,
|
||||
};
|
||||
}
|
||||
|
||||
type ObserverCallback = (event: AppStateEvent, data?: any) => Promise<void>
|
||||
type ObserverCallback = (event: AppStateEvent, data?: any) => Promise<void>;
|
||||
|
||||
const SHOW_BETA_WARNING_KEY = 'show_beta_warning';
|
||||
|
||||
@@ -76,7 +76,8 @@ export class SyncState {
|
||||
this.errorMessage = status.error?.message;
|
||||
this.inProgress = status.syncInProgress;
|
||||
const stats = status.getStats();
|
||||
const completionPercentage = stats.uploadCompletionCount === 0
|
||||
const completionPercentage =
|
||||
stats.uploadCompletionCount === 0
|
||||
? 0
|
||||
: stats.uploadCompletionCount / stats.uploadTotalCount;
|
||||
|
||||
@@ -92,6 +93,9 @@ export class SyncState {
|
||||
}
|
||||
|
||||
export class AppState {
|
||||
readonly enableUnfinishedFeatures =
|
||||
isDev || location.host.includes('app-dev.standardnotes.org');
|
||||
|
||||
$rootScope: ng.IRootScopeService;
|
||||
$timeout: ng.ITimeoutService;
|
||||
application: WebApplication;
|
||||
@@ -106,31 +110,36 @@ export class AppState {
|
||||
showBetaWarning = false;
|
||||
readonly actionsMenu = new ActionsMenuState();
|
||||
readonly sync = new SyncState();
|
||||
isSessionsModalVisible = true;
|
||||
|
||||
/* @ngInject */
|
||||
constructor(
|
||||
$rootScope: ng.IRootScopeService,
|
||||
$timeout: ng.ITimeoutService,
|
||||
application: WebApplication,
|
||||
private bridge: Bridge,
|
||||
private bridge: Bridge
|
||||
) {
|
||||
this.$timeout = $timeout;
|
||||
this.$rootScope = $rootScope;
|
||||
this.application = application;
|
||||
makeObservable(this, {
|
||||
showBetaWarning: observable,
|
||||
isSessionsModalVisible: observable,
|
||||
|
||||
enableBetaWarning: action,
|
||||
disableBetaWarning: action,
|
||||
openSessionsModal: action,
|
||||
closeSessionsModal: action,
|
||||
});
|
||||
this.addAppEventObserver();
|
||||
this.streamNotesAndTags();
|
||||
this.onVisibilityChange = () => {
|
||||
const visible = document.visibilityState === "visible";
|
||||
const visible = document.visibilityState === 'visible';
|
||||
const event = visible
|
||||
? AppStateEvent.WindowDidFocus
|
||||
: AppStateEvent.WindowDidBlur;
|
||||
this.notifyEvent(event);
|
||||
}
|
||||
};
|
||||
this.registerVisibilityObservers();
|
||||
this.determineBetaWarningValue();
|
||||
}
|
||||
@@ -153,6 +162,14 @@ export class AppState {
|
||||
this.onVisibilityChange = undefined;
|
||||
}
|
||||
|
||||
openSessionsModal() {
|
||||
this.isSessionsModalVisible = true;
|
||||
}
|
||||
|
||||
closeSessionsModal() {
|
||||
this.isSessionsModalVisible = false;
|
||||
}
|
||||
|
||||
disableBetaWarning() {
|
||||
this.showBetaWarning = false;
|
||||
localStorage.setItem(SHOW_BETA_WARNING_KEY, 'false');
|
||||
@@ -188,10 +205,10 @@ export class AppState {
|
||||
async createEditor(title?: string) {
|
||||
const activeEditor = this.getActiveEditor();
|
||||
const activeTagUuid = this.selectedTag
|
||||
? this.selectedTag.isSmartTag()
|
||||
? undefined
|
||||
: this.selectedTag.uuid
|
||||
: undefined;
|
||||
? this.selectedTag.isSmartTag()
|
||||
? undefined
|
||||
: this.selectedTag.uuid
|
||||
: undefined;
|
||||
|
||||
if (!activeEditor || this.multiEditorEnabled) {
|
||||
this.application.editorGroup.createEditor(
|
||||
@@ -216,10 +233,13 @@ export class AppState {
|
||||
}
|
||||
await this.notifyEvent(AppStateEvent.ActiveEditorChanged);
|
||||
};
|
||||
if (note && note.safeContent.protected &&
|
||||
await this.application.privilegesService!.actionRequiresPrivilege(
|
||||
if (
|
||||
note &&
|
||||
note.safeContent.protected &&
|
||||
(await this.application.privilegesService!.actionRequiresPrivilege(
|
||||
ProtectedAction.ViewProtectedNotes
|
||||
)) {
|
||||
))
|
||||
) {
|
||||
return new Promise((resolve) => {
|
||||
this.application.presentPrivilegesModal(
|
||||
ProtectedAction.ViewProtectedNotes,
|
||||
@@ -267,8 +287,8 @@ export class AppState {
|
||||
async (items, source) => {
|
||||
/** Close any editors for deleted/trashed/archived notes */
|
||||
if (source === PayloadSource.PreSyncSave) {
|
||||
const notes = items.filter((candidate) =>
|
||||
candidate.content_type === ContentType.Note
|
||||
const notes = items.filter(
|
||||
(candidate) => candidate.content_type === ContentType.Note
|
||||
) as SNNote[];
|
||||
for (const note of notes) {
|
||||
const editor = this.editorForNote(note);
|
||||
@@ -285,7 +305,9 @@ export class AppState {
|
||||
}
|
||||
}
|
||||
if (this.selectedTag) {
|
||||
const matchingTag = items.find((candidate) => candidate.uuid === this.selectedTag!.uuid);
|
||||
const matchingTag = items.find(
|
||||
(candidate) => candidate.uuid === this.selectedTag!.uuid
|
||||
);
|
||||
if (matchingTag) {
|
||||
this.selectedTag = matchingTag as SNTag;
|
||||
}
|
||||
@@ -319,9 +341,12 @@ export class AppState {
|
||||
this.rootScopeCleanup1 = this.$rootScope.$on('window-lost-focus', () => {
|
||||
this.notifyEvent(AppStateEvent.WindowDidBlur);
|
||||
});
|
||||
this.rootScopeCleanup2 = this.$rootScope.$on('window-gained-focus', () => {
|
||||
this.notifyEvent(AppStateEvent.WindowDidFocus);
|
||||
});
|
||||
this.rootScopeCleanup2 = this.$rootScope.$on(
|
||||
'window-gained-focus',
|
||||
() => {
|
||||
this.notifyEvent(AppStateEvent.WindowDidFocus);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
/* Tab visibility listener, web only */
|
||||
document.addEventListener('visibilitychange', this.onVisibilityChange);
|
||||
@@ -341,7 +366,7 @@ export class AppState {
|
||||
* Timeout is particullary important so we can give all initial
|
||||
* controllers a chance to construct before propogting any events *
|
||||
*/
|
||||
return new Promise((resolve) => {
|
||||
return new Promise<void>((resolve) => {
|
||||
this.$timeout(async () => {
|
||||
for (const callback of this.observers) {
|
||||
await callback(eventName, data);
|
||||
@@ -357,20 +382,17 @@ export class AppState {
|
||||
}
|
||||
const previousTag = this.selectedTag;
|
||||
this.selectedTag = tag;
|
||||
this.notifyEvent(
|
||||
AppStateEvent.TagChanged,
|
||||
{
|
||||
tag: tag,
|
||||
previousTag: previousTag
|
||||
}
|
||||
);
|
||||
this.notifyEvent(AppStateEvent.TagChanged, {
|
||||
tag: tag,
|
||||
previousTag: previousTag,
|
||||
});
|
||||
}
|
||||
|
||||
/** Returns the tags that are referncing this note */
|
||||
public getNoteTags(note: SNNote) {
|
||||
return this.application.referencingForItem(note).filter((ref) => {
|
||||
return ref.content_type === ContentType.Tag;
|
||||
}) as SNTag[]
|
||||
}) as SNTag[];
|
||||
}
|
||||
|
||||
public getSelectedTag() {
|
||||
@@ -378,32 +400,21 @@ export class AppState {
|
||||
}
|
||||
|
||||
panelDidResize(name: string, collapsed: boolean) {
|
||||
this.notifyEvent(
|
||||
AppStateEvent.PanelResized,
|
||||
{
|
||||
panel: name,
|
||||
collapsed: collapsed
|
||||
}
|
||||
);
|
||||
this.notifyEvent(AppStateEvent.PanelResized, {
|
||||
panel: name,
|
||||
collapsed: collapsed,
|
||||
});
|
||||
}
|
||||
|
||||
editorDidFocus(eventSource: EventSource) {
|
||||
this.notifyEvent(
|
||||
AppStateEvent.EditorFocused,
|
||||
{ eventSource: eventSource }
|
||||
);
|
||||
this.notifyEvent(AppStateEvent.EditorFocused, { eventSource: eventSource });
|
||||
}
|
||||
|
||||
beganBackupDownload() {
|
||||
this.notifyEvent(
|
||||
AppStateEvent.BeganBackupDownload
|
||||
);
|
||||
this.notifyEvent(AppStateEvent.BeganBackupDownload);
|
||||
}
|
||||
|
||||
endedBackupDownload(success: boolean) {
|
||||
this.notifyEvent(
|
||||
AppStateEvent.EndedBackupDownload,
|
||||
{ success: success }
|
||||
);
|
||||
this.notifyEvent(AppStateEvent.EndedBackupDownload, { success: success });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user