diff --git a/app/database/components/index.tsx b/app/database/components/index.tsx new file mode 100644 index 000000000..7acef0f73 --- /dev/null +++ b/app/database/components/index.tsx @@ -0,0 +1,61 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React, {ComponentType, useEffect, useState} from 'react'; +import {Database} from '@nozbe/watermelondb'; +import DatabaseProvider from '@nozbe/watermelondb/DatabaseProvider'; + +import {MM_TABLES} from '@constants/database'; +import DatabaseManager from '@database/manager'; +import Servers from '@database/models/default/servers'; + +const {SERVERS} = MM_TABLES.DEFAULT; + +//TODO: Remove when DatabaseManager is Singleton +const DBManager = new DatabaseManager(); + +export function withServerDatabase( + Component: ComponentType, +): ComponentType { + return function ServerDatabaseComponent(props) { + const [database, setDatabase] = useState(); + + // If we don't need to await the async functions this side effect is not needed + useEffect(() => { + const observer = async (servers: Servers[]) => { + const server = servers.reduce((a, b) => (a.lastActiveAt > b.lastActiveAt ? a : b)); + + // The server database should already exists at this point + // there should not be a need to await + const serverDatabase = await DBManager.retrieveDatabaseInstances([server.url]); + if (serverDatabase?.length) { + setDatabase(serverDatabase[0]); + } + }; + + const init = async () => { + // TODO: At this point the database should be already present + // there should not be a need to await + + const db = await DBManager.getDefaultDatabase(); + db?.collections. + get(SERVERS). + query(). + observeWithColumns(['last_active_at']). + subscribe(observer); + }; + + init(); + }); + + if (!database) { + return null; + } + + return ( + + + + ); + }; +} diff --git a/app/database/models/default/servers.ts b/app/database/models/default/servers.ts index bcac8b1dd..c98490fed 100644 --- a/app/database/models/default/servers.ts +++ b/app/database/models/default/servers.ts @@ -30,4 +30,10 @@ export default class Servers extends Model { /** url : The online address for the Mattermost server */ @field('url') url!: string; + + /** last_active_at: The last time this server was active */ + @field('last_active_at') lastActiveAt!: number; + + /** is_secured: Determines if the protocol used for this server url is HTTP or HTTPS */ + @field('is_secured') isSecured!: boolean; } diff --git a/app/database/operator/handlers/base_handler.test.ts b/app/database/operator/handlers/base_handler.test.ts index 8d32cceb5..8f2c633a5 100644 --- a/app/database/operator/handlers/base_handler.test.ts +++ b/app/database/operator/handlers/base_handler.test.ts @@ -136,6 +136,8 @@ describe('*** DataOperator: Base Handlers tests ***', () => { mention_count: 0, unread_count: 0, url: 'https://community.mattermost.com', + isSecured: true, + lastActiveAt: 1623926359, }, ]; @@ -156,6 +158,8 @@ describe('*** DataOperator: Base Handlers tests ***', () => { mention_count: 0, unread_count: 0, url: 'https://community.mattermost.com', + isSecured: true, + lastActiveAt: 1623926359, }, ], tableName: 'servers', diff --git a/app/database/operator/prepareRecords/general.test.ts b/app/database/operator/prepareRecords/general.test.ts index 7367cf92f..a13709ec2 100644 --- a/app/database/operator/prepareRecords/general.test.ts +++ b/app/database/operator/prepareRecords/general.test.ts @@ -82,6 +82,8 @@ describe('*** Isolated Prepare Records Test ***', () => { mention_count: 1, unread_count: 0, url: 'https://community.mattermost.com', + isSecured: true, + lastActiveAt: 1623926359, }, }, }); diff --git a/app/database/operator/prepareRecords/general.ts b/app/database/operator/prepareRecords/general.ts index faf543f06..602403b61 100644 --- a/app/database/operator/prepareRecords/general.ts +++ b/app/database/operator/prepareRecords/general.ts @@ -105,6 +105,8 @@ export const prepareServersRecord = ({action, database, value}: DataFactoryArgs) servers.mentionCount = raw?.mention_count; servers.unreadCount = raw?.unread_count; servers.url = raw?.url; + servers.isSecured = raw?.isSecured; + servers.lastActiveAt = raw?.lastActiveAt; }; return prepareBaseRecord({ diff --git a/app/database/schema/default/index.ts b/app/database/schema/default/index.ts index 85b2ba310..a37416ae4 100644 --- a/app/database/schema/default/index.ts +++ b/app/database/schema/default/index.ts @@ -32,6 +32,8 @@ export const defaultSchema: AppSchema = appSchema({ {name: 'mention_count', type: 'number'}, {name: 'unread_count', type: 'number'}, {name: 'url', type: 'string', isIndexed: true}, + {name: 'last_active_at', type: 'number', isIndexed: true}, + {name: 'is_secured', type: 'boolean'}, ], }), ], diff --git a/app/database/schema/default/table_schemas/servers.ts b/app/database/schema/default/table_schemas/servers.ts index 17514dad0..ba6dc379e 100644 --- a/app/database/schema/default/table_schemas/servers.ts +++ b/app/database/schema/default/table_schemas/servers.ts @@ -15,5 +15,7 @@ export default tableSchema({ {name: 'mention_count', type: 'number'}, {name: 'unread_count', type: 'number'}, {name: 'url', type: 'string', isIndexed: true}, + {name: 'last_active_at', type: 'number', isIndexed: true}, + {name: 'is_secured', type: 'boolean'}, ], }); diff --git a/app/database/schema/default/test.ts b/app/database/schema/default/test.ts index 568fc8acc..ec9d8356a 100644 --- a/app/database/schema/default/test.ts +++ b/app/database/schema/default/test.ts @@ -44,6 +44,8 @@ describe('*** Test schema for DEFAULT database ***', () => { mention_count: {name: 'mention_count', type: 'number'}, unread_count: {name: 'unread_count', type: 'number'}, url: {name: 'url', type: 'string', isIndexed: true}, + last_active_at: {name: 'last_active_at', type: 'number', isIndexed: true}, + is_secured: {name: 'is_secured', type: 'boolean'}, }, columnArray: [ {name: 'db_path', type: 'string'}, @@ -51,6 +53,8 @@ describe('*** Test schema for DEFAULT database ***', () => { {name: 'mention_count', type: 'number'}, {name: 'unread_count', type: 'number'}, {name: 'url', type: 'string', isIndexed: true}, + {name: 'last_active_at', type: 'number', isIndexed: true}, + {name: 'is_secured', type: 'boolean'}, ], }, }, diff --git a/app/screens/index.tsx b/app/screens/index.tsx index 93e825fb7..c022fa0d9 100644 --- a/app/screens/index.tsx +++ b/app/screens/index.tsx @@ -12,6 +12,8 @@ import {withManagedConfig} from '@mattermost/react-native-emm'; import {Screens} from '@constants'; import {DEFAULT_LOCALE, getTranslations} from '@i18n'; +import {withServerDatabase} from '@database/components'; + // TODO: Remove this and uncomment screens as they get added /* eslint-disable */ @@ -217,6 +219,6 @@ export function registerScreens() { const channelScreen = require('@screens/channel').default; const serverScreen = require('@screens/server').default; - Navigation.registerComponent(Screens.CHANNEL, () => withManagedConfig(channelScreen)); + Navigation.registerComponent(Screens.CHANNEL, () => withIntl(withServerDatabase(withManagedConfig(channelScreen)))); Navigation.registerComponent(Screens.SERVER, () => withIntl(withManagedConfig(serverScreen))); } diff --git a/types/database/database.d.ts b/types/database/database.d.ts index 9afcd03d0..25ece2ded 100644 --- a/types/database/database.d.ts +++ b/types/database/database.d.ts @@ -50,6 +50,8 @@ export type RawServers = { mention_count: number; unread_count: number; url: string; + isSecured: boolean; + lastActiveAt: number; }; export type RawCustomEmoji = { diff --git a/types/database/servers.d.ts b/types/database/servers.d.ts index aadb40776..63ad6b61f 100644 --- a/types/database/servers.d.ts +++ b/types/database/servers.d.ts @@ -25,4 +25,10 @@ export default class Servers extends Model { /** url : The online address for the Mattermost server */ url: string; + + /** last_active_at: The last time this server was active */ + lastActiveAt!: number; + + /** is_secured: Determines if the protocol used for this server url is HTTP or HTTPS */ + isSecured!: boolean; }