From 7a90f2d4a8d4858a9dd0401c802a9be6d1481562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Espino=20Garc=C3=ADa?= Date: Fri, 15 Apr 2022 00:56:48 +0200 Subject: [PATCH] Performance improvements in the area of home and channel switch. (#6174) * Performance improvements * Revert hidden DM/GMs changes * Minor fixes related to the revert * Add observeWithColumns missed in merge --- app/actions/remote/channel.ts | 2 +- app/actions/websocket/channel.ts | 2 +- .../categories/body/category_body.test.tsx | 3 - .../categories/body/category_body.tsx | 13 ++-- .../body/channel/channel_list_item.test.tsx | 1 + .../body/channel/channel_list_item.tsx | 5 +- .../categories/body/channel/index.ts | 57 +++++++++++----- .../channel_list/categories/body/index.ts | 18 +++-- .../channel_list/categories/categories.tsx | 50 ++++++-------- .../channel_list/categories/index.ts | 50 ++------------ .../channel_list/categories/unreads/index.ts | 67 +++++++++++++++++++ .../categories/{ => unreads}/unreads.test.tsx | 5 +- .../categories/{ => unreads}/unreads.tsx | 31 ++++----- index.ts | 1 + 14 files changed, 173 insertions(+), 132 deletions(-) create mode 100644 app/components/channel_list/categories/unreads/index.ts rename app/components/channel_list/categories/{ => unreads}/unreads.test.tsx (85%) rename app/components/channel_list/categories/{ => unreads}/unreads.tsx (67%) diff --git a/app/actions/remote/channel.ts b/app/actions/remote/channel.ts index 5966ca80c..9f07ca7dc 100644 --- a/app/actions/remote/channel.ts +++ b/app/actions/remote/channel.ts @@ -7,7 +7,6 @@ import {IntlShape} from 'react-intl'; import {storeCategories} from '@actions/local/category'; import {addChannelToDefaultCategory, storeMyChannelsForTeam, switchToChannel} from '@actions/local/channel'; -import EphemeralStore from '@app/store/ephemeral_store'; import {General, Preferences} from '@constants'; import DatabaseManager from '@database/manager'; import {privateChannelJoinPrompt} from '@helpers/api/channel'; @@ -18,6 +17,7 @@ import {queryPreferencesByCategoryAndName} from '@queries/servers/preference'; import {getCommonSystemValues, getCurrentTeamId, getCurrentUserId} from '@queries/servers/system'; import {prepareMyTeams, getNthLastChannelFromTeam, getMyTeamById, getTeamById, getTeamByName} from '@queries/servers/team'; import {getCurrentUser} from '@queries/servers/user'; +import EphemeralStore from '@store/ephemeral_store'; import {generateChannelNameFromDisplayName, getDirectChannelName, isDMorGM} from '@utils/channel'; import {PERMALINK_GENERIC_TEAM_NAME_REDIRECT} from '@utils/url'; import {displayGroupMessageName, displayUsername} from '@utils/user'; diff --git a/app/actions/websocket/channel.ts b/app/actions/websocket/channel.ts index 6edc4013f..a141c3b59 100644 --- a/app/actions/websocket/channel.ts +++ b/app/actions/websocket/channel.ts @@ -17,7 +17,6 @@ import {fetchMissingSidebarInfo, fetchMyChannel, fetchChannelStats, fetchChannel import {fetchPostsForChannel} from '@actions/remote/post'; import {fetchRolesIfNeeded} from '@actions/remote/role'; import {fetchUsersByIds, updateUsersNoLongerVisible} from '@actions/remote/user'; -import EphemeralStore from '@app/store/ephemeral_store'; import Events from '@constants/events'; import DatabaseManager from '@database/manager'; import {queryActiveServer} from '@queries/app/servers'; @@ -26,6 +25,7 @@ import {prepareCommonSystemValues, getConfig, setCurrentChannelId, getCurrentCha import {getNthLastChannelFromTeam} from '@queries/servers/team'; import {getCurrentUser, getTeammateNameDisplay, getUserById} from '@queries/servers/user'; import {dismissAllModals, popToRoot} from '@screens/navigation'; +import EphemeralStore from '@store/ephemeral_store'; import {isTablet} from '@utils/helpers'; // Received when current user created a channel in a different client diff --git a/app/components/channel_list/categories/body/category_body.test.tsx b/app/components/channel_list/categories/body/category_body.test.tsx index 9dad4a1b2..e84931f84 100644 --- a/app/components/channel_list/categories/body/category_body.test.tsx +++ b/app/components/channel_list/categories/body/category_body.test.tsx @@ -35,9 +35,6 @@ describe('components/channel_list/categories/body', () => { , {database}, ); diff --git a/app/components/channel_list/categories/body/category_body.tsx b/app/components/channel_list/categories/body/category_body.tsx index 615e5cf32..41a90ab8e 100644 --- a/app/components/channel_list/categories/body/category_body.tsx +++ b/app/components/channel_list/categories/body/category_body.tsx @@ -12,7 +12,6 @@ import ChannelListItem from './channel'; import type CategoryModel from '@typings/database/models/servers/category'; type Props = { - currentChannelId: string; sortedChannels: ChannelModel[]; hiddenChannelIds: Set; category: CategoryModel; @@ -21,7 +20,7 @@ type Props = { const extractKey = (item: ChannelModel) => item.id; -const CategoryBody = ({currentChannelId, sortedChannels, category, hiddenChannelIds, limit}: Props) => { +const CategoryBody = ({sortedChannels, category, hiddenChannelIds, limit}: Props) => { const ids = useMemo(() => { let filteredChannels = sortedChannels; @@ -36,26 +35,28 @@ const CategoryBody = ({currentChannelId, sortedChannels, category, hiddenChannel return filteredChannels; }, [category.type, limit, hiddenChannelIds, sortedChannels]); - const ChannelItem = useCallback(({item}: {item: ChannelModel}) => { + const renderItem = useCallback(({item}: {item: ChannelModel}) => { return ( ); - }, [currentChannelId, category.collapsed]); + }, [category.collapsed]); return ( ); }; diff --git a/app/components/channel_list/categories/body/channel/channel_list_item.test.tsx b/app/components/channel_list/categories/body/channel/channel_list_item.test.tsx index c52dd3ade..ba9a8d9a9 100644 --- a/app/components/channel_list/categories/body/channel/channel_list_item.test.tsx +++ b/app/components/channel_list/categories/body/channel/channel_list_item.test.tsx @@ -38,6 +38,7 @@ describe('components/channel_list/categories/body/channel/item', () => { collapsed={false} currentUserId={'id'} testID='channel_list_item' + isVisible={true} />, ); diff --git a/app/components/channel_list/categories/body/channel/channel_list_item.tsx b/app/components/channel_list/categories/body/channel/channel_list_item.tsx index 992b4919e..153b6430b 100644 --- a/app/components/channel_list/categories/body/channel/channel_list_item.tsx +++ b/app/components/channel_list/categories/body/channel/channel_list_item.tsx @@ -77,10 +77,11 @@ type Props = { myChannel?: MyChannelModel; collapsed: boolean; currentUserId: string; + isVisible: boolean; testID?: string; } -const ChannelListItem = ({channel, isActive, currentUserId, isMuted, myChannel, collapsed, testID}: Props) => { +const ChannelListItem = ({channel, isActive, currentUserId, isMuted, isVisible, myChannel, collapsed, testID}: Props) => { const {formatMessage} = useIntl(); const theme = useTheme(); const styles = getStyleSheet(theme); @@ -132,7 +133,7 @@ const ChannelListItem = ({channel, isActive, currentUserId, isMuted, myChannel, displayName = formatMessage({id: 'channel_header.directchannel.you', defaultMessage: '{displayName} (you)'}, {displayName}); } - if ((channel.deleteAt > 0 && !isActive) || !myChannel) { + if ((channel.deleteAt > 0 && !isActive) || !myChannel || !isVisible) { return null; } diff --git a/app/components/channel_list/categories/body/channel/index.ts b/app/components/channel_list/categories/body/channel/index.ts index dd84ecd24..536956ebd 100644 --- a/app/components/channel_list/categories/body/channel/index.ts +++ b/app/components/channel_list/categories/body/channel/index.ts @@ -3,41 +3,66 @@ import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider'; import withObservables from '@nozbe/with-observables'; -import {of as of$} from 'rxjs'; -import {switchMap} from 'rxjs/operators'; +import React from 'react'; +import {of as of$, combineLatest} from 'rxjs'; +import {switchMap, distinctUntilChanged} from 'rxjs/operators'; +import {Preferences} from '@constants'; +import {getPreferenceAsBool} from '@helpers/api/preference'; import {observeMyChannel} from '@queries/servers/channel'; -import {observeCurrentUserId} from '@queries/servers/system'; +import {queryPreferencesByCategoryAndName} from '@queries/servers/preference'; +import {observeCurrentChannelId, observeCurrentUserId} from '@queries/servers/system'; import ChannelModel from '@typings/database/models/servers/channel'; +import MyChannelModel from '@typings/database/models/servers/my_channel'; import ChannelListItem from './channel_list_item'; import type {WithDatabaseArgs} from '@typings/database/database'; +import type PreferenceModel from '@typings/database/models/servers/preference'; -const enhance = withObservables(['channel'], ({channel, database}: {channel: ChannelModel} & WithDatabaseArgs) => { +const observeIsMutedSetting = (mc: MyChannelModel) => mc.settings.observe().pipe(switchMap((s) => of$(s?.notifyProps?.mark_unread === 'mention'))); + +const enhance = withObservables(['channel', 'isUnreads'], ({channel, isUnreads, database}: {channel: ChannelModel; isUnreads?: boolean} & WithDatabaseArgs) => { const currentUserId = observeCurrentUserId(database); - const myChannel = observeMyChannel(database, channel.id); - let isMuted = of$(false); - if (myChannel) { - const settings = myChannel.pipe( - switchMap((mc) => { - return mc ? mc.settings.observe() : of$(undefined); - }), + const isActive = observeCurrentChannelId(database).pipe(switchMap((id) => of$(id ? id === channel.id : false)), distinctUntilChanged()); + const unreadsOnTop = queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_SIDEBAR_SETTINGS, Preferences.CHANNEL_SIDEBAR_GROUP_UNREADS). + observeWithColumns(['value']). + pipe( + switchMap((prefs: PreferenceModel[]) => of$(getPreferenceAsBool(prefs, Preferences.CATEGORY_SIDEBAR_SETTINGS, Preferences.CHANNEL_SIDEBAR_GROUP_UNREADS, false))), ); - isMuted = settings?.pipe( - switchMap((s) => of$(s?.notifyProps?.mark_unread === 'mention')), - ); - } + const isVisible = combineLatest([myChannel, unreadsOnTop]).pipe( + switchMap(([mc, u]) => { + if (!mc) { + return of$(false); + } + if (isUnreads) { + return of$(u); + } + + return u ? of$(!mc.isUnread) : of$(true); + }), + ); + + const isMuted = myChannel.pipe( + switchMap((mc) => { + if (!mc) { + return of$(false); + } + return observeIsMutedSetting(mc); + }), + ); return { currentUserId, isMuted, + isActive, + isVisible, myChannel, channel: channel.observe(), }; }); -export default withDatabase(enhance(ChannelListItem)); +export default React.memo(withDatabase(enhance(ChannelListItem))); diff --git a/app/components/channel_list/categories/body/index.ts b/app/components/channel_list/categories/body/index.ts index d09225f5e..e7251baf7 100644 --- a/app/components/channel_list/categories/body/index.ts +++ b/app/components/channel_list/categories/body/index.ts @@ -11,6 +11,7 @@ import {General, Preferences} from '@constants'; import {DMS_CATEGORY} from '@constants/categories'; import {queryChannelsByNames, queryMyChannelSettingsByIds} from '@queries/servers/channel'; import {queryPreferencesByCategoryAndName} from '@queries/servers/preference'; +import {observeCurrentUserId} from '@queries/servers/system'; import {WithDatabaseArgs} from '@typings/database/database'; import {getDirectChannelName} from '@utils/channel'; @@ -70,12 +71,10 @@ export const getChannelsFromRelation = async (relations: CategoryChannelModel[] return Promise.all(relations.map((r) => r.channel?.fetch())); }; -const getSortedChannels = (database: Database, category: CategoryModel, unreadChannelIds: Set, locale: string) => { +const getSortedChannels = (database: Database, category: CategoryModel, locale: string) => { switch (category.sorting) { case 'alpha': { - const channels = category.channels.observeWithColumns(['display_name']).pipe( - map((cs) => cs.filter((c) => !unreadChannelIds.has(c.id))), - ); + const channels = category.channels.observeWithColumns(['display_name']); const settings = channels.pipe( switchMap((cs) => observeSettings(database, cs)), ); @@ -85,14 +84,12 @@ const getSortedChannels = (database: Database, category: CategoryModel, unreadCh } case 'manual': { return category.categoryChannelsBySortOrder.observeWithColumns(['sort_order']).pipe( - map((cc) => cc.filter((c) => !unreadChannelIds.has(c.channelId))), map(getChannelsFromRelation), concatAll(), ); } default: return category.myChannels.observeWithColumns(['last_post_at']).pipe( - map((myCs) => myCs.filter((myC) => !unreadChannelIds.has(myC.id))), map(getChannelsFromRelation), concatAll(), ); @@ -107,13 +104,14 @@ type EnhanceProps = { category: CategoryModel; locale: string; currentUserId: string; - unreadChannelIds: Set; } & WithDatabaseArgs -const enhance = withObservables(['category', 'locale', 'unreadChannelIds'], ({category, locale, database, currentUserId, unreadChannelIds}: EnhanceProps) => { +const withUserId = withObservables([], ({database}: WithDatabaseArgs) => ({currentUserId: observeCurrentUserId(database)})); + +const enhance = withObservables(['category', 'locale'], ({category, locale, database, currentUserId}: EnhanceProps) => { const observedCategory = category.observe(); const sortedChannels = observedCategory.pipe( - switchMap((c) => getSortedChannels(database, c, unreadChannelIds, locale)), + switchMap((c) => getSortedChannels(database, c, locale)), ); const dmMap = (p: PreferenceModel) => getDirectChannelName(p.name, currentUserId); @@ -154,4 +152,4 @@ const enhance = withObservables(['category', 'locale', 'unreadChannelIds'], ({ca }; }); -export default withDatabase(enhance(CategoryBody)); +export default withDatabase(withUserId(enhance(CategoryBody))); diff --git a/app/components/channel_list/categories/categories.tsx b/app/components/channel_list/categories/categories.tsx index 9492bb575..91210c373 100644 --- a/app/components/channel_list/categories/categories.tsx +++ b/app/components/channel_list/categories/categories.tsx @@ -11,14 +11,11 @@ import CategoryHeader from './header'; import UnreadCategories from './unreads'; import type CategoryModel from '@typings/database/models/servers/category'; -import type ChannelModel from '@typings/database/models/servers/channel'; type Props = { categories: CategoryModel[]; - unreadChannels: ChannelModel[]; - currentChannelId: string; - currentUserId: string; currentTeamId: string; + unreadsOnTop: boolean; } const styles = StyleSheet.create({ @@ -29,51 +26,39 @@ const styles = StyleSheet.create({ }, }); -const extractKey = (item: CategoryModel) => (Array.isArray(item) ? 'UNREADS' : item.id); +const extractKey = (item: CategoryModel | 'UNREADS') => (item === 'UNREADS' ? 'UNREADS' : item.id); -const Categories = ({categories, currentChannelId, currentUserId, currentTeamId, unreadChannels}: Props) => { +const Categories = ({categories, currentTeamId, unreadsOnTop}: Props) => { const intl = useIntl(); const listRef = useRef(null); - const unreadChannelIds = useMemo(() => new Set(unreadChannels.map((myC) => myC.id)), [unreadChannels]); - const categoriesToDisplay: Array = useMemo(() => { - if (unreadChannelIds.size) { - return [Array.from(unreadChannelIds), ...categories]; + const renderCategory = useCallback((data: {item: CategoryModel | 'UNREADS'}) => { + if (data.item === 'UNREADS') { + return ; } - - return categories; - }, [categories, unreadChannelIds]); - - const renderCategory = useCallback((data: {item: CategoryModel | string[]}) => { - if (Array.isArray(data.item)) { - return ( - - ); - } - return ( <> ); - }, [categories, currentChannelId, intl.locale, unreadChannels]); + }, [intl.locale]); useEffect(() => { listRef.current?.scrollToOffset({animated: false, offset: 0}); }, [currentTeamId]); - // Sort Categories - categories.sort((a, b) => a.sortOrder - b.sortOrder); + const categoriesToShow = useMemo(() => { + const orderedCategories = [...categories]; + orderedCategories.sort((a, b) => a.sortOrder - b.sortOrder); + if (unreadsOnTop) { + return ['UNREADS' as const, ...orderedCategories]; + } + return orderedCategories; + }, [categories, unreadsOnTop]); if (!categories.length) { return ; @@ -81,7 +66,7 @@ const Categories = ({categories, currentChannelId, currentUserId, currentTeamId, return ( ); }; diff --git a/app/components/channel_list/categories/index.ts b/app/components/channel_list/categories/index.ts index 3e3098533..11cadbb7b 100644 --- a/app/components/channel_list/categories/index.ts +++ b/app/components/channel_list/categories/index.ts @@ -3,38 +3,24 @@ import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider'; import withObservables from '@nozbe/with-observables'; -import {combineLatest, of as of$} from 'rxjs'; -import {concatAll, map, switchMap} from 'rxjs/operators'; +import {of as of$} from 'rxjs'; +import {switchMap} from 'rxjs/operators'; -import {Preferences} from '@app/constants'; -import {getPreferenceAsBool} from '@app/helpers/api/preference'; -import {getChannelById, queryMyChannelUnreads} from '@app/queries/servers/channel'; -import {queryPreferencesByCategoryAndName} from '@app/queries/servers/preference'; +import {Preferences} from '@constants'; +import {getPreferenceAsBool} from '@helpers/api/preference'; import {queryCategoriesByTeamIds} from '@queries/servers/categories'; -import {observeCurrentChannelId, observeCurrentUserId, observeLastUnreadChannelId} from '@queries/servers/system'; +import {queryPreferencesByCategoryAndName} from '@queries/servers/preference'; -import {getChannelsFromRelation} from './body'; import Categories from './categories'; import type {WithDatabaseArgs} from '@typings/database/database'; -import type ChannelModel from '@typings/database/models/servers/channel'; import type PreferenceModel from '@typings/database/models/servers/preference'; -type CA = [ - a: Array, - b: ChannelModel | undefined, -] -const concatenateChannelsArray = ([a, b]: CA) => { - return of$(b ? a.filter((c) => c && c.id !== b.id).concat(b) : a); -}; - type WithDatabaseProps = { currentTeamId: string } & WithDatabaseArgs const enhanced = withObservables( ['currentTeamId'], ({currentTeamId, database}: WithDatabaseProps) => { - const currentChannelId = observeCurrentChannelId(database); - const currentUserId = observeCurrentUserId(database); const categories = queryCategoriesByTeamIds(database, [currentTeamId]).observeWithColumns(['sort_order']); const unreadsOnTop = queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_SIDEBAR_SETTINGS, Preferences.CHANNEL_SIDEBAR_GROUP_UNREADS). @@ -43,33 +29,9 @@ const enhanced = withObservables( switchMap((prefs: PreferenceModel[]) => of$(getPreferenceAsBool(prefs, Preferences.CATEGORY_SIDEBAR_SETTINGS, Preferences.CHANNEL_SIDEBAR_GROUP_UNREADS, false))), ); - const getC = (lastUnreadChannelId: string) => getChannelById(database, lastUnreadChannelId); - - const unreadChannels = unreadsOnTop.pipe(switchMap((gU) => { - if (gU) { - const lastUnread = observeLastUnreadChannelId(database).pipe( - switchMap(getC), - ); - - const unreads = queryMyChannelUnreads(database, currentTeamId).observe().pipe( - map(getChannelsFromRelation), - concatAll(), - ); - - const combined = combineLatest([unreads, lastUnread]).pipe( - switchMap(concatenateChannelsArray), - ); - - return combined; - } - return of$([]); - })); - return { - unreadChannels, categories, - currentUserId, - currentChannelId, + unreadsOnTop, }; }); diff --git a/app/components/channel_list/categories/unreads/index.ts b/app/components/channel_list/categories/unreads/index.ts new file mode 100644 index 000000000..4d3b20e53 --- /dev/null +++ b/app/components/channel_list/categories/unreads/index.ts @@ -0,0 +1,67 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider'; +import withObservables from '@nozbe/with-observables'; +import {of as of$, combineLatest} from 'rxjs'; +import {concatAll, map, switchMap} from 'rxjs/operators'; + +import {Preferences} from '@constants'; +import {getPreferenceAsBool} from '@helpers/api/preference'; +import {getChannelById, queryMyChannelUnreads} from '@queries/servers/channel'; +import {queryPreferencesByCategoryAndName} from '@queries/servers/preference'; +import {observeLastUnreadChannelId} from '@queries/servers/system'; + +import {getChannelsFromRelation} from '../body'; + +import UnreadCategories from './unreads'; + +import type {WithDatabaseArgs} from '@typings/database/database'; +import type ChannelModel from '@typings/database/models/servers/channel'; +import type PreferenceModel from '@typings/database/models/servers/preference'; + +type WithDatabaseProps = { currentTeamId: string } & WithDatabaseArgs + +type CA = [ + a: Array, + b: ChannelModel | undefined, +] + +const concatenateChannelsArray = ([a, b]: CA) => { + return of$(b ? a.filter((c) => c && c.id !== b.id).concat(b) : a); +}; + +const enhanced = withObservables(['currentTeamId'], ({currentTeamId, database}: WithDatabaseProps) => { + const unreadsOnTop = queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_SIDEBAR_SETTINGS, Preferences.CHANNEL_SIDEBAR_GROUP_UNREADS). + observeWithColumns(['value']). + pipe( + switchMap((prefs: PreferenceModel[]) => of$(getPreferenceAsBool(prefs, Preferences.CATEGORY_SIDEBAR_SETTINGS, Preferences.CHANNEL_SIDEBAR_GROUP_UNREADS, false))), + ); + + const getC = (lastUnreadChannelId: string) => getChannelById(database, lastUnreadChannelId); + + const unreadChannels = unreadsOnTop.pipe(switchMap((gU) => { + if (gU) { + const lastUnread = observeLastUnreadChannelId(database).pipe( + switchMap(getC), + ); + + const unreads = queryMyChannelUnreads(database, currentTeamId).observe().pipe( + map(getChannelsFromRelation), + concatAll(), + ); + + const combined = combineLatest([unreads, lastUnread]).pipe( + switchMap(concatenateChannelsArray), + ); + + return combined; + } + return of$([]); + })); + return { + unreadChannels, + }; +}); + +export default withDatabase(enhanced(UnreadCategories)); diff --git a/app/components/channel_list/categories/unreads.test.tsx b/app/components/channel_list/categories/unreads/unreads.test.tsx similarity index 85% rename from app/components/channel_list/categories/unreads.test.tsx rename to app/components/channel_list/categories/unreads/unreads.test.tsx index 14eb1f3e9..e98f08644 100644 --- a/app/components/channel_list/categories/unreads.test.tsx +++ b/app/components/channel_list/categories/unreads/unreads.test.tsx @@ -17,15 +17,14 @@ describe('components/channel_list/categories/body', () => { database = server.database; }); - it('render without error', () => { + it('do not render when there are no unread channels', () => { const wrapper = renderWithEverything( , {database}, ); - expect(wrapper.toJSON()).toBeTruthy(); + expect(wrapper.toJSON()).toBeNull(); }); }); diff --git a/app/components/channel_list/categories/unreads.tsx b/app/components/channel_list/categories/unreads/unreads.tsx similarity index 67% rename from app/components/channel_list/categories/unreads.tsx rename to app/components/channel_list/categories/unreads/unreads.tsx index 0a40d14ee..7f90cedb4 100644 --- a/app/components/channel_list/categories/unreads.tsx +++ b/app/components/channel_list/categories/unreads/unreads.tsx @@ -1,15 +1,15 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {useCallback} from 'react'; +import React from 'react'; import {useIntl} from 'react-intl'; import {FlatList, Text} from 'react-native'; -import {changeOpacity, makeStyleSheetFromTheme} from '@app/utils/theme'; import {useTheme} from '@context/theme'; +import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; import {typography} from '@utils/typography'; -import ChannelListItem from './body/channel'; +import ChannelListItem from '../body/channel'; import type ChannelModel from '@typings/database/models/servers/channel'; @@ -23,26 +23,27 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({ }, })); +const renderItem = ({item}: {item: ChannelModel}) => { + return ( + + ); +}; type UnreadCategoriesProps = { unreadChannels: ChannelModel[]; - currentChannelId: string; } -const UnreadCategories = ({unreadChannels, currentChannelId}: UnreadCategoriesProps) => { +const UnreadCategories = ({unreadChannels}: UnreadCategoriesProps) => { const theme = useTheme(); const styles = getStyleSheet(theme); const intl = useIntl(); - const renderItem = useCallback(({item}: {item: ChannelModel}) => { - return ( - - ); - }, [currentChannelId]); - + if (!unreadChannels.length) { + return null; + } return ( <>