Make app init more idempotent (#7676)

* Make app init more idempotent

* Remove previous subscriptions
This commit is contained in:
Daniel Espino García 2023-12-04 17:01:08 +01:00 committed by GitHub
parent ab7da5f664
commit d469470592
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 28 deletions

View file

@ -19,10 +19,6 @@ import NavigationStore from '@store/navigation_store';
// or on the Share Extension, for example.
let baseAppInitialized = false;
// Controls whether the app initialization (websockets, screen listeners, etc...) is done, mainly
// on app launch
let mainAppInitialized = false;
let serverCredentials: ServerCredential[];
// Fallback Polyfill for Promise.allSettle
@ -55,25 +51,19 @@ export async function initialize() {
}
export async function start() {
if (baseAppInitialized) {
// Clean relevant information on ephemeral stores
NavigationStore.reset();
EphemeralStore.setCurrentThreadId('');
EphemeralStore.setProcessingNotification('');
}
// Clean relevant information on ephemeral stores
NavigationStore.reset();
EphemeralStore.setCurrentThreadId('');
EphemeralStore.setProcessingNotification('');
await initialize();
if (!mainAppInitialized) {
mainAppInitialized = true;
PushNotifications.init(serverCredentials.length > 0);
PushNotifications.init(serverCredentials.length > 0);
registerNavigationListeners();
registerScreens();
registerNavigationListeners();
registerScreens();
await WebsocketManager.init(serverCredentials);
}
await WebsocketManager.init(serverCredentials);
initialLaunch();
}

View file

@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {AppState, DeviceEventEmitter, Platform} from 'react-native';
import {AppState, DeviceEventEmitter, Platform, type EmitterSubscription} from 'react-native';
import {
Notification,
NotificationAction,
@ -36,12 +36,16 @@ import {convertToNotificationData} from '@utils/notification';
class PushNotifications {
configured = false;
subscriptions?: EmitterSubscription[];
init(register: boolean) {
Notifications.events().registerNotificationOpened(this.onNotificationOpened);
Notifications.events().registerRemoteNotificationsRegistered(this.onRemoteNotificationsRegistered);
Notifications.events().registerNotificationReceivedBackground(this.onNotificationReceivedBackground);
Notifications.events().registerNotificationReceivedForeground(this.onNotificationReceivedForeground);
this.subscriptions?.forEach((v) => v.remove());
this.subscriptions = [
Notifications.events().registerNotificationOpened(this.onNotificationOpened),
Notifications.events().registerRemoteNotificationsRegistered(this.onRemoteNotificationsRegistered),
Notifications.events().registerNotificationReceivedBackground(this.onNotificationReceivedBackground),
Notifications.events().registerNotificationReceivedForeground(this.onNotificationReceivedForeground),
];
if (register) {
this.registerIfNeeded();

View file

@ -70,6 +70,10 @@ class WebsocketManager {
};
public createClient = (serverUrl: string, bearerToken: string, storedLastDisconnect = 0) => {
if (this.clients[serverUrl]) {
this.invalidateClient(serverUrl);
}
const client = new WebSocketClient(serverUrl, bearerToken, storedLastDisconnect);
client.setFirstConnectCallback(() => this.onFirstConnect(serverUrl));

View file

@ -4,8 +4,8 @@
/* eslint-disable max-lines */
import merge from 'deepmerge';
import {Appearance, DeviceEventEmitter, NativeModules, StatusBar, Platform, Alert} from 'react-native';
import {type ComponentWillAppearEvent, type ImageResource, type LayoutOrientation, Navigation, type Options, OptionsModalPresentationStyle, type OptionsTopBarButton, type ScreenPoppedEvent} from 'react-native-navigation';
import {Appearance, DeviceEventEmitter, NativeModules, StatusBar, Platform, Alert, type EmitterSubscription} from 'react-native';
import {type ComponentWillAppearEvent, type ImageResource, type LayoutOrientation, Navigation, type Options, OptionsModalPresentationStyle, type OptionsTopBarButton, type ScreenPoppedEvent, type EventSubscription} from 'react-native-navigation';
import tinyColor from 'tinycolor2';
import CompassIcon from '@components/compass_icon';
@ -30,14 +30,18 @@ const alpha = {
to: 1,
duration: 150,
};
let subscriptions: Array<EmitterSubscription | EventSubscription> | undefined;
export const allOrientations: LayoutOrientation[] = ['sensor', 'sensorLandscape', 'sensorPortrait', 'landscape', 'portrait'];
export const portraitOrientation: LayoutOrientation[] = ['portrait'];
export function registerNavigationListeners() {
Navigation.events().registerScreenPoppedListener(onPoppedListener);
Navigation.events().registerCommandListener(onCommandListener);
Navigation.events().registerComponentWillAppearListener(onScreenWillAppear);
subscriptions?.forEach((v) => v.remove());
subscriptions = [
Navigation.events().registerScreenPoppedListener(onPoppedListener),
Navigation.events().registerCommandListener(onCommandListener),
Navigation.events().registerComponentWillAppearListener(onScreenWillAppear),
];
}
function onCommandListener(name: string, params: any) {