[Gekidou] upgrade to RN 68 (old arch) (#6138)

* upgrade to RN 68 (old arch)

* remove test setup unused & commented mock

* Android target set to 30

* Fix theme when opening app from push notification

* upgrade common mark
This commit is contained in:
Elias Nahum
2022-04-08 12:40:44 -04:00
committed by GitHub
parent 9a72837f04
commit b530dbeb09
59 changed files with 3987 additions and 5610 deletions

View File

@@ -15,9 +15,11 @@ import {prepareCommonSystemValues, PrepareCommonSystemValuesArgs, getCommonSyste
import {addChannelToTeamHistory, addTeamToTeamHistory, getTeamById, queryMyTeams, removeChannelFromTeamHistory} from '@queries/servers/team';
import {getCurrentUser} from '@queries/servers/user';
import {dismissAllModalsAndPopToRoot, dismissAllModalsAndPopToScreen} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import {makeCategoryChannelId, makeCategoryId} from '@utils/categories';
import {isDMorGM} from '@utils/channel';
import {isTablet} from '@utils/helpers';
import {setThemeDefaults, updateThemeIfNeeded} from '@utils/theme';
import {displayGroupMessageName, displayUsername, getUserIdFromChannelName} from '@utils/user';
import type ChannelModel from '@typings/database/models/servers/channel';
@@ -84,6 +86,18 @@ export const switchToChannel = async (serverUrl: string, channelId: string, team
await operator.batchRecords(models);
}
if (!EphemeralStore.theme) {
// When opening the app from a push notification the theme may not be set in the EphemeralStore
// causing the goToScreen to use the Appearance theme instead and that causes the screen background color to potentially
// not match the theme
const themes = await queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_THEME, toTeamId).fetch();
let theme = Preferences.THEMES.denim;
if (themes.length) {
theme = setThemeDefaults(JSON.parse(themes[0].value) as Theme);
}
updateThemeIfNeeded(theme, true);
}
if (isTabletDevice) {
dismissAllModalsAndPopToRoot();
DeviceEventEmitter.emit(NavigationConstants.NAVIGATION_HOME);

View File

@@ -2,11 +2,11 @@
// See LICENSE.txt for license information.
import {ClientResponse, ProgressPromise} from '@mattermost/react-native-network-client';
import * as FileSystem from 'expo-file-system';
import React, {forwardRef, useImperativeHandle, useRef, useState} from 'react';
import {useIntl} from 'react-intl';
import {Platform, StatusBar, StatusBarStyle, StyleSheet, TouchableOpacity, View} from 'react-native';
import FileViewer from 'react-native-file-viewer';
import FileSystem from 'react-native-fs';
import tinyColor from 'tinycolor2';
import ProgressBar from '@components/progress_bar';
@@ -15,6 +15,7 @@ import {useServerUrl} from '@context/server';
import NetworkManager from '@init/network_manager';
import {alertDownloadDocumentDisabled, alertDownloadFailed, alertFailedToOpenDocument} from '@utils/document';
import {fileExists, getLocalFilePathFromFile} from '@utils/file';
import {emptyFunction} from '@utils/general';
import FileIcon from './file_icon';
@@ -83,7 +84,7 @@ const DocumentFile = forwardRef<DocumentFileRef, DocumentFileProps>(({background
}
} catch (error) {
if (path) {
FileSystem.deleteAsync(path, {idempotent: true});
FileSystem.unlink(path).catch(emptyFunction);
}
setDownloading(false);
setProgress(0);
@@ -136,7 +137,7 @@ const DocumentFile = forwardRef<DocumentFileRef, DocumentFileProps>(({background
onDonePreviewingFile();
if (path) {
FileSystem.deleteAsync(path, {idempotent: true});
FileSystem.unlink(path).catch(emptyFunction);
}
});
}

View File

@@ -1,9 +1,9 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {getThumbnailAsync} from 'expo-video-thumbnails';
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {StyleSheet, useWindowDimensions, View} from 'react-native';
import {createThumbnail} from 'react-native-create-thumbnail';
import {updateLocalFile} from '@actions/local/file';
import {buildFilePreviewUrl, fetchPublicLink} from '@actions/remote/file';
@@ -89,7 +89,7 @@ const VideoFile = ({
// library
const publicUri = await fetchPublicLink(serverUrl, data.id!);
if (('link') in publicUri) {
const {uri, height, width} = await getThumbnailAsync(data.localPath || publicUri.link, {time: 2000});
const {path: uri, height, width} = await createThumbnail({url: data.localPath || publicUri.link, timeStamp: 2000});
data.mini_preview = uri;
data.height = height;
data.width = width;

View File

@@ -1,11 +1,11 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import * as FileSystem from 'expo-file-system';
import DeviceInfo from 'react-native-device-info';
import FileSystem from 'react-native-fs';
export default {
DOCUMENTS_PATH: `${FileSystem.cacheDirectory}/Documents`,
DOCUMENTS_PATH: `${FileSystem.CachesDirectoryPath}/Documents`,
IS_TABLET: DeviceInfo.isTablet(),
PUSH_NOTIFY_ANDROID_REACT_NATIVE: 'android_rn',
PUSH_NOTIFY_APPLE_REACT_NATIVE: 'apple_rn',

View File

@@ -8,8 +8,7 @@ import {Appearance, EventSubscription} from 'react-native';
import {Preferences} from '@constants';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {observeCurrentTeamId} from '@queries/servers/system';
import EphemeralStore from '@store/ephemeral_store';
import {setNavigationStackStyles, setThemeDefaults} from '@utils/theme';
import {setThemeDefaults, updateThemeIfNeeded} from '@utils/theme';
import type {PreferenceModel} from '@database/models/server';
import type Database from '@nozbe/watermelondb/Database';
@@ -34,15 +33,6 @@ export function getDefaultThemeByAppearance(): Theme {
export const ThemeContext = createContext(getDefaultThemeByAppearance());
const {Consumer, Provider} = ThemeContext;
const updateThemeIfNeeded = (theme: Theme) => {
if (theme !== EphemeralStore.theme) {
EphemeralStore.theme = theme;
requestAnimationFrame(() => {
setNavigationStackStyles(theme);
});
}
};
const ThemeProvider = ({currentTeamId, children, themes}: Props) => {
const getTheme = (): Theme => {
if (currentTeamId) {

View File

@@ -4,8 +4,8 @@
import {Database, Q} from '@nozbe/watermelondb';
import LokiJSAdapter from '@nozbe/watermelondb/adapters/lokijs';
import logger from '@nozbe/watermelondb/utils/common/logger';
import * as FileSystem from 'expo-file-system';
import {DeviceEventEmitter, Platform} from 'react-native';
import FileSystem from 'react-native-fs';
import {MIGRATION_EVENTS, MM_TABLES} from '@constants/database';
import AppDatabaseMigrations from '@database/migration/app';
@@ -301,8 +301,17 @@ class DatabaseManager {
const databaseFile = `${androidFilesDir}${databaseName}.db`;
const databaseJournal = `${androidFilesDir}${databaseName}.db-journal`;
await FileSystem.deleteAsync(databaseFile);
await FileSystem.deleteAsync(databaseJournal);
try {
await FileSystem.unlink(databaseFile);
} catch {
// do nothing
}
try {
await FileSystem.unlink(databaseJournal);
} catch {
// do nothing
}
};
factoryReset = async (shouldRemoveDirectory: boolean): Promise<boolean> => {
@@ -315,7 +324,7 @@ class DatabaseManager {
// On Android, we'll remove the databases folder under the Document Directory
const androidFilesDir = `${this.databaseDirectory}databases/`;
await FileSystem.deleteAsync(androidFilesDir);
await FileSystem.unlink(androidFilesDir);
return true;
} catch (e) {
return false;

View File

@@ -4,9 +4,9 @@
import {Database, Q} from '@nozbe/watermelondb';
import SQLiteAdapter from '@nozbe/watermelondb/adapters/sqlite';
import logger from '@nozbe/watermelondb/utils/common/logger';
import * as FileSystem from 'expo-file-system';
import {DeviceEventEmitter, Platform} from 'react-native';
import DeviceInfo from 'react-native-device-info';
import FileSystem from 'react-native-fs';
import {MIGRATION_EVENTS, MM_TABLES} from '@constants/database';
import AppDatabaseMigrations from '@database/migration/app';
@@ -24,6 +24,7 @@ import {schema as appSchema} from '@database/schema/app';
import {serverSchema} from '@database/schema/server';
import {queryActiveServer, queryServer, queryServerByIdentifier} from '@queries/app/servers';
import {DatabaseType} from '@typings/database/enums';
import {emptyFunction} from '@utils/general';
import {deleteIOSDatabase, getIOSAppGroupDetails} from '@utils/mattermost_managed';
import {hashCode} from '@utils/security';
@@ -49,7 +50,7 @@ class DatabaseManager {
ThreadModel, ThreadParticipantModel, ThreadInTeamModel, UserModel,
];
this.databaseDirectory = Platform.OS === 'ios' ? getIOSAppGroupDetails().appGroupDatabase : `${FileSystem.documentDirectory}databases/`;
this.databaseDirectory = Platform.OS === 'ios' ? getIOSAppGroupDetails().appGroupDatabase : `${FileSystem.DocumentDirectoryPath}/databases/`;
}
/**
@@ -82,7 +83,7 @@ class DatabaseManager {
const databaseName = APP_DATABASE;
if (Platform.OS === 'android') {
await FileSystem.makeDirectoryAsync(this.databaseDirectory!, {intermediates: true});
await FileSystem.mkdir(this.databaseDirectory!);
}
const databaseFilePath = this.getDatabaseFilePath(databaseName);
const modelClasses = this.appModels;
@@ -390,9 +391,9 @@ class DatabaseManager {
const databaseShm = `${androidFilesDir}${databaseName}.db-shm`;
const databaseWal = `${androidFilesDir}${databaseName}.db-wal`;
FileSystem.deleteAsync(databaseFile, {idempotent: true});
FileSystem.deleteAsync(databaseShm, {idempotent: true});
FileSystem.deleteAsync(databaseWal, {idempotent: true});
FileSystem.unlink(databaseFile).catch(emptyFunction);
FileSystem.unlink(databaseShm).catch(emptyFunction);
FileSystem.unlink(databaseWal).catch(emptyFunction);
};
/**
@@ -410,7 +411,7 @@ class DatabaseManager {
// On Android, we'll remove the databases folder under the Document Directory
const androidFilesDir = `${this.databaseDirectory}databases/`;
await FileSystem.deleteAsync(androidFilesDir);
await FileSystem.unlink(androidFilesDir);
return true;
} catch (e) {
return false;
@@ -458,7 +459,7 @@ class DatabaseManager {
* @returns {string}
*/
private getDatabaseFilePath = (dbName: string): string => {
return Platform.OS === 'ios' ? `${this.databaseDirectory}/${dbName}.db` : `${this.databaseDirectory}${dbName}.db`;
return Platform.OS === 'ios' ? `${this.databaseDirectory}/${dbName}.db` : `${this.databaseDirectory}/${dbName}.db`;
};
}

View File

@@ -2,12 +2,12 @@
// See LICENSE.txt for license information.
import CameraRoll from '@react-native-community/cameraroll';
import * as FileSystem from 'expo-file-system';
import React, {useEffect, useRef, useState} from 'react';
import {useIntl} from 'react-intl';
import {NativeModules, Platform, StyleSheet, Text, View} from 'react-native';
import DeviceInfo from 'react-native-device-info';
import FileViewer from 'react-native-file-viewer';
import FileSystem from 'react-native-fs';
import {TouchableOpacity} from 'react-native-gesture-handler';
import {useAnimatedStyle, withTiming} from 'react-native-reanimated';
import Share from 'react-native-share';
@@ -116,11 +116,10 @@ const DownloadWithAction = ({action, item, onDownloadSuccess, setAction}: Props)
const cancel = async () => {
try {
await downloadPromise.current?.cancel?.();
downloadPromise.current?.cancel?.();
const path = getLocalFilePathFromFile(serverUrl, galleryItemToFileInfo(item));
await FileSystem.deleteAsync(path, {idempotent: true});
downloadPromise.current = undefined;
await FileSystem.unlink(path);
} catch {
// do nothing
} finally {
@@ -159,7 +158,7 @@ const DownloadWithAction = ({action, item, onDownloadSuccess, setAction}: Props)
if (mounted.current) {
if (Platform.OS === 'android') {
try {
await NativeModules.MattermostManaged.saveFile(path.replace('file://', '/'));
await NativeModules.MattermostManaged.saveFile(path);
} catch {
// do nothing in case the user decides not to save the file
}

View File

@@ -3,13 +3,13 @@
import {PastedFile} from '@mattermost/react-native-paste-input';
import Model from '@nozbe/watermelondb/Model';
import * as FileSystem from 'expo-file-system';
import mimeDB from 'mime-db';
import {IntlShape} from 'react-intl';
import {Alert, Platform} from 'react-native';
import AndroidOpenSettings from 'react-native-android-open-settings';
import DeviceInfo from 'react-native-device-info';
import {DocumentPickerResponse} from 'react-native-document-picker';
import FileSystem from 'react-native-fs';
import {Asset} from 'react-native-image-picker';
import Permissions, {PERMISSIONS} from 'react-native-permissions';
@@ -95,61 +95,22 @@ function populateMaps() {
});
}
const vectorIconsDir = 'vectorIcons';
const dirsToExclude = ['Cache.db', 'WebKit', 'WebView', vectorIconsDir];
async function getDirectorySize(fileStats: FileSystem.FileInfo) {
if (fileStats?.exists) {
let total = 0;
if (fileStats.isDirectory) {
const exclude = dirsToExclude.find((f) => fileStats.uri.includes(f));
if (!exclude) {
const paths = await FileSystem.readDirectoryAsync(fileStats.uri);
for await (const path of paths) {
const info = await FileSystem.getInfoAsync(`${fileStats.uri}/${path}`, {size: true});
if (info.isDirectory) {
const dirSize = await getDirectorySize(info);
total += dirSize;
} else {
total += (info.size || 0);
}
}
}
} else {
total = fileStats.size;
}
return total;
}
return 0;
}
export async function getFileCacheSize() {
if (FileSystem.cacheDirectory) {
const cacheStats = await FileSystem.getInfoAsync(FileSystem.cacheDirectory);
const size = await getDirectorySize(cacheStats);
return size;
}
return 0;
}
export async function deleteV1Data() {
const dir = Platform.OS === 'ios' ? getIOSAppGroupDetails().appGroupSharedDirectory : FileSystem.documentDirectory;
const dir = Platform.OS === 'ios' ? getIOSAppGroupDetails().appGroupSharedDirectory : FileSystem.DocumentDirectoryPath;
try {
const mmkvDirInfo = await FileSystem.getInfoAsync(`${dir}/mmkv`);
if (mmkvDirInfo.exists) {
await FileSystem.deleteAsync(mmkvDirInfo.uri, {idempotent: true});
const directory = `${dir}/mmkv`;
const mmkvDirInfo = await FileSystem.exists(directory);
if (mmkvDirInfo) {
await FileSystem.unlink(directory);
}
} catch {
// do nothing
}
try {
const entitiesInfo = await FileSystem.getInfoAsync(`${dir}/entities`);
if (entitiesInfo.exists) {
const entitiesInfo = await FileSystem.exists(`${dir}/entities`);
if (entitiesInfo) {
deleteEntititesFile();
}
} catch (e) {
@@ -159,17 +120,17 @@ export async function deleteV1Data() {
export async function deleteFileCache(serverUrl: string) {
const serverDir = hashCode(serverUrl);
const cacheDir = `${FileSystem.cacheDirectory}/${serverDir}`;
const cacheDir = `${FileSystem.CachesDirectoryPath}/${serverDir}`;
if (cacheDir) {
const cacheDirInfo = await FileSystem.getInfoAsync(cacheDir);
if (cacheDirInfo.exists) {
const cacheDirInfo = await FileSystem.exists(cacheDir);
if (cacheDirInfo) {
if (Platform.OS === 'ios') {
await FileSystem.deleteAsync(cacheDir, {idempotent: true});
await FileSystem.makeDirectoryAsync(cacheDir, {intermediates: true});
await FileSystem.unlink(cacheDir);
await FileSystem.mkdir(cacheDir);
} else {
const lstat = await FileSystem.readDirectoryAsync(cacheDir);
lstat.forEach((stat: string) => {
FileSystem.deleteAsync(stat, {idempotent: true});
const lstat = await FileSystem.readDir(cacheDir);
lstat.forEach((stat: FileSystem.ReadDirItem) => {
FileSystem.unlink(stat.path);
});
}
}
@@ -363,9 +324,9 @@ export function getLocalFilePathFromFile(serverUrl: string, file: FileInfo | Fil
}
}
return `${FileSystem.cacheDirectory}${server}/${filename}-${hashCode(file.id!)}.${extension}`;
return `${FileSystem.CachesDirectoryPath}/${server}/${filename}-${hashCode(file.id!)}.${extension}`;
} else if (file?.id && file?.extension) {
return `${FileSystem.cacheDirectory}${server}/${file.id}.${file.extension}`;
return `${FileSystem.CachesDirectoryPath}/${server}/${file.id}.${file.extension}`;
}
}
@@ -397,10 +358,9 @@ export async function extractFileInfo(files: Array<Asset | DocumentPickerRespons
});
let fileInfo;
try {
fileInfo = await FileSystem.getInfoAsync(path);
const uri = fileInfo.uri;
fileInfo = await FileSystem.stat(path);
outFile.size = fileInfo.size || 0;
outFile.name = uri.substring(uri.lastIndexOf('/') + 1);
outFile.name = path.substring(path.lastIndexOf('/') + 1);
} catch (e) {
return;
}
@@ -446,8 +406,7 @@ export function uploadDisabledWarning(intl: IntlShape) {
export const fileExists = async (path: string) => {
try {
const filePath = Platform.select({ios: path.replace('file://', ''), default: path});
const info = await FileSystem.getInfoAsync(filePath);
return info.exists;
return FileSystem.exists(filePath);
} catch {
return false;
}

View File

@@ -256,3 +256,12 @@ export function setThemeDefaults(theme: Theme): Theme {
return processedTheme as Theme;
}
export const updateThemeIfNeeded = (theme: Theme, force = false) => {
if (theme !== EphemeralStore.theme || force) {
EphemeralStore.theme = theme;
requestAnimationFrame(() => {
setNavigationStackStyles(theme);
});
}
};