// 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, {useCallback, useMemo} from 'react'; import {useIntl, defineMessages} from 'react-intl'; import {Platform, StyleSheet, Text, View} from 'react-native'; 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, isEmail} from '@utils/helpers'; import {isTelHref} from '@utils/phone_number'; import {showSnackBar} from '@utils/snack_bar'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; import {typography} from '@utils/typography'; type Props = { channelId: string; createdAt: number; createdBy: string; customStatus?: UserCustomStatus; header?: string; isCustomStatusEnabled: boolean; } const headerMetadata = {header: {width: 1, height: 1}}; const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({ container: { marginBottom: 20, }, item: { marginTop: 16, }, extraHeading: { color: changeOpacity(theme.centerChannelColor, 0.56), marginBottom: 8, ...typography('Body', 75), }, header: { color: theme.centerChannelColor, ...typography('Body', 200), fontWeight: undefined, }, created: { color: changeOpacity(theme.centerChannelColor, 0.48), ...typography('Body', 75), }, customStatus: { alignItems: 'center', flexDirection: 'row', }, customStatusEmoji: { marginRight: 10, }, customStatusLabel: { color: theme.centerChannelColor, marginRight: 8, ...typography('Body', 200), }, customStatusExpiry: { color: changeOpacity(theme.centerChannelColor, 0.64), ...typography('Body', 75), }, })); const style = StyleSheet.create({ bottomSheet: { flex: 1, }, }); const headerTestId = 'channel_info.extra.header'; const messages = defineMessages({ copyEmail: { id: 'mobile.markdown.link.copy_email', defaultMessage: 'Copy Email Address', }, copyPhone: { id: 'mobile.markdown.link.copy_phone', defaultMessage: 'Copy Phone Number', }, copyURL: { id: 'mobile.markdown.link.copy_url', defaultMessage: 'Copy URL', }, }); 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 theme = useTheme(); const managedConfig = useManagedConfig(); const styles = getStyleSheet(theme); const created = useMemo(() => ({ user: createdBy, date: ( ), }), [createdAt, createdBy, styles.created]); const handleLongPress = useCallback((url?: string) => { if (managedConfig?.copyAndPasteProtection !== 'true') { const cleanUrl = url?.replace(/^(mailto:|tel:)/i, '') || ''; let copyMessage = messages.copyURL; if (url && isTelHref(url)) { copyMessage = messages.copyPhone; } else if (isEmail(cleanUrl)) { copyMessage = messages.copyEmail; } const renderContent = () => ( { onCopy(header!); }} testID={`${headerTestId}.bottom_sheet.copy_header_text`} text={intl.formatMessage({ id: 'mobile.markdown.copy_header', defaultMessage: 'Copy header text', })} /> {Boolean(url) && ( { onCopy(cleanUrl, true); }} testID={`${headerTestId}.bottom_sheet.copy_url`} text={intl.formatMessage(copyMessage)} /> )} { dismissBottomSheet(); }} testID={`${headerTestId}.bottom_sheet.cancel`} text={intl.formatMessage({ id: 'mobile.post.cancel', defaultMessage: 'Cancel', })} /> ); bottomSheet(renderContent, [1, bottomSheetSnapPoint(url ? 3 : 2, ITEM_HEIGHT)]); } }, [managedConfig?.copyAndPasteProtection, intl, header]); const touchableHandleLongPress = useCallback(() => handleLongPress(), [handleLongPress]); return ( {isCustomStatusEnabled && Boolean(customStatus) && {Boolean(customStatus?.emoji) && } {Boolean(customStatus?.text) && {customStatus?.text} } {Boolean(customStatus?.duration) && } } {Boolean(header) && } {Boolean(createdAt && createdBy) && } {Boolean(createdAt && !createdBy) && } ); }; export default Extra;