From f88bdfb97c4e592c1c883716266065266913d32d Mon Sep 17 00:00:00 2001 From: Reinaldo Neto <47038980+reinaldonetof@users.noreply.github.com> Date: Tue, 1 Feb 2022 10:39:09 -0300 Subject: [PATCH] Chore: Migrate Database to Typescript (#3580) Co-authored-by: Gleidson Daniel Silva Co-authored-by: Diego Mello --- app/containers/Avatar/index.tsx | 12 ++-- app/containers/EmojiPicker/index.tsx | 8 +-- app/containers/MessageActions/Header.tsx | 5 +- app/containers/MessageActions/index.tsx | 15 ++-- app/containers/MessageErrorActions.tsx | 4 +- app/containers/ThreadDetails.tsx | 5 +- app/containers/message/Reply.tsx | 2 +- app/containers/message/interfaces.ts | 2 +- app/containers/message/utils.ts | 3 +- app/definitions/IFrequentlyUsedEmoji.ts | 2 +- app/definitions/ILoggedUser.ts | 2 +- app/definitions/IServerHistory.ts | 2 +- app/definitions/ISubscription.ts | 2 - app/definitions/IThread.ts | 12 ++-- app/definitions/index.ts | 19 +++-- app/definitions/redux/index.ts | 3 +- app/lib/database/{index.js => index.ts} | 26 ++++--- app/lib/database/interfaces.ts | 72 +++++++++++++++++++ app/lib/database/model/CustomEmoji.js | 4 +- app/lib/database/model/FrequentlyUsedEmoji.js | 3 +- app/lib/database/model/Message.js | 4 +- app/lib/database/model/Permission.js | 4 +- app/lib/database/model/Role.js | 4 +- app/lib/database/model/Room.js | 4 +- app/lib/database/model/ServersHistory.js | 4 +- app/lib/database/model/Setting.js | 4 +- app/lib/database/model/SlashCommand.js | 4 +- app/lib/database/model/Subscription.js | 4 +- app/lib/database/model/Thread.js | 4 +- app/lib/database/model/ThreadMessage.js | 4 +- app/lib/database/model/Upload.js | 4 +- app/lib/database/model/User.js | 4 +- app/lib/database/model/index.ts | 16 +++++ app/lib/database/model/servers/Server.js | 4 +- app/lib/database/model/servers/User.js | 4 +- app/lib/database/services/Message.js | 4 +- app/lib/database/services/Subscription.js | 4 +- app/lib/database/services/Thread.js | 4 +- app/lib/database/services/ThreadMessage.js | 4 +- app/lib/methods/getPermissions.js | 2 +- app/lib/methods/getRoles.js | 2 +- app/utils/goRoom.ts | 9 ++- app/views/AddExistingChannelView.tsx | 17 +++-- .../CreateDiscussionView/SelectChannel.tsx | 3 +- .../CreateDiscussionView/SelectUsers.tsx | 4 +- app/views/NewMessageView.tsx | 21 +++--- app/views/NewServerView/ServerInput/Item.tsx | 6 +- app/views/NewServerView/ServerInput/index.tsx | 6 +- app/views/NewServerView/index.tsx | 12 ++-- .../NotificationPreferencesView/index.tsx | 4 +- app/views/RoomActionsView/index.js | 2 +- app/views/RoomView/List/index.js | 6 +- app/views/RoomView/UploadProgress.js | 2 +- app/views/RoomView/index.js | 2 +- app/views/RoomsListView/ServerDropdown.js | 2 +- app/views/RoomsListView/index.js | 4 +- app/views/ScreenLockConfigView.tsx | 4 +- app/views/SelectedUsersView.tsx | 9 ++- app/views/ThreadMessagesView/index.tsx | 17 +++-- 59 files changed, 280 insertions(+), 145 deletions(-) rename app/lib/database/{index.js => index.ts} (81%) create mode 100644 app/lib/database/interfaces.ts create mode 100644 app/lib/database/model/index.ts diff --git a/app/containers/Avatar/index.tsx b/app/containers/Avatar/index.tsx index 2ce066479..637596410 100644 --- a/app/containers/Avatar/index.tsx +++ b/app/containers/Avatar/index.tsx @@ -1,16 +1,18 @@ import React from 'react'; import { connect } from 'react-redux'; import { Q } from '@nozbe/watermelondb'; +import { Observable, Subscription } from 'rxjs'; import database from '../../lib/database'; import { getUserSelector } from '../../selectors/login'; +import { TSubscriptionModel, TUserModel } from '../../definitions'; import Avatar from './Avatar'; import { IAvatar } from './interfaces'; class AvatarContainer extends React.Component { private mounted: boolean; - private subscription: any; + private subscription?: Subscription; static defaultProps = { text: '', @@ -59,15 +61,17 @@ class AvatarContainer extends React.Component { record = user; } else { const { rid } = this.props; - record = await subsCollection.find(rid); + if (rid) { + record = await subsCollection.find(rid); + } } } catch { // Record not found } if (record) { - const observable = record.observe(); - this.subscription = observable.subscribe((r: any) => { + const observable = record.observe() as Observable; + this.subscription = observable.subscribe(r => { const { avatarETag } = r; if (this.mounted) { this.setState({ avatarETag }); diff --git a/app/containers/EmojiPicker/index.tsx b/app/containers/EmojiPicker/index.tsx index 12217cf95..5fc4a5b9b 100644 --- a/app/containers/EmojiPicker/index.tsx +++ b/app/containers/EmojiPicker/index.tsx @@ -36,7 +36,7 @@ interface IEmojiPickerProps { } interface IEmojiPickerState { - frequentlyUsed: []; + frequentlyUsed: (string | { content?: string; extension?: string; isCustom: boolean })[]; customEmojis: any; show: boolean; width: number | null; @@ -114,7 +114,7 @@ class EmojiPicker extends Component { // Do nothing } - await db.action(async () => { + await db.write(async () => { if (freqEmojiRecord) { await freqEmojiRecord.update((f: any) => { f.count += 1; @@ -132,8 +132,8 @@ class EmojiPicker extends Component { updateFrequentlyUsed = async () => { const db = database.active; const frequentlyUsedRecords = await db.get('frequently_used_emojis').query().fetch(); - let frequentlyUsed: any = orderBy(frequentlyUsedRecords, ['count'], ['desc']); - frequentlyUsed = frequentlyUsed.map((item: IEmoji) => { + const frequentlyUsedOrdered = orderBy(frequentlyUsedRecords, ['count'], ['desc']); + const frequentlyUsed = frequentlyUsedOrdered.map(item => { if (item.isCustom) { return { content: item.content, extension: item.extension, isCustom: item.isCustom }; } diff --git a/app/containers/MessageActions/Header.tsx b/app/containers/MessageActions/Header.tsx index ace8d56b7..0c8e07bd8 100644 --- a/app/containers/MessageActions/Header.tsx +++ b/app/containers/MessageActions/Header.tsx @@ -10,6 +10,7 @@ import database from '../../lib/database'; import { Button } from '../ActionSheet'; import { useDimensions } from '../../dimensions'; import sharedStyles from '../../views/Styles'; +import { TFrequentlyUsedEmojiModel } from '../../definitions/IFrequentlyUsedEmoji'; import { IEmoji } from '../EmojiPicker/interfaces'; interface IHeader { @@ -90,14 +91,14 @@ const HeaderFooter = React.memo(({ onReaction, theme }: THeaderFooter) => ( )); const Header = React.memo(({ handleReaction, server, message, isMasterDetail, theme }: IHeader) => { - const [items, setItems] = useState([]); + const [items, setItems] = useState<(TFrequentlyUsedEmojiModel | string)[]>([]); const { width, height }: any = useDimensions(); const setEmojis = async () => { try { const db = database.active; const freqEmojiCollection = db.get('frequently_used_emojis'); - let freqEmojis = await freqEmojiCollection.query().fetch(); + let freqEmojis: (TFrequentlyUsedEmojiModel | string)[] = await freqEmojiCollection.query().fetch(); const isLandscape = width > height; const size = (isLandscape || isMasterDetail ? width / 2 : width) - CONTAINER_MARGIN * 2; diff --git a/app/containers/MessageActions/index.tsx b/app/containers/MessageActions/index.tsx index 4237e2c1e..87a28e74c 100644 --- a/app/containers/MessageActions/index.tsx +++ b/app/containers/MessageActions/index.tsx @@ -15,6 +15,7 @@ import { showConfirmationAlert } from '../../utils/info'; import { useActionSheet } from '../ActionSheet'; import Header, { HEADER_HEIGHT } from './Header'; import events from '../../utils/log/events'; +import { TMessageModel } from '../../definitions/IMessage'; interface IMessageActions { room: { @@ -182,9 +183,9 @@ const MessageActions = React.memo( if (result.success) { const subCollection = db.get('subscriptions'); const subRecord = await subCollection.find(rid); - await db.action(async () => { + await db.write(async () => { try { - await subRecord.update((sub: any) => (sub.lastOpen = ts)); + await subRecord.update(sub => (sub.lastOpen = ts)); } catch { // do nothing } @@ -269,11 +270,11 @@ const MessageActions = React.memo( } }; - const handleToggleTranslation = async (message: any) => { + const handleToggleTranslation = async (message: TMessageModel) => { try { const db = database.active; - await db.action(async () => { - await message.update((m: any) => { + await db.write(async () => { + await message.update(m => { m.autoTranslate = !m.autoTranslate; m._updatedAt = new Date(); }); @@ -320,7 +321,7 @@ const MessageActions = React.memo( }); }; - const getOptions = (message: any) => { + const getOptions = (message: TMessageModel) => { let options: any = []; // Reply @@ -446,7 +447,7 @@ const MessageActions = React.memo( return options; }; - const showMessageActions = async (message: any) => { + const showMessageActions = async (message: TMessageModel) => { logEvent(events.ROOM_SHOW_MSG_ACTIONS); await getPermissions(); showActionSheet({ diff --git a/app/containers/MessageErrorActions.tsx b/app/containers/MessageErrorActions.tsx index 6f56e54db..40b57536e 100644 --- a/app/containers/MessageErrorActions.tsx +++ b/app/containers/MessageErrorActions.tsx @@ -36,7 +36,7 @@ const MessageErrorActions = forwardRef(({ tmid }: any, ref): any => { try { // Find the thread header and update it const msg = await msgCollection.find(tmid); - if (msg.tcount <= 1) { + if (msg?.tcount && msg.tcount <= 1) { deleteBatch.push( msg.prepareUpdate((m: any) => { m.tcount = null; @@ -62,7 +62,7 @@ const MessageErrorActions = forwardRef(({ tmid }: any, ref): any => { // Do nothing: message not found } } - await db.action(async () => { + await db.write(async () => { await db.batch(...deleteBatch); }); } catch (e) { diff --git a/app/containers/ThreadDetails.tsx b/app/containers/ThreadDetails.tsx index 90f3faa4b..8e9c36d19 100644 --- a/app/containers/ThreadDetails.tsx +++ b/app/containers/ThreadDetails.tsx @@ -52,8 +52,9 @@ interface IThreadDetails { } const ThreadDetails = ({ item, user, badgeColor, toggleFollowThread, style, theme }: IThreadDetails) => { - let { tcount } = item; - if (tcount! >= 1000) { + let tcount: number | string = item?.tcount ?? 0; + + if (tcount >= 1000) { tcount = '+999'; } diff --git a/app/containers/message/Reply.tsx b/app/containers/message/Reply.tsx index 8d8126050..56fdc6071 100644 --- a/app/containers/message/Reply.tsx +++ b/app/containers/message/Reply.tsx @@ -182,7 +182,7 @@ const Fields = React.memo( {field.title} {/* @ts-ignore*/} { return ''; }; -export const getMessageTranslation = (message: { translations: any }, autoTranslateLanguage: string) => { +export const getMessageTranslation = (message: TMessageModel, autoTranslateLanguage: string) => { if (!autoTranslateLanguage) { return null; } diff --git a/app/definitions/IFrequentlyUsedEmoji.ts b/app/definitions/IFrequentlyUsedEmoji.ts index a659e2abd..87e46cf33 100644 --- a/app/definitions/IFrequentlyUsedEmoji.ts +++ b/app/definitions/IFrequentlyUsedEmoji.ts @@ -7,4 +7,4 @@ export interface IFrequentlyUsedEmoji { count: number; } -export type TFrequentlyUsedEmoji = IFrequentlyUsedEmoji & Model; +export type TFrequentlyUsedEmojiModel = IFrequentlyUsedEmoji & Model; diff --git a/app/definitions/ILoggedUser.ts b/app/definitions/ILoggedUser.ts index 487d29c18..380bcd86c 100644 --- a/app/definitions/ILoggedUser.ts +++ b/app/definitions/ILoggedUser.ts @@ -15,4 +15,4 @@ export interface ILoggedUser { enableMessageParserEarlyAdoption?: boolean; } -export type TLoggedUser = ILoggedUser & Model; +export type TLoggedUserModel = ILoggedUser & Model; diff --git a/app/definitions/IServerHistory.ts b/app/definitions/IServerHistory.ts index 296cba4ed..68d25df4f 100644 --- a/app/definitions/IServerHistory.ts +++ b/app/definitions/IServerHistory.ts @@ -7,4 +7,4 @@ export interface IServerHistory { updatedAt: Date; } -export type TServerHistory = IServerHistory & Model; +export type TServerHistoryModel = IServerHistory & Model; diff --git a/app/definitions/ISubscription.ts b/app/definitions/ISubscription.ts index 1f241599a..5f561edfb 100644 --- a/app/definitions/ISubscription.ts +++ b/app/definitions/ISubscription.ts @@ -79,8 +79,6 @@ export interface ISubscription { avatarETag?: string; teamId?: string; teamMain?: boolean; - search?: boolean; - username?: string; // https://nozbe.github.io/WatermelonDB/Relation.html#relation-api messages: Relation; threads: Relation; diff --git a/app/definitions/IThread.ts b/app/definitions/IThread.ts index e97b2348c..ad151283b 100644 --- a/app/definitions/IThread.ts +++ b/app/definitions/IThread.ts @@ -43,10 +43,10 @@ export interface IThread { id: string; msg?: string; t?: SubscriptionType; - rid?: string; - _updatedAt?: Date; - ts?: Date; - u?: IUserMessage; + rid: string; + _updatedAt: Date; + ts: Date; + u: IUserMessage; alias?: string; parseUrls?: boolean; groupable?: boolean; @@ -64,8 +64,8 @@ export interface IThread { dcount?: number; dlm?: number; tmid?: string; - tcount: number | string; - tlm?: string; + tcount?: number; + tlm?: Date; replies?: string[]; mentions?: IUserMention[]; channels?: IUserChannel[]; diff --git a/app/definitions/index.ts b/app/definitions/index.ts index 5abdd95c3..e37eae1f4 100644 --- a/app/definitions/index.ts +++ b/app/definitions/index.ts @@ -3,12 +3,23 @@ import { StackNavigationProp } from '@react-navigation/stack'; import { Dispatch } from 'redux'; export * from './IAttachment'; -export * from './IMessage'; export * from './INotification'; -export * from './IRoom'; -export * from './IServer'; -export * from './ISubscription'; export * from './IPreferences'; +export * from './ISubscription'; +export * from './IRoom'; +export * from './IMessage'; +export * from './IThread'; +export * from './IThreadMessage'; +export * from './ICustomEmoji'; +export * from './IFrequentlyUsedEmoji'; +export * from './IUpload'; +export * from './ISettings'; +export * from './IRole'; +export * from './IPermission'; +export * from './ISlashCommand'; +export * from './IUser'; +export * from './IServer'; +export * from './ILoggedUser'; export * from './IServerHistory'; export interface IBaseScreen, S extends string> { diff --git a/app/definitions/redux/index.ts b/app/definitions/redux/index.ts index e43b1e878..3a46d6ef3 100644 --- a/app/definitions/redux/index.ts +++ b/app/definitions/redux/index.ts @@ -16,7 +16,6 @@ import { ISelectedUsers } from '../../reducers/selectedUsers'; import { IConnect } from '../../reducers/connect'; import { ISettings } from '../../reducers/settings'; - export interface IApplicationState { settings: ISettings; login: any; @@ -49,4 +48,4 @@ export type TApplicationActions = TActionActiveUsers & IActionSettings & TActionEncryption & TActionSortPreferences & - TActionUserTyping; + TActionUserTyping; diff --git a/app/lib/database/index.js b/app/lib/database/index.ts similarity index 81% rename from app/lib/database/index.js rename to app/lib/database/index.ts index ee02e6212..1b8df955b 100644 --- a/app/lib/database/index.js +++ b/app/lib/database/index.ts @@ -25,6 +25,7 @@ import serversSchema from './schema/servers'; import appSchema from './schema/app'; import migrations from './model/migrations'; import serversMigrations from './model/servers/migrations'; +import { TAppDatabase, TServerDatabase } from './interfaces'; const appGroupPath = isIOS ? appGroup.path : ''; @@ -32,9 +33,9 @@ if (__DEV__ && isIOS) { console.log(appGroupPath); } -const getDatabasePath = name => `${appGroupPath}${name}${isOfficial ? '' : '-experimental'}.db`; +const getDatabasePath = (name: string) => `${appGroupPath}${name}${isOfficial ? '' : '-experimental'}.db`; -export const getDatabase = (database = '') => { +export const getDatabase = (database = ''): Database => { const path = database.replace(/(^\w+:|^)\/\//, '').replace(/\//g, '.'); const dbName = getDatabasePath(path); @@ -64,8 +65,14 @@ export const getDatabase = (database = '') => { }); }; +interface IDatabases { + shareDB?: TAppDatabase; + serversDB: TServerDatabase; + activeDB?: TAppDatabase; +} + class DB { - databases = { + databases: IDatabases = { serversDB: new Database({ adapter: new SQLiteAdapter({ dbName: getDatabasePath('default'), @@ -73,11 +80,12 @@ class DB { migrations: serversMigrations }), modelClasses: [Server, LoggedUser, ServersHistory] - }) + }) as TServerDatabase }; - get active() { - return this.databases.shareDB || this.databases.activeDB; + // Expected at least one database + get active(): TAppDatabase { + return this.databases.shareDB || this.databases.activeDB!; } get share() { @@ -116,11 +124,11 @@ class DB { Setting, User ] - }); + }) as TAppDatabase; } - setActiveDB(database) { - this.databases.activeDB = getDatabase(database); + setActiveDB(database: string) { + this.databases.activeDB = getDatabase(database) as TAppDatabase; } } diff --git a/app/lib/database/interfaces.ts b/app/lib/database/interfaces.ts new file mode 100644 index 000000000..49c30e068 --- /dev/null +++ b/app/lib/database/interfaces.ts @@ -0,0 +1,72 @@ +import { Database, Collection } from '@nozbe/watermelondb'; + +import * as models from './model'; +import * as definitions from '../../definitions'; + +export type TAppDatabaseNames = + | typeof models.SUBSCRIPTIONS_TABLE + | typeof models.ROOMS_TABLE + | typeof models.MESSAGES_TABLE + | typeof models.THREADS_TABLE + | typeof models.THREAD_MESSAGES_TABLE + | typeof models.CUSTOM_EMOJIS_TABLE + | typeof models.FREQUENTLY_USED_EMOJIS_TABLE + | typeof models.UPLOADS_TABLE + | typeof models.SETTINGS_TABLE + | typeof models.ROLES_TABLE + | typeof models.PERMISSIONS_TABLE + | typeof models.SLASH_COMMANDS_TABLE + | typeof models.USERS_TABLE; + +// Verify if T extends one type from TAppDatabaseNames, and if is truly, +// returns the specific model type. +// https://stackoverflow.com/a/54166010 TypeScript function return type based on input parameter +type ObjectType = T extends typeof models.SUBSCRIPTIONS_TABLE + ? definitions.TSubscriptionModel + : T extends typeof models.ROOMS_TABLE + ? definitions.TRoomModel + : T extends typeof models.MESSAGES_TABLE + ? definitions.TMessageModel + : T extends typeof models.THREADS_TABLE + ? definitions.TThreadModel + : T extends typeof models.THREAD_MESSAGES_TABLE + ? definitions.TThreadMessageModel + : T extends typeof models.CUSTOM_EMOJIS_TABLE + ? definitions.TCustomEmojiModel + : T extends typeof models.FREQUENTLY_USED_EMOJIS_TABLE + ? definitions.TFrequentlyUsedEmojiModel + : T extends typeof models.UPLOADS_TABLE + ? definitions.TUploadModel + : T extends typeof models.SETTINGS_TABLE + ? definitions.TSettingsModel + : T extends typeof models.ROLES_TABLE + ? definitions.TRoleModel + : T extends typeof models.PERMISSIONS_TABLE + ? definitions.TPermissionModel + : T extends typeof models.SLASH_COMMANDS_TABLE + ? definitions.TSlashCommandModel + : T extends typeof models.USERS_TABLE + ? definitions.TUserModel + : never; + +export type TAppDatabase = { + get: (db: T) => Collection>; +} & Database; + +// Migration to server database +export type TServerDatabaseNames = + | typeof models.SERVERS_TABLE + | typeof models.LOGGED_USERS_TABLE + | typeof models.SERVERS_HISTORY_TABLE; + +type ObjectServerType = T extends typeof models.SERVERS_TABLE + ? definitions.TServerModel + : T extends typeof models.LOGGED_USERS_TABLE + ? definitions.TLoggedUserModel + : T extends typeof models.SERVERS_HISTORY_TABLE + ? definitions.TServerHistoryModel + : never; + +export type TServerDatabase = { + get: (db: T) => Collection>; +} & Database; diff --git a/app/lib/database/model/CustomEmoji.js b/app/lib/database/model/CustomEmoji.js index 9f3e1b6a8..c8fdedd05 100644 --- a/app/lib/database/model/CustomEmoji.js +++ b/app/lib/database/model/CustomEmoji.js @@ -3,8 +3,10 @@ import { date, field, json } from '@nozbe/watermelondb/decorators'; import { sanitizer } from '../utils'; +export const CUSTOM_EMOJIS_TABLE = 'custom_emojis'; + export default class CustomEmoji extends Model { - static table = 'custom_emojis'; + static table = CUSTOM_EMOJIS_TABLE; @field('name') name; diff --git a/app/lib/database/model/FrequentlyUsedEmoji.js b/app/lib/database/model/FrequentlyUsedEmoji.js index 9629d3a99..2c6c815ed 100644 --- a/app/lib/database/model/FrequentlyUsedEmoji.js +++ b/app/lib/database/model/FrequentlyUsedEmoji.js @@ -1,8 +1,9 @@ import { Model } from '@nozbe/watermelondb'; import { field } from '@nozbe/watermelondb/decorators'; +export const FREQUENTLY_USED_EMOJIS_TABLE = 'frequently_used_emojis'; export default class FrequentlyUsedEmoji extends Model { - static table = 'frequently_used_emojis'; + static table = FREQUENTLY_USED_EMOJIS_TABLE; @field('content') content; diff --git a/app/lib/database/model/Message.js b/app/lib/database/model/Message.js index 20134733b..392283a63 100644 --- a/app/lib/database/model/Message.js +++ b/app/lib/database/model/Message.js @@ -3,10 +3,10 @@ import { date, field, json, relation } from '@nozbe/watermelondb/decorators'; import { sanitizer } from '../utils'; -export const TABLE_NAME = 'messages'; +export const MESSAGES_TABLE = 'messages'; export default class Message extends Model { - static table = TABLE_NAME; + static table = MESSAGES_TABLE; static associations = { subscriptions: { type: 'belongs_to', key: 'rid' } diff --git a/app/lib/database/model/Permission.js b/app/lib/database/model/Permission.js index 5923f83dc..c397f079a 100644 --- a/app/lib/database/model/Permission.js +++ b/app/lib/database/model/Permission.js @@ -3,8 +3,10 @@ import { date, json } from '@nozbe/watermelondb/decorators'; import { sanitizer } from '../utils'; +export const PERMISSIONS_TABLE = 'permissions'; + export default class Permission extends Model { - static table = 'permissions'; + static table = PERMISSIONS_TABLE; @json('roles', sanitizer) roles; diff --git a/app/lib/database/model/Role.js b/app/lib/database/model/Role.js index ad9256d58..e0633b045 100644 --- a/app/lib/database/model/Role.js +++ b/app/lib/database/model/Role.js @@ -1,8 +1,10 @@ import { Model } from '@nozbe/watermelondb'; import { field } from '@nozbe/watermelondb/decorators'; +export const ROLES_TABLE = 'roles'; + export default class Role extends Model { - static table = 'roles'; + static table = ROLES_TABLE; @field('description') description; } diff --git a/app/lib/database/model/Room.js b/app/lib/database/model/Room.js index 131fbaf0e..e2a1127bf 100644 --- a/app/lib/database/model/Room.js +++ b/app/lib/database/model/Room.js @@ -3,8 +3,10 @@ import { field, json } from '@nozbe/watermelondb/decorators'; import { sanitizer } from '../utils'; +export const ROOMS_TABLE = 'rooms'; + export default class Room extends Model { - static table = 'rooms'; + static table = ROOMS_TABLE; @json('custom_fields', sanitizer) customFields; diff --git a/app/lib/database/model/ServersHistory.js b/app/lib/database/model/ServersHistory.js index 4bbef3e98..168403782 100644 --- a/app/lib/database/model/ServersHistory.js +++ b/app/lib/database/model/ServersHistory.js @@ -1,8 +1,10 @@ import { Model } from '@nozbe/watermelondb'; import { date, field, readonly } from '@nozbe/watermelondb/decorators'; +export const SERVERS_HISTORY_TABLE = 'servers_history'; + export default class ServersHistory extends Model { - static table = 'servers_history'; + static table = SERVERS_HISTORY_TABLE; @field('url') url; diff --git a/app/lib/database/model/Setting.js b/app/lib/database/model/Setting.js index 753d965ba..1597272bd 100644 --- a/app/lib/database/model/Setting.js +++ b/app/lib/database/model/Setting.js @@ -3,8 +3,10 @@ import { date, field, json } from '@nozbe/watermelondb/decorators'; import { sanitizer } from '../utils'; +export const SETTINGS_TABLE = 'settings'; + export default class Setting extends Model { - static table = 'settings'; + static table = SETTINGS_TABLE; @field('value_as_string') valueAsString; diff --git a/app/lib/database/model/SlashCommand.js b/app/lib/database/model/SlashCommand.js index 418e72144..8bcba65f7 100644 --- a/app/lib/database/model/SlashCommand.js +++ b/app/lib/database/model/SlashCommand.js @@ -1,8 +1,10 @@ import { Model } from '@nozbe/watermelondb'; import { field } from '@nozbe/watermelondb/decorators'; +export const SLASH_COMMANDS_TABLE = 'slash_commands'; + export default class SlashCommand extends Model { - static table = 'slash_commands'; + static table = SLASH_COMMANDS_TABLE; @field('params') params; diff --git a/app/lib/database/model/Subscription.js b/app/lib/database/model/Subscription.js index aab0e0bbb..7b177349a 100644 --- a/app/lib/database/model/Subscription.js +++ b/app/lib/database/model/Subscription.js @@ -3,10 +3,10 @@ import { children, date, field, json } from '@nozbe/watermelondb/decorators'; import { sanitizer } from '../utils'; -export const TABLE_NAME = 'subscriptions'; +export const SUBSCRIPTIONS_TABLE = 'subscriptions'; export default class Subscription extends Model { - static table = TABLE_NAME; + static table = SUBSCRIPTIONS_TABLE; static associations = { messages: { type: 'has_many', foreignKey: 'rid' }, diff --git a/app/lib/database/model/Thread.js b/app/lib/database/model/Thread.js index 5d1246af8..1224554b6 100644 --- a/app/lib/database/model/Thread.js +++ b/app/lib/database/model/Thread.js @@ -3,10 +3,10 @@ import { date, field, json, relation } from '@nozbe/watermelondb/decorators'; import { sanitizer } from '../utils'; -export const TABLE_NAME = 'threads'; +export const THREADS_TABLE = 'threads'; export default class Thread extends Model { - static table = TABLE_NAME; + static table = THREADS_TABLE; static associations = { subscriptions: { type: 'belongs_to', key: 'rid' } diff --git a/app/lib/database/model/ThreadMessage.js b/app/lib/database/model/ThreadMessage.js index 27ea0e850..bc5502fd2 100644 --- a/app/lib/database/model/ThreadMessage.js +++ b/app/lib/database/model/ThreadMessage.js @@ -3,10 +3,10 @@ import { date, field, json, relation } from '@nozbe/watermelondb/decorators'; import { sanitizer } from '../utils'; -export const TABLE_NAME = 'thread_messages'; +export const THREAD_MESSAGES_TABLE = 'thread_messages'; export default class ThreadMessage extends Model { - static table = TABLE_NAME; + static table = THREAD_MESSAGES_TABLE; static associations = { subscriptions: { type: 'belongs_to', key: 'subscription_id' } diff --git a/app/lib/database/model/Upload.js b/app/lib/database/model/Upload.js index 810fcd5b7..d03a87729 100644 --- a/app/lib/database/model/Upload.js +++ b/app/lib/database/model/Upload.js @@ -1,8 +1,10 @@ import { Model } from '@nozbe/watermelondb'; import { field, relation } from '@nozbe/watermelondb/decorators'; +export const UPLOADS_TABLE = 'uploads'; + export default class Upload extends Model { - static table = 'uploads'; + static table = UPLOADS_TABLE; static associations = { subscriptions: { type: 'belongs_to', key: 'rid' } diff --git a/app/lib/database/model/User.js b/app/lib/database/model/User.js index 9bc1f2008..23978d1ca 100644 --- a/app/lib/database/model/User.js +++ b/app/lib/database/model/User.js @@ -3,8 +3,10 @@ import { field, json } from '@nozbe/watermelondb/decorators'; import { sanitizer } from '../utils'; +export const USERS_TABLE = 'users'; + export default class User extends Model { - static table = 'users'; + static table = USERS_TABLE; @field('_id') _id; diff --git a/app/lib/database/model/index.ts b/app/lib/database/model/index.ts new file mode 100644 index 000000000..064204244 --- /dev/null +++ b/app/lib/database/model/index.ts @@ -0,0 +1,16 @@ +export * from './CustomEmoji'; +export * from './FrequentlyUsedEmoji'; +export * from './Message'; +export * from './Permission'; +export * from './Role'; +export * from './Room'; +export * from './Setting'; +export * from './SlashCommand'; +export * from './Subscription'; +export * from './Thread'; +export * from './ThreadMessage'; +export * from './Upload'; +export * from './User'; +export * from './ServersHistory'; +export * from './servers/Server'; +export * from './servers/User'; diff --git a/app/lib/database/model/servers/Server.js b/app/lib/database/model/servers/Server.js index 0bff69ffe..e0098075c 100644 --- a/app/lib/database/model/servers/Server.js +++ b/app/lib/database/model/servers/Server.js @@ -1,8 +1,10 @@ import { Model } from '@nozbe/watermelondb'; import { date, field } from '@nozbe/watermelondb/decorators'; +export const SERVERS_TABLE = 'servers'; + export default class Server extends Model { - static table = 'servers'; + static table = SERVERS_TABLE; @field('name') name; diff --git a/app/lib/database/model/servers/User.js b/app/lib/database/model/servers/User.js index 30bd5f57d..5d3438237 100644 --- a/app/lib/database/model/servers/User.js +++ b/app/lib/database/model/servers/User.js @@ -3,8 +3,10 @@ import { field, json } from '@nozbe/watermelondb/decorators'; import { sanitizer } from '../../utils'; +export const LOGGED_USERS_TABLE = 'users'; + export default class User extends Model { - static table = 'users'; + static table = LOGGED_USERS_TABLE; @field('token') token; diff --git a/app/lib/database/services/Message.js b/app/lib/database/services/Message.js index 594513dec..562bf589d 100644 --- a/app/lib/database/services/Message.js +++ b/app/lib/database/services/Message.js @@ -1,7 +1,7 @@ import database from '..'; -import { TABLE_NAME } from '../model/Message'; +import { MESSAGES_TABLE } from '../model/Message'; -const getCollection = db => db.get(TABLE_NAME); +const getCollection = db => db.get(MESSAGES_TABLE); export const getMessageById = async messageId => { const db = database.active; diff --git a/app/lib/database/services/Subscription.js b/app/lib/database/services/Subscription.js index 68bf8ac96..19be6d58f 100644 --- a/app/lib/database/services/Subscription.js +++ b/app/lib/database/services/Subscription.js @@ -1,7 +1,7 @@ import database from '..'; -import { TABLE_NAME } from '../model/Subscription'; +import { SUBSCRIPTIONS_TABLE } from '../model/Subscription'; -const getCollection = db => db.get(TABLE_NAME); +const getCollection = db => db.get(SUBSCRIPTIONS_TABLE); export const getSubscriptionByRoomId = async rid => { const db = database.active; diff --git a/app/lib/database/services/Thread.js b/app/lib/database/services/Thread.js index 9b362dcb1..9d90dc00d 100644 --- a/app/lib/database/services/Thread.js +++ b/app/lib/database/services/Thread.js @@ -1,7 +1,7 @@ import database from '..'; -import { TABLE_NAME } from '../model/Thread'; +import { THREADS_TABLE } from '../model/Thread'; -const getCollection = db => db.get(TABLE_NAME); +const getCollection = db => db.get(THREADS_TABLE); export const getThreadById = async tmid => { const db = database.active; diff --git a/app/lib/database/services/ThreadMessage.js b/app/lib/database/services/ThreadMessage.js index e9509774e..7ac937b2a 100644 --- a/app/lib/database/services/ThreadMessage.js +++ b/app/lib/database/services/ThreadMessage.js @@ -1,7 +1,7 @@ import database from '..'; -import { TABLE_NAME } from '../model/ThreadMessage'; +import { THREAD_MESSAGES_TABLE } from '../model/ThreadMessage'; -const getCollection = db => db.get(TABLE_NAME); +const getCollection = db => db.get(THREAD_MESSAGES_TABLE); export const getThreadMessageById = async messageId => { const db = database.active; diff --git a/app/lib/methods/getPermissions.js b/app/lib/methods/getPermissions.js index b680a9196..889aeaf16 100644 --- a/app/lib/methods/getPermissions.js +++ b/app/lib/methods/getPermissions.js @@ -61,7 +61,7 @@ const PERMISSIONS = [ export async function setPermissions() { const db = database.active; - const permissionsCollection = db.collections.get('permissions'); + const permissionsCollection = db.get('permissions'); const allPermissions = await permissionsCollection.query(Q.where('id', Q.oneOf(PERMISSIONS))).fetch(); const parsed = allPermissions.reduce((acc, item) => ({ ...acc, [item.id]: item.roles }), {}); diff --git a/app/lib/methods/getRoles.js b/app/lib/methods/getRoles.js index d8beb5785..77bc5cf83 100644 --- a/app/lib/methods/getRoles.js +++ b/app/lib/methods/getRoles.js @@ -8,7 +8,7 @@ import protectedFunction from './helpers/protectedFunction'; export async function setRoles() { const db = database.active; - const rolesCollection = db.collections.get('roles'); + const rolesCollection = db.get('roles'); const allRoles = await rolesCollection.query().fetch(); const parsed = allRoles.reduce((acc, item) => ({ ...acc, [item.id]: item.description || item.id }), {}); reduxStore.dispatch(setRolesAction(parsed)); diff --git a/app/utils/goRoom.ts b/app/utils/goRoom.ts index dc8a31882..e2623a47e 100644 --- a/app/utils/goRoom.ts +++ b/app/utils/goRoom.ts @@ -31,9 +31,8 @@ const navigate = ({ }; interface IItem extends Partial { - rid: string; - name: string; - t: SubscriptionType; + search?: boolean; // comes from spotlight + username?: string; } export const goRoom = async ({ @@ -46,7 +45,7 @@ export const goRoom = async ({ navigationMethod?: any; jumpToMessageId?: string; }): Promise => { - if (item.t === 'd' && item.search) { + if (item.t === SubscriptionType.DIRECT && item?.search) { // if user is using the search we need first to join/create room try { const { username } = item; @@ -55,7 +54,7 @@ export const goRoom = async ({ return navigate({ item: { rid: result.room._id, - name: username!, + name: username, t: SubscriptionType.DIRECT }, isMasterDetail, diff --git a/app/views/AddExistingChannelView.tsx b/app/views/AddExistingChannelView.tsx index 98fe4d2ba..2a36734eb 100644 --- a/app/views/AddExistingChannelView.tsx +++ b/app/views/AddExistingChannelView.tsx @@ -22,11 +22,11 @@ import { goRoom } from '../utils/goRoom'; import { showErrorAlert } from '../utils/info'; import debounce from '../utils/debounce'; import { ChatsStackParamList } from '../stacks/types'; -import { IRoom } from '../definitions/IRoom'; +import { TSubscriptionModel, SubscriptionType } from '../definitions'; interface IAddExistingChannelViewState { - search: Array; - channels: Array; + search: TSubscriptionModel[]; + channels: TSubscriptionModel[]; selected: string[]; loading: boolean; } @@ -83,7 +83,7 @@ class AddExistingChannelView extends React.Component) => { + const asyncFilter = async (channelsArray: TSubscriptionModel[]) => { const results = await Promise.all( - channelsArray.map(async (channel: IRoom) => { + channelsArray.map(async channel => { if (channel.prid) { return false; } @@ -173,11 +173,10 @@ class AddExistingChannelView extends React.Component { + renderItem = ({ item }: { item: TSubscriptionModel }) => { const isChecked = this.isChecked(item.rid); // TODO: reuse logic inside RoomTypeIcon - const icon = item.t === 'p' && !item.teamId ? 'channel-private' : 'channel-public'; + const icon = item.t === SubscriptionType.DIRECT && !item?.teamId ? 'channel-private' : 'channel-public'; return ( { - const [channels, setChannels] = useState([]); + const [channels, setChannels] = useState([]); const getChannels = debounce(async (keyword = '') => { try { diff --git a/app/views/CreateDiscussionView/SelectUsers.tsx b/app/views/CreateDiscussionView/SelectUsers.tsx index d63c5ae6a..6ef6e25df 100644 --- a/app/views/CreateDiscussionView/SelectUsers.tsx +++ b/app/views/CreateDiscussionView/SelectUsers.tsx @@ -38,11 +38,11 @@ const SelectUsers = ({ const res = await RocketChat.search({ text: keyword, filterRooms: false }); let items = [ ...users.filter((u: IUser) => selected.includes(u.name)), - ...res.filter((r: IUser) => !users.find((u: IUser) => u.name === r.name)) + ...res.filter(r => !users.find((u: IUser) => u.name === r.name)) ]; const records = await usersCollection.query(Q.where('username', Q.oneOf(items.map(u => u.name)))).fetch(); items = items.map(item => { - const index = records.findIndex((r: IUser) => r.username === item.name); + const index = records.findIndex(r => r.username === item.name); if (index > -1) { const record = records[index]; return { diff --git a/app/views/NewMessageView.tsx b/app/views/NewMessageView.tsx index cd1822513..25df26684 100644 --- a/app/views/NewMessageView.tsx +++ b/app/views/NewMessageView.tsx @@ -24,6 +24,7 @@ import { createChannelRequest } from '../actions/createChannel'; import { goRoom } from '../utils/goRoom'; import SafeAreaView from '../containers/SafeAreaView'; import { compareServerVersion, methods } from '../lib/utils'; +import { TSubscriptionModel } from '../definitions'; import sharedStyles from './Styles'; const QUERY_SIZE = 50; @@ -68,9 +69,8 @@ interface ISearch { } interface INewMessageViewState { - search: ISearch[]; - // TODO: Refactor when migrate room - chats: any[]; + search: (ISearch | TSubscriptionModel)[]; + chats: TSubscriptionModel[]; permissions: boolean[]; } @@ -108,7 +108,7 @@ class NewMessageView extends React.Component { try { const db = database.active; - const chats = await db.collections + const chats = await db .get('subscriptions') .query(Q.where('t', 'd'), Q.experimentalTake(QUERY_SIZE), Q.experimentalSortBy('room_updated_at', Q.desc)) .fetch(); @@ -153,7 +153,7 @@ class NewMessageView extends React.Component { - const result = await RocketChat.search({ text, filterRooms: false }); + const result: ISearch[] | TSubscriptionModel[] = await RocketChat.search({ text, filterRooms: false }); this.setState({ search: result }); @@ -280,8 +280,7 @@ class NewMessageView extends React.Component { + renderItem = ({ item, index }: { item: ISearch | TSubscriptionModel; index: number }) => { const { search, chats } = this.state; const { theme } = this.props; @@ -295,10 +294,14 @@ class NewMessageView extends React.Component this.goRoom(item)} testID={`new-message-view-item-${item.name}`} style={style} diff --git a/app/views/NewServerView/ServerInput/Item.tsx b/app/views/NewServerView/ServerInput/Item.tsx index cc8a9e3a7..a73f455a0 100644 --- a/app/views/NewServerView/ServerInput/Item.tsx +++ b/app/views/NewServerView/ServerInput/Item.tsx @@ -6,7 +6,7 @@ import { themes } from '../../../constants/colors'; import { CustomIcon } from '../../../lib/Icons'; import sharedStyles from '../../Styles'; import Touch from '../../../utils/touch'; -import { TServerHistory } from '../../../definitions/IServerHistory'; +import { TServerHistoryModel } from '../../../definitions/IServerHistory'; const styles = StyleSheet.create({ container: { @@ -28,10 +28,10 @@ const styles = StyleSheet.create({ }); interface IItem { - item: TServerHistory; + item: TServerHistoryModel; theme: string; onPress(url: string): void; - onDelete(item: TServerHistory): void; + onDelete(item: TServerHistoryModel): void; } const Item = ({ item, theme, onPress, onDelete }: IItem): JSX.Element => ( diff --git a/app/views/NewServerView/ServerInput/index.tsx b/app/views/NewServerView/ServerInput/index.tsx index e2b14fd69..7868754f3 100644 --- a/app/views/NewServerView/ServerInput/index.tsx +++ b/app/views/NewServerView/ServerInput/index.tsx @@ -5,7 +5,7 @@ import TextInput from '../../../containers/TextInput'; import * as List from '../../../containers/List'; import { themes } from '../../../constants/colors'; import I18n from '../../../i18n'; -import { TServerHistory } from '../../../definitions/IServerHistory'; +import { TServerHistoryModel } from '../../../definitions/IServerHistory'; import Item from './Item'; const styles = StyleSheet.create({ @@ -33,8 +33,8 @@ interface IServerInput extends TextInputProps { theme: string; serversHistory: any[]; onSubmit(): void; - onDelete(item: TServerHistory): void; - onPressServerHistory(serverHistory: TServerHistory): void; + onDelete(item: TServerHistoryModel): void; + onPressServerHistory(serverHistory: TServerHistoryModel): void; } const ServerInput = ({ diff --git a/app/views/NewServerView/index.tsx b/app/views/NewServerView/index.tsx index 191895ceb..06d562803 100644 --- a/app/views/NewServerView/index.tsx +++ b/app/views/NewServerView/index.tsx @@ -14,7 +14,7 @@ import Button from '../../containers/Button'; import FormContainer, { FormContainerInner } from '../../containers/FormContainer'; import * as HeaderButton from '../../containers/HeaderButton'; import OrSeparator from '../../containers/OrSeparator'; -import { IBaseScreen, TServerHistory } from '../../definitions'; +import { IBaseScreen, TServerHistoryModel } from '../../definitions'; import { withDimensions } from '../../dimensions'; import I18n from '../../i18n'; import database from '../../lib/database'; @@ -77,7 +77,7 @@ interface INewServerViewState { text: string; connectingOpen: boolean; certificate: any; - serversHistory: TServerHistory[]; + serversHistory: TServerHistoryModel[]; } interface ISubmitParams { @@ -153,7 +153,7 @@ class NewServerView extends React.Component { + onPressServerHistory = (serverHistory: TServerHistoryModel) => { this.setState({ text: serverHistory.url }, () => this.submit({ fromServerHistory: true, username: serverHistory?.username })); }; @@ -269,14 +269,14 @@ class NewServerView extends React.Component { + deleteServerHistory = async (item: TServerHistoryModel) => { const db = database.servers; try { await db.write(async () => { await item.destroyPermanently(); }); this.setState((prevstate: INewServerViewState) => ({ - serversHistory: prevstate.serversHistory.filter((server: TServerHistory) => server.id !== item.id) + serversHistory: prevstate.serversHistory.filter(server => server.id !== item.id) })); } catch { // Nothing diff --git a/app/views/NotificationPreferencesView/index.tsx b/app/views/NotificationPreferencesView/index.tsx index 5e33cec49..2c0c6295f 100644 --- a/app/views/NotificationPreferencesView/index.tsx +++ b/app/views/NotificationPreferencesView/index.tsx @@ -80,7 +80,7 @@ class NotificationPreferencesView extends React.Component { + await db.write(async () => { await room.update( protectedFunction((r: any) => { r[key] = value; @@ -97,7 +97,7 @@ class NotificationPreferencesView extends React.Component { + await db.write(async () => { await room.update( protectedFunction((r: any) => { r[key] = room[key]; diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index cb034bf3d..e56f84040 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -643,7 +643,7 @@ class RoomActionsView extends React.Component { const { addTeamChannelPermission, createTeamPermission } = this.props; const QUERY_SIZE = 50; const db = database.active; - const teams = await db.collections + const teams = await db .get('subscriptions') .query( Q.where('team_main', true), diff --git a/app/views/RoomView/List/index.js b/app/views/RoomView/List/index.js index 0db6c8b69..6ecd0480a 100644 --- a/app/views/RoomView/List/index.js +++ b/app/views/RoomView/List/index.js @@ -144,11 +144,11 @@ class ListContainer extends React.Component { if (tmid) { try { - this.thread = await db.collections.get('threads').find(tmid); + this.thread = await db.get('threads').find(tmid); } catch (e) { console.log(e); } - this.messagesObservable = db.collections + this.messagesObservable = db .get('thread_messages') .query(Q.where('rid', tmid), Q.experimentalSortBy('ts', Q.desc), Q.experimentalSkip(0), Q.experimentalTake(this.count)) .observe(); @@ -162,7 +162,7 @@ class ListContainer extends React.Component { if (!showMessageInMainThread) { whereClause.push(Q.or(Q.where('tmid', null), Q.where('tshow', Q.eq(true)))); } - this.messagesObservable = db.collections + this.messagesObservable = db .get('messages') .query(...whereClause) .observe(); diff --git a/app/views/RoomView/UploadProgress.js b/app/views/RoomView/UploadProgress.js index 9fc5595bf..1b61c0ac1 100644 --- a/app/views/RoomView/UploadProgress.js +++ b/app/views/RoomView/UploadProgress.js @@ -91,7 +91,7 @@ class UploadProgress extends Component { } const db = database.active; - this.uploadsObservable = db.collections.get('uploads').query(Q.where('rid', rid)).observeWithColumns(['progress', 'error']); + this.uploadsObservable = db.get('uploads').query(Q.where('rid', rid)).observeWithColumns(['progress', 'error']); this.uploadsSubscription = this.uploadsObservable.subscribe(uploads => { if (this.mounted) { diff --git a/app/views/RoomView/index.js b/app/views/RoomView/index.js index 241cd1902..20c80d2ba 100644 --- a/app/views/RoomView/index.js +++ b/app/views/RoomView/index.js @@ -690,7 +690,7 @@ class RoomView extends React.Component { // eslint-disable-next-line react/sort-comp updateUnreadCount = async () => { const db = database.active; - const observable = await db.collections + const observable = await db .get('subscriptions') .query(Q.where('archived', false), Q.where('open', true), Q.where('rid', Q.notEq(this.rid))) .observeWithColumns(['unread']); diff --git a/app/views/RoomsListView/ServerDropdown.js b/app/views/RoomsListView/ServerDropdown.js index 8dd42ee92..94232accc 100644 --- a/app/views/RoomsListView/ServerDropdown.js +++ b/app/views/RoomsListView/ServerDropdown.js @@ -47,7 +47,7 @@ class ServerDropdown extends Component { async componentDidMount() { const serversDB = database.servers; - const observable = await serversDB.collections.get('servers').query().observeWithColumns(['name']); + const observable = await serversDB.get('servers').query().observeWithColumns(['name']); this.subscription = observable.subscribe(data => { this.setState({ servers: data }); diff --git a/app/views/RoomsListView/index.js b/app/views/RoomsListView/index.js index 1ee94cee6..45065b907 100644 --- a/app/views/RoomsListView/index.js +++ b/app/views/RoomsListView/index.js @@ -450,7 +450,7 @@ class RoomsListView extends React.Component { // When we're grouping by something if (this.isGrouping) { - observable = await db.collections + observable = await db .get('subscriptions') .query(...defaultWhereClause) .observeWithColumns(['alert']); @@ -458,7 +458,7 @@ class RoomsListView extends React.Component { // When we're NOT grouping } else { this.count += QUERY_SIZE; - observable = await db.collections + observable = await db .get('subscriptions') .query(...defaultWhereClause, Q.experimentalSkip(0), Q.experimentalTake(this.count)) .observe(); diff --git a/app/views/ScreenLockConfigView.tsx b/app/views/ScreenLockConfigView.tsx index 76f0d0957..626f88cab 100644 --- a/app/views/ScreenLockConfigView.tsx +++ b/app/views/ScreenLockConfigView.tsx @@ -92,7 +92,7 @@ class ScreenLockConfigView extends React.Component { this.observable = this.serverRecord?.observe()?.subscribe(({ biometry }) => { - this.setState({ biometry }); + this.setState({ biometry: !!biometry }); }); }; diff --git a/app/views/SelectedUsersView.tsx b/app/views/SelectedUsersView.tsx index 85311154e..531b96987 100644 --- a/app/views/SelectedUsersView.tsx +++ b/app/views/SelectedUsersView.tsx @@ -109,10 +109,7 @@ class SelectedUsersView extends React.Component { try { const db = database.active; - const observable = await db.collections - .get('subscriptions') - .query(Q.where('t', 'd')) - .observeWithColumns(['room_updated_at']); + const observable = await db.get('subscriptions').query(Q.where('t', 'd')).observeWithColumns(['room_updated_at']); // TODO: Refactor when migrate room this.querySubscription = observable.subscribe((data: any) => { @@ -129,7 +126,9 @@ class SelectedUsersView extends React.Component { - const result = await RocketChat.search({ text, filterRooms: false }); + // TODO: When migrate rocketchat.js pass the param IUser to there and the return should be + // IUser | TSubscriptionModel, this because we do a local search too + const result = (await RocketChat.search({ text, filterRooms: false })) as ISelectedUser[]; this.setState({ search: result }); diff --git a/app/views/ThreadMessagesView/index.tsx b/app/views/ThreadMessagesView/index.tsx index 2b53159bf..bed452f28 100644 --- a/app/views/ThreadMessagesView/index.tsx +++ b/app/views/ThreadMessagesView/index.tsx @@ -7,7 +7,6 @@ import { EdgeInsets, withSafeAreaInsets } from 'react-native-safe-area-context'; import { HeaderBackButton, StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack'; import { RouteProp } from '@react-navigation/native'; import { Observable, Subscription } from 'rxjs'; -import Model from '@nozbe/watermelondb/Model'; import Database from '@nozbe/watermelondb/Database'; import ActivityIndicator from '../../containers/ActivityIndicator'; @@ -86,7 +85,7 @@ class ThreadMessagesView extends React.Component; + private messagesObservable?: Observable; constructor(props: IThreadMessagesViewProps) { super(props); @@ -188,7 +187,7 @@ class ThreadMessagesView extends React.Component { this.setState({ subscription: data }); @@ -214,15 +213,15 @@ class ThreadMessagesView extends React.Component { + this.messagesSubscription = this.messagesObservable.subscribe(messages => { const { currentFilter } = this.state; - const displayingThreads = this.getFilteredThreads(messages, subscription!, currentFilter); + const displayingThreads = this.getFilteredThreads(messages, subscription, currentFilter); if (this.mounted) { this.setState({ messages, displayingThreads }); } else { @@ -419,14 +418,14 @@ class ThreadMessagesView extends React.Component { + getFilteredThreads = (messages: TThreadModel[], subscription?: TSubscriptionModel, currentFilter?: Filter): TThreadModel[] => { // const { currentFilter } = this.state; const { user } = this.props; if (currentFilter === Filter.Following) { - return messages?.filter((item: { replies: any[] }) => item?.replies?.find(u => u === user.id)); + return messages?.filter(item => item?.replies?.find(u => u === user.id)); } if (currentFilter === Filter.Unread) { - return messages?.filter((item: { id: string }) => subscription?.tunread?.includes(item?.id)); + return messages?.filter(item => subscription?.tunread?.includes(item?.id)); } return messages; };