Do not access record children directly to avoid crashes if the child is not present in the db (#7028) (#7036)

(cherry picked from commit 50b845452e)

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
This commit is contained in:
Mattermost Build 2023-01-27 18:10:45 +02:00 committed by GitHub
parent ee7b4f05d5
commit cfb09ce7d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 121 additions and 60 deletions

View file

@ -10,7 +10,7 @@ import {switchMap, distinctUntilChanged} from 'rxjs/operators';
import {observeChannelsWithCalls} from '@calls/state';
import {General} from '@constants';
import {withServerUrl} from '@context/server';
import {observeChannelSettings, observeMyChannel} from '@queries/servers/channel';
import {observeChannelSettings, observeMyChannel, queryChannelMembers} from '@queries/servers/channel';
import {queryDraft} from '@queries/servers/drafts';
import {observeCurrentChannelId, observeCurrentUserId} from '@queries/servers/system';
import {observeTeam} from '@queries/servers/team';
@ -67,7 +67,7 @@ const enhance = withObservables(['channel', 'showTeamName'], ({
let membersCount = of$(0);
if (channel.type === General.GM_CHANNEL) {
membersCount = channel.members.observeCount(false);
membersCount = queryChannelMembers(database, channel.id).observeCount(false);
}
const isUnread = myChannel.pipe(

View file

@ -6,6 +6,7 @@ import withObservables from '@nozbe/with-observables';
import {combineLatest, of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {observeChannel} from '@queries/servers/channel';
import {observeCurrentTeamId} from '@queries/servers/system';
import {observeTeam} from '@queries/servers/team';
@ -17,7 +18,7 @@ import type TeamModel from '@typings/database/models/servers/team';
const enhanced = withObservables(['post'], ({post, database}: WithDatabaseArgs & { post: PostModel }) => {
const currentTeamId = observeCurrentTeamId(database);
const channel = post.channel.observe();
const channel = observeChannel(database, post.id);
const teamName = combineLatest([channel, currentTeamId]).pipe(
switchMap(([c, tid]) => {

View file

@ -1,18 +1,20 @@
// 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 {observeTeamIdByThread} from '@queries/servers/thread';
import FollowThreadOption from './follow_thread_option';
import type {WithDatabaseArgs} from '@typings/database/database';
import type ThreadModel from '@typings/database/models/servers/thread';
const enhanced = withObservables(['thread'], ({thread}: { thread: ThreadModel }) => {
const enhanced = withObservables(['thread'], ({thread, database}: {thread: ThreadModel} & WithDatabaseArgs) => {
return {
teamId: observeTeamIdByThread(thread),
teamId: observeTeamIdByThread(database, thread),
};
});
export default enhanced(FollowThreadOption);
export default withDatabase(enhanced(FollowThreadOption));

View file

@ -6,6 +6,7 @@ import withObservables from '@nozbe/with-observables';
import {combineLatest, of as of$, from as from$} from 'rxjs';
import {map, switchMap} from 'rxjs/operators';
import {queryFilesForPost} from '@queries/servers/file';
import {observeConfigBooleanValue, observeLicense} from '@queries/servers/system';
import {fileExists} from '@utils/file';
@ -47,7 +48,7 @@ const enhance = withObservables(['post'], ({database, post}: EnhanceProps) => {
map(([download, compliance]) => compliance || download),
);
const filesInfo = post.files.observeWithColumns(['local_path']).pipe(
const filesInfo = queryFilesForPost(database, post.id).observeWithColumns(['local_path']).pipe(
switchMap((fs) => from$(filesLocalPathValidation(fs, post.userId))),
);

View file

@ -7,7 +7,7 @@ import React from 'react';
import {of as of$} from 'rxjs';
import {switchMap, distinctUntilChanged} from 'rxjs/operators';
import {observeChannel} from '@queries/servers/channel';
import {observeChannel, observeChannelInfo} from '@queries/servers/channel';
import {observeConfigBooleanValue, observeConfigIntValue} from '@queries/servers/system';
import PostInput from './post_input';
@ -31,7 +31,7 @@ const enhanced = withObservables(['channelId'], ({database, channelId}: WithData
);
const membersInChannel = channel.pipe(
switchMap((c) => (c ? c.info.observe() : of$({memberCount: 0}))),
switchMap((c) => (c ? observeChannelInfo(database, c.id) : of$({memberCount: 0}))),
switchMap((i: ChannelInfoModel) => of$(i.memberCount)),
distinctUntilChanged(),
);

View file

@ -8,7 +8,7 @@ import {switchMap} from 'rxjs/operators';
import {General, Permissions} from '@constants';
import {MAX_MESSAGE_LENGTH_FALLBACK} from '@constants/post_draft';
import {observeChannel, observeCurrentChannel} from '@queries/servers/channel';
import {observeChannel, observeChannelInfo, observeCurrentChannel} from '@queries/servers/channel';
import {queryAllCustomEmojis} from '@queries/servers/custom_emoji';
import {observePermissionForChannel} from '@queries/servers/role';
import {observeConfigBooleanValue, observeConfigIntValue, observeCurrentUserId} from '@queries/servers/system';
@ -56,7 +56,7 @@ const enhanced = withObservables([], (ownProps: WithDatabaseArgs & OwnProps) =>
}),
);
const channelInfo = channel.pipe(switchMap((c) => (c ? c.info.observe() : of$(undefined))));
const channelInfo = channel.pipe(switchMap((c) => (c ? observeChannelInfo(database, c.id) : of$(undefined))));
const membersCount = channelInfo.pipe(
switchMap((i) => (i ? of$(i.memberCount) : of$(0))),
);

View file

@ -6,19 +6,19 @@ import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {observeChannel} from '@queries/servers/channel';
import {observeCurrentUser} from '@queries/servers/user';
import AddMembers from './add_members';
import type {WithDatabaseArgs} from '@typings/database/database';
import type ChannelModel from '@typings/database/models/servers/channel';
import type PostModel from '@typings/database/models/servers/post';
const enhance = withObservables(['post'], ({database, post}: WithDatabaseArgs & {post: PostModel}) => ({
currentUser: observeCurrentUser(database),
channelType: post.channel.observe().pipe(
channelType: observeChannel(database, post.channelId).pipe(
switchMap(
(channel: ChannelModel) => (channel ? of$(channel.type) : of$(null)),
(channel) => (channel ? of$(channel.type) : of$(null)),
),
),
}));

View file

@ -12,6 +12,7 @@ import {handleBindingClick, postEphemeralCallResponseForPost} from '@actions/rem
import {handleGotoLocation} from '@actions/remote/command';
import {AppBindingLocations, AppCallResponseTypes} from '@constants/apps';
import {useServerUrl} from '@context/server';
import {observeChannel} from '@queries/servers/channel';
import {observeCurrentTeamId} from '@queries/servers/system';
import {showAppForm} from '@screens/navigation';
import {createCallContext} from '@utils/apps';
@ -22,7 +23,6 @@ import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme';
import ButtonBindingText from './button_binding_text';
import type {WithDatabaseArgs} from '@typings/database/database';
import type ChannelModel from '@typings/database/models/servers/channel';
import type PostModel from '@typings/database/models/servers/post';
type Props = {
@ -137,7 +137,7 @@ const ButtonBinding = ({currentTeamId, binding, post, teamID, theme}: Props) =>
};
const withTeamId = withObservables(['post'], ({post, database}: {post: PostModel} & WithDatabaseArgs) => ({
teamID: post.channel.observe().pipe(map((channel: ChannelModel) => channel.teamId)),
teamID: observeChannel(database, post.channelId).pipe(map((channel) => channel?.teamId)),
currentTeamId: observeCurrentTeamId(database),
}));

View file

@ -10,11 +10,11 @@ import {postEphemeralCallResponseForPost} from '@actions/remote/apps';
import AutocompleteSelector from '@components/autocomplete_selector';
import {useServerUrl} from '@context/server';
import {useAppBinding} from '@hooks/apps';
import {observeChannel} from '@queries/servers/channel';
import {observeCurrentTeamId} from '@queries/servers/system';
import {logDebug} from '@utils/log';
import type {WithDatabaseArgs} from '@typings/database/database';
import type ChannelModel from '@typings/database/models/servers/channel';
import type PostModel from '@typings/database/models/servers/post';
type Props = {
@ -79,7 +79,7 @@ const MenuBinding = ({binding, currentTeamId, post, teamID}: Props) => {
};
const withTeamId = withObservables(['post'], ({post, database}: {post: PostModel} & WithDatabaseArgs) => ({
teamID: post.channel.observe().pipe(map((channel: ChannelModel) => channel.teamId)),
teamID: observeChannel(database, post.channelId).pipe(map((channel) => channel?.teamId)),
currentTeamId: observeCurrentTeamId(database),
}));

View file

@ -8,6 +8,7 @@ import {map, switchMap} from 'rxjs/operators';
import {General, Permissions} from '@constants';
import {observeChannel} from '@queries/servers/channel';
import {observeReactionsForPost} from '@queries/servers/reaction';
import {observePermissionForPost} from '@queries/servers/role';
import {observeConfigBooleanValue, observeCurrentUserId} from '@queries/servers/system';
import {observeUser} from '@queries/servers/user';
@ -42,7 +43,7 @@ const withReactions = withObservables(['post'], ({database, post}: WithReactions
currentUserId,
disabled,
postId: of$(post.id),
reactions: post.reactions.observe(),
reactions: observeReactionsForPost(database, post.id),
};
});

View file

@ -16,7 +16,7 @@ const enhanced = withObservables(
({database, thread}: WithDatabaseArgs & {thread: ThreadModel}) => {
return {
participants: queryThreadParticipants(database, thread.id).observe(),
teamId: observeTeamIdByThread(thread),
teamId: observeTeamIdByThread(database, thread),
};
},
);

View file

@ -8,10 +8,10 @@ import {map, switchMap} from 'rxjs/operators';
import {Preferences} from '@constants';
import {getPreferenceAsBool} from '@helpers/api/preference';
import {observePostAuthor, queryPostReplies} from '@queries/servers/post';
import {observePost, observePostAuthor, queryPostReplies} from '@queries/servers/post';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {observeConfigBooleanValue} from '@queries/servers/system';
import {observeTeammateNameDisplay} from '@queries/servers/user';
import {observeTeammateNameDisplay, observeUser} from '@queries/servers/user';
import Header from './header';
@ -35,9 +35,9 @@ const withHeaderProps = withObservables(
const teammateNameDisplay = observeTeammateNameDisplay(database);
const commentCount = queryPostReplies(database, post.rootId || post.id).observeCount();
const isCustomStatusEnabled = observeConfigBooleanValue(database, 'EnableCustomUserStatuses');
const rootPostAuthor = differentThreadSequence ? post.root.observe().pipe(switchMap((root) => {
if (root.length) {
return root[0].author.observe();
const rootPostAuthor = differentThreadSequence ? observePost(database, post.rootId).pipe(switchMap((root) => {
if (root) {
return observeUser(database, root.userId);
}
return of$(null);

View file

@ -8,7 +8,9 @@ import {of as of$, combineLatest} from 'rxjs';
import {switchMap, distinctUntilChanged} from 'rxjs/operators';
import {Permissions, Preferences, Screens} from '@constants';
import {observePostAuthor, queryPostsBetween} from '@queries/servers/post';
import {queryFilesForPost} from '@queries/servers/file';
import {observePost, observePostAuthor, queryPostsBetween} from '@queries/servers/post';
import {queryReactionsForPost} from '@queries/servers/reaction';
import {observeCanManageChannelMembers, observePermissionForPost} from '@queries/servers/role';
import {observeIsPostPriorityEnabled} from '@queries/servers/system';
import {observeThreadById} from '@queries/servers/thread';
@ -34,7 +36,7 @@ type PropsInput = WithDatabaseArgs & {
function observeShouldHighlightReplyBar(database: Database, currentUser: UserModel, post: PostModel, postsInThread: PostsInThreadModel) {
const myPostsCount = queryPostsBetween(database, postsInThread.earliest, postsInThread.latest, null, currentUser.id, '', post.rootId || post.id).observeCount();
const root = post.root.observe().pipe(switchMap((rl) => (rl.length ? rl[0].observe() : of$(undefined))));
const root = observePost(database, post.rootId);
return combineLatest([myPostsCount, root]).pipe(
switchMap(([mpc, r]) => {
@ -62,14 +64,14 @@ function observeShouldHighlightReplyBar(database: Database, currentUser: UserMod
);
}
function observeHasReplies(post: PostModel) {
function observeHasReplies(database: Database, post: PostModel) {
if (!post.rootId) {
return post.postsInThread.observe().pipe(switchMap((c) => of$(c.length > 0)));
}
return post.root.observe().pipe(switchMap((rl) => {
if (rl.length) {
return rl[0].postsInThread.observe().pipe(switchMap((c) => of$(c.length > 0)));
return observePost(database, post.rootId).pipe(switchMap((r) => {
if (r) {
return r.postsInThread.observe().pipe(switchMap((c) => of$(c.length > 0)));
}
return of$(false);
}));
@ -122,19 +124,19 @@ const withPost = withObservables(
isLastReply = of$(!(nextPost?.rootId === post.rootId));
}
const hasReplies = observeHasReplies(post);//Need to review and understand
const hasReplies = observeHasReplies(database, post);//Need to review and understand
const isConsecutivePost = author.pipe(
switchMap((user) => of$(Boolean(post && previousPost && !user?.isBot && areConsecutivePosts(post, previousPost)))),
distinctUntilChanged(),
);
const hasFiles = post.files.observeCount().pipe(
const hasFiles = queryFilesForPost(database, post.id).observeCount().pipe(
switchMap((c) => of$(c > 0)),
distinctUntilChanged(),
);
const hasReactions = post.reactions.observeCount().pipe(
const hasReactions = queryReactionsForPost(database, post.id).observeCount().pipe(
switchMap((c) => of$(c > 0)),
distinctUntilChanged(),
);

View file

@ -1,14 +1,18 @@
// 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 {observeUser} from '@queries/servers/user';
import SystemMessage from './system_message';
import type {WithDatabaseArgs} from '@typings/database/database';
import type PostModel from '@typings/database/models/servers/post';
const withPost = withObservables(['post'], ({post}: {post: PostModel}) => ({
author: post.author.observe(),
const enhance = withObservables(['post'], ({post, database}: {post: PostModel} & WithDatabaseArgs) => ({
author: observeUser(database, post.userId),
}));
export default withPost(SystemMessage);
export default withDatabase(enhance(SystemMessage));

View file

@ -1,27 +1,30 @@
// 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 {switchMap, of as of$} from 'rxjs';
import {observeChannel} from '@queries/servers/channel';
import {observeTeam} from '@queries/servers/team';
import ChannelInfo from './channel_info';
import type {WithDatabaseArgs} from '@typings/database/database';
import type PostModel from '@typings/database/models/servers/post';
const enhance = withObservables(['post'], ({post}: {post: PostModel}) => {
const channel = post.channel.observe();
const enhance = withObservables(['post'], ({post, database}: {post: PostModel} & WithDatabaseArgs) => {
const channel = observeChannel(database, post.channelId);
return {
channelName: channel.pipe(
switchMap((chan) => (chan ? of$(chan.displayName) : '')),
),
teamName: channel.pipe(
switchMap((chan) => (chan && chan.teamId ? observeTeam(post.database, chan.teamId) : of$(null))),
switchMap((chan) => (chan && chan.teamId ? observeTeam(database, chan.teamId) : of$(null))),
switchMap((team) => of$(team?.displayName || null)),
),
};
});
export default enhance(ChannelInfo);
export default withDatabase(enhance(ChannelInfo));

View file

@ -1,6 +1,8 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
/* eslint-disable max-lines */
import {Database, Model, Q, Query, Relation} from '@nozbe/watermelondb';
import {of as of$, Observable} from 'rxjs';
import {map as map$, switchMap, distinctUntilChanged} from 'rxjs/operators';
@ -664,3 +666,13 @@ export const queryChannelsForAutocomplete = (database: Database, matchTerm: stri
return database.get<ChannelModel>(CHANNEL).query(...clauses);
};
export const queryChannelMembers = (database: Database, channelId: string) => {
return database.get<ChannelMembershipModel>(CHANNEL_MEMBERSHIP).query(
Q.where('channel_id', channelId),
);
};
export const observeChannelMembers = (database: Database, channelId: string) => {
return queryChannelMembers(database, channelId).observe();
};

View file

@ -1,9 +1,10 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Database, Q} from '@nozbe/watermelondb';
import {MM_TABLES} from '@constants/database';
import type {Database} from '@nozbe/watermelondb';
import type FileModel from '@typings/database/models/servers/file';
const {SERVER: {FILE}} = MM_TABLES;
@ -16,3 +17,13 @@ export const getFileById = async (database: Database, fileId: string) => {
return undefined;
}
};
export const queryFilesForPost = (database: Database, postId: string) => {
return database.get<FileModel>(FILE).query(
Q.where('post_id', postId),
);
};
export const observeFilesForPost = (database: Database, postId: string) => {
return queryFilesForPost(database, postId).observe();
};

View file

@ -6,6 +6,7 @@ import {Database, Q} from '@nozbe/watermelondb';
import {MM_TABLES} from '@constants/database';
import type ReactionModel from '@typings/database/models/servers/reaction';
const {SERVER: {REACTION}} = MM_TABLES;
export const queryReaction = (database: Database, emojiName: string, postId: string, userId: string) => {
@ -15,3 +16,14 @@ export const queryReaction = (database: Database, emojiName: string, postId: str
Q.where('user_id', userId),
);
};
export const queryReactionsForPost = (database: Database, postId: string) => {
return database.get<ReactionModel>(REACTION).query(
Q.where('post_id', postId),
);
};
export const observeReactionsForPost = (database: Database, postId: string) => {
return queryReactionsForPost(database, postId).observe();
};

View file

@ -9,6 +9,8 @@ import {Preferences} from '@constants';
import {MM_TABLES} from '@constants/database';
import {processIsCRTEnabled} from '@utils/thread';
import {observeChannel} from './channel';
import {observePost} from './post';
import {queryPreferencesByCategoryAndName} from './preference';
import {getConfig, observeConfigValue} from './system';
@ -61,13 +63,13 @@ export const observeThreadById = (database: Database, threadId: string) => {
);
};
export const observeTeamIdByThread = (thread: ThreadModel) => {
return thread.post.observe().pipe(
export const observeTeamIdByThread = (database: Database, thread: ThreadModel) => {
return observePost(database, thread.id).pipe(
switchMap((post) => {
if (!post) {
return of$(undefined);
}
return post.channel.observe().pipe(
return observeChannel(database, post.channelId).pipe(
switchMap((channel) => of$(channel?.teamId)),
);
}),

View file

@ -7,6 +7,7 @@ import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {General} from '@constants';
import {observeChannelMembers} from '@queries/servers/channel';
import {observeCurrentUserId} from '@queries/servers/system';
import {observeUser} from '@queries/servers/user';
import {getUserIdFromChannelName} from '@utils/user';
@ -21,7 +22,7 @@ const observeIsBot = (user: UserModel | undefined) => of$(Boolean(user?.isBot));
const enhanced = withObservables([], ({channel, database}: {channel: ChannelModel} & WithDatabaseArgs) => {
const currentUserId = observeCurrentUserId(database);
const members = channel.members.observe();
const members = observeChannelMembers(database, channel.id);
let isBot = of$(false);
if (channel.type === General.DM_CHANNEL) {

View file

@ -4,12 +4,15 @@
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {observeUser} from '@queries/servers/user';
import Member from './member';
import type {WithDatabaseArgs} from '@typings/database/database';
import type ChannelMembershipModel from '@typings/database/models/servers/channel_membership';
const enhanced = withObservables([], ({member}: {member: ChannelMembershipModel}) => ({
user: member.memberUser.observe(),
const enhanced = withObservables([], ({member, database}: {member: ChannelMembershipModel} & WithDatabaseArgs) => ({
user: observeUser(database, member.userId),
}));
export default withDatabase(enhanced(Member));

View file

@ -6,7 +6,7 @@ import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {observeChannel} from '@queries/servers/channel';
import {observeChannel, observeChannelMembers} from '@queries/servers/channel';
import {observeCurrentUserId} from '@queries/servers/system';
import GroupMessage from './group_message';
@ -20,7 +20,7 @@ type Props = WithDatabaseArgs & {
const enhanced = withObservables(['channelId'], ({channelId, database}: Props) => {
const currentUserId = observeCurrentUserId(database);
const channel = observeChannel(database, channelId);
const members = channel.pipe(switchMap((c) => (c ? c.members.observe() : of$([]))));
const members = channel.pipe(switchMap((c) => (c ? observeChannelMembers(database, channelId) : of$([]))));
return {
currentUserId,

View file

@ -7,6 +7,7 @@ import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {MAX_MESSAGE_LENGTH_FALLBACK} from '@constants/post_draft';
import {observeFilesForPost} from '@queries/servers/file';
import {observeConfigIntValue} from '@queries/servers/system';
import EditPost from './edit_post';
@ -17,7 +18,7 @@ import type PostModel from '@typings/database/models/servers/post';
const enhance = withObservables([], ({database, post}: WithDatabaseArgs & { post: PostModel}) => {
const maxPostSize = observeConfigIntValue(database, 'MaxPostSize', MAX_MESSAGE_LENGTH_FALLBACK);
const hasFilesAttached = post.files.observe().pipe(switchMap((files) => of$(files?.length > 0)));
const hasFilesAttached = observeFilesForPost(database, post.id).pipe(switchMap((files) => of$(files?.length > 0)));
return {
maxPostSize,

View file

@ -43,7 +43,8 @@ const enhanced = withObservables(['item'], ({database, item}: FooterProps) => {
const channel = combineLatest([currentChannelId, post]).pipe(
switchMap(([cId, p]) => {
return p?.channel.observe() || observeChannel(database, cId);
const id = p?.channelId || cId;
return observeChannel(database, id);
}),
);
const enablePostUsernameOverride = observeConfigBooleanValue(database, 'EnablePostUsernameOverride');

View file

@ -6,6 +6,7 @@ import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {observeChannel} from '@queries/servers/channel';
import {observePost} from '@queries/servers/post';
import {observeCurrentTeamId} from '@queries/servers/system';
import {queryMyTeamsByIds, queryTeamByName} from '@queries/servers/team';
@ -32,7 +33,7 @@ const enhance = withObservables([], ({database, postId, teamName}: OwnProps) =>
return {
channel: post.pipe(
switchMap((p) => (p ? p.channel.observe() : of$(undefined))),
switchMap((p) => (p ? observeChannel(database, p.channelId) : of$(undefined))),
),
rootId: post.pipe(
switchMap((p) => of$(p?.rootId)),

View file

@ -10,7 +10,9 @@ import {General, Permissions, Post, Screens} from '@constants';
import {AppBindingLocations} from '@constants/apps';
import {MAX_ALLOWED_REACTIONS} from '@constants/emoji';
import AppsManager from '@managers/apps_manager';
import {observeChannel} from '@queries/servers/channel';
import {observePost, observePostSaved} from '@queries/servers/post';
import {observeReactionsForPost} from '@queries/servers/reaction';
import {observePermissionForChannel, observePermissionForPost} from '@queries/servers/role';
import {observeConfigBooleanValue, observeConfigIntValue, observeConfigValue, observeLicense} from '@queries/servers/system';
import {observeIsCRTEnabled, observeThreadById} from '@queries/servers/thread';
@ -74,7 +76,7 @@ const withPost = withObservables([], ({post, database}: {post: Post | PostModel}
});
const enhanced = withObservables([], ({combinedPost, post, showAddReaction, location, database, serverUrl}: EnhancedProps) => {
const channel = post.channel.observe();
const channel = observeChannel(database, post.channelId);
const channelIsArchived = channel.pipe(switchMap((ch: ChannelModel) => of$(ch.deleteAt !== 0)));
const currentUser = observeCurrentUser(database);
const isLicensed = observeLicense(database).pipe(switchMap((lcs) => of$(lcs?.IsLicensed === 'true')));
@ -95,7 +97,7 @@ const enhanced = withObservables([], ({combinedPost, post, showAddReaction, loca
return of$(c?.name === General.DEFAULT_CHANNEL && (u && !isSystemAdmin(u.roles)) && readOnly);
}));
const isUnderMaxAllowedReactions = post.reactions.observe().pipe(
const isUnderMaxAllowedReactions = observeReactionsForPost(database, post.id).pipe(
// eslint-disable-next-line max-nested-callbacks
switchMap((reactions: ReactionModel[]) => of$(new Set(reactions.map((r) => r.emojiName)).size < MAX_ALLOWED_REACTIONS)),
);

View file

@ -7,6 +7,7 @@ import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {observePost} from '@queries/servers/post';
import {observeReactionsForPost} from '@queries/servers/reaction';
import Reactions from './reactions';
@ -21,7 +22,7 @@ const enhanced = withObservables([], ({postId, database}: EnhancedProps) => {
return {
reactions: post.pipe(
switchMap((p) => (p ? p.reactions.observe() : of$(undefined))),
switchMap((p) => (p ? observeReactionsForPost(database, postId) : of$(undefined))),
),
};
});

View file

@ -4,7 +4,7 @@
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {observePostSaved} from '@queries/servers/post';
import {observePost, observePostSaved} from '@queries/servers/post';
import {observeCurrentTeam} from '@queries/servers/team';
import ThreadOptions from './thread_options';
@ -19,7 +19,7 @@ type Props = WithDatabaseArgs & {
const enhanced = withObservables(['thread'], ({database, thread}: Props) => {
return {
isSaved: observePostSaved(database, thread.id),
post: thread.post.observe(),
post: observePost(database, thread.id),
team: observeCurrentTeam(database),
};
});

View file

@ -8,7 +8,7 @@ import {switchMap, distinctUntilChanged} from 'rxjs/operators';
import {General} from '@constants';
import {withServerUrl} from '@context/server';
import {observeMyChannel} from '@queries/servers/channel';
import {observeMyChannel, queryChannelMembers} from '@queries/servers/channel';
import {observeCurrentUserId} from '@queries/servers/system';
import {observeTeam} from '@queries/servers/team';
@ -37,7 +37,7 @@ const enhance = withObservables(['channel', 'showTeamName'], ({channel, showTeam
let membersCount = of$(0);
if (channel.type === General.GM_CHANNEL) {
membersCount = channel.members.observeCount(false);
membersCount = queryChannelMembers(database, channel.id).observeCount(false);
}
const hasMember = myChannel.pipe(