2021-11-16 15:59:58 +00:00
|
|
|
import React, { useContext, useState } from 'react';
|
2021-09-13 20:41:05 +00:00
|
|
|
import { StyleSheet, Text, View } from 'react-native';
|
|
|
|
import moment from 'moment';
|
|
|
|
import { dequal } from 'dequal';
|
2022-05-31 16:08:18 +00:00
|
|
|
import FastImage from 'react-native-fast-image';
|
2021-09-13 20:41:05 +00:00
|
|
|
|
|
|
|
import Touchable from './Touchable';
|
|
|
|
import Markdown from '../markdown';
|
2022-06-06 14:17:51 +00:00
|
|
|
import openLink from '../../lib/methods/helpers/openLink';
|
2021-09-13 20:41:05 +00:00
|
|
|
import sharedStyles from '../../views/Styles';
|
2022-04-07 14:10:03 +00:00
|
|
|
import { themes } from '../../lib/constants';
|
2021-09-13 20:41:05 +00:00
|
|
|
import MessageContext from './Context';
|
2022-06-06 14:17:51 +00:00
|
|
|
import { fileDownloadAndPreview } from './helpers/fileDownload';
|
2022-05-15 18:29:07 +00:00
|
|
|
import { IAttachment, TGetCustomEmoji } from '../../definitions';
|
2021-11-16 15:59:58 +00:00
|
|
|
import RCActivityIndicator from '../ActivityIndicator';
|
2022-03-21 20:44:06 +00:00
|
|
|
import Attachments from './Attachments';
|
2022-04-12 16:27:05 +00:00
|
|
|
import { TSupportedThemes, useTheme } from '../../theme';
|
2022-04-07 13:13:19 +00:00
|
|
|
import { formatAttachmentUrl } from '../../lib/methods/helpers/formatAttachmentUrl';
|
2022-05-15 18:29:07 +00:00
|
|
|
import messageStyles from './styles';
|
2021-09-13 20:41:05 +00:00
|
|
|
|
|
|
|
const styles = StyleSheet.create({
|
|
|
|
button: {
|
|
|
|
flex: 1,
|
|
|
|
flexDirection: 'row',
|
|
|
|
alignItems: 'center',
|
2022-03-21 20:44:06 +00:00
|
|
|
marginVertical: 4,
|
2021-09-13 20:41:05 +00:00
|
|
|
alignSelf: 'flex-start',
|
2022-03-21 20:44:06 +00:00
|
|
|
borderLeftWidth: 2
|
2021-09-13 20:41:05 +00:00
|
|
|
},
|
|
|
|
attachmentContainer: {
|
|
|
|
flex: 1,
|
|
|
|
borderRadius: 4,
|
|
|
|
flexDirection: 'column',
|
2022-03-21 20:44:06 +00:00
|
|
|
paddingVertical: 4,
|
|
|
|
paddingLeft: 8
|
2021-09-13 20:41:05 +00:00
|
|
|
},
|
2021-11-16 15:59:58 +00:00
|
|
|
backdrop: {
|
|
|
|
...StyleSheet.absoluteFillObject
|
|
|
|
},
|
2021-09-13 20:41:05 +00:00
|
|
|
authorContainer: {
|
|
|
|
flex: 1,
|
|
|
|
flexDirection: 'row',
|
2022-03-21 20:44:06 +00:00
|
|
|
alignItems: 'center',
|
|
|
|
marginBottom: 8
|
2021-09-13 20:41:05 +00:00
|
|
|
},
|
|
|
|
author: {
|
|
|
|
fontSize: 16,
|
2022-10-04 13:05:40 +00:00
|
|
|
...sharedStyles.textMedium,
|
|
|
|
flexShrink: 1
|
2021-09-13 20:41:05 +00:00
|
|
|
},
|
|
|
|
fieldsContainer: {
|
|
|
|
flex: 1,
|
|
|
|
flexWrap: 'wrap',
|
|
|
|
flexDirection: 'row'
|
|
|
|
},
|
|
|
|
fieldContainer: {
|
|
|
|
flexDirection: 'column',
|
|
|
|
padding: 10
|
|
|
|
},
|
|
|
|
fieldTitle: {
|
|
|
|
fontSize: 14,
|
|
|
|
...sharedStyles.textSemibold
|
|
|
|
},
|
|
|
|
fieldValue: {
|
|
|
|
fontSize: 14,
|
|
|
|
...sharedStyles.textRegular
|
|
|
|
},
|
|
|
|
marginTop: {
|
|
|
|
marginTop: 4
|
|
|
|
},
|
|
|
|
marginBottom: {
|
|
|
|
marginBottom: 4
|
|
|
|
},
|
|
|
|
image: {
|
|
|
|
height: 200,
|
|
|
|
flex: 1,
|
|
|
|
borderTopLeftRadius: 4,
|
|
|
|
borderTopRightRadius: 4,
|
|
|
|
marginBottom: 1
|
|
|
|
},
|
|
|
|
title: {
|
|
|
|
flex: 1,
|
|
|
|
fontSize: 16,
|
|
|
|
marginBottom: 3,
|
|
|
|
...sharedStyles.textMedium
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
interface IMessageReply {
|
2022-01-11 13:51:48 +00:00
|
|
|
attachment: IAttachment;
|
2022-03-02 14:18:01 +00:00
|
|
|
timeFormat?: string;
|
2021-09-13 20:41:05 +00:00
|
|
|
index: number;
|
2022-02-17 15:27:01 +00:00
|
|
|
getCustomEmoji: TGetCustomEmoji;
|
2021-09-13 20:41:05 +00:00
|
|
|
}
|
|
|
|
|
2022-04-12 16:27:05 +00:00
|
|
|
const Title = React.memo(
|
|
|
|
({ attachment, timeFormat, theme }: { attachment: IAttachment; timeFormat?: string; theme: TSupportedThemes }) => {
|
|
|
|
const time = attachment.message_link && attachment.ts ? moment(attachment.ts).format(timeFormat) : null;
|
|
|
|
return (
|
|
|
|
<View style={styles.authorContainer}>
|
|
|
|
{attachment.author_name ? (
|
2022-10-04 13:05:40 +00:00
|
|
|
<Text numberOfLines={1} style={[styles.author, { color: themes[theme].auxiliaryTintColor }]}>
|
|
|
|
{attachment.author_name}
|
|
|
|
</Text>
|
2022-04-12 16:27:05 +00:00
|
|
|
) : null}
|
2022-05-23 16:37:56 +00:00
|
|
|
{time ? <Text style={[messageStyles.time, { color: themes[theme].auxiliaryText }]}>{time}</Text> : null}
|
2022-04-12 16:27:05 +00:00
|
|
|
{attachment.title ? <Text style={[styles.title, { color: themes[theme].bodyText }]}>{attachment.title}</Text> : null}
|
|
|
|
</View>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
);
|
2021-09-13 20:41:05 +00:00
|
|
|
|
|
|
|
const Description = React.memo(
|
2022-04-12 16:27:05 +00:00
|
|
|
({
|
|
|
|
attachment,
|
|
|
|
getCustomEmoji,
|
|
|
|
theme
|
|
|
|
}: {
|
|
|
|
attachment: IAttachment;
|
|
|
|
getCustomEmoji: TGetCustomEmoji;
|
|
|
|
theme: TSupportedThemes;
|
|
|
|
}) => {
|
2022-10-21 18:27:55 +00:00
|
|
|
const { user } = useContext(MessageContext);
|
2021-09-13 20:41:05 +00:00
|
|
|
const text = attachment.text || attachment.title;
|
2022-04-11 18:01:43 +00:00
|
|
|
|
2021-09-13 20:41:05 +00:00
|
|
|
if (!text) {
|
|
|
|
return null;
|
|
|
|
}
|
2022-04-11 18:01:43 +00:00
|
|
|
|
2022-03-21 20:44:06 +00:00
|
|
|
return (
|
|
|
|
<Markdown
|
|
|
|
msg={text}
|
|
|
|
style={[{ color: themes[theme].auxiliaryTintColor, fontSize: 14 }]}
|
|
|
|
username={user.username}
|
|
|
|
getCustomEmoji={getCustomEmoji}
|
2022-07-04 18:10:14 +00:00
|
|
|
theme={theme}
|
2022-03-21 20:44:06 +00:00
|
|
|
/>
|
|
|
|
);
|
2021-09-13 20:41:05 +00:00
|
|
|
},
|
|
|
|
(prevProps, nextProps) => {
|
|
|
|
if (prevProps.attachment.text !== nextProps.attachment.text) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (prevProps.attachment.title !== nextProps.attachment.title) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (prevProps.theme !== nextProps.theme) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
const UrlImage = React.memo(
|
2022-04-01 21:52:38 +00:00
|
|
|
({ image }: { image?: string }) => {
|
2022-04-11 18:01:43 +00:00
|
|
|
const { baseUrl, user } = useContext(MessageContext);
|
|
|
|
|
2021-09-13 20:41:05 +00:00
|
|
|
if (!image) {
|
|
|
|
return null;
|
|
|
|
}
|
2022-04-11 18:01:43 +00:00
|
|
|
|
2021-09-13 20:41:05 +00:00
|
|
|
image = image.includes('http') ? image : `${baseUrl}/${image}?rc_uid=${user.id}&rc_token=${user.token}`;
|
|
|
|
return <FastImage source={{ uri: image }} style={styles.image} resizeMode={FastImage.resizeMode.cover} />;
|
|
|
|
},
|
|
|
|
(prevProps, nextProps) => prevProps.image === nextProps.image
|
|
|
|
);
|
|
|
|
|
|
|
|
const Fields = React.memo(
|
2022-04-12 16:27:05 +00:00
|
|
|
({
|
|
|
|
attachment,
|
|
|
|
theme,
|
|
|
|
getCustomEmoji
|
|
|
|
}: {
|
|
|
|
attachment: IAttachment;
|
|
|
|
theme: TSupportedThemes;
|
|
|
|
getCustomEmoji: TGetCustomEmoji;
|
|
|
|
}) => {
|
2022-10-21 18:27:55 +00:00
|
|
|
const { user } = useContext(MessageContext);
|
2022-04-11 18:01:43 +00:00
|
|
|
|
2021-09-13 20:41:05 +00:00
|
|
|
if (!attachment.fields) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<View style={styles.fieldsContainer}>
|
|
|
|
{attachment.fields.map(field => (
|
|
|
|
<View key={field.title} style={[styles.fieldContainer, { width: field.short ? '50%' : '100%' }]}>
|
|
|
|
<Text style={[styles.fieldTitle, { color: themes[theme].bodyText }]}>{field.title}</Text>
|
2022-10-21 18:27:55 +00:00
|
|
|
<Markdown msg={field?.value || ''} username={user.username} getCustomEmoji={getCustomEmoji} theme={theme} />
|
2021-09-13 20:41:05 +00:00
|
|
|
</View>
|
|
|
|
))}
|
|
|
|
</View>
|
|
|
|
);
|
|
|
|
},
|
|
|
|
(prevProps, nextProps) =>
|
|
|
|
dequal(prevProps.attachment.fields, nextProps.attachment.fields) && prevProps.theme === nextProps.theme
|
|
|
|
);
|
|
|
|
|
|
|
|
const Reply = React.memo(
|
feat: add media auto-download (#5076)
* feat: media auto-download view
* media auto download view completed and saving the settings in mmkv
* audio download preference
* audio auto download when the user who sent the audio is the same logged on mobile
* creation of isAutoDownloadEnabled, evaluate hist hook, Image Full Size preload done
* minor tweak audio show play button after download
* refactor audioFile to handleMediaDownload and fixed the audio download
* desestructured params to download too
* image download and autoDownload, algo fix the formatAttachmentUrl to show the image from local
* add the possibility to cancel image download and clear local images
* refactor blur component
* video download and auto download, also keeped the behavior to download unsuportted videos to the gallery
* add the possibility to start downloading a video, then exit the room, back again to room and cancel the video previously downloading
* remove the custom hook for autoDownload
* remove blurcomponent, fix the blur style in image.tsx, minor tweak video function name
* send messageId to video
* introducing the reducer to keep the downloads in progress
* create a media download selector
* remove all the redux stuff and do the same as file upload
* video download behavior
* done for image and audio
* fix the try catch download media
* clean up
* image container uiKit
* fix lint
* change rn-fetch-blob to expo-filesystem
* add pt-br
* pass the correct message id when there is an attachment on reply
* refactor some changes requested
* fix audio and move the netInfo from autoDownloadPreference to redux
* variable isAutoDownloadEnable name and handleMediaDownload getExtension
* message/Image refactored, change the component to show the image from FastImage to Image
* refactor handleMediaDownload and deleteMedia
* minor tweak
* refactor audio
* refactor video
* fix the type on the messagesView(the view of files)
* minor tweak
* fix the name of searchMediaFIleAsync's result
* minor tweak, add the default behavior, add the OFF as label
* minor tweaks
* verify if the media auto download exists on settings view
* fix media auto download view layout and minor tweak wifi
* avoid auto download from reply
* minor tweak at comment
* tweak list.section
* change the name to netInfoState and Local_document_directory
* remove mediaType and refactor audio and image
* separate blurview
* thumbnail video and video behavior
* add Audio to i18n and minor tweak
* set the blur as always dark and add the possibility to overlay
* don't need to controle the filepath in the view
* fix the loading in image and video at begin
* save the file with a similar filename as expected
* removed the necessity of messageId or id
* minor tweak
* switch useLayoutEffect to useEffect
* avoid onpress do some edge case because of cached at video
* minor tweak
* tweak at audio comment extension
* minor tweak type userpreferences
* remove test id from mediaAutoDownloadView
* change action's name to SET_NET_INFO_STATE
* caching and deleting video's thumbnails
* remove generate thumbnail
* minor tweak in image
* update camera-roll and save the file from local url
* remove local_cache_directory and deleteThumbnail
* update blur to fix error on android
* fix blur is hiding the file description
* avoid download unsupported video
* return void when it is loading the audio
2023-08-07 14:02:30 +00:00
|
|
|
({ attachment, timeFormat, index, getCustomEmoji }: IMessageReply) => {
|
2021-11-16 15:59:58 +00:00
|
|
|
const [loading, setLoading] = useState(false);
|
2022-04-01 21:52:38 +00:00
|
|
|
const { theme } = useTheme();
|
2022-04-11 18:01:43 +00:00
|
|
|
const { baseUrl, user, jumpToMessage } = useContext(MessageContext);
|
2021-11-16 15:59:58 +00:00
|
|
|
|
2021-09-13 20:41:05 +00:00
|
|
|
if (!attachment) {
|
|
|
|
return null;
|
|
|
|
}
|
2022-03-21 20:44:06 +00:00
|
|
|
|
2021-11-16 15:59:58 +00:00
|
|
|
const onPress = async () => {
|
2021-09-13 20:41:05 +00:00
|
|
|
let url = attachment.title_link || attachment.author_link;
|
|
|
|
if (attachment.message_link) {
|
|
|
|
return jumpToMessage(attachment.message_link);
|
|
|
|
}
|
|
|
|
if (!url) {
|
|
|
|
return;
|
|
|
|
}
|
2022-02-07 18:44:04 +00:00
|
|
|
if (attachment.type === 'file' && attachment.title_link) {
|
2021-11-16 15:59:58 +00:00
|
|
|
setLoading(true);
|
|
|
|
url = formatAttachmentUrl(attachment.title_link, user.id, user.token, baseUrl);
|
|
|
|
await fileDownloadAndPreview(url, attachment);
|
|
|
|
setLoading(false);
|
|
|
|
return;
|
2021-09-13 20:41:05 +00:00
|
|
|
}
|
|
|
|
openLink(url, theme);
|
|
|
|
};
|
|
|
|
|
2022-03-21 20:44:06 +00:00
|
|
|
let { borderColor } = themes[theme];
|
|
|
|
if (attachment.color) {
|
|
|
|
borderColor = attachment.color;
|
2021-09-13 20:41:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
2023-03-23 22:47:05 +00:00
|
|
|
{/* The testID is to test properly quoted messages using it as ancestor */}
|
2021-09-13 20:41:05 +00:00
|
|
|
<Touchable
|
2023-03-23 22:47:05 +00:00
|
|
|
testID={`reply-${attachment?.author_name}-${attachment?.text}`}
|
2021-09-13 20:41:05 +00:00
|
|
|
onPress={onPress}
|
|
|
|
style={[
|
|
|
|
styles.button,
|
|
|
|
index > 0 && styles.marginTop,
|
|
|
|
attachment.description && styles.marginBottom,
|
|
|
|
{
|
|
|
|
borderColor
|
|
|
|
}
|
|
|
|
]}
|
2021-11-16 15:59:58 +00:00
|
|
|
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
2022-08-08 21:02:08 +00:00
|
|
|
disabled={loading}
|
|
|
|
>
|
2021-09-13 20:41:05 +00:00
|
|
|
<View style={styles.attachmentContainer}>
|
|
|
|
<Title attachment={attachment} timeFormat={timeFormat} theme={theme} />
|
2023-03-08 14:20:01 +00:00
|
|
|
<Description attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} />
|
|
|
|
<UrlImage image={attachment.thumb_url} />
|
2022-03-21 20:44:06 +00:00
|
|
|
<Attachments
|
|
|
|
attachments={attachment.attachments}
|
|
|
|
getCustomEmoji={getCustomEmoji}
|
|
|
|
timeFormat={timeFormat}
|
|
|
|
style={[{ color: themes[theme].auxiliaryTintColor, fontSize: 14, marginBottom: 8 }]}
|
|
|
|
isReply
|
|
|
|
/>
|
2021-09-13 20:41:05 +00:00
|
|
|
<Fields attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} />
|
2021-11-16 15:59:58 +00:00
|
|
|
{loading ? (
|
|
|
|
<View style={[styles.backdrop]}>
|
|
|
|
<View
|
|
|
|
style={[
|
|
|
|
styles.backdrop,
|
|
|
|
{ backgroundColor: themes[theme].bannerBackground, opacity: themes[theme].attachmentLoadingOpacity }
|
2022-08-08 21:02:08 +00:00
|
|
|
]}
|
|
|
|
></View>
|
2022-03-18 02:37:10 +00:00
|
|
|
<RCActivityIndicator />
|
2021-11-16 15:59:58 +00:00
|
|
|
</View>
|
|
|
|
) : null}
|
2021-09-13 20:41:05 +00:00
|
|
|
</View>
|
|
|
|
</Touchable>
|
2022-10-21 18:27:55 +00:00
|
|
|
<Markdown msg={attachment.description} username={user.username} getCustomEmoji={getCustomEmoji} theme={theme} />
|
2021-09-13 20:41:05 +00:00
|
|
|
</>
|
|
|
|
);
|
|
|
|
},
|
2022-03-21 20:44:06 +00:00
|
|
|
(prevProps, nextProps) => dequal(prevProps.attachment, nextProps.attachment)
|
2021-09-13 20:41:05 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
Reply.displayName = 'MessageReply';
|
|
|
|
Title.displayName = 'MessageReplyTitle';
|
|
|
|
Description.displayName = 'MessageReplyDescription';
|
|
|
|
Fields.displayName = 'MessageReplyFields';
|
|
|
|
|
|
|
|
export default Reply;
|