fix: improve deinit logic and flow
This commit is contained in:
@@ -196,10 +196,17 @@ export class ApplicationView extends PureComponent<Props, State> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
if (this.application['dealloced'] === true) {
|
||||||
|
console.error('Attempting to render dealloced application');
|
||||||
|
return <div></div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderAppContents = !this.state.needsUnlock && this.state.launched;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PremiumModalProvider state={this.appState.features}>
|
<PremiumModalProvider state={this.appState?.features}>
|
||||||
<div className={this.platformString + ' main-ui-view sn-component'}>
|
<div className={this.platformString + ' main-ui-view sn-component'}>
|
||||||
{!this.state.needsUnlock && this.state.launched && (
|
{renderAppContents && (
|
||||||
<div
|
<div
|
||||||
id="app"
|
id="app"
|
||||||
className={this.state.appClass + ' app app-column-container'}
|
className={this.state.appClass + ' app app-column-container'}
|
||||||
@@ -215,23 +222,25 @@ export class ApplicationView extends PureComponent<Props, State> {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!this.state.needsUnlock && this.state.launched && (
|
{renderAppContents && (
|
||||||
<Footer
|
<>
|
||||||
application={this.application}
|
<Footer
|
||||||
applicationGroup={this.props.mainApplicationGroup}
|
application={this.application}
|
||||||
/>
|
applicationGroup={this.props.mainApplicationGroup}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SessionsModal
|
||||||
|
application={this.application}
|
||||||
|
appState={this.appState}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PreferencesViewWrapper
|
||||||
|
appState={this.appState}
|
||||||
|
application={this.application}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<SessionsModal
|
|
||||||
application={this.application}
|
|
||||||
appState={this.appState}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<PreferencesViewWrapper
|
|
||||||
appState={this.appState}
|
|
||||||
application={this.application}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{this.state.challenges.map((challenge) => {
|
{this.state.challenges.map((challenge) => {
|
||||||
return (
|
return (
|
||||||
<div className="sk-modal">
|
<div className="sk-modal">
|
||||||
@@ -245,15 +254,19 @@ export class ApplicationView extends PureComponent<Props, State> {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
<NotesContextMenu
|
{renderAppContents && (
|
||||||
application={this.application}
|
<>
|
||||||
appState={this.appState}
|
<NotesContextMenu
|
||||||
/>
|
application={this.application}
|
||||||
|
appState={this.appState}
|
||||||
|
/>
|
||||||
|
|
||||||
<PurchaseFlowWrapper
|
<PurchaseFlowWrapper
|
||||||
application={this.application}
|
application={this.application}
|
||||||
appState={this.appState}
|
appState={this.appState}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</PremiumModalProvider>
|
</PremiumModalProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { FeaturesState } from '@/ui_models/app_state/features_state';
|
import { FeaturesState } from '@/ui_models/app_state/features_state';
|
||||||
import { observer } from 'mobx-react-lite';
|
import { observer } from 'mobx-react-lite';
|
||||||
import { FunctionalComponent } from 'preact';
|
import { FunctionalComponent } from 'preact';
|
||||||
import { useCallback, useContext, useState } from 'preact/hooks';
|
import { useContext } from 'preact/hooks';
|
||||||
import { createContext } from 'react';
|
import { createContext } from 'react';
|
||||||
import { PremiumFeaturesModal } from '../PremiumFeaturesModal';
|
import { PremiumFeaturesModal } from '../PremiumFeaturesModal';
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,6 @@ export class AppState {
|
|||||||
|
|
||||||
private readonly tagChangedDisposer: IReactionDisposer;
|
private readonly tagChangedDisposer: IReactionDisposer;
|
||||||
|
|
||||||
/* @ngInject */
|
|
||||||
constructor(application: WebApplication, private bridge: Bridge) {
|
constructor(application: WebApplication, private bridge: Bridge) {
|
||||||
this.application = application;
|
this.application = application;
|
||||||
this.notes = new NotesState(
|
this.notes = new NotesState(
|
||||||
@@ -171,18 +170,39 @@ export class AppState {
|
|||||||
storage.remove(StorageKey.ShowBetaWarning);
|
storage.remove(StorageKey.ShowBetaWarning);
|
||||||
this.noAccountWarning.reset();
|
this.noAccountWarning.reset();
|
||||||
}
|
}
|
||||||
|
(this.application as unknown) = undefined;
|
||||||
this.actionsMenu.reset();
|
this.actionsMenu.reset();
|
||||||
this.unsubApp?.();
|
this.unsubApp?.();
|
||||||
this.unsubApp = undefined;
|
this.unsubApp = undefined;
|
||||||
this.observers.length = 0;
|
this.observers.length = 0;
|
||||||
|
|
||||||
this.appEventObserverRemovers.forEach((remover) => remover());
|
this.appEventObserverRemovers.forEach((remover) => remover());
|
||||||
this.features.deinit();
|
|
||||||
this.appEventObserverRemovers.length = 0;
|
this.appEventObserverRemovers.length = 0;
|
||||||
|
|
||||||
|
this.features.deinit();
|
||||||
|
(this.features as unknown) = undefined;
|
||||||
|
|
||||||
this.webAppEventDisposer?.();
|
this.webAppEventDisposer?.();
|
||||||
this.webAppEventDisposer = undefined;
|
this.webAppEventDisposer = undefined;
|
||||||
|
|
||||||
|
(this.quickSettingsMenu as unknown) = undefined;
|
||||||
|
(this.accountMenu as unknown) = undefined;
|
||||||
|
(this.actionsMenu as unknown) = undefined;
|
||||||
|
(this.preferences as unknown) = undefined;
|
||||||
|
(this.purchaseFlow as unknown) = undefined;
|
||||||
|
(this.noteTags as unknown) = undefined;
|
||||||
|
(this.sync as unknown) = undefined;
|
||||||
|
(this.searchOptions as unknown) = undefined;
|
||||||
|
(this.notes as unknown) = undefined;
|
||||||
|
(this.features as unknown) = undefined;
|
||||||
|
(this.tags as unknown) = undefined;
|
||||||
|
(this.notesView as unknown) = undefined;
|
||||||
|
|
||||||
document.removeEventListener('visibilitychange', this.onVisibilityChange);
|
document.removeEventListener('visibilitychange', this.onVisibilityChange);
|
||||||
this.onVisibilityChange = undefined;
|
this.onVisibilityChange = undefined;
|
||||||
|
|
||||||
this.tagChangedDisposer();
|
this.tagChangedDisposer();
|
||||||
|
(this.tagChangedDisposer as unknown) = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
openSessionsModal(): void {
|
openSessionsModal(): void {
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ export type WebEventObserver = (event: WebAppEvent) => void;
|
|||||||
|
|
||||||
export class WebApplication extends SNApplication {
|
export class WebApplication extends SNApplication {
|
||||||
private webServices!: WebServices;
|
private webServices!: WebServices;
|
||||||
public noteControllerGroup: NoteGroupController;
|
|
||||||
private webEventObservers: WebEventObserver[] = [];
|
private webEventObservers: WebEventObserver[] = [];
|
||||||
|
public noteControllerGroup: NoteGroupController;
|
||||||
public iconsController: IconsController;
|
public iconsController: IconsController;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -70,28 +70,26 @@ export class WebApplication extends SNApplication {
|
|||||||
this.iconsController = new IconsController();
|
this.iconsController = new IconsController();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @override */
|
|
||||||
deinit(source: DeinitSource): void {
|
deinit(source: DeinitSource): void {
|
||||||
for (const service of Object.values(this.webServices)) {
|
super.deinit(source);
|
||||||
if ('deinit' in service) {
|
try {
|
||||||
service.deinit?.(source);
|
for (const service of Object.values(this.webServices)) {
|
||||||
|
if ('deinit' in service) {
|
||||||
|
service.deinit?.(source);
|
||||||
|
}
|
||||||
|
(service as any).application = undefined;
|
||||||
}
|
}
|
||||||
(service as any).application = undefined;
|
this.webServices = {} as WebServices;
|
||||||
}
|
this.noteControllerGroup.deinit();
|
||||||
this.webServices = {} as WebServices;
|
this.iconsController.deinit();
|
||||||
this.noteControllerGroup.deinit();
|
this.webEventObservers.length = 0;
|
||||||
this.iconsController.deinit();
|
|
||||||
this.webEventObservers.length = 0;
|
|
||||||
/**
|
|
||||||
* Allow any pending renders to complete before destroying the global
|
|
||||||
* application instance and all its services
|
|
||||||
*/
|
|
||||||
setTimeout(() => {
|
|
||||||
super.deinit(source);
|
|
||||||
if (source === DeinitSource.SignOut) {
|
if (source === DeinitSource.SignOut) {
|
||||||
this.bridge.onSignOut();
|
this.bridge.onSignOut();
|
||||||
}
|
}
|
||||||
}, 0);
|
} catch (error) {
|
||||||
|
console.error('Error while deiniting application', error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setWebServices(services: WebServices): void {
|
setWebServices(services: WebServices): void {
|
||||||
|
|||||||
@@ -84,7 +84,7 @@
|
|||||||
"@reach/tooltip": "^0.16.2",
|
"@reach/tooltip": "^0.16.2",
|
||||||
"@standardnotes/components": "1.7.0",
|
"@standardnotes/components": "1.7.0",
|
||||||
"@standardnotes/features": "1.29.0",
|
"@standardnotes/features": "1.29.0",
|
||||||
"@standardnotes/snjs": "2.52.1",
|
"@standardnotes/snjs": "2.52.2",
|
||||||
"@standardnotes/settings": "^1.11.3",
|
"@standardnotes/settings": "^1.11.3",
|
||||||
"@standardnotes/sncrypto-web": "1.6.2",
|
"@standardnotes/sncrypto-web": "1.6.2",
|
||||||
"mobx": "^6.3.5",
|
"mobx": "^6.3.5",
|
||||||
|
|||||||
@@ -2650,10 +2650,10 @@
|
|||||||
buffer "^6.0.3"
|
buffer "^6.0.3"
|
||||||
libsodium-wrappers "^0.7.9"
|
libsodium-wrappers "^0.7.9"
|
||||||
|
|
||||||
"@standardnotes/snjs@2.52.1":
|
"@standardnotes/snjs@2.52.2":
|
||||||
version "2.52.1"
|
version "2.52.2"
|
||||||
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.52.1.tgz#00e2e1f7eaeef2c95b6830470031496e48ff4b83"
|
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.52.2.tgz#34d1edd3028aa860648548292291d6ecf8666a5f"
|
||||||
integrity sha512-U35dangXmhl1uEnPcDmWrRlqHyT/N5KIE5izT8w0xkhrWpc5a62j+m0u2uJNYU7C00d6ERqVWXeHCDsdSXTx8A==
|
integrity sha512-5w2RXSquTmyYNSyKgEYqmLLqbHyYCsyrqfWlL0nuQ//hBFcf8OUbsY+Ys132TodpGZn637Al+kygoZxGBVcSyA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/auth" "^3.15.4"
|
"@standardnotes/auth" "^3.15.4"
|
||||||
"@standardnotes/common" "^1.9.0"
|
"@standardnotes/common" "^1.9.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user