diff --git a/app/containers/message/Components/Attachments/Video.tsx b/app/containers/message/Components/Attachments/Video.tsx index 23b72e6e46..201c9b617a 100644 --- a/app/containers/message/Components/Attachments/Video.tsx +++ b/app/containers/message/Components/Attachments/Video.tsx @@ -1,5 +1,7 @@ -import React, { useContext } from 'react'; -import { StyleProp, StyleSheet, Text, TextStyle, View } from 'react-native'; +import React, { useContext, useEffect, useState } from 'react'; +import { StyleProp, StyleSheet, TextStyle, View } from 'react-native'; +import FastImage from 'react-native-fast-image'; +import { getThumbnailAsync } from 'expo-video-thumbnails'; import { IUserMessage } from '../../../../definitions'; import { IAttachment } from '../../../../definitions/IAttachment'; @@ -8,70 +10,107 @@ import I18n from '../../../../i18n'; import { fileDownload, isIOS } from '../../../../lib/methods/helpers'; import EventEmitter from '../../../../lib/methods/helpers/events'; import { useTheme } from '../../../../theme'; -import sharedStyles from '../../../../views/Styles'; -import { TIconsName } from '../../../CustomIcon'; import { LISTENER } from '../../../Toast'; import Markdown from '../../../markdown'; import MessageContext from '../../Context'; import Touchable from '../../Touchable'; import { useMediaAutoDownload } from '../../hooks/useMediaAutoDownload'; -import BlurComponent from '../OverlayComponent'; -import { TDownloadState } from '../../../../lib/methods/handleMediaDownload'; import messageStyles from '../../styles'; +import OverlayComponent from '../OverlayComponent'; +import { CustomIcon, TIconsName } from '../../../CustomIcon'; +import { themes } from '../../../../lib/constants'; +import { TDownloadState } from '../../../../lib/methods/handleMediaDownload'; const SUPPORTED_TYPES = ['video/quicktime', 'video/mp4', ...(isIOS ? [] : ['video/3gp', 'video/mkv'])]; const isTypeSupported = (type: string) => SUPPORTED_TYPES.indexOf(type) !== -1; const styles = StyleSheet.create({ - cancelContainer: { - position: 'absolute', - top: 8, - right: 8 + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center' + }, + overlay: { + flex: 1 + }, + image: { + width: '100%', + height: '100%' }, - text: { - ...sharedStyles.textRegular, - fontSize: 12 + playerIcon: { + position: 'absolute', + textShadowRadius: 3, + textShadowOffset: { + width: 0.5, + height: 0.5 + } } }); -interface IMessageVideo { - file: IAttachment; - showAttachment?: (file: IAttachment) => void; - getCustomEmoji: TGetCustomEmoji; - author?: IUserMessage; - style?: StyleProp[]; - isReply?: boolean; - msg?: string; -} +type TThumbnailImage = string | null; -const CancelIndicator = () => { - const { colors } = useTheme(); - return ( - - {I18n.t('Cancel')} - - ); +type ThumbnailProps = { + url: string; + status: TDownloadState; + encrypted?: boolean; }; -const Thumbnail = ({ status, encrypted = false }: { status: TDownloadState; encrypted: boolean }) => { - const { colors } = useTheme(); +const Thumbnail = ({ url, status, encrypted = false }: ThumbnailProps) => { + const { theme } = useTheme(); + let icon: TIconsName = status === 'downloaded' ? 'play-filled' : 'arrow-down-circle'; if (encrypted && status === 'downloaded') { icon = 'encrypted'; } + const [image, setImage] = useState(null); + + const generateThumbnail = async () => { + try { + if (!url) return; + + const { uri } = await getThumbnailAsync(url, { + time: 1 + }); + setImage(uri); + } catch (e) { + console.warn(e); + } + }; + + useEffect(() => { + generateThumbnail(); + }, [url]); + return ( - <> - - {status === 'loading' ? : null} - + + {status === 'loading' || !image || encrypted ? ( + + ) : ( + <> + + + + )} + ); }; +interface IMessageVideo { + file: IAttachment; + showAttachment?: (file: IAttachment) => void; + getCustomEmoji: TGetCustomEmoji; + author?: IUserMessage; + style?: StyleProp[]; + isReply?: boolean; + msg?: string; +} + const Video = ({ file, showAttachment, @@ -112,7 +151,7 @@ const Video = ({ <> - + );