2023-07-12 18:28:25 +00:00
|
|
|
import { CameraRoll } from '@react-native-camera-roll/camera-roll';
|
2023-06-29 21:10:49 +00:00
|
|
|
import { HeaderBackground, useHeaderHeight } from '@react-navigation/elements';
|
|
|
|
import { StackNavigationOptions } from '@react-navigation/stack';
|
|
|
|
import { ResizeMode, Video } from 'expo-av';
|
|
|
|
import React from 'react';
|
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
|
|
|
import { PermissionsAndroid, useWindowDimensions, View } from 'react-native';
|
2023-06-29 21:10:49 +00:00
|
|
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
|
|
import { shallowEqual } from 'react-redux';
|
2020-11-30 17:00:06 +00:00
|
|
|
import RNFetchBlob from 'rn-fetch-blob';
|
2019-12-18 21:13:11 +00:00
|
|
|
|
|
|
|
import RCActivityIndicator from '../containers/ActivityIndicator';
|
2020-10-30 16:15:58 +00:00
|
|
|
import * as HeaderButton from '../containers/HeaderButton';
|
2023-06-29 21:10:49 +00:00
|
|
|
import { ImageViewer } from '../containers/ImageViewer';
|
2020-06-26 20:22:56 +00:00
|
|
|
import StatusBar from '../containers/StatusBar';
|
2023-06-29 21:10:49 +00:00
|
|
|
import { LISTENER } from '../containers/Toast';
|
|
|
|
import { IAttachment } from '../definitions';
|
|
|
|
import I18n from '../i18n';
|
|
|
|
import { useAppSelector } from '../lib/hooks';
|
|
|
|
import { useAppNavigation, useAppRoute } from '../lib/hooks/navigation';
|
|
|
|
import { formatAttachmentUrl, isAndroid } from '../lib/methods/helpers';
|
|
|
|
import EventEmitter from '../lib/methods/helpers/events';
|
|
|
|
import { getUserSelector } from '../selectors/login';
|
|
|
|
import { TNavigation } from '../stacks/stackType';
|
|
|
|
import { useTheme } from '../theme';
|
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
|
|
|
import { LOCAL_DOCUMENT_DIRECTORY, getFilename } from '../lib/methods/handleMediaDownload';
|
2023-06-29 21:10:49 +00:00
|
|
|
|
|
|
|
const RenderContent = ({
|
|
|
|
setLoading,
|
|
|
|
attachment
|
|
|
|
}: {
|
|
|
|
setLoading: React.Dispatch<React.SetStateAction<boolean>>;
|
2021-11-17 19:59:53 +00:00
|
|
|
attachment: IAttachment;
|
2023-06-29 21:10:49 +00:00
|
|
|
}) => {
|
|
|
|
const videoRef = React.useRef<Video>(null);
|
|
|
|
const insets = useSafeAreaInsets();
|
|
|
|
const { width, height } = useWindowDimensions();
|
|
|
|
const headerHeight = useHeaderHeight();
|
|
|
|
const navigation = useAppNavigation<TNavigation, 'AttachmentView'>();
|
|
|
|
const { baseUrl, user } = useAppSelector(
|
|
|
|
state => ({
|
|
|
|
baseUrl: state.server.server,
|
|
|
|
user: { id: getUserSelector(state).id, token: getUserSelector(state).token }
|
|
|
|
}),
|
|
|
|
shallowEqual
|
|
|
|
);
|
2019-12-18 21:13:11 +00:00
|
|
|
|
2023-06-29 21:10:49 +00:00
|
|
|
React.useLayoutEffect(() => {
|
|
|
|
const blurSub = navigation.addListener('blur', () => {
|
|
|
|
if (videoRef.current && videoRef.current.stopAsync) {
|
|
|
|
videoRef.current.stopAsync();
|
2020-02-28 16:18:45 +00:00
|
|
|
}
|
|
|
|
});
|
2023-06-29 21:10:49 +00:00
|
|
|
return () => {
|
|
|
|
blurSub();
|
|
|
|
};
|
|
|
|
}, [navigation]);
|
2020-02-28 16:18:45 +00:00
|
|
|
|
2023-06-29 21:10:49 +00:00
|
|
|
if (attachment.image_url) {
|
|
|
|
const url = formatAttachmentUrl(attachment.title_link || attachment.image_url, user.id, user.token, baseUrl);
|
|
|
|
const uri = encodeURI(url);
|
|
|
|
return (
|
|
|
|
<ImageViewer
|
|
|
|
uri={uri}
|
|
|
|
onLoadEnd={() => setLoading(false)}
|
|
|
|
width={width}
|
|
|
|
height={height - insets.top - insets.bottom - (headerHeight || 0)}
|
|
|
|
/>
|
|
|
|
);
|
2019-12-18 21:13:11 +00:00
|
|
|
}
|
2023-06-29 21:10:49 +00:00
|
|
|
if (attachment.video_url) {
|
|
|
|
const url = formatAttachmentUrl(attachment.video_url, user.id, user.token, baseUrl);
|
|
|
|
const uri = encodeURI(url);
|
|
|
|
return (
|
|
|
|
<Video
|
|
|
|
source={{ uri }}
|
|
|
|
rate={1.0}
|
|
|
|
volume={1.0}
|
|
|
|
isMuted={false}
|
|
|
|
resizeMode={ResizeMode.CONTAIN}
|
|
|
|
shouldPlay
|
|
|
|
isLooping={false}
|
|
|
|
style={{ flex: 1 }}
|
|
|
|
useNativeControls
|
|
|
|
onLoad={() => setLoading(false)}
|
|
|
|
onError={console.log}
|
|
|
|
ref={videoRef}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
};
|
|
|
|
|
|
|
|
const AttachmentView = (): React.ReactElement => {
|
|
|
|
const navigation = useAppNavigation<TNavigation, 'AttachmentView'>();
|
|
|
|
const {
|
|
|
|
params: { attachment }
|
|
|
|
} = useAppRoute<TNavigation, 'AttachmentView'>();
|
|
|
|
const [loading, setLoading] = React.useState(true);
|
|
|
|
const { colors } = useTheme();
|
|
|
|
|
|
|
|
const { baseUrl, user, Allow_Save_Media_to_Gallery } = useAppSelector(
|
|
|
|
state => ({
|
|
|
|
baseUrl: state.server.server,
|
|
|
|
user: { id: getUserSelector(state).id, token: getUserSelector(state).token },
|
|
|
|
Allow_Save_Media_to_Gallery: (state.settings.Allow_Save_Media_to_Gallery as boolean) ?? true
|
|
|
|
}),
|
|
|
|
shallowEqual
|
|
|
|
);
|
2019-12-18 21:13:11 +00:00
|
|
|
|
2023-06-29 21:10:49 +00:00
|
|
|
const setHeader = () => {
|
2020-07-08 16:40:51 +00:00
|
|
|
let { title } = attachment;
|
|
|
|
try {
|
2022-03-29 20:06:50 +00:00
|
|
|
if (title) {
|
|
|
|
title = decodeURI(title);
|
|
|
|
}
|
2020-07-08 16:40:51 +00:00
|
|
|
} catch {
|
|
|
|
// Do nothing
|
|
|
|
}
|
2022-07-06 13:23:02 +00:00
|
|
|
const options: StackNavigationOptions = {
|
|
|
|
title: title || '',
|
|
|
|
headerTitleAlign: 'center',
|
2023-06-29 21:10:49 +00:00
|
|
|
headerTitleStyle: { color: colors.previewTintColor },
|
|
|
|
headerTintColor: colors.previewTintColor,
|
2022-07-06 13:23:02 +00:00
|
|
|
headerTitleContainerStyle: { flex: 1, maxWidth: undefined },
|
|
|
|
headerLeftContainerStyle: { flexGrow: undefined, flexBasis: undefined },
|
|
|
|
headerRightContainerStyle: { flexGrow: undefined, flexBasis: undefined },
|
|
|
|
headerLeft: () => (
|
2023-06-29 21:10:49 +00:00
|
|
|
<HeaderButton.CloseModal testID='close-attachment-view' navigation={navigation} color={colors.previewTintColor} />
|
2022-07-06 13:23:02 +00:00
|
|
|
),
|
|
|
|
headerRight: () =>
|
|
|
|
Allow_Save_Media_to_Gallery ? (
|
2023-06-29 21:10:49 +00:00
|
|
|
<HeaderButton.Download testID='save-image' onPress={handleSave} color={colors.previewTintColor} />
|
2022-07-06 13:23:02 +00:00
|
|
|
) : null,
|
|
|
|
headerBackground: () => (
|
2023-06-29 21:10:49 +00:00
|
|
|
<HeaderBackground style={{ backgroundColor: colors.previewBackground, shadowOpacity: 0, elevation: 0 }} />
|
2022-07-06 13:23:02 +00:00
|
|
|
)
|
2020-06-15 14:00:46 +00:00
|
|
|
};
|
|
|
|
navigation.setOptions(options);
|
2021-09-13 20:41:05 +00:00
|
|
|
};
|
2020-06-15 14:00:46 +00:00
|
|
|
|
2023-06-29 21:10:49 +00:00
|
|
|
React.useLayoutEffect(() => {
|
|
|
|
setHeader();
|
|
|
|
}, [navigation]);
|
2020-02-28 16:18:45 +00:00
|
|
|
|
2023-06-29 21:10:49 +00:00
|
|
|
const handleSave = async () => {
|
2021-09-14 18:31:36 +00:00
|
|
|
const { title_link, image_url, image_type, video_url, video_type } = attachment;
|
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
|
|
|
// When the attachment is a video, the video_url refers to local file and the title_link to the link
|
|
|
|
const url = video_url || title_link || image_url;
|
2019-12-18 21:13:11 +00:00
|
|
|
|
2022-02-07 18:44:04 +00:00
|
|
|
if (!url) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-12-18 21:13:11 +00:00
|
|
|
if (isAndroid) {
|
|
|
|
const rationale = {
|
|
|
|
title: I18n.t('Write_External_Permission'),
|
2021-11-17 19:59:53 +00:00
|
|
|
message: I18n.t('Write_External_Permission_Message'),
|
|
|
|
buttonPositive: 'Ok'
|
2019-12-18 21:13:11 +00:00
|
|
|
};
|
|
|
|
const result = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, rationale);
|
|
|
|
if (!(result || result === PermissionsAndroid.RESULTS.GRANTED)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-29 21:10:49 +00:00
|
|
|
setLoading(true);
|
2019-12-18 21:13:11 +00:00
|
|
|
try {
|
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
|
|
|
if (LOCAL_DOCUMENT_DIRECTORY && url.startsWith(LOCAL_DOCUMENT_DIRECTORY)) {
|
|
|
|
await CameraRoll.save(url, { album: 'Rocket.Chat' });
|
|
|
|
} else {
|
|
|
|
const mediaAttachment = formatAttachmentUrl(url, user.id, user.token, baseUrl);
|
|
|
|
let filename = '';
|
|
|
|
if (image_url) {
|
|
|
|
filename = getFilename({ title: attachment.title, type: 'image', mimeType: image_type, url });
|
|
|
|
} else {
|
|
|
|
filename = getFilename({ title: attachment.title, type: 'video', mimeType: video_type, url });
|
|
|
|
}
|
|
|
|
const documentDir = `${RNFetchBlob.fs.dirs.DocumentDir}/`;
|
|
|
|
const path = `${documentDir + filename}`;
|
|
|
|
const file = await RNFetchBlob.config({ path }).fetch('GET', mediaAttachment);
|
|
|
|
await CameraRoll.save(path, { album: 'Rocket.Chat' });
|
|
|
|
file.flush();
|
|
|
|
}
|
2019-12-18 21:13:11 +00:00
|
|
|
EventEmitter.emit(LISTENER, { message: I18n.t('saved_to_gallery') });
|
|
|
|
} catch (e) {
|
2020-04-30 18:08:48 +00:00
|
|
|
EventEmitter.emit(LISTENER, { message: I18n.t(image_url ? 'error-save-image' : 'error-save-video') });
|
2019-12-18 21:13:11 +00:00
|
|
|
}
|
2023-06-29 21:10:49 +00:00
|
|
|
setLoading(false);
|
2019-12-18 21:13:11 +00:00
|
|
|
};
|
|
|
|
|
2023-06-29 21:10:49 +00:00
|
|
|
return (
|
|
|
|
<View style={{ backgroundColor: colors.backgroundColor, flex: 1 }}>
|
|
|
|
<StatusBar barStyle='light-content' backgroundColor={colors.previewBackground} />
|
|
|
|
<RenderContent attachment={attachment} setLoading={setLoading} />
|
|
|
|
{loading ? <RCActivityIndicator absolute size='large' /> : null}
|
|
|
|
</View>
|
2019-12-18 21:13:11 +00:00
|
|
|
);
|
2023-06-29 21:10:49 +00:00
|
|
|
};
|
2019-12-18 21:13:11 +00:00
|
|
|
|
2023-06-29 21:10:49 +00:00
|
|
|
export default AttachmentView;
|