fix: improve deinit logic and flow

This commit is contained in:
Mo
2022-02-08 21:35:31 -06:00
parent 1dd70364e7
commit e43c8a6f07
6 changed files with 82 additions and 51 deletions

View File

@@ -196,10 +196,17 @@ export class ApplicationView extends PureComponent<Props, State> {
};
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 (
<PremiumModalProvider state={this.appState.features}>
<PremiumModalProvider state={this.appState?.features}>
<div className={this.platformString + ' main-ui-view sn-component'}>
{!this.state.needsUnlock && this.state.launched && (
{renderAppContents && (
<div
id="app"
className={this.state.appClass + ' app app-column-container'}
@@ -215,23 +222,25 @@ export class ApplicationView extends PureComponent<Props, State> {
</div>
)}
{!this.state.needsUnlock && this.state.launched && (
<Footer
application={this.application}
applicationGroup={this.props.mainApplicationGroup}
/>
{renderAppContents && (
<>
<Footer
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) => {
return (
<div className="sk-modal">
@@ -245,15 +254,19 @@ export class ApplicationView extends PureComponent<Props, State> {
);
})}
<NotesContextMenu
application={this.application}
appState={this.appState}
/>
{renderAppContents && (
<>
<NotesContextMenu
application={this.application}
appState={this.appState}
/>
<PurchaseFlowWrapper
application={this.application}
appState={this.appState}
/>
<PurchaseFlowWrapper
application={this.application}
appState={this.appState}
/>
</>
)}
</div>
</PremiumModalProvider>
);

View File

@@ -1,7 +1,7 @@
import { FeaturesState } from '@/ui_models/app_state/features_state';
import { observer } from 'mobx-react-lite';
import { FunctionalComponent } from 'preact';
import { useCallback, useContext, useState } from 'preact/hooks';
import { useContext } from 'preact/hooks';
import { createContext } from 'react';
import { PremiumFeaturesModal } from '../PremiumFeaturesModal';

View File

@@ -93,7 +93,6 @@ export class AppState {
private readonly tagChangedDisposer: IReactionDisposer;
/* @ngInject */
constructor(application: WebApplication, private bridge: Bridge) {
this.application = application;
this.notes = new NotesState(
@@ -171,18 +170,39 @@ export class AppState {
storage.remove(StorageKey.ShowBetaWarning);
this.noAccountWarning.reset();
}
(this.application as unknown) = undefined;
this.actionsMenu.reset();
this.unsubApp?.();
this.unsubApp = undefined;
this.observers.length = 0;
this.appEventObserverRemovers.forEach((remover) => remover());
this.features.deinit();
this.appEventObserverRemovers.length = 0;
this.features.deinit();
(this.features as unknown) = undefined;
this.webAppEventDisposer?.();
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);
this.onVisibilityChange = undefined;
this.tagChangedDisposer();
(this.tagChangedDisposer as unknown) = undefined;
}
openSessionsModal(): void {

View File

@@ -39,8 +39,8 @@ export type WebEventObserver = (event: WebAppEvent) => void;
export class WebApplication extends SNApplication {
private webServices!: WebServices;
public noteControllerGroup: NoteGroupController;
private webEventObservers: WebEventObserver[] = [];
public noteControllerGroup: NoteGroupController;
public iconsController: IconsController;
constructor(
@@ -70,28 +70,26 @@ export class WebApplication extends SNApplication {
this.iconsController = new IconsController();
}
/** @override */
deinit(source: DeinitSource): void {
for (const service of Object.values(this.webServices)) {
if ('deinit' in service) {
service.deinit?.(source);
super.deinit(source);
try {
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.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);
this.webServices = {} as WebServices;
this.noteControllerGroup.deinit();
this.iconsController.deinit();
this.webEventObservers.length = 0;
if (source === DeinitSource.SignOut) {
this.bridge.onSignOut();
}
}, 0);
} catch (error) {
console.error('Error while deiniting application', error);
}
}
setWebServices(services: WebServices): void {

View File

@@ -84,7 +84,7 @@
"@reach/tooltip": "^0.16.2",
"@standardnotes/components": "1.7.0",
"@standardnotes/features": "1.29.0",
"@standardnotes/snjs": "2.52.1",
"@standardnotes/snjs": "2.52.2",
"@standardnotes/settings": "^1.11.3",
"@standardnotes/sncrypto-web": "1.6.2",
"mobx": "^6.3.5",

View File

@@ -2650,10 +2650,10 @@
buffer "^6.0.3"
libsodium-wrappers "^0.7.9"
"@standardnotes/snjs@2.52.1":
version "2.52.1"
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.52.1.tgz#00e2e1f7eaeef2c95b6830470031496e48ff4b83"
integrity sha512-U35dangXmhl1uEnPcDmWrRlqHyT/N5KIE5izT8w0xkhrWpc5a62j+m0u2uJNYU7C00d6ERqVWXeHCDsdSXTx8A==
"@standardnotes/snjs@2.52.2":
version "2.52.2"
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.52.2.tgz#34d1edd3028aa860648548292291d6ecf8666a5f"
integrity sha512-5w2RXSquTmyYNSyKgEYqmLLqbHyYCsyrqfWlL0nuQ//hBFcf8OUbsY+Ys132TodpGZn637Al+kygoZxGBVcSyA==
dependencies:
"@standardnotes/auth" "^3.15.4"
"@standardnotes/common" "^1.9.0"