copy header text in channel info implemented (#7605)

* copy header text in channel info implemented

* changes fixed
This commit is contained in:
Tanmay Vardhaman Thole 2023-10-30 16:43:52 +05:30 committed by GitHub
parent 1199c3772c
commit d8d607257f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 139 additions and 24 deletions

View file

@ -71,6 +71,7 @@ type MarkdownProps = {
textStyles?: MarkdownTextStyles;
theme: Theme;
value?: string;
onLinkLongPress?: (url?: string) => void;
}
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
@ -133,7 +134,7 @@ const Markdown = ({
enableInlineLatex, enableLatex, maxNodes,
imagesMetadata, isEdited, isReplyPost, isSearchResult, layoutHeight, layoutWidth,
location, mentionKeys, minimumHashtagLength = 3, onPostPress, postId, searchPatterns,
textStyles = {}, theme, value = '', baseParagraphStyle,
textStyles = {}, theme, value = '', baseParagraphStyle, onLinkLongPress,
}: MarkdownProps) => {
const style = getStyleSheet(theme);
const managedConfig = useManagedConfig<ManagedConfig>();
@ -402,7 +403,10 @@ const Markdown = ({
const renderLink = ({children, href}: {children: ReactElement; href: string}) => {
return (
<MarkdownLink href={href}>
<MarkdownLink
href={href}
onLinkLongPress={onLinkLongPress}
>
{children}
</MarkdownLink>
);

View file

@ -23,6 +23,7 @@ type MarkdownLinkProps = {
experimentalNormalizeMarkdownLinks: string;
href: string;
siteURL: string;
onLinkLongPress?: (url?: string) => void;
}
const style = StyleSheet.create({
@ -44,7 +45,7 @@ const parseLinkLiteral = (literal: string) => {
return parsed.href;
};
const MarkdownLink = ({children, experimentalNormalizeMarkdownLinks, href, siteURL}: MarkdownLinkProps) => {
const MarkdownLink = ({children, experimentalNormalizeMarkdownLinks, href, siteURL, onLinkLongPress}: MarkdownLinkProps) => {
const intl = useIntl();
const {bottom} = useSafeAreaInsets();
const managedConfig = useManagedConfig<ManagedConfig>();
@ -109,6 +110,11 @@ const MarkdownLink = ({children, experimentalNormalizeMarkdownLinks, href, siteU
const handleLongPress = useCallback(() => {
if (managedConfig?.copyAndPasteProtection !== 'true') {
if (onLinkLongPress) {
onLinkLongPress(href);
return;
}
const renderContent = () => {
return (
<View
@ -145,7 +151,7 @@ const MarkdownLink = ({children, experimentalNormalizeMarkdownLinks, href, siteU
theme,
});
}
}, [managedConfig, intl, bottom, theme]);
}, [managedConfig, intl, bottom, theme, onLinkLongPress]);
const renderChildren = experimentalNormalizeMarkdownLinks ? parseChildren() : children;

View file

@ -1,18 +1,29 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {useManagedConfig} from '@mattermost/react-native-emm';
import Clipboard from '@react-native-clipboard/clipboard';
import moment from 'moment';
import React, {useMemo} from 'react';
import {Text, View} from 'react-native';
import React, {useCallback, useMemo} from 'react';
import {useIntl} from 'react-intl';
import {Platform, StyleSheet, Text, View} from 'react-native';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import CustomStatusExpiry from '@components/custom_status/custom_status_expiry';
import Emoji from '@components/emoji';
import FormattedDate from '@components/formatted_date';
import FormattedText from '@components/formatted_text';
import Markdown from '@components/markdown';
import SlideUpPanelItem, {ITEM_HEIGHT} from '@components/slide_up_panel_item';
import TouchableWithFeedback from '@components/touchable_with_feedback';
import {Screens} from '@constants';
import {SNACK_BAR_TYPE} from '@constants/snack_bar';
import {ANDROID_33, OS_VERSION} from '@constants/versions';
import {useTheme} from '@context/theme';
import {bottomSheet, dismissBottomSheet} from '@screens/navigation';
import {bottomSheetSnapPoint} from '@utils/helpers';
import {getMarkdownBlockStyles, getMarkdownTextStyles} from '@utils/markdown';
import {showSnackBar} from '@utils/snack_bar';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
@ -66,8 +77,30 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
},
}));
const style = StyleSheet.create({
bottomSheet: {
flex: 1,
},
});
const headerTestId = 'channel_info.extra.header';
const onCopy = async (text: string, isLink?: boolean) => {
Clipboard.setString(text);
await dismissBottomSheet();
if ((Platform.OS === OS_VERSION.ANDROID && Number(Platform.Version) < ANDROID_33) || Platform.OS === OS_VERSION.IOS) {
showSnackBar({
barType: isLink ? SNACK_BAR_TYPE.LINK_COPIED : SNACK_BAR_TYPE.TEXT_COPIED,
});
}
};
const Extra = ({channelId, createdAt, createdBy, customStatus, header, isCustomStatusEnabled}: Props) => {
const intl = useIntl();
const {bottom} = useSafeAreaInsets();
const theme = useTheme();
const managedConfig = useManagedConfig<ManagedConfig>();
const styles = getStyleSheet(theme);
const blockStyles = getMarkdownBlockStyles(theme);
const textStyles = getMarkdownTextStyles(theme);
@ -81,6 +114,70 @@ const Extra = ({channelId, createdAt, createdBy, customStatus, header, isCustomS
),
}), [createdAt, createdBy, theme]);
const handleLongPress = useCallback((url?: string) => {
if (managedConfig?.copyAndPasteProtection !== 'true') {
const renderContent = () => (
<View
testID={`${headerTestId}.bottom_sheet`}
style={style.bottomSheet}
>
<SlideUpPanelItem
leftIcon='content-copy'
onPress={() => {
onCopy(header!);
}}
testID={`${headerTestId}.bottom_sheet.copy_header_text`}
text={intl.formatMessage({
id: 'mobile.markdown.copy_header',
defaultMessage: 'Copy header text',
})}
/>
{Boolean(url) && (
<SlideUpPanelItem
leftIcon='link-variant'
onPress={() => {
onCopy(url!, true);
}}
testID={`${headerTestId}.bottom_sheet.copy_url`}
text={intl.formatMessage({
id: 'mobile.markdown.link.copy_url',
defaultMessage: 'Copy URL',
})}
/>
)}
<SlideUpPanelItem
destructive={true}
leftIcon='cancel'
onPress={() => {
dismissBottomSheet();
}}
testID={`${headerTestId}.bottom_sheet.cancel`}
text={intl.formatMessage({
id: 'mobile.post.cancel',
defaultMessage: 'Cancel',
})}
/>
</View>
);
bottomSheet({
closeButtonId: 'close-markdown-link',
renderContent,
snapPoints: [1, bottomSheetSnapPoint(url ? 3 : 2, ITEM_HEIGHT, bottom)],
title: intl.formatMessage({id: 'post.options.title', defaultMessage: 'Options'}),
theme,
});
}
}, [
header,
bottom,
theme,
intl.formatMessage,
managedConfig?.copyAndPasteProtection,
]);
const touchableHandleLongPress = useCallback(() => handleLongPress(), [handleLongPress]);
return (
<View style={styles.container}>
{isCustomStatusEnabled && Boolean(customStatus) &&
@ -131,25 +228,32 @@ const Extra = ({channelId, createdAt, createdBy, customStatus, header, isCustomS
id='channel_info.header'
defaultMessage='Header:'
style={styles.extraHeading}
testID='channel_info.extra.header'
/>
<Markdown
channelId={channelId}
baseTextStyle={styles.header}
blockStyles={blockStyles}
disableBlockQuote={true}
disableCodeBlock={true}
disableGallery={true}
disableHeading={true}
disableTables={true}
location={Screens.CHANNEL_INFO}
textStyles={textStyles}
layoutHeight={48}
layoutWidth={100}
theme={theme}
imagesMetadata={headerMetadata}
value={header}
testID={headerTestId}
/>
<TouchableWithFeedback
type='opacity'
activeOpacity={0.8}
onLongPress={touchableHandleLongPress}
>
<Markdown
channelId={channelId}
baseTextStyle={styles.header}
blockStyles={blockStyles}
disableBlockQuote={true}
disableCodeBlock={true}
disableGallery={true}
disableHeading={true}
disableTables={true}
location={Screens.CHANNEL_INFO}
textStyles={textStyles}
layoutHeight={48}
layoutWidth={100}
theme={theme}
imagesMetadata={headerMetadata}
value={header}
onLinkLongPress={handleLongPress}
/>
</TouchableWithFeedback>
</View>
}
{Boolean(createdAt && createdBy) &&

View file

@ -613,6 +613,7 @@
"mobile.managed.settings": "Go to settings",
"mobile.markdown.code.copy_code": "Copy Code",
"mobile.markdown.code.plusMoreLines": "+{count, number} more {count, plural, one {line} other {lines}}",
"mobile.markdown.copy_header": "Copy header text",
"mobile.markdown.image.too_large": "Image exceeds max dimensions of {maxWidth} by {maxHeight}:",
"mobile.markdown.link.copy_url": "Copy URL",
"mobile.mention.copy_mention": "Copy Mention",