Fix problems related to closing react but keeping other state (#7405)

This commit is contained in:
Daniel Espino García
2023-06-28 12:49:58 +02:00
committed by GitHub
parent 72f7c639c7
commit 0a3f5e5914
7 changed files with 63 additions and 10 deletions

View File

@@ -180,6 +180,13 @@ export const backgroundNotification = async (serverUrl: string, notification: No
};
export const openNotification = async (serverUrl: string, notification: NotificationWithData) => {
// Wait for initial launch to kick in if needed
await new Promise((r) => setTimeout(r, 500));
if (EphemeralStore.getProcessingNotification() === notification.identifier) {
return {};
}
EphemeralStore.setNotificationTapped(true);
const channelId = notification.payload!.channel_id!;

View File

@@ -12,8 +12,17 @@ import SessionManager from '@managers/session_manager';
import WebsocketManager from '@managers/websocket_manager';
import {registerScreens} from '@screens/index';
import {registerNavigationListeners} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import NavigationStore from '@store/navigation_store';
// Controls whether the main initialization (database, etc...) is done, either on app launch
// 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 alreadyInitialized = false;
let serverCredentials: ServerCredential[];
// Fallback Polyfill for Promise.allSettle
@@ -31,8 +40,8 @@ Promise.allSettled = Promise.allSettled || (<T>(promises: Array<Promise<T>>) =>
));
export async function initialize() {
if (!alreadyInitialized) {
alreadyInitialized = true;
if (!baseAppInitialized) {
baseAppInitialized = true;
serverCredentials = await getAllServerCredentials();
const serverUrls = serverCredentials.map((credential) => credential.serverUrl);
@@ -46,12 +55,25 @@ export async function initialize() {
}
export async function start() {
if (baseAppInitialized) {
// Clean relevant information on ephemeral stores
NavigationStore.reset();
EphemeralStore.setCurrentThreadId('');
EphemeralStore.setProcessingNotification('');
}
await initialize();
PushNotifications.init(serverCredentials.length > 0);
if (!mainAppInitialized) {
mainAppInitialized = true;
PushNotifications.init(serverCredentials.length > 0);
registerNavigationListeners();
registerScreens();
await WebsocketManager.init(serverCredentials);
}
registerNavigationListeners();
registerScreens();
await WebsocketManager.init(serverCredentials);
initialLaunch();
}

View File

@@ -42,7 +42,9 @@ export const initialLaunch = async () => {
tapped = delivered.find((d) => (d as unknown as NotificationData).ack_id === notification?.payload.ack_id) == null;
}
if (initialNotificationTypes.includes(notification?.payload?.type) && tapped) {
return launchAppFromNotification(convertToNotificationData(notification!), true);
const notificationData = convertToNotificationData(notification!);
EphemeralStore.setProcessingNotification(notificationData.identifier);
return launchAppFromNotification(notificationData, true);
}
const coldStart = notification ? (tapped || AppState.currentState === 'active') : true;

View File

@@ -14,6 +14,7 @@ import {NOT_READY} from '@constants/screens';
import {getDefaultThemeByAppearance} from '@context/theme';
import EphemeralStore from '@store/ephemeral_store';
import NavigationStore from '@store/navigation_store';
import {logError} from '@utils/log';
import {appearanceControlledScreens, mergeNavigationOptions} from '@utils/navigation';
import {changeOpacity, setNavigatorStyles} from '@utils/theme';
@@ -449,6 +450,11 @@ export function goToScreen(name: AvailableScreens, title: string, passProps = {}
const theme = getThemeFromState();
const isDark = tinyColor(theme.sidebarBg).isDark();
const componentId = NavigationStore.getVisibleScreen();
if (!componentId) {
logError('Trying to go to screen without any screen on the navigation store');
return '';
}
const defaultOptions: Options = {
layout: {
componentBackgroundColor: theme.centerChannelBg,

View File

@@ -38,6 +38,16 @@ class EphemeralStore {
private notificationTapped = false;
private enablingCRT = false;
// There are some corner cases where the react context is not loaded (and therefore
// launch will be called) but the notification callbacks are registered. This is used
// so the notification is processed only once (preferably on launch).
private processingNotification = '';
setProcessingNotification = (v: string) => {
this.processingNotification = v;
};
getProcessingNotification = () => this.processingNotification;
addLoadingMessagesForChannel = (serverUrl: string, channelId: string) => {
if (!this.loadingMessagesForChannel[serverUrl]) {
this.loadingMessagesForChannel[serverUrl] = new Set();

View File

@@ -9,6 +9,13 @@ class NavigationStore {
private visibleTab = 'Home';
private tosOpen = false;
reset = () => {
this.screensInStack = [];
this.modalsInStack = [];
this.visibleTab = 'Home';
this.tosOpen = false;
};
addModalToStack = (modalId: AvailableScreens) => {
this.removeModalFromStack(modalId);
this.addScreenToStack(modalId);

View File

@@ -8,7 +8,7 @@ import {RUNNING_E2E} from 'react-native-dotenv';
import 'react-native-gesture-handler';
import {Navigation} from 'react-native-navigation';
import {initialize, start} from './app/init/app';
import {start} from './app/init/app';
import setFontFamily from './app/utils/font_family';
import {logInfo} from './app/utils/log';
@@ -59,6 +59,5 @@ if (Platform.OS === 'android') {
}
Navigation.events().registerAppLaunchedListener(async () => {
await initialize();
start();
});