forked from Ivasoft/mattermost-mobile
Fix problems related to closing react but keeping other state (#7405)
This commit is contained in:
committed by
GitHub
parent
72f7c639c7
commit
0a3f5e5914
@@ -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!;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
3
index.ts
3
index.ts
@@ -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();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user