Dismiss correct bottom sheet screen for post / thread options (#6919)

This commit is contained in:
Elias Nahum
2023-01-01 22:54:04 +02:00
committed by GitHub
parent 312c019841
commit f913819b79
15 changed files with 89 additions and 51 deletions

View File

@@ -15,19 +15,20 @@ import {showSnackBar} from '@utils/snack_bar';
import type PostModel from '@typings/database/models/servers/post';
type Props = {
bottomSheetId: typeof Screens[keyof typeof Screens];
sourceScreen: typeof Screens[keyof typeof Screens];
post: PostModel;
teamName: string;
}
const CopyPermalinkOption = ({teamName, post, sourceScreen}: Props) => {
const CopyPermalinkOption = ({bottomSheetId, teamName, post, sourceScreen}: Props) => {
const serverUrl = useServerUrl();
const handleCopyLink = useCallback(async () => {
const permalink = `${serverUrl}/${teamName}/pl/${post.id}`;
Clipboard.setString(permalink);
await dismissBottomSheet(Screens.POST_OPTIONS);
await dismissBottomSheet(bottomSheetId);
showSnackBar({barType: SNACK_BAR_TYPE.LINK_COPIED, sourceScreen});
}, [teamName, post.id]);
}, [teamName, post.id, bottomSheetId]);
return (
<BaseOption

View File

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import React, {useCallback} from 'react';
import {updateThreadFollowing} from '@actions/remote/thread';
import {BaseOption} from '@components/common_post_options';
@@ -13,11 +13,12 @@ import {dismissBottomSheet} from '@screens/navigation';
import type ThreadModel from '@typings/database/models/servers/thread';
type FollowThreadOptionProps = {
bottomSheetId: typeof Screens[keyof typeof Screens];
thread: ThreadModel;
teamId?: string;
};
const FollowThreadOption = ({thread, teamId}: FollowThreadOptionProps) => {
const FollowThreadOption = ({bottomSheetId, thread, teamId}: FollowThreadOptionProps) => {
let id: string;
let defaultMessage: string;
let icon: string;
@@ -44,13 +45,13 @@ const FollowThreadOption = ({thread, teamId}: FollowThreadOptionProps) => {
const serverUrl = useServerUrl();
const handleToggleFollow = async () => {
const handleToggleFollow = useCallback(async () => {
if (teamId == null) {
return;
}
await dismissBottomSheet(Screens.POST_OPTIONS);
await dismissBottomSheet(bottomSheetId);
updateThreadFollowing(serverUrl, teamId, thread.id, !thread.isFollowing);
};
}, [bottomSheetId, teamId, thread]);
const followThreadOptionTestId = thread.isFollowing ? 'post_options.following_thread.option' : 'post_options.follow_thread.option';

View File

@@ -14,16 +14,16 @@ import type PostModel from '@typings/database/models/servers/post';
type Props = {
post: PostModel;
location?: typeof Screens[keyof typeof Screens];
bottomSheetId: typeof Screens[keyof typeof Screens];
}
const ReplyOption = ({post, location}: Props) => {
const ReplyOption = ({post, bottomSheetId}: Props) => {
const serverUrl = useServerUrl();
const handleReply = useCallback(async () => {
const rootId = post.rootId || post.id;
await dismissBottomSheet(location || Screens.POST_OPTIONS);
await dismissBottomSheet(bottomSheetId);
fetchAndSwitchToThread(serverUrl, rootId);
}, [post, serverUrl]);
}, [bottomSheetId, post, serverUrl]);
return (
<BaseOption

View File

@@ -11,18 +11,19 @@ import {t} from '@i18n';
import {dismissBottomSheet} from '@screens/navigation';
type CopyTextProps = {
bottomSheetId: typeof Screens[keyof typeof Screens];
isSaved: boolean;
postId: string;
}
const SaveOption = ({isSaved, postId}: CopyTextProps) => {
const SaveOption = ({bottomSheetId, isSaved, postId}: CopyTextProps) => {
const serverUrl = useServerUrl();
const onHandlePress = useCallback(async () => {
const remoteAction = isSaved ? deleteSavedPost : savePostPreference;
await dismissBottomSheet(Screens.POST_OPTIONS);
await dismissBottomSheet(bottomSheetId);
remoteAction(serverUrl, postId);
}, [postId, serverUrl]);
}, [bottomSheetId, postId, serverUrl]);
const id = isSaved ? t('mobile.post_info.unsave') : t('mobile.post_info.save');
const defaultMessage = isSaved ? 'Unsave' : 'Save';

View File

@@ -21,13 +21,14 @@ import {preventDoubleTap} from '@utils/tap';
import type PostModel from '@typings/database/models/servers/post';
type Props = {
bottomSheetId: typeof Screens[keyof typeof Screens];
bindings: AppBinding[];
post: PostModel;
serverUrl: string;
teamId: string;
}
const AppBindingsPostOptions = ({serverUrl, post, teamId, bindings}: Props) => {
const AppBindingsPostOptions = ({bottomSheetId, serverUrl, post, teamId, bindings}: Props) => {
const onCallResponse = useCallback((callResp: AppCallResponse, message: string) => {
postEphemeralCallResponseForPost(serverUrl, callResp, message, post);
}, [serverUrl, post]);
@@ -48,11 +49,11 @@ const AppBindingsPostOptions = ({serverUrl, post, teamId, bindings}: Props) => {
const onPress = useCallback(async (binding: AppBinding) => {
const submitPromise = handleBindingSubmit(binding);
await dismissBottomSheet(Screens.POST_OPTIONS);
await dismissBottomSheet(bottomSheetId);
const finish = await submitPromise;
await finish();
}, [handleBindingSubmit]);
}, [bottomSheetId, handleBindingSubmit]);
if (isSystemMessage(post)) {
return null;

View File

@@ -12,12 +12,13 @@ import {dismissBottomSheet} from '@screens/navigation';
import {showSnackBar} from '@utils/snack_bar';
type Props = {
bottomSheetId: typeof Screens[keyof typeof Screens];
sourceScreen: typeof Screens[keyof typeof Screens];
postMessage: string;
}
const CopyTextOption = ({postMessage, sourceScreen}: Props) => {
const CopyTextOption = ({bottomSheetId, postMessage, sourceScreen}: Props) => {
const handleCopyText = useCallback(async () => {
await dismissBottomSheet(Screens.POST_OPTIONS);
await dismissBottomSheet(bottomSheetId);
Clipboard.setString(postMessage);
showSnackBar({barType: SNACK_BAR_TYPE.MESSAGE_COPIED, sourceScreen});
}, [postMessage]);

View File

@@ -15,10 +15,11 @@ import {dismissBottomSheet} from '@screens/navigation';
import type PostModel from '@typings/database/models/servers/post';
type Props = {
bottomSheetId: typeof Screens[keyof typeof Screens];
combinedPost?: Post | PostModel;
post: PostModel;
}
const DeletePostOption = ({combinedPost, post}: Props) => {
const DeletePostOption = ({bottomSheetId, combinedPost, post}: Props) => {
const serverUrl = useServerUrl();
const {formatMessage} = useIntl();
@@ -36,12 +37,12 @@ const DeletePostOption = ({combinedPost, post}: Props) => {
text: formatMessage({id: 'post_info.del', defaultMessage: 'Delete'}),
style: 'destructive',
onPress: async () => {
await dismissBottomSheet(Screens.POST_OPTIONS);
await dismissBottomSheet(bottomSheetId);
deletePost(serverUrl, combinedPost || post);
},
}],
);
}, [post, combinedPost, serverUrl]);
}, [bottomSheetId, post, combinedPost, serverUrl]);
return (
<BaseOption

View File

@@ -14,15 +14,16 @@ import {dismissBottomSheet, showModal} from '@screens/navigation';
import type PostModel from '@typings/database/models/servers/post';
type Props = {
bottomSheetId: typeof Screens[keyof typeof Screens];
post: PostModel;
canDelete: boolean;
}
const EditOption = ({post, canDelete}: Props) => {
const EditOption = ({bottomSheetId, post, canDelete}: Props) => {
const intl = useIntl();
const theme = useTheme();
const onPress = useCallback(async () => {
await dismissBottomSheet(Screens.POST_OPTIONS);
await dismissBottomSheet(bottomSheetId);
const title = intl.formatMessage({id: 'mobile.edit_post.title', defaultMessage: 'Editing Message'});
const closeButton = CompassIcon.getImageSourceSync('close', 24, theme.sidebarHeaderTextColor);
@@ -38,7 +39,7 @@ const EditOption = ({post, canDelete}: Props) => {
},
};
showModal(Screens.EDIT_POST, title, passProps, options);
}, [post]);
}, [bottomSheetId, post]);
return (
<BaseOption

View File

@@ -14,24 +14,25 @@ import {dismissBottomSheet} from '@screens/navigation';
import type PostModel from '@typings/database/models/servers/post';
type Props = {
bottomSheetId: typeof Screens[keyof typeof Screens];
isCRTEnabled: boolean;
sourceScreen: typeof Screens[keyof typeof Screens];
post: PostModel;
teamId: string;
}
const MarkAsUnreadOption = ({isCRTEnabled, sourceScreen, post, teamId}: Props) => {
const MarkAsUnreadOption = ({bottomSheetId, isCRTEnabled, sourceScreen, post, teamId}: Props) => {
const serverUrl = useServerUrl();
const onPress = useCallback(async () => {
await dismissBottomSheet(Screens.POST_OPTIONS);
await dismissBottomSheet(bottomSheetId);
if (sourceScreen === Screens.THREAD && isCRTEnabled) {
const threadId = post.rootId || post.id;
markThreadAsUnread(serverUrl, teamId, threadId, post.id);
} else {
markPostAsUnread(serverUrl, post.id);
}
}, [sourceScreen, post, serverUrl, teamId]);
}, [bottomSheetId, sourceScreen, post, serverUrl, teamId]);
return (
<BaseOption

View File

@@ -11,17 +11,18 @@ import {t} from '@i18n';
import {dismissBottomSheet} from '@screens/navigation';
type PinChannelProps = {
bottomSheetId: typeof Screens[keyof typeof Screens];
isPostPinned: boolean;
postId: string;
}
const PinChannelOption = ({isPostPinned, postId}: PinChannelProps) => {
const PinChannelOption = ({bottomSheetId, isPostPinned, postId}: PinChannelProps) => {
const serverUrl = useServerUrl();
const onPress = useCallback(async () => {
await dismissBottomSheet(Screens.POST_OPTIONS);
await dismissBottomSheet(bottomSheetId);
togglePinPost(serverUrl, postId);
}, [postId, serverUrl]);
}, [bottomSheetId, postId, serverUrl]);
let defaultMessage;
let id;

View File

@@ -9,7 +9,7 @@ import {ITEM_HEIGHT} from '@components/option_item';
import {Screens} from '@constants';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import BottomSheet from '@screens/bottom_sheet';
import {dismissModal} from '@screens/navigation';
import {dismissBottomSheet} from '@screens/navigation';
import {isSystemMessage} from '@utils/post';
import AppBindingsPostOptions from './options/app_bindings_post_option';
@@ -50,7 +50,7 @@ const PostOptions = ({
const managedConfig = useManagedConfig<ManagedConfig>();
const close = () => {
dismissModal({componentId});
return dismissBottomSheet(Screens.POST_OPTIONS);
};
useNavButtonPressed(POST_OPTIONS_BUTTON, componentId, close, []);
@@ -74,53 +74,74 @@ const PostOptions = ({
const renderContent = () => {
return (
<>
{canAddReaction && <ReactionBar postId={post.id}/>}
{canReply && sourceScreen !== Screens.THREAD && <ReplyOption post={post}/>}
{canAddReaction &&
<ReactionBar
bottomSheetId={Screens.POST_OPTIONS}
postId={post.id}
/>
}
{canReply && sourceScreen !== Screens.THREAD &&
<ReplyOption
bottomSheetId={Screens.POST_OPTIONS}
post={post}
/>
}
{shouldRenderFollow &&
<FollowThreadOption thread={thread}/>
<FollowThreadOption
bottomSheetId={Screens.POST_OPTIONS}
thread={thread}
/>
}
{canMarkAsUnread && !isSystemPost &&
<MarkAsUnreadOption
bottomSheetId={Screens.POST_OPTIONS}
post={post}
sourceScreen={sourceScreen}
/>
}
{canCopyPermalink &&
<CopyPermalinkOption
bottomSheetId={Screens.POST_OPTIONS}
post={post}
sourceScreen={sourceScreen}
/>
}
{!isSystemPost &&
<SaveOption
bottomSheetId={Screens.POST_OPTIONS}
isSaved={isSaved}
postId={post.id}
/>
}
{Boolean(canCopyText && post.message) &&
<CopyTextOption
bottomSheetId={Screens.POST_OPTIONS}
postMessage={post.message}
sourceScreen={sourceScreen}
/>}
{canPin &&
<PinChannelOption
bottomSheetId={Screens.POST_OPTIONS}
isPostPinned={post.isPinned}
postId={post.id}
/>
}
{canEdit &&
<EditOption
bottomSheetId={Screens.POST_OPTIONS}
post={post}
canDelete={canDelete}
/>
}
{canDelete &&
<DeletePostOption
bottomSheetId={Screens.POST_OPTIONS}
combinedPost={combinedPost}
post={post}
/>}
{shouldShowBindings &&
<AppBindingsPostOptions
bottomSheetId={Screens.POST_OPTIONS}
post={post}
serverUrl={serverUrl}
bindings={bindings}

View File

@@ -26,6 +26,7 @@ import PickReaction from './pick_reaction';
import Reaction from './reaction';
type QuickReactionProps = {
bottomSheetId: typeof Screens[keyof typeof Screens];
recentEmojis: string[];
postId: string;
};
@@ -43,7 +44,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
};
});
const ReactionBar = ({recentEmojis = [], postId}: QuickReactionProps) => {
const ReactionBar = ({bottomSheetId, recentEmojis = [], postId}: QuickReactionProps) => {
const theme = useTheme();
const intl = useIntl();
const {width} = useWindowDimensions();
@@ -54,12 +55,12 @@ const ReactionBar = ({recentEmojis = [], postId}: QuickReactionProps) => {
const isTablet = useIsTablet();
const handleEmojiPress = useCallback(async (emoji: string) => {
await dismissBottomSheet(Screens.POST_OPTIONS);
await dismissBottomSheet(bottomSheetId);
addReaction(serverUrl, postId, emoji);
}, [postId, serverUrl]);
}, [bottomSheetId, postId, serverUrl]);
const openEmojiPicker = useCallback(async () => {
await dismissBottomSheet(Screens.POST_OPTIONS);
await dismissBottomSheet(bottomSheetId);
const closeButton = CompassIcon.getImageSourceSync('close', 24, theme.sidebarHeaderTextColor);
const screen = Screens.EMOJI_PICKER;
@@ -67,7 +68,7 @@ const ReactionBar = ({recentEmojis = [], postId}: QuickReactionProps) => {
const passProps = {closeButton, onEmojiPress: handleEmojiPress};
showModal(screen, title, passProps);
}, [intl, theme]);
}, [bottomSheetId, intl, theme]);
let containerSize = LARGE_CONTAINER_SIZE;
let iconSize = LARGE_ICON_SIZE;

View File

@@ -13,20 +13,21 @@ import {dismissBottomSheet} from '@screens/navigation';
import type ThreadModel from '@typings/database/models/servers/thread';
type Props = {
bottomSheetId: typeof Screens[keyof typeof Screens];
teamId: string;
thread: ThreadModel;
}
const MarkAsUnreadOption = ({teamId, thread}: Props) => {
const MarkAsUnreadOption = ({bottomSheetId, teamId, thread}: Props) => {
const serverUrl = useServerUrl();
const onHandlePress = useCallback(async () => {
await dismissBottomSheet(Screens.THREAD_OPTIONS);
await dismissBottomSheet(bottomSheetId);
if (thread.unreadReplies) {
markThreadAsRead(serverUrl, teamId, thread.id);
} else {
markThreadAsUnread(serverUrl, teamId, thread.id, thread.id);
}
}, [serverUrl, teamId, thread]);
}, [bottomSheetId, serverUrl, teamId, thread]);
const id = thread.unreadReplies ? t('global_threads.options.mark_as_read') : t('mobile.post_info.mark_unread');
const defaultMessage = thread.unreadReplies ? 'Mark as Read' : 'Mark as Unread';

View File

@@ -12,16 +12,17 @@ import {t} from '@i18n';
import {dismissBottomSheet} from '@screens/navigation';
type Props = {
bottomSheetId: typeof Screens[keyof typeof Screens];
threadId: string;
}
const OpenInChannelOption = ({threadId}: Props) => {
const OpenInChannelOption = ({bottomSheetId, threadId}: Props) => {
const intl = useIntl();
const serverUrl = useServerUrl();
const onHandlePress = useCallback(async () => {
await dismissBottomSheet(Screens.THREAD_OPTIONS);
await dismissBottomSheet(bottomSheetId);
showPermalink(serverUrl, '', threadId);
}, [intl, serverUrl, threadId]);
}, [bottomSheetId, intl, serverUrl, threadId]);
return (
<BaseOption

View File

@@ -14,7 +14,7 @@ import {useTheme} from '@context/theme';
import {useIsTablet} from '@hooks/device';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import BottomSheet from '@screens/bottom_sheet';
import {dismissModal} from '@screens/navigation';
import {dismissBottomSheet} from '@screens/navigation';
import {bottomSheetSnapPoint} from '@utils/helpers';
import {makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
@@ -63,31 +63,35 @@ const ThreadOptions = ({
const style = getStyleSheet(theme);
const close = () => {
dismissModal({componentId});
return dismissBottomSheet(Screens.THREAD_OPTIONS);
};
useNavButtonPressed(THREAD_OPTIONS_BUTTON, componentId, close, []);
const options = [
<ReplyOption
bottomSheetId={Screens.THREAD_OPTIONS}
key='reply'
location={Screens.THREAD_OPTIONS}
post={post}
/>,
<FollowThreadOption
bottomSheetId={Screens.THREAD_OPTIONS}
key='unfollow'
thread={thread}
/>,
<OpenInChannelOption
bottomSheetId={Screens.THREAD_OPTIONS}
key='open-in-channel'
threadId={thread.id}
/>,
<MarkAsUnreadOption
bottomSheetId={Screens.THREAD_OPTIONS}
key='mark-as-unread'
teamId={team.id}
thread={thread}
/>,
<SaveOption
bottomSheetId={Screens.THREAD_OPTIONS}
key='save'
isSaved={isSaved}
postId={thread.id}
@@ -99,6 +103,7 @@ const ThreadOptions = ({
if (canCopyLink) {
options.push(
<CopyPermalinkOption
bottomSheetId={Screens.THREAD_OPTIONS}
key='copy-link'
post={post}
sourceScreen={Screens.THREAD_OPTIONS}