forked from Ivasoft/mattermost-mobile
* Fix upgrade path
* Introduce Upgrade helper
* Reset server database schema version to 1
* Enable release builds on the CI
* Bump build number to 450
(cherry picked from commit 4199b13843)
Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
This commit is contained in:
@@ -309,13 +309,13 @@ jobs:
|
||||
- save:
|
||||
filename: "*.apk"
|
||||
|
||||
# build-android-release:
|
||||
# executor: android
|
||||
# steps:
|
||||
# - build-android
|
||||
# - persist
|
||||
# - save:
|
||||
# filename: "*.apk"
|
||||
build-android-release:
|
||||
executor: android
|
||||
steps:
|
||||
- build-android
|
||||
- persist
|
||||
- save:
|
||||
filename: "*.apk"
|
||||
|
||||
build-android-pr:
|
||||
executor: android
|
||||
@@ -326,27 +326,27 @@ jobs:
|
||||
- save:
|
||||
filename: "*.apk"
|
||||
|
||||
# build-android-unsigned:
|
||||
# executor: android
|
||||
# steps:
|
||||
# - checkout:
|
||||
# path: ~/mattermost-mobile
|
||||
# - npm-dependencies
|
||||
# - assets
|
||||
# - fastlane-dependencies:
|
||||
# for: android
|
||||
# - gradle-dependencies
|
||||
# - run:
|
||||
# name: Jetify Android libraries
|
||||
# command: ./node_modules/.bin/jetify
|
||||
# - run:
|
||||
# working_directory: fastlane
|
||||
# name: Run fastlane to build unsigned android
|
||||
# no_output_timeout: 30m
|
||||
# command: bundle exec fastlane android unsigned
|
||||
# - persist
|
||||
# - save:
|
||||
# filename: "*.apk"
|
||||
build-android-unsigned:
|
||||
executor: android
|
||||
steps:
|
||||
- checkout:
|
||||
path: ~/mattermost-mobile
|
||||
- npm-dependencies
|
||||
- assets
|
||||
- fastlane-dependencies:
|
||||
for: android
|
||||
- gradle-dependencies
|
||||
- run:
|
||||
name: Jetify Android libraries
|
||||
command: ./node_modules/.bin/jetify
|
||||
- run:
|
||||
working_directory: fastlane
|
||||
name: Run fastlane to build unsigned android
|
||||
no_output_timeout: 30m
|
||||
command: bundle exec fastlane android unsigned
|
||||
- persist
|
||||
- save:
|
||||
filename: "*.apk"
|
||||
|
||||
build-ios-beta:
|
||||
executor:
|
||||
@@ -358,13 +358,13 @@ jobs:
|
||||
- save:
|
||||
filename: "*.ipa"
|
||||
|
||||
# build-ios-release:
|
||||
# executor: ios
|
||||
# steps:
|
||||
# - build-ios
|
||||
# - persist
|
||||
# - save:
|
||||
# filename: "*.ipa"
|
||||
build-ios-release:
|
||||
executor: ios
|
||||
steps:
|
||||
- build-ios
|
||||
- persist
|
||||
- save:
|
||||
filename: "*.ipa"
|
||||
|
||||
build-ios-pr:
|
||||
executor: ios
|
||||
@@ -375,63 +375,63 @@ jobs:
|
||||
- save:
|
||||
filename: "*.ipa"
|
||||
|
||||
# build-ios-unsigned:
|
||||
# executor: ios
|
||||
# steps:
|
||||
# - checkout:
|
||||
# path: ~/mattermost-mobile
|
||||
# - npm-dependencies
|
||||
# - pods-dependencies
|
||||
# - assets
|
||||
# - fastlane-dependencies:
|
||||
# for: ios
|
||||
# - run:
|
||||
# working_directory: fastlane
|
||||
# name: Run fastlane to build unsigned iOS
|
||||
# no_output_timeout: 30m
|
||||
# command: |
|
||||
# HOMEBREW_NO_AUTO_UPDATE=1 brew install watchman
|
||||
# bundle exec fastlane ios unsigned
|
||||
# - persist_to_workspace:
|
||||
# root: ~/
|
||||
# paths:
|
||||
# - mattermost-mobile/*.ipa
|
||||
# - save:
|
||||
# filename: "*.ipa"
|
||||
build-ios-unsigned:
|
||||
executor: ios
|
||||
steps:
|
||||
- checkout:
|
||||
path: ~/mattermost-mobile
|
||||
- npm-dependencies
|
||||
- pods-dependencies
|
||||
- assets
|
||||
- fastlane-dependencies:
|
||||
for: ios
|
||||
- run:
|
||||
working_directory: fastlane
|
||||
name: Run fastlane to build unsigned iOS
|
||||
no_output_timeout: 30m
|
||||
command: |
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install watchman
|
||||
bundle exec fastlane ios unsigned
|
||||
- persist_to_workspace:
|
||||
root: ~/
|
||||
paths:
|
||||
- mattermost-mobile/*.ipa
|
||||
- save:
|
||||
filename: "*.ipa"
|
||||
|
||||
# build-ios-simulator:
|
||||
# executor: ios
|
||||
# steps:
|
||||
# - checkout:
|
||||
# path: ~/mattermost-mobile
|
||||
# - npm-dependencies
|
||||
# - pods-dependencies
|
||||
# - assets
|
||||
# - fastlane-dependencies:
|
||||
# for: ios
|
||||
# - run:
|
||||
# working_directory: fastlane
|
||||
# name: Run fastlane to build unsigned x86_64 iOS app for iPhone simulator
|
||||
# no_output_timeout: 30m
|
||||
# command: |
|
||||
# HOMEBREW_NO_AUTO_UPDATE=1 brew install watchman
|
||||
# bundle exec fastlane ios simulator
|
||||
# - persist_to_workspace:
|
||||
# root: ~/
|
||||
# paths:
|
||||
# - mattermost-mobile/Mattermost-simulator-x86_64.app.zip
|
||||
# - save:
|
||||
# filename: "Mattermost-simulator-x86_64.app.zip"
|
||||
build-ios-simulator:
|
||||
executor: ios
|
||||
steps:
|
||||
- checkout:
|
||||
path: ~/mattermost-mobile
|
||||
- npm-dependencies
|
||||
- pods-dependencies
|
||||
- assets
|
||||
- fastlane-dependencies:
|
||||
for: ios
|
||||
- run:
|
||||
working_directory: fastlane
|
||||
name: Run fastlane to build unsigned x86_64 iOS app for iPhone simulator
|
||||
no_output_timeout: 30m
|
||||
command: |
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install watchman
|
||||
bundle exec fastlane ios simulator
|
||||
- persist_to_workspace:
|
||||
root: ~/
|
||||
paths:
|
||||
- mattermost-mobile/Mattermost-simulator-x86_64.app.zip
|
||||
- save:
|
||||
filename: "Mattermost-simulator-x86_64.app.zip"
|
||||
|
||||
# deploy-android-release:
|
||||
# executor:
|
||||
# name: android
|
||||
# resource_class: medium
|
||||
# steps:
|
||||
# - deploy-to-store:
|
||||
# task: "Deploy to Google Play"
|
||||
# target: android
|
||||
# file: "*.apk"
|
||||
deploy-android-release:
|
||||
executor:
|
||||
name: android
|
||||
resource_class: medium
|
||||
steps:
|
||||
- deploy-to-store:
|
||||
task: "Deploy to Google Play"
|
||||
target: android
|
||||
file: "*.apk"
|
||||
|
||||
deploy-android-beta:
|
||||
executor:
|
||||
@@ -444,13 +444,13 @@ jobs:
|
||||
file: "*.apk"
|
||||
env: "SUPPLY_TRACK=alpha"
|
||||
|
||||
# deploy-ios-release:
|
||||
# executor: ios
|
||||
# steps:
|
||||
# - deploy-to-store:
|
||||
# task: "Deploy to TestFlight"
|
||||
# target: ios
|
||||
# file: "*.ipa"
|
||||
deploy-ios-release:
|
||||
executor: ios
|
||||
steps:
|
||||
- deploy-to-store:
|
||||
task: "Deploy to TestFlight"
|
||||
target: ios
|
||||
file: "*.ipa"
|
||||
|
||||
deploy-ios-beta:
|
||||
executor: ios
|
||||
@@ -461,17 +461,17 @@ jobs:
|
||||
file: "*.ipa"
|
||||
env: ""
|
||||
|
||||
# github-release:
|
||||
# executor:
|
||||
# name: android
|
||||
# resource_class: medium
|
||||
# steps:
|
||||
# - attach_workspace:
|
||||
# at: ~/
|
||||
# - run:
|
||||
# name: Create GitHub release
|
||||
# working_directory: fastlane
|
||||
# command: bundle exec fastlane github
|
||||
github-release:
|
||||
executor:
|
||||
name: android
|
||||
resource_class: medium
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: ~/
|
||||
- run:
|
||||
name: Create GitHub release
|
||||
working_directory: fastlane
|
||||
command: bundle exec fastlane github
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
@@ -483,26 +483,24 @@ workflows:
|
||||
# requires:
|
||||
# - test
|
||||
|
||||
# - build-android-release:
|
||||
# context: mattermost-mobile-android-release
|
||||
# requires:
|
||||
# - test
|
||||
# filters:
|
||||
# branches:
|
||||
# only:
|
||||
# - /^build-\d+$/
|
||||
# - /^build-android-\d+$/
|
||||
# - /^build-android-release-\d+$/
|
||||
# - deploy-android-release:
|
||||
# context: mattermost-mobile-android-release
|
||||
# requires:
|
||||
# - build-android-release
|
||||
# filters:
|
||||
# branches:
|
||||
# only:
|
||||
# - /^build-\d+$/
|
||||
# - /^build-android-\d+$/
|
||||
# - /^build-android-release-\d+$/
|
||||
- build-android-release:
|
||||
context: mattermost-mobile-android-release
|
||||
requires:
|
||||
- test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /^build-release-\d+$/
|
||||
- /^build-android-release-\d+$/
|
||||
- deploy-android-release:
|
||||
context: mattermost-mobile-android-release
|
||||
requires:
|
||||
- build-android-release
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /^build-release-\d+$/
|
||||
- /^build-android-release-\d+$/
|
||||
|
||||
- build-android-beta:
|
||||
context: mattermost-mobile-android-beta
|
||||
@@ -523,26 +521,24 @@ workflows:
|
||||
- /^build-android-\d+$/
|
||||
- /^build-android-beta-\d+$/
|
||||
|
||||
# - build-ios-release:
|
||||
# context: mattermost-mobile-ios-release
|
||||
# requires:
|
||||
# - test
|
||||
# filters:
|
||||
# branches:
|
||||
# only:
|
||||
# - /^build-\d+$/
|
||||
# - /^build-ios-\d+$/
|
||||
# - /^build-ios-release-\d+$/
|
||||
# - deploy-ios-release:
|
||||
# context: mattermost-mobile-ios-release
|
||||
# requires:
|
||||
# - build-ios-release
|
||||
# filters:
|
||||
# branches:
|
||||
# only:
|
||||
# - /^build-\d+$/
|
||||
# - /^build-ios-\d+$/
|
||||
# - /^build-ios-release-\d+$/
|
||||
- build-ios-release:
|
||||
context: mattermost-mobile-ios-release
|
||||
requires:
|
||||
- test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /^build-release-\d+$/
|
||||
- /^build-ios-release-\d+$/
|
||||
- deploy-ios-release:
|
||||
context: mattermost-mobile-ios-release
|
||||
requires:
|
||||
- build-ios-release
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /^build-release-\d+$/
|
||||
- /^build-ios-release-\d+$/
|
||||
|
||||
- build-ios-beta:
|
||||
context: mattermost-mobile-ios-beta
|
||||
@@ -578,43 +574,41 @@ workflows:
|
||||
branches:
|
||||
only: /^(build|ios)-pr-.*/
|
||||
|
||||
# - build-android-unsigned:
|
||||
# context: mattermost-mobile-unsigned
|
||||
# requires:
|
||||
# - test
|
||||
# filters:
|
||||
# tags:
|
||||
# only: /^v(\d+\.)(\d+\.)(\d+)(.*)?$/
|
||||
# branches:
|
||||
# only: unsigned
|
||||
# - build-ios-unsigned:
|
||||
# context: mattermost-mobile-unsigned
|
||||
# requires:
|
||||
# - test
|
||||
# filters:
|
||||
# tags:
|
||||
# only: /^v(\d+\.)(\d+\.)(\d+)(.*)?$/
|
||||
# branches:
|
||||
# only: unsigned
|
||||
# - build-ios-simulator:
|
||||
# context: mattermost-mobile-unsigned
|
||||
# requires:
|
||||
# - test
|
||||
# filters:
|
||||
# branches:
|
||||
# only:
|
||||
# - /^build-\d+$/
|
||||
# - /^build-ios-\d+$/
|
||||
# - /^build-ios-beta-\d+$/
|
||||
# - /^build-ios-sim-\d+$/
|
||||
- build-android-unsigned:
|
||||
context: mattermost-mobile-unsigned
|
||||
requires:
|
||||
- test
|
||||
filters:
|
||||
tags:
|
||||
only: /^v(\d+\.)(\d+\.)(\d+)(.*)?$/
|
||||
branches:
|
||||
only: unsigned
|
||||
- build-ios-unsigned:
|
||||
context: mattermost-mobile-unsigned
|
||||
requires:
|
||||
- test
|
||||
filters:
|
||||
tags:
|
||||
only: /^v(\d+\.)(\d+\.)(\d+)(.*)?$/
|
||||
branches:
|
||||
only: unsigned
|
||||
- build-ios-simulator:
|
||||
context: mattermost-mobile-unsigned
|
||||
requires:
|
||||
- test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /^build-\d+$/
|
||||
- /^build-ios-sim-\d+$/
|
||||
|
||||
# - github-release:
|
||||
# context: mattermost-mobile-unsigned
|
||||
# requires:
|
||||
# - build-android-unsigned
|
||||
# - build-ios-unsigned
|
||||
# filters:
|
||||
# tags:
|
||||
# only: /^v(\d+\.)(\d+\.)(\d+)(.*)?$/
|
||||
# branches:
|
||||
# only: unsigned
|
||||
- github-release:
|
||||
context: mattermost-mobile-unsigned
|
||||
requires:
|
||||
- build-android-unsigned
|
||||
- build-ios-unsigned
|
||||
filters:
|
||||
tags:
|
||||
only: /^v(\d+\.)(\d+\.)(\d+)(.*)?$/
|
||||
branches:
|
||||
only: unsigned
|
||||
|
||||
@@ -145,7 +145,7 @@ android {
|
||||
applicationId "com.mattermost.rnbeta"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 449
|
||||
versionCode 450
|
||||
versionName "2.0.0"
|
||||
testBuildType System.getProperty('testBuildType', 'debug')
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
|
||||
@@ -8,6 +8,7 @@ import {prepareCommonSystemValues, getCurrentTeamId, getWebSocketLastDisconnecte
|
||||
import {getCurrentUser} from '@queries/servers/user';
|
||||
import {setTeamLoading} from '@store/team_load_store';
|
||||
import {deleteV1Data} from '@utils/file';
|
||||
import {isTablet} from '@utils/helpers';
|
||||
import {logInfo} from '@utils/log';
|
||||
|
||||
import {handleEntryAfterLoadNavigation, registerDeviceToken, syncOtherServers, verifyPushProxy} from './common';
|
||||
@@ -29,7 +30,7 @@ export async function appEntry(serverUrl: string, since = 0, isUpgrade = false)
|
||||
// clear lastUnreadChannelId
|
||||
const removeLastUnreadChannelId = await prepareCommonSystemValues(operator, {lastUnreadChannelId: ''});
|
||||
if (removeLastUnreadChannelId) {
|
||||
operator.batchRecords(removeLastUnreadChannelId);
|
||||
await operator.batchRecords(removeLastUnreadChannelId);
|
||||
}
|
||||
|
||||
const {database} = operator;
|
||||
@@ -47,7 +48,12 @@ export async function appEntry(serverUrl: string, since = 0, isUpgrade = false)
|
||||
|
||||
const {models, initialTeamId, initialChannelId, prefData, teamData, chData, meData} = entryData;
|
||||
if (isUpgrade && meData?.user) {
|
||||
const me = await prepareCommonSystemValues(operator, {currentUserId: meData.user.id});
|
||||
const isTabletDevice = await isTablet();
|
||||
const me = await prepareCommonSystemValues(operator, {
|
||||
currentUserId: meData.user.id,
|
||||
currentTeamId: initialTeamId,
|
||||
currentChannelId: isTabletDevice ? initialChannelId : undefined,
|
||||
});
|
||||
if (me?.length) {
|
||||
await operator.batchRecords(me);
|
||||
}
|
||||
@@ -84,8 +90,8 @@ export async function upgradeEntry(serverUrl: string) {
|
||||
const error = configAndLicense.error || entryData.error;
|
||||
|
||||
if (!error) {
|
||||
DatabaseManager.updateServerIdentifier(serverUrl, configAndLicense.config!.DiagnosticId);
|
||||
DatabaseManager.setActiveServerDatabase(serverUrl);
|
||||
await DatabaseManager.updateServerIdentifier(serverUrl, configAndLicense.config!.DiagnosticId);
|
||||
await DatabaseManager.setActiveServerDatabase(serverUrl);
|
||||
deleteV1Data();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import AppDataOperator from '@database/operator/app_data_operator';
|
||||
import ServerDataOperator from '@database/operator/server_data_operator';
|
||||
import {schema as appSchema} from '@database/schema/app';
|
||||
import {serverSchema} from '@database/schema/server';
|
||||
import {beforeUpgrade} from '@helpers/database/upgrade';
|
||||
import {getActiveServer, getServer, getServerByIdentifier} from '@queries/app/servers';
|
||||
import {querySystemValue} from '@queries/servers/system';
|
||||
import {deleteLegacyFileCache} from '@utils/file';
|
||||
@@ -63,14 +64,17 @@ class DatabaseManager {
|
||||
*/
|
||||
public init = async (serverUrls: string[]): Promise<void> => {
|
||||
await this.createAppDatabase();
|
||||
const buildNumber = DeviceInfo.getBuildNumber();
|
||||
const versionNumber = DeviceInfo.getVersion();
|
||||
await beforeUpgrade.call(this, serverUrls, versionNumber, buildNumber);
|
||||
for await (const serverUrl of serverUrls) {
|
||||
await this.initServerDatabase(serverUrl);
|
||||
}
|
||||
this.appDatabase?.operator.handleInfo({
|
||||
info: [{
|
||||
build_number: DeviceInfo.getBuildNumber(),
|
||||
build_number: buildNumber,
|
||||
created_at: Date.now(),
|
||||
version_number: DeviceInfo.getVersion(),
|
||||
version_number: versionNumber,
|
||||
}],
|
||||
prepareRecordsOnly: false,
|
||||
});
|
||||
@@ -428,7 +432,7 @@ class DatabaseManager {
|
||||
*/
|
||||
private deleteServerDatabaseFiles = async (serverUrl: string): Promise<void> => {
|
||||
const databaseName = urlSafeBase64Encode(serverUrl);
|
||||
this.deleteServerDatabaseFilesByName(databaseName);
|
||||
return this.deleteServerDatabaseFilesByName(databaseName);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -439,7 +443,7 @@ class DatabaseManager {
|
||||
private deleteServerDatabaseFilesByName = async (databaseName: string): Promise<void> => {
|
||||
if (Platform.OS === 'ios') {
|
||||
// On iOS, we'll delete the *.db file under the shared app-group/databases folder
|
||||
deleteIOSDatabase({databaseName});
|
||||
await deleteIOSDatabase({databaseName});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -449,14 +453,15 @@ class DatabaseManager {
|
||||
const databaseShm = `${androidFilesDir}${databaseName}.db-shm`;
|
||||
const databaseWal = `${androidFilesDir}${databaseName}.db-wal`;
|
||||
|
||||
FileSystem.unlink(databaseFile).catch(emptyFunction);
|
||||
FileSystem.unlink(databaseShm).catch(emptyFunction);
|
||||
FileSystem.unlink(databaseWal).catch(emptyFunction);
|
||||
await FileSystem.unlink(databaseFile).catch(emptyFunction);
|
||||
await FileSystem.unlink(databaseShm).catch(emptyFunction);
|
||||
await FileSystem.unlink(databaseWal).catch(emptyFunction);
|
||||
};
|
||||
|
||||
/**
|
||||
* deleteServerDatabaseFilesByName: Removes the *.db file from the App-Group directory for iOS or the files directory for Android, given the database name
|
||||
* renameDatabase: Renames the *.db file from the App-Group directory for iOS or the files directory for Android
|
||||
* @param {string} databaseName
|
||||
* @param {string} newDBName
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private renameDatabase = async (databaseName: string, newDBName: string): Promise<void> => {
|
||||
|
||||
@@ -4,105 +4,6 @@
|
||||
// NOTE : To implement migration, please follow this document
|
||||
// https://nozbe.github.io/WatermelonDB/Advanced/Migrations.html
|
||||
|
||||
import {schemaMigrations, addColumns, createTable} from '@nozbe/watermelondb/Schema/migrations';
|
||||
import {schemaMigrations} from '@nozbe/watermelondb/Schema/migrations';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {tableSchemaSpec as configSpec} from '@database/schema/server/table_schemas/config';
|
||||
import {tableSchemaSpec as teamThreadsSyncSpec} from '@database/schema/server/table_schemas/team_threads_sync';
|
||||
import {tableSchemaSpec as threadSpec} from '@database/schema/server/table_schemas/thread';
|
||||
import {tableSchemaSpec as threadInTeamSpec} from '@database/schema/server/table_schemas/thread_in_team';
|
||||
import {tableSchemaSpec as threadParticipantSpec} from '@database/schema/server/table_schemas/thread_participant';
|
||||
|
||||
const {SERVER: {
|
||||
GROUP,
|
||||
MY_CHANNEL,
|
||||
TEAM,
|
||||
THREAD,
|
||||
THREAD_PARTICIPANT,
|
||||
THREADS_IN_TEAM,
|
||||
USER,
|
||||
}} = MM_TABLES;
|
||||
|
||||
export default schemaMigrations({migrations: [
|
||||
{
|
||||
toVersion: 7,
|
||||
steps: [
|
||||
|
||||
// Along with adding the new table - TeamThreadsSync,
|
||||
// We need to clear the data in thread related tables (DROP & CREATE) to fetch the fresh data from the server
|
||||
createTable({
|
||||
...teamThreadsSyncSpec,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
unsafeSql: (baseSql) => {
|
||||
return `
|
||||
${baseSql}
|
||||
DROP TABLE ${THREAD};
|
||||
DROP TABLE ${THREADS_IN_TEAM};
|
||||
DROP TABLE ${THREAD_PARTICIPANT};
|
||||
`;
|
||||
},
|
||||
}),
|
||||
createTable(threadSpec),
|
||||
createTable(threadInTeamSpec),
|
||||
createTable(threadParticipantSpec),
|
||||
],
|
||||
},
|
||||
{
|
||||
toVersion: 6,
|
||||
steps: [
|
||||
addColumns({
|
||||
table: USER,
|
||||
columns: [
|
||||
{name: 'terms_of_service_id', type: 'string'},
|
||||
{name: 'terms_of_service_create_at', type: 'number'},
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
toVersion: 5,
|
||||
steps: [
|
||||
createTable(configSpec),
|
||||
],
|
||||
},
|
||||
{
|
||||
toVersion: 4,
|
||||
steps: [
|
||||
addColumns({
|
||||
table: TEAM,
|
||||
columns: [
|
||||
{name: 'invite_id', type: 'string'},
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
toVersion: 3,
|
||||
steps: [
|
||||
addColumns({
|
||||
table: GROUP,
|
||||
columns: [
|
||||
{name: 'member_count', type: 'number'},
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
toVersion: 2,
|
||||
steps: [
|
||||
addColumns({
|
||||
table: MY_CHANNEL,
|
||||
columns: [
|
||||
{name: 'last_fetched_at', type: 'number', isIndexed: true},
|
||||
],
|
||||
}),
|
||||
addColumns({
|
||||
table: THREAD,
|
||||
columns: [
|
||||
{name: 'last_fetched_at', type: 'number', isIndexed: true},
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
]});
|
||||
export default schemaMigrations({migrations: []});
|
||||
|
||||
@@ -39,7 +39,7 @@ import {
|
||||
} from './table_schemas';
|
||||
|
||||
export const serverSchema: AppSchema = appSchema({
|
||||
version: 7,
|
||||
version: 1,
|
||||
tables: [
|
||||
CategorySchema,
|
||||
CategoryChannelSchema,
|
||||
|
||||
30
app/helpers/database/upgrade.ts
Normal file
30
app/helpers/database/upgrade.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {getLastInstalledVersion} from '@queries/app/info';
|
||||
import {logError, logInfo} from '@utils/log';
|
||||
|
||||
import type {DatabaseManager} from '@typings/database/manager';
|
||||
import type InfoModel from '@typings/database/models/app/info';
|
||||
|
||||
export async function beforeUpgrade(serverUrls: string[], versionNumber: string, buildNumber: string) {
|
||||
const info = await getLastInstalledVersion();
|
||||
const manager: DatabaseManager | undefined = this.serverDatabases ? this : undefined;
|
||||
if (manager && serverUrls.length && info && (versionNumber !== info.versionNumber || buildNumber !== info.buildNumber)) {
|
||||
await beforeUpgradeTo450(manager, serverUrls, info);
|
||||
}
|
||||
}
|
||||
|
||||
async function beforeUpgradeTo450(manager: DatabaseManager, serverUrls: string[], info: InfoModel) {
|
||||
try {
|
||||
const buildNumber = parseInt(info.buildNumber, 10);
|
||||
if (info.versionNumber === '2.0.0' && buildNumber < 450) {
|
||||
for await (const serverUrl of serverUrls) {
|
||||
logInfo('Remove database before upgrading for', serverUrl);
|
||||
await manager.deleteServerDatabaseFiles(serverUrl);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
logError('Error running the upgrade before build 450', e);
|
||||
}
|
||||
}
|
||||
@@ -47,11 +47,11 @@ export async function initialize() {
|
||||
|
||||
export async function start() {
|
||||
await initialize();
|
||||
await WebsocketManager.init(serverCredentials);
|
||||
|
||||
PushNotifications.init(serverCredentials.length > 0);
|
||||
|
||||
registerNavigationListeners();
|
||||
registerScreens();
|
||||
initialLaunch();
|
||||
await initialLaunch();
|
||||
WebsocketManager.init(serverCredentials);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ const initialNotificationTypes = [PushNotification.NOTIFICATION_TYPE.MESSAGE, Pu
|
||||
export const initialLaunch = async () => {
|
||||
const deepLinkUrl = await Linking.getInitialURL();
|
||||
if (deepLinkUrl) {
|
||||
launchAppFromDeepLink(deepLinkUrl, true);
|
||||
await launchAppFromDeepLink(deepLinkUrl, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -43,21 +43,21 @@ 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) {
|
||||
launchAppFromNotification(convertToNotificationData(notification!), true);
|
||||
await launchAppFromNotification(convertToNotificationData(notification!), true);
|
||||
return;
|
||||
}
|
||||
|
||||
launchApp({launchType: Launch.Normal, coldStart: true});
|
||||
await launchApp({launchType: Launch.Normal, coldStart: true});
|
||||
};
|
||||
|
||||
const launchAppFromDeepLink = (deepLinkUrl: string, coldStart = false) => {
|
||||
const launchAppFromDeepLink = async (deepLinkUrl: string, coldStart = false) => {
|
||||
const props = getLaunchPropsFromDeepLink(deepLinkUrl, coldStart);
|
||||
launchApp(props);
|
||||
return launchApp(props);
|
||||
};
|
||||
|
||||
const launchAppFromNotification = async (notification: NotificationWithData, coldStart = false) => {
|
||||
const props = await getLaunchPropsFromNotification(notification, coldStart);
|
||||
launchApp(props);
|
||||
return launchApp(props);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
24
app/queries/app/info.ts
Normal file
24
app/queries/app/info.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Q} from '@nozbe/watermelondb';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import DatabaseManager from '@database/manager';
|
||||
|
||||
import type InfoModel from '@typings/database/models/app/info';
|
||||
|
||||
const {APP: {INFO}} = MM_TABLES;
|
||||
|
||||
export const getLastInstalledVersion = async () => {
|
||||
try {
|
||||
const {database} = DatabaseManager.getAppDatabaseAndOperator();
|
||||
const infos = await database.get<InfoModel>(INFO).query(
|
||||
Q.sortBy('created_at', Q.desc),
|
||||
Q.take(1),
|
||||
).fetch();
|
||||
return infos[0];
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
@@ -36,12 +36,12 @@ export const getIOSAppGroupDetails = (): IOSAppGroupDetails => {
|
||||
* e.g :
|
||||
* MattermostManaged.deleteDatabaseDirectory(databaseName, shouldRemoveDirectory, (error: any, success: any) => { });
|
||||
*/
|
||||
export const deleteIOSDatabase = ({
|
||||
export const deleteIOSDatabase = async ({
|
||||
databaseName = undefined,
|
||||
shouldRemoveDirectory = false,
|
||||
}: IOSDeleteDatabase) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
MattermostManaged.deleteDatabaseDirectory(databaseName, shouldRemoveDirectory, () => null);
|
||||
return MattermostManaged.deleteDatabaseDirectory(databaseName, shouldRemoveDirectory, () => null);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1116,7 +1116,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 449;
|
||||
CURRENT_PROJECT_VERSION = 450;
|
||||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
ENABLE_BITCODE = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
@@ -1160,7 +1160,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 449;
|
||||
CURRENT_PROJECT_VERSION = 450;
|
||||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
ENABLE_BITCODE = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
@@ -1303,7 +1303,7 @@
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 449;
|
||||
CURRENT_PROJECT_VERSION = 450;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
@@ -1354,7 +1354,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 449;
|
||||
CURRENT_PROJECT_VERSION = 450;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>449</string>
|
||||
<string>450</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.0.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>449</string>
|
||||
<string>450</string>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>OpenSans-Bold.ttf</string>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.0.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>449</string>
|
||||
<string>450</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
|
||||
45
types/database/manager.ts
Normal file
45
types/database/manager.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {Database} from '@nozbe/watermelondb';
|
||||
import type {AppDatabase, ServerDatabase, ServerDatabases} from '@typings/database/database';
|
||||
|
||||
export type DatabaseManager = {
|
||||
serverDatabases: ServerDatabases;
|
||||
|
||||
updateServerIdentifier: (serverUrl: string, identifier: string, displayName?: string) => Promise<void>;
|
||||
|
||||
updateServerDisplayName: (serverUrl: string, displayName: string) => Promise<void>;
|
||||
|
||||
isServerPresent: (serverUrl: string) => Promise<boolean>;
|
||||
|
||||
getActiveServerUrl: () => Promise<string|undefined>;
|
||||
|
||||
getActiveServerDisplayName: () => Promise<string|undefined>;
|
||||
|
||||
getServerUrlFromIdentifier: (identifier: string) => Promise<string|undefined>;
|
||||
|
||||
getActiveServerDatabase: () => Promise<Database|undefined>;
|
||||
|
||||
getAppDatabaseAndOperator: () => AppDatabase|undefined;
|
||||
|
||||
getServerDatabaseAndOperator: (serverUrl: string) => ServerDatabase | undefined;
|
||||
|
||||
setActiveServerDatabase: (serverUrl: string) => Promise<void>;
|
||||
|
||||
deleteServerDatabase: (serverUrl: string) => Promise<void>;
|
||||
|
||||
destroyServerDatabase: (serverUrl: string) => Promise<void>;
|
||||
|
||||
deleteServerDatabaseFiles: (serverUrl: string) => Promise<void>;
|
||||
|
||||
deleteServerDatabaseFilesByName: (databaseName: string) => Promise<void>;
|
||||
|
||||
renameDatabase: (databaseName: string, newDBName: string) => Promise<void>;
|
||||
|
||||
factoryReset: (shouldRemoveDirectory: boolean) => Promise<boolean>;
|
||||
|
||||
getDatabaseFilePath: (dbName: string) => string;
|
||||
|
||||
searchUrl: (toFind: string) => string | undefined;
|
||||
}
|
||||
Reference in New Issue
Block a user