Entry point when upgrading from v1 (#5707)

This commit is contained in:
Elias Nahum
2021-10-01 02:56:28 -03:00
committed by GitHub
parent 9ce4bfac38
commit e2ecf2f0f7
6 changed files with 113 additions and 11 deletions

View File

@@ -16,6 +16,7 @@ import {prepareCommonSystemValues, queryCommonSystemValues, queryConfig, queryCu
import {addChannelToTeamHistory, deleteMyTeams, queryAvailableTeamIds, queryMyTeams, queryTeamsById} from '@queries/servers/team';
import {queryCurrentUser} from '@queries/servers/user';
import {selectDefaultChannelForTeam} from '@utils/channel';
import {deleteV1Data} from '@utils/file';
import {fetchMissingSidebarInfo, fetchMyChannelsForTeam, MyChannelsRequest} from './channel';
import {fetchGroupsForTeam} from './group';
@@ -99,7 +100,7 @@ export const appEntry = async (serverUrl: string) => {
deferredAppEntryActions(serverUrl, currentUserId, currentUserLocale, prefData.preferences, config, license, teamData, chData, initialTeamId);
const error = teamData.error || chData?.error || prefData.error || meData.error;
return {error, time: Date.now() - dt};
return {error, time: Date.now() - dt, userId: meData?.user?.id};
};
export const loginEntry = async ({serverUrl, user, deviceToken}: AfterLoginArgs) => {
@@ -230,6 +231,34 @@ export const loginEntry = async ({serverUrl, user, deviceToken}: AfterLoginArgs)
}
};
export const upgradeEntry = async (serverUrl: string) => {
const dt = Date.now();
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
if (!operator) {
return {error: `${serverUrl} database not found`};
}
try {
const configAndLicense = await fetchConfigAndLicense(serverUrl, false);
const entry = await appEntry(serverUrl);
const error = configAndLicense.error || entry.error;
if (!error) {
const models = await prepareCommonSystemValues(operator, {currentUserId: entry.userId});
if (models?.length) {
await operator.batchRecords(models);
}
DatabaseManager.setActiveServerDatabase(serverUrl);
deleteV1Data();
}
return {error, time: Date.now() - dt};
} catch (e) {
return {error: e, time: Date.now() - dt};
}
};
const fetchAppEntryData = async (serverUrl: string, initialTeamId: string): Promise<AppEntryData | AppEntryError> => {
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
if (!database) {

View File

@@ -1,14 +1,16 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Linking} from 'react-native';
import Emm from '@mattermost/react-native-emm';
import {Alert, Linking} from 'react-native';
import {Notifications} from 'react-native-notifications';
import {appEntry} from '@actions/remote/entry';
import {appEntry, upgradeEntry} from '@actions/remote/entry';
import {Screens} from '@constants';
import DatabaseManager from '@database/manager';
import {getActiveServerUrl, getServerCredentials} from '@init/credentials';
import {queryThemeForCurrentTeam} from '@queries/servers/preference';
import {queryCurrentUserId} from '@queries/servers/system';
import {goToScreen, resetToHome, resetToSelectServer} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import {DeepLinkChannel, DeepLinkDM, DeepLinkGM, DeepLinkPermalink, DeepLinkType, DeepLinkWithData, LaunchProps, LaunchType} from '@typings/launch';
@@ -67,12 +69,30 @@ const launchApp = async (props: LaunchProps, resetNavigation = true) => {
const credentials = await getServerCredentials(serverUrl);
if (credentials) {
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
let hasCurrentUser = false;
if (database) {
EphemeralStore.theme = await queryThemeForCurrentTeam(database);
const currentUserId = await queryCurrentUserId(database);
hasCurrentUser = Boolean(currentUserId);
}
launchToHome({...props, serverUrl}, resetNavigation);
if (!hasCurrentUser) {
// migrating from v1
const result = await upgradeEntry(serverUrl);
if (result.error) {
Alert.alert(
'Error Upgrading',
`An error ocurred while upgrading the app to the new version.\n\nDetails: ${result.error}\n\nThe app will now quit.`,
[{
text: 'OK',
onPress: () => Emm.exitApp(),
}],
);
return;
}
}
launchToHome({...props, launchType: hasCurrentUser ? LaunchType.Normal : LaunchType.Upgrade, serverUrl}, resetNavigation);
return;
}
}
@@ -91,8 +111,9 @@ const launchToHome = (props: LaunchProps, resetNavigation: Boolean) => {
// pushNotificationEntry({props.serverUrl, props.extra})
break;
}
default:
case LaunchType.Normal:
appEntry(props.serverUrl!);
break;
}
const passProps = {
@@ -108,7 +129,7 @@ const launchToHome = (props: LaunchProps, resetNavigation: Boolean) => {
}
const title = '';
goToScreen(Screens.CHANNEL, title, passProps);
goToScreen(Screens.HOME, title, passProps);
};
const launchToServer = (props: LaunchProps, resetNavigation: Boolean) => {

View File

@@ -7,6 +7,7 @@ import {Platform} from 'react-native';
import {FileSystem} from 'react-native-unimodules';
import {Files} from '@constants';
import {deleteEntititesFile, getIOSAppGroupDetails} from '@utils/mattermost_managed';
import {hashCode} from '@utils/security';
import {removeProtocol} from '@utils/url';
@@ -127,6 +128,28 @@ export async function getFileCacheSize() {
return 0;
}
export async function deleteV1Data() {
const dir = Platform.OS === 'ios' ? getIOSAppGroupDetails().appGroupSharedDirectory : FileSystem.documentDirectory;
try {
const mmkvDirInfo = await FileSystem.getInfoAsync(`${dir}/mmkv`);
if (mmkvDirInfo.exists) {
await FileSystem.deleteAsync(mmkvDirInfo.uri, {idempotent: true});
}
} catch {
// do nothing
}
try {
const entitiesInfo = await FileSystem.getInfoAsync(`${dir}/entities`);
if (entitiesInfo.exists) {
deleteEntititesFile();
}
} catch (e) {
// do nothing
}
}
export async function deleteFileCache(serverUrl: string) {
const serverDir = hashCode(serverUrl);
const cacheDir = `${FileSystem.cacheDirectory}/${serverDir}`;

View File

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {NativeModules} from 'react-native';
import {NativeModules, Platform} from 'react-native';
const {MattermostManaged} = NativeModules;
@@ -43,3 +43,15 @@ export const deleteIOSDatabase = ({
// eslint-disable-next-line @typescript-eslint/no-unused-vars
MattermostManaged.deleteDatabaseDirectory(databaseName, shouldRemoveDirectory, () => null);
};
export const deleteEntititesFile = (callback?: (success: boolean) => void) => {
if (Platform.OS === 'ios') {
MattermostManaged.deleteEntititesFile((result: boolean) => {
if (callback) {
callback(result);
}
});
} else if (callback) {
callback(true);
}
};

View File

@@ -60,8 +60,8 @@ RCT_EXPORT_METHOD(isRunningInSplitView:(RCTPromiseResolveBlock)resolve rejecter:
RCT_EXPORT_METHOD(deleteDatabaseDirectory: (NSString *)databaseName shouldRemoveDirectory: (BOOL) shouldRemoveDirectory callback: (RCTResponseSenderBlock)callback){
@try {
NSDictionary * appGroupDir = [self appGroupSharedDirectory];
NSString * databaseDir;
NSDictionary *appGroupDir = [self appGroupSharedDirectory];
NSString *databaseDir;
if(databaseName){
databaseDir = [NSString stringWithFormat:@"%@/%@%@", appGroupDir[@"databasePath"], databaseName , @".db"];
@@ -72,18 +72,34 @@ RCT_EXPORT_METHOD(deleteDatabaseDirectory: (NSString *)databaseName shouldRemov
}
NSFileManager * fileManager = [NSFileManager defaultManager];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
BOOL successCode = [fileManager removeItemAtPath:databaseDir error:&error];
NSNumber * success= [NSNumber numberWithBool:successCode];
NSNumber *success= [NSNumber numberWithBool:successCode];
callback(@[(error ?: [NSNull null]), success]);
}
@catch (NSException *exception) {
NSLog(@"%@", exception.reason);
callback(@[exception.reason, @NO]);
}
}
RCT_EXPORT_METHOD(deleteEntititesFile: (RCTResponseSenderBlock) callback) {
@try {
NSDictionary *appGroupDir = [self appGroupSharedDirectory];
NSString *entities = [NSString stringWithFormat:@"%@/entities", appGroupDir[@"sharedDirectory"]];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
BOOL successCode = [fileManager removeItemAtPath:entities error:&error];
NSNumber *success= [NSNumber numberWithBool:successCode];
callback(@[success]);
}
@catch (NSException *exception) {
callback(@[@NO]);
}
}
@end

View File

@@ -41,6 +41,7 @@ export const LaunchType = {
Normal: 'normal',
DeepLink: 'deeplink',
Notification: 'notification',
Upgrade: 'upgrade',
} as const;
export type LaunchType = typeof LaunchType[keyof typeof LaunchType];