diff --git a/app/components/post_list/date_separator/index.tsx b/app/components/post_list/date_separator/index.tsx index 69e365a93..0284e69f2 100644 --- a/app/components/post_list/date_separator/index.tsx +++ b/app/components/post_list/date_separator/index.tsx @@ -86,4 +86,4 @@ const DateSeparator = (props: DateSeparatorProps) => { ); }; -export default DateSeparator; +export default React.memo(DateSeparator); diff --git a/app/components/post_list/post/index.ts b/app/components/post_list/post/index.ts index 3bddd9213..8b5bec0b0 100644 --- a/app/components/post_list/post/index.ts +++ b/app/components/post_list/post/index.ts @@ -5,7 +5,7 @@ import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider'; import withObservables from '@nozbe/with-observables'; import React from 'react'; import {of as of$, combineLatest} from 'rxjs'; -import {switchMap} from 'rxjs/operators'; +import {switchMap, distinctUntilChanged} from 'rxjs/operators'; import {Permissions, Preferences} from '@constants'; import {queryAllCustomEmojis} from '@queries/servers/custom_emoji'; @@ -107,6 +107,7 @@ const withPost = withObservables( const isSaved = queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_SAVED_POST, post.id). observeWithColumns(['value']).pipe( switchMap((pref) => of$(Boolean(pref.length))), + distinctUntilChanged(), ); if (post.props?.add_channel_member && isPostEphemeral(post)) { @@ -119,7 +120,9 @@ const withPost = withObservables( return observeShouldHighlightReplyBar(database, currentUser, post, postsInThreads[0]); } return of$(false); - })); + }), + distinctUntilChanged(), + ); let differentThreadSequence = true; if (post.rootId) { @@ -129,14 +132,17 @@ const withPost = withObservables( if (post.message.length && !(/^\s{4}/).test(post.message)) { isJumboEmoji = queryAllCustomEmojis(database).observe().pipe( - // eslint-disable-next-line max-nested-callbacks - switchMap((customEmojis: CustomEmojiModel[]) => of$(hasJumboEmojiOnly(post.message, customEmojis.map((c) => c.name))), + switchMap( + // eslint-disable-next-line max-nested-callbacks + (customEmojis: CustomEmojiModel[]) => of$(hasJumboEmojiOnly(post.message, customEmojis.map((c) => c.name))), ), + distinctUntilChanged(), ); } const hasReplies = observeHasReplies(post); const isConsecutivePost = author.pipe( switchMap((user) => of$(Boolean(post && previousPost && !user?.isBot && areConsecutivePosts(post, previousPost)))), + distinctUntilChanged(), ); return { diff --git a/app/queries/servers/role.ts b/app/queries/servers/role.ts index 6726e63da..f36106fe3 100644 --- a/app/queries/servers/role.ts +++ b/app/queries/servers/role.ts @@ -3,7 +3,7 @@ import {Database, Q} from '@nozbe/watermelondb'; import {of as of$, combineLatest} from 'rxjs'; -import {switchMap} from 'rxjs/operators'; +import {switchMap, distinctUntilChanged} from 'rxjs/operators'; import {Database as DatabaseConstants, General, Permissions} from '@constants'; import {isDMorGM} from '@utils/channel'; @@ -52,7 +52,9 @@ export function observePermissionForChannel(database: Database, channel: Channel return queryRolesByNames(database, rolesArray).observeWithColumns(['permissions']).pipe( switchMap((r) => of$(hasPermission(r, permission, defaultValue))), ); - })); + }), + distinctUntilChanged(), + ); } export function observePermissionForTeam(database: Database, team: TeamModel, user: UserModel, permission: string, defaultValue: boolean) { @@ -68,20 +70,27 @@ export function observePermissionForTeam(database: Database, team: TeamModel, us switchMap((roles) => of$(hasPermission(roles, permission, defaultValue))), ); }), + distinctUntilChanged(), ); } export function observePermissionForPost(database: Database, post: PostModel, user: UserModel, permission: string, defaultValue: boolean) { - return observeChannel(database, post.channelId).pipe(switchMap((c) => (c ? observePermissionForChannel(database, c, user, permission, defaultValue) : of$(defaultValue)))); + return observeChannel(database, post.channelId).pipe( + switchMap((c) => (c ? observePermissionForChannel(database, c, user, permission, defaultValue) : of$(defaultValue))), + distinctUntilChanged(), + ); } export function observeCanManageChannelMembers(database: Database, post: PostModel, user: UserModel) { - return observeChannel(database, post.channelId).pipe((switchMap((c) => { - if (!c || c.deleteAt !== 0 || isDMorGM(c) || c.name === General.DEFAULT_CHANNEL) { - return of$(false); - } + return observeChannel(database, post.channelId).pipe( + switchMap((c) => { + if (!c || c.deleteAt !== 0 || isDMorGM(c) || c.name === General.DEFAULT_CHANNEL) { + return of$(false); + } - const permission = c.type === General.OPEN_CHANNEL ? Permissions.MANAGE_PUBLIC_CHANNEL_MEMBERS : Permissions.MANAGE_PRIVATE_CHANNEL_MEMBERS; - return observePermissionForChannel(database, c, user, permission, true); - }))); + const permission = c.type === General.OPEN_CHANNEL ? Permissions.MANAGE_PUBLIC_CHANNEL_MEMBERS : Permissions.MANAGE_PRIVATE_CHANNEL_MEMBERS; + return observePermissionForChannel(database, c, user, permission, true); + }), + distinctUntilChanged(), + ); } diff --git a/app/queries/servers/thread.ts b/app/queries/servers/thread.ts index 9e64ea743..d9ae4d12d 100644 --- a/app/queries/servers/thread.ts +++ b/app/queries/servers/thread.ts @@ -41,6 +41,7 @@ export const observeIsCRTEnabled = (database: Database) => { map( ([cfg, prefs]) => processIsCRTEnabled(prefs, cfg), ), + distinctUntilChanged(), ); }; diff --git a/app/screens/channel/channel_post_list/index.ts b/app/screens/channel/channel_post_list/index.ts index 2828a4e7a..c46ceb12e 100644 --- a/app/screens/channel/channel_post_list/index.ts +++ b/app/screens/channel/channel_post_list/index.ts @@ -7,7 +7,7 @@ import withObservables from '@nozbe/with-observables'; import React from 'react'; import {AppStateStatus} from 'react-native'; import {combineLatest, of as of$} from 'rxjs'; -import {switchMap} from 'rxjs/operators'; +import {switchMap, distinctUntilChanged} from 'rxjs/operators'; import {Preferences} from '@constants'; import {getPreferenceAsBool} from '@helpers/api/preference'; @@ -28,6 +28,7 @@ const enhanced = withObservables(['channelId', 'forceQueryAfterAppState'], ({dat isCRTEnabled: isCRTEnabledObserver, lastViewedAt: observeMyChannel(database, channelId).pipe( switchMap((myChannel) => of$(myChannel?.viewedAt)), + distinctUntilChanged(), ), posts: combineLatest([isCRTEnabledObserver, postsInChannelObserver]).pipe( switchMap(([isCRTEnabled, postsInChannel]) => { @@ -42,6 +43,7 @@ const enhanced = withObservables(['channelId', 'forceQueryAfterAppState'], ({dat shouldShowJoinLeaveMessages: queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_ADVANCED_SETTINGS, Preferences.ADVANCED_FILTER_JOIN_LEAVE). observeWithColumns(['value']).pipe( switchMap((preferences) => of$(getPreferenceAsBool(preferences, Preferences.CATEGORY_ADVANCED_SETTINGS, Preferences.ADVANCED_FILTER_JOIN_LEAVE, true))), + distinctUntilChanged(), ), }; });