forked from Ivasoft/mattermost-mobile
Add minor fixes and performance improvements on channel switch (#6469)
* Add minor fixes and performance improvements * Add comment
This commit is contained in:
committed by
GitHub
parent
52d5f903f3
commit
3abaf8893d
@@ -4,11 +4,12 @@
|
||||
/* eslint-disable max-lines */
|
||||
import {Model} from '@nozbe/watermelondb';
|
||||
import {IntlShape} from 'react-intl';
|
||||
import {DeviceEventEmitter} from 'react-native';
|
||||
|
||||
import {addChannelToDefaultCategory, storeCategories} from '@actions/local/category';
|
||||
import {removeCurrentUserFromChannel, setChannelDeleteAt, storeMyChannelsForTeam, switchToChannel} from '@actions/local/channel';
|
||||
import {switchToGlobalThreads} from '@actions/local/thread';
|
||||
import {General, Preferences, Screens} from '@constants';
|
||||
import {Events, General, Preferences, Screens} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {privateChannelJoinPrompt} from '@helpers/api/channel';
|
||||
import {getTeammateNameDisplaySetting} from '@helpers/api/preference';
|
||||
@@ -1101,12 +1102,16 @@ export async function switchToChannelById(serverUrl: string, channelId: string,
|
||||
return {error: `${serverUrl} database not found`};
|
||||
}
|
||||
|
||||
DeviceEventEmitter.emit(Events.CHANNEL_SWITCH, true);
|
||||
|
||||
fetchPostsForChannel(serverUrl, channelId);
|
||||
await switchToChannel(serverUrl, channelId, teamId, skipLastUnread);
|
||||
setDirectChannelVisible(serverUrl, channelId);
|
||||
markChannelAsRead(serverUrl, channelId);
|
||||
fetchChannelStats(serverUrl, channelId);
|
||||
|
||||
DeviceEventEmitter.emit(Events.CHANNEL_SWITCH, false);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -42,9 +42,9 @@ const enhanced = withObservables([], ({database, channelId}: WithDatabaseArgs &
|
||||
switchMap((c) => of$(Boolean(c?.isGroupConstrained))),
|
||||
);
|
||||
|
||||
useChannelMentions = combineLatest([currentUser, currentChannel]).pipe(switchMap(([u, c]) => (u && c ? observePermissionForChannel(database, c, u, Permissions.USE_CHANNEL_MENTIONS, false) : of$(false))));
|
||||
useChannelMentions = combineLatest([currentUser, currentChannel]).pipe(switchMap(([u, c]) => observePermissionForChannel(database, c, u, Permissions.USE_CHANNEL_MENTIONS, false)));
|
||||
useGroupMentions = combineLatest([currentUser, currentChannel, hasLicense]).pipe(
|
||||
switchMap(([u, c, lcs]) => (lcs && u && c ? observePermissionForChannel(database, c, u, Permissions.USE_GROUP_MENTIONS, false) : of$(false))),
|
||||
switchMap(([u, c, lcs]) => (lcs ? observePermissionForChannel(database, c, u, Permissions.USE_GROUP_MENTIONS, false) : of$(false))),
|
||||
);
|
||||
} else {
|
||||
useChannelMentions = of$(false);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
|
||||
import withObservables from '@nozbe/with-observables';
|
||||
import {of as of$} from 'rxjs';
|
||||
import {switchMap} from 'rxjs/operators';
|
||||
import {switchMap, distinctUntilChanged} from 'rxjs/operators';
|
||||
|
||||
import {observeChannelInfo} from '@queries/servers/channel';
|
||||
|
||||
@@ -23,6 +23,11 @@ const enhanced = withObservables(['channelId'], ({channelId, database}: OwnProps
|
||||
const channelInfo = observeChannelInfo(database, channelId);
|
||||
const isHeaderSet = channelInfo.pipe(
|
||||
switchMap((c) => of$(Boolean(c?.header))),
|
||||
|
||||
// Channel info is fetched when we switch to the channel, and should update
|
||||
// the member count whenever a user joins or leaves the channel, so this should
|
||||
// save us a few renders.
|
||||
distinctUntilChanged(),
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@@ -142,7 +142,9 @@ const AtMention = ({
|
||||
// Effects
|
||||
useEffect(() => {
|
||||
// Fetches and updates the local db store with the mention
|
||||
fetchUserOrGroupsByMentionsInBatch(serverUrl, mentionName);
|
||||
if (!user.username) {
|
||||
fetchUserOrGroupsByMentionsInBatch(serverUrl, mentionName);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const openUserProfile = () => {
|
||||
|
||||
@@ -5,9 +5,9 @@ import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
|
||||
import withObservables from '@nozbe/with-observables';
|
||||
import React from 'react';
|
||||
import {of as of$} from 'rxjs';
|
||||
import {switchMap} from 'rxjs/operators';
|
||||
import {switchMap, distinctUntilChanged} from 'rxjs/operators';
|
||||
|
||||
import {observeChannel, observeCurrentChannel} from '@queries/servers/channel';
|
||||
import {observeChannel} from '@queries/servers/channel';
|
||||
import {observeConfig} from '@queries/servers/system';
|
||||
|
||||
import PostInput from './post_input';
|
||||
@@ -17,10 +17,9 @@ import type ChannelInfoModel from '@typings/database/models/servers/channel_info
|
||||
|
||||
type OwnProps = {
|
||||
channelId: string;
|
||||
rootId?: string;
|
||||
}
|
||||
|
||||
const enhanced = withObservables([], ({database, channelId, rootId}: WithDatabaseArgs & OwnProps) => {
|
||||
const enhanced = withObservables(['channelId'], ({database, channelId}: WithDatabaseArgs & OwnProps) => {
|
||||
const config = observeConfig(database);
|
||||
const timeBetweenUserTypingUpdatesMilliseconds = config.pipe(
|
||||
switchMap((cfg) => of$(parseInt(cfg?.TimeBetweenUserTypingUpdatesMilliseconds || '0', 10))),
|
||||
@@ -34,12 +33,7 @@ const enhanced = withObservables([], ({database, channelId, rootId}: WithDatabas
|
||||
switchMap((cfg) => of$(parseInt(cfg?.MaxNotificationsPerChannel || '0', 10))),
|
||||
);
|
||||
|
||||
let channel;
|
||||
if (rootId) {
|
||||
channel = observeChannel(database, channelId);
|
||||
} else {
|
||||
channel = observeCurrentChannel(database);
|
||||
}
|
||||
const channel = observeChannel(database, channelId);
|
||||
|
||||
const channelDisplayName = channel.pipe(
|
||||
switchMap((c) => of$(c?.displayName)),
|
||||
@@ -47,8 +41,8 @@ const enhanced = withObservables([], ({database, channelId, rootId}: WithDatabas
|
||||
|
||||
const membersInChannel = channel.pipe(
|
||||
switchMap((c) => (c ? c.info.observe() : of$({memberCount: 0}))),
|
||||
).pipe(
|
||||
switchMap((i: ChannelInfoModel) => of$(i.memberCount)),
|
||||
distinctUntilChanged(),
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@@ -28,7 +28,7 @@ const withCombinedPosts = withObservables(['postId'], ({database, postId}: WithD
|
||||
const posts = queryPostsById(database, postIds).observe();
|
||||
const post = posts.pipe(map((ps) => generateCombinedPost(postId, ps)));
|
||||
const canDelete = combineLatest([posts, currentUser]).pipe(
|
||||
switchMap(([ps, u]) => (u && ps.length ? observePermissionForPost(database, ps[0], u, Permissions.DELETE_OTHERS_POSTS, false) : of$(false))),
|
||||
switchMap(([ps, u]) => (ps.length ? observePermissionForPost(database, ps[0], u, Permissions.DELETE_OTHERS_POSTS, false) : of$(false))),
|
||||
);
|
||||
|
||||
const usernamesById = post.pipe(
|
||||
|
||||
@@ -23,7 +23,7 @@ import type {SearchPattern} from '@typings/global/markdown';
|
||||
|
||||
type BodyProps = {
|
||||
appsEnabled: boolean;
|
||||
filesCount: number;
|
||||
hasFiles: boolean;
|
||||
hasReactions: boolean;
|
||||
highlight: boolean;
|
||||
highlightReplyBar: boolean;
|
||||
@@ -74,7 +74,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
});
|
||||
|
||||
const Body = ({
|
||||
appsEnabled, filesCount, hasReactions, highlight, highlightReplyBar,
|
||||
appsEnabled, hasFiles, hasReactions, highlight, highlightReplyBar,
|
||||
isEphemeral, isFirstReply, isJumboEmoji, isLastReply, isPendingOrFailed, isPostAddChannelMember,
|
||||
location, post, searchPatterns, showAddReaction, theme,
|
||||
}: BodyProps) => {
|
||||
@@ -170,7 +170,7 @@ const Body = ({
|
||||
theme={theme}
|
||||
/>
|
||||
}
|
||||
{filesCount > 0 &&
|
||||
{hasFiles &&
|
||||
<Files
|
||||
failed={isFailed}
|
||||
layoutWidth={layoutWidth}
|
||||
|
||||
@@ -33,8 +33,8 @@ const withReactions = withObservables(['post'], ({database, post}: WithReactions
|
||||
map(([u, c, readOnly]) => ((c && c.deleteAt > 0) || (c?.name === General.DEFAULT_CHANNEL && !isSystemAdmin(u?.roles || '') && readOnly))),
|
||||
);
|
||||
|
||||
const canAddReaction = currentUser.pipe(switchMap((u) => (u ? observePermissionForPost(database, post, u, Permissions.ADD_REACTION, true) : of$(true))));
|
||||
const canRemoveReaction = currentUser.pipe(switchMap((u) => (u ? observePermissionForPost(database, post, u, Permissions.REMOVE_REACTION, true) : of$(true))));
|
||||
const canAddReaction = currentUser.pipe(switchMap((u) => observePermissionForPost(database, post, u, Permissions.ADD_REACTION, true)));
|
||||
const canRemoveReaction = currentUser.pipe(switchMap((u) => observePermissionForPost(database, post, u, Permissions.REMOVE_REACTION, true)));
|
||||
|
||||
return {
|
||||
canAddReaction,
|
||||
|
||||
@@ -96,7 +96,7 @@ const withSystem = withObservables([], ({database}: WithDatabaseArgs) => ({
|
||||
|
||||
const withPost = withObservables(
|
||||
['currentUser', 'isCRTEnabled', 'post', 'previousPost', 'nextPost'],
|
||||
({appsEnabled, currentUser, database, isCRTEnabled, post, previousPost, nextPost}: PropsInput) => {
|
||||
({currentUser, database, isCRTEnabled, post, previousPost, nextPost}: PropsInput) => {
|
||||
let isJumboEmoji = of$(false);
|
||||
let isLastReply = of$(true);
|
||||
let isPostAddChannelMember = of$(false);
|
||||
@@ -145,11 +145,20 @@ const withPost = withObservables(
|
||||
distinctUntilChanged(),
|
||||
);
|
||||
|
||||
const hasFiles = post.files.observe().pipe(
|
||||
switchMap((ff) => of$(Boolean(ff.length))),
|
||||
distinctUntilChanged(),
|
||||
);
|
||||
|
||||
const hasReactions = post.reactions.observe().pipe(
|
||||
switchMap((rr) => of$(Boolean(rr.length))),
|
||||
distinctUntilChanged(),
|
||||
);
|
||||
|
||||
return {
|
||||
appsEnabled: of$(appsEnabled),
|
||||
canDelete,
|
||||
differentThreadSequence: of$(differentThreadSequence),
|
||||
filesCount: post.files.observeCount(),
|
||||
hasFiles,
|
||||
hasReplies,
|
||||
highlightReplyBar,
|
||||
isConsecutivePost,
|
||||
@@ -161,7 +170,7 @@ const withPost = withObservables(
|
||||
isPostAddChannelMember,
|
||||
post: post.observe(),
|
||||
thread: isCRTEnabled ? observeThreadById(database, post.id) : of$(undefined),
|
||||
reactionsCount: post.reactions.observeCount(),
|
||||
hasReactions,
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ type PostProps = {
|
||||
canDelete: boolean;
|
||||
currentUser: UserModel;
|
||||
differentThreadSequence: boolean;
|
||||
filesCount: number;
|
||||
hasFiles: boolean;
|
||||
hasReplies: boolean;
|
||||
highlight?: boolean;
|
||||
highlightPinnedOrSaved?: boolean;
|
||||
@@ -54,7 +54,7 @@ type PostProps = {
|
||||
location: string;
|
||||
post: PostModel;
|
||||
previousPost?: PostModel;
|
||||
reactionsCount: number;
|
||||
hasReactions: boolean;
|
||||
searchPatterns?: SearchPattern[];
|
||||
shouldRenderReplyButton?: boolean;
|
||||
showAddReaction?: boolean;
|
||||
@@ -103,9 +103,9 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
});
|
||||
|
||||
const Post = ({
|
||||
appsEnabled, canDelete, currentUser, differentThreadSequence, filesCount, hasReplies, highlight, highlightPinnedOrSaved = true, highlightReplyBar,
|
||||
appsEnabled, canDelete, currentUser, differentThreadSequence, hasFiles, hasReplies, highlight, highlightPinnedOrSaved = true, highlightReplyBar,
|
||||
isCRTEnabled, isConsecutivePost, isEphemeral, isFirstReply, isSaved, isJumboEmoji, isLastReply, isPostAddChannelMember,
|
||||
location, post, reactionsCount, searchPatterns, shouldRenderReplyButton, skipSavedHeader, skipPinnedHeader, showAddReaction = true, style,
|
||||
location, post, hasReactions, searchPatterns, shouldRenderReplyButton, skipSavedHeader, skipPinnedHeader, showAddReaction = true, style,
|
||||
testID, thread, previousPost,
|
||||
}: PostProps) => {
|
||||
const pressDetected = useRef(false);
|
||||
@@ -274,8 +274,8 @@ const Post = ({
|
||||
body = (
|
||||
<Body
|
||||
appsEnabled={appsEnabled}
|
||||
filesCount={filesCount}
|
||||
hasReactions={reactionsCount > 0}
|
||||
hasFiles={hasFiles}
|
||||
hasReactions={hasReactions}
|
||||
highlight={Boolean(highlightedStyle)}
|
||||
highlightReplyBar={highlightReplyBar}
|
||||
isEphemeral={isEphemeral}
|
||||
|
||||
@@ -6,6 +6,7 @@ import keyMirror from '@utils/key_mirror';
|
||||
export default keyMirror({
|
||||
ACCOUNT_SELECT_TABLET_VIEW: null,
|
||||
CHANNEL_ARCHIVED: null,
|
||||
CHANNEL_SWITCH: null,
|
||||
CLOSE_BOTTOM_SHEET: null,
|
||||
CONFIG_CHANGED: null,
|
||||
FETCHING_POSTS: null,
|
||||
|
||||
33
app/hooks/channel_switch.ts
Normal file
33
app/hooks/channel_switch.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {useEffect, useState} from 'react';
|
||||
import {DeviceEventEmitter} from 'react-native';
|
||||
|
||||
import {Events} from '@constants';
|
||||
|
||||
export const useChannelSwitch = () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
useEffect(() => {
|
||||
let time: NodeJS.Timeout | undefined;
|
||||
const l = DeviceEventEmitter.addListener(Events.CHANNEL_SWITCH, (switching: boolean) => {
|
||||
if (time) {
|
||||
clearTimeout(time);
|
||||
}
|
||||
if (switching) {
|
||||
setLoading(true);
|
||||
} else {
|
||||
// eslint-disable-next-line max-nested-callbacks
|
||||
time = setTimeout(() => setLoading(false), 0);
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
l.remove();
|
||||
if (time) {
|
||||
clearTimeout(time);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return loading;
|
||||
};
|
||||
@@ -37,7 +37,10 @@ export const queryRolesByNames = (database: Database, names: string[]) => {
|
||||
return database.get<RoleModel>(ROLE).query(Q.where('name', Q.oneOf(names)));
|
||||
};
|
||||
|
||||
export function observePermissionForChannel(database: Database, channel: ChannelModel, user: UserModel, permission: string, defaultValue: boolean) {
|
||||
export function observePermissionForChannel(database: Database, channel: ChannelModel | null | undefined, user: UserModel | undefined, permission: string, defaultValue: boolean) {
|
||||
if (!user || !channel) {
|
||||
return of$(defaultValue);
|
||||
}
|
||||
const myChannel = observeMyChannel(database, channel.id);
|
||||
const myTeam = channel.teamId ? observeMyTeam(database, channel.teamId) : of$(undefined);
|
||||
|
||||
@@ -57,7 +60,11 @@ export function observePermissionForChannel(database: Database, channel: Channel
|
||||
);
|
||||
}
|
||||
|
||||
export function observePermissionForTeam(database: Database, team: TeamModel, user: UserModel, permission: string, defaultValue: boolean) {
|
||||
export function observePermissionForTeam(database: Database, team: TeamModel | undefined, user: UserModel | undefined, permission: string, defaultValue: boolean) {
|
||||
if (!team || !user) {
|
||||
return of$(defaultValue);
|
||||
}
|
||||
|
||||
return observeMyTeam(database, team.id).pipe(
|
||||
switchMap((myTeam) => {
|
||||
const rolesArray = [...user.roles.split(' ')];
|
||||
@@ -74,9 +81,9 @@ export function observePermissionForTeam(database: Database, team: TeamModel, us
|
||||
);
|
||||
}
|
||||
|
||||
export function observePermissionForPost(database: Database, post: PostModel, user: UserModel, permission: string, defaultValue: boolean) {
|
||||
export function observePermissionForPost(database: Database, post: PostModel, user: UserModel | undefined, permission: string, defaultValue: boolean) {
|
||||
return observeChannel(database, post.channelId).pipe(
|
||||
switchMap((c) => (c ? observePermissionForChannel(database, c, user, permission, defaultValue) : of$(defaultValue))),
|
||||
switchMap((c) => observePermissionForChannel(database, c, user, permission, defaultValue)),
|
||||
distinctUntilChanged(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import FreezeScreen from '@components/freeze_screen';
|
||||
import PostDraft from '@components/post_draft';
|
||||
import {Events} from '@constants';
|
||||
import {ACCESSORIES_CONTAINER_NATIVE_ID} from '@constants/post_draft';
|
||||
import {useChannelSwitch} from '@hooks/channel_switch';
|
||||
import {useAppState, useIsTablet} from '@hooks/device';
|
||||
import {useDefaultHeaderHeight} from '@hooks/header';
|
||||
import {useTeamSwitch} from '@hooks/team_switch';
|
||||
@@ -39,9 +40,12 @@ const Channel = ({channelId, componentId}: ChannelProps) => {
|
||||
const insets = useSafeAreaInsets();
|
||||
const [shouldRenderPosts, setShouldRenderPosts] = useState(false);
|
||||
const switchingTeam = useTeamSwitch();
|
||||
const switchingChannels = useChannelSwitch();
|
||||
const defaultHeight = useDefaultHeaderHeight();
|
||||
const postDraftRef = useRef<KeyboardTrackingViewRef>(null);
|
||||
|
||||
const shouldRender = !switchingTeam && !switchingChannels && shouldRenderPosts && Boolean(channelId);
|
||||
|
||||
useEffect(() => {
|
||||
const listener = DeviceEventEmitter.addListener(Events.PAUSE_KEYBOARD_TRACKING_VIEW, (pause: boolean) => {
|
||||
if (pause) {
|
||||
@@ -99,8 +103,11 @@ const Channel = ({channelId, componentId}: ChannelProps) => {
|
||||
edges={edges}
|
||||
testID='channel.screen'
|
||||
>
|
||||
<ChannelHeader componentId={componentId}/>
|
||||
{!switchingTeam && shouldRenderPosts && Boolean(channelId) &&
|
||||
<ChannelHeader
|
||||
channelId={channelId}
|
||||
componentId={componentId}
|
||||
/>
|
||||
{shouldRender &&
|
||||
<>
|
||||
<View style={[styles.flex, {marginTop}]}>
|
||||
<ChannelPostList
|
||||
|
||||
@@ -8,7 +8,7 @@ import {combineLatestWith, switchMap} from 'rxjs/operators';
|
||||
|
||||
import {General} from '@constants';
|
||||
import {observeChannel, observeChannelInfo} from '@queries/servers/channel';
|
||||
import {observeCurrentChannelId, observeCurrentTeamId, observeCurrentUserId} from '@queries/servers/system';
|
||||
import {observeCurrentTeamId, observeCurrentUserId} from '@queries/servers/system';
|
||||
import {observeUser} from '@queries/servers/user';
|
||||
import {getUserCustomStatus, getUserIdFromChannelName, isCustomStatusExpired as checkCustomStatusIsExpired} from '@utils/user';
|
||||
|
||||
@@ -16,19 +16,14 @@ import ChannelHeader from './header';
|
||||
|
||||
import type {WithDatabaseArgs} from '@typings/database/database';
|
||||
|
||||
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
|
||||
const enhanced = withObservables(['channelId'], ({channelId, database}: WithDatabaseArgs & {channelId: string}) => {
|
||||
const currentUserId = observeCurrentUserId(database);
|
||||
const channelId = observeCurrentChannelId(database);
|
||||
const teamId = observeCurrentTeamId(database);
|
||||
|
||||
const channel = channelId.pipe(
|
||||
switchMap((id) => observeChannel(database, id)),
|
||||
);
|
||||
const channel = observeChannel(database, channelId);
|
||||
|
||||
const channelType = channel.pipe(switchMap((c) => of$(c?.type)));
|
||||
const channelInfo = channelId.pipe(
|
||||
switchMap((id) => observeChannelInfo(database, id)),
|
||||
);
|
||||
const channelInfo = observeChannelInfo(database, channelId);
|
||||
|
||||
const dmUser = currentUserId.pipe(
|
||||
combineLatestWith(channel),
|
||||
@@ -74,7 +69,6 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
|
||||
switchMap(([ci, dm]) => of$(dm ? undefined : ci?.memberCount)));
|
||||
|
||||
return {
|
||||
channelId,
|
||||
channelType,
|
||||
customStatus,
|
||||
displayName,
|
||||
|
||||
@@ -21,15 +21,15 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
|
||||
const currentUser = observeCurrentUser(database);
|
||||
|
||||
const canJoinChannels = combineLatest([currentUser, team]).pipe(
|
||||
switchMap(([u, t]) => (t && u ? observePermissionForTeam(database, t, u, Permissions.JOIN_PUBLIC_CHANNELS, true) : of$(false))),
|
||||
switchMap(([u, t]) => observePermissionForTeam(database, t, u, Permissions.JOIN_PUBLIC_CHANNELS, true)),
|
||||
);
|
||||
|
||||
const canCreatePublicChannels = combineLatest([currentUser, team]).pipe(
|
||||
switchMap(([u, t]) => (t && u ? observePermissionForTeam(database, t, u, Permissions.CREATE_PUBLIC_CHANNEL, true) : of$(false))),
|
||||
switchMap(([u, t]) => observePermissionForTeam(database, t, u, Permissions.CREATE_PUBLIC_CHANNEL, true)),
|
||||
);
|
||||
|
||||
const canCreatePrivateChannels = combineLatest([currentUser, team]).pipe(
|
||||
switchMap(([u, t]) => (t && u ? observePermissionForTeam(database, t, u, Permissions.CREATE_PRIVATE_CHANNEL, false) : of$(false))),
|
||||
switchMap(([u, t]) => observePermissionForTeam(database, t, u, Permissions.CREATE_PRIVATE_CHANNEL, false)),
|
||||
);
|
||||
|
||||
const canCreateChannels = combineLatest([canCreatePublicChannels, canCreatePrivateChannels]).pipe(
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
|
||||
import withObservables from '@nozbe/with-observables';
|
||||
import {combineLatest, of as of$} from 'rxjs';
|
||||
import {switchMap, distinctUntilChanged} from 'rxjs/operators';
|
||||
import {switchMap} from 'rxjs/operators';
|
||||
|
||||
import {Permissions} from '@constants';
|
||||
import {observePermissionForTeam} from '@queries/servers/role';
|
||||
@@ -22,18 +22,15 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
|
||||
const currentUser = observeCurrentUser(database);
|
||||
|
||||
const canJoinChannels = combineLatest([currentUser, team]).pipe(
|
||||
switchMap(([u, t]) => (t && u ? observePermissionForTeam(database, t, u, Permissions.JOIN_PUBLIC_CHANNELS, true) : of$(false))),
|
||||
distinctUntilChanged(),
|
||||
switchMap(([u, t]) => observePermissionForTeam(database, t, u, Permissions.JOIN_PUBLIC_CHANNELS, true)),
|
||||
);
|
||||
|
||||
const canCreatePublicChannels = combineLatest([currentUser, team]).pipe(
|
||||
switchMap(([u, t]) => (t && u ? observePermissionForTeam(database, t, u, Permissions.CREATE_PUBLIC_CHANNEL, true) : of$(false))),
|
||||
distinctUntilChanged(),
|
||||
switchMap(([u, t]) => observePermissionForTeam(database, t, u, Permissions.CREATE_PUBLIC_CHANNEL, true)),
|
||||
);
|
||||
|
||||
const canCreatePrivateChannels = combineLatest([currentUser, team]).pipe(
|
||||
switchMap(([u, t]) => (t && u ? observePermissionForTeam(database, t, u, Permissions.CREATE_PRIVATE_CHANNEL, false) : of$(false))),
|
||||
distinctUntilChanged(),
|
||||
switchMap(([u, t]) => observePermissionForTeam(database, t, u, Permissions.CREATE_PRIVATE_CHANNEL, false)),
|
||||
);
|
||||
|
||||
const canCreateChannels = combineLatest([canCreatePublicChannels, canCreatePrivateChannels]).pipe(
|
||||
|
||||
@@ -79,11 +79,11 @@ const enhanced = withObservables([], ({combinedPost, post, showAddReaction, loca
|
||||
const serverVersion = config.pipe(switchMap((cfg) => of$(cfg?.Version || '')));
|
||||
const postEditTimeLimit = config.pipe(switchMap((cfg) => of$(parseInt(cfg?.PostEditTimeLimit || '-1', 10))));
|
||||
|
||||
const canPostPermission = combineLatest([channel, currentUser]).pipe(switchMap(([c, u]) => ((c && u) ? observePermissionForChannel(database, c, u, Permissions.CREATE_POST, false) : of$(false))));
|
||||
const hasAddReactionPermission = currentUser.pipe(switchMap((u) => (u ? observePermissionForPost(database, post, u, Permissions.ADD_REACTION, true) : of$(false))));
|
||||
const canPostPermission = combineLatest([channel, currentUser]).pipe(switchMap(([c, u]) => observePermissionForChannel(database, c, u, Permissions.CREATE_POST, false)));
|
||||
const hasAddReactionPermission = currentUser.pipe(switchMap((u) => observePermissionForPost(database, post, u, Permissions.ADD_REACTION, true)));
|
||||
const canDeletePostPermission = currentUser.pipe(switchMap((u) => {
|
||||
const isOwner = post.userId === u?.id;
|
||||
return u ? observePermissionForPost(database, post, u, isOwner ? Permissions.DELETE_POST : Permissions.DELETE_OTHERS_POSTS, false) : of$(false);
|
||||
return observePermissionForPost(database, post, u, isOwner ? Permissions.DELETE_POST : Permissions.DELETE_OTHERS_POSTS, false);
|
||||
}));
|
||||
|
||||
const experimentalTownSquareIsReadOnly = config.pipe(switchMap((value) => of$(value?.ExperimentalTownSquareIsReadOnly === 'true')));
|
||||
|
||||
Reference in New Issue
Block a user