From b6ae55e57fe8e876a4c03cd0b37cb8495b0f26c4 Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Mon, 3 Jul 2023 14:28:22 -0300 Subject: [PATCH] remove mediaType and refactor audio and image --- app/containers/message/Audio.tsx | 91 ++++++++++++----------- app/containers/message/Image.tsx | 39 +++++----- app/containers/message/Video.tsx | 11 ++- app/lib/methods/autoDownloadPreference.ts | 21 +++--- app/lib/methods/handleMediaDownload.ts | 29 +++----- 5 files changed, 99 insertions(+), 92 deletions(-) diff --git a/app/containers/message/Audio.tsx b/app/containers/message/Audio.tsx index e4a6b400f..eded0bdd0 100644 --- a/app/containers/message/Audio.tsx +++ b/app/containers/message/Audio.tsx @@ -19,7 +19,7 @@ import { withDimensions } from '../../dimensions'; import { TGetCustomEmoji } from '../../definitions/IEmoji'; import { IAttachment, IUserMessage } from '../../definitions'; import { TSupportedThemes, useTheme } from '../../theme'; -import { downloadMediaFile, searchMediaFileAsync } from '../../lib/methods/handleMediaDownload'; +import { downloadMediaFile, getMediaCache } from '../../lib/methods/handleMediaDownload'; import EventEmitter from '../../lib/methods/helpers/events'; import { PAUSE_AUDIO } from './constants'; import { fetchAutoDownloadEnabled } from '../../lib/methods/autoDownloadPreference'; @@ -130,7 +130,7 @@ class MessageAudio extends React.Component { - const { file } = this.props; - // @ts-ignore can't use declare to type this - const { baseUrl } = this.context; - - let url = file.audio_url; - if (url && !url.startsWith('http')) { - url = `${baseUrl}${file.audio_url}`; - } - return url as string; - }; - - handleAutoDownload = async () => { - const { author } = this.props; - // @ts-ignore can't use declare to type this - const { user } = this.context; - const url = this.getUrl(); - try { - if (url) { - const isCurrentUserAuthor = author?._id === user.id; - const isAutoDownloadEnabled = fetchAutoDownloadEnabled('audioPreferenceDownload'); - if (isAutoDownloadEnabled || isCurrentUserAuthor) { - await this.handleDownload(); - return; - } - - return this.setState({ loading: false, cached: false }); - } - } catch { - // Do nothing - } - }; - shouldComponentUpdate(nextProps: IMessageAudioProps, nextState: IMessageAudioState) { const { currentTime, duration, paused, loading, cached } = this.state; const { file, theme } = this.props; @@ -236,6 +207,39 @@ class MessageAudio extends React.Component { + const { file } = this.props; + // @ts-ignore can't use declare to type this + const { baseUrl } = this.context; + + let url = file.audio_url; + if (url && !url.startsWith('http')) { + url = `${baseUrl}${file.audio_url}`; + } + return url; + }; + + handleAutoDownload = async () => { + const { author } = this.props; + // @ts-ignore can't use declare to type this + const { user } = this.context; + const url = this.getUrl(); + try { + if (url) { + const isCurrentUserAuthor = author?._id === user.id; + const isAutoDownloadEnabled = fetchAutoDownloadEnabled('audioPreferenceDownload'); + if (isAutoDownloadEnabled || isCurrentUserAuthor) { + await this.handleDownload(); + return; + } + + this.setState({ loading: false, cached: false }); + } + } catch { + // Do nothing + } + }; + onPlaybackStatusUpdate = (status: AVPlaybackStatus) => { if (status) { this.onLoad(status); @@ -294,21 +298,24 @@ class MessageAudio extends React.Component { const { cached } = this.state; - return cached ? this.togglePlayPause() : this.handleDownload(); + if (cached) { + this.togglePlayPause(); + return; + } + this.handleDownload(); }; playPause = async () => { diff --git a/app/containers/message/Image.tsx b/app/containers/message/Image.tsx index 7e17d4ae0..926e1f30c 100644 --- a/app/containers/message/Image.tsx +++ b/app/containers/message/Image.tsx @@ -12,7 +12,7 @@ import { TGetCustomEmoji } from '../../definitions/IEmoji'; import { IAttachment, IUserMessage } from '../../definitions'; import { useTheme } from '../../theme'; import { formatAttachmentUrl } from '../../lib/methods/helpers/formatAttachmentUrl'; -import { cancelDownload, downloadMediaFile, isDownloadActive, searchMediaFileAsync } from '../../lib/methods/handleMediaDownload'; +import { cancelDownload, downloadMediaFile, isDownloadActive, getMediaCache } from '../../lib/methods/handleMediaDownload'; import { fetchAutoDownloadEnabled } from '../../lib/methods/autoDownloadPreference'; import RCActivityIndicator from '../ActivityIndicator'; import { CustomIcon } from '../CustomIcon'; @@ -82,7 +82,7 @@ const ImageContainer = React.memo( ({ file, imageUrl, showAttachment, getCustomEmoji, style, isReply, author }: IMessageImage) => { const [imageCached, setImageCached] = useState(file); const [cached, setCached] = useState(false); - const [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(true); const { theme } = useTheme(); const { baseUrl, user } = useContext(MessageContext); const filePath = useRef(''); @@ -93,9 +93,9 @@ const ImageContainer = React.memo( const imgUrlToCache = getUrl(imageCached.title_link || imageCached.image_url); useLayoutEffect(() => { - const handleImageSearchAndDownload = async () => { + const handleCache = async () => { if (img) { - const cachedImageResult = await searchMediaFileAsync({ + const cachedImageResult = await getMediaCache({ type: 'image', mimeType: imageCached.image_type, urlToCache: imgUrlToCache @@ -106,16 +106,21 @@ const ImageContainer = React.memo( ...prev, title_link: cachedImageResult.file?.uri })); - return setCached(true); + setLoading(false); + setCached(true); + return; } - if (isReply) return; - if (isDownloadActive('image', imgUrlToCache)) { - return setLoading(true); + if (isReply) { + setLoading(false); + return; + } + if (isDownloadActive(imgUrlToCache)) { + return; } await handleAutoDownload(); } }; - handleImageSearchAndDownload(); + handleCache(); }, []); if (!img) { @@ -131,11 +136,9 @@ const ImageContainer = React.memo( }; const handleDownload = async () => { - setLoading(true); try { const imageUri = await downloadMediaFile({ downloadUrl: imgUrlToCache, - mediaType: 'image', path: filePath.current }); setImageCached(prev => ({ @@ -146,23 +149,25 @@ const ImageContainer = React.memo( setLoading(false); } catch (e) { setLoading(false); - return setCached(false); + setCached(false); } }; const onPress = () => { - if (loading && isDownloadActive('image', imgUrlToCache)) { - cancelDownload('image', imgUrlToCache); + if (loading && isDownloadActive(imgUrlToCache)) { + cancelDownload(imgUrlToCache); setLoading(false); - return setCached(false); + setCached(false); + return; } if (!cached && !loading) { - return handleDownload(); + handleDownload(); + return; } if (!showAttachment) { return; } - return showAttachment(imageCached); + showAttachment(imageCached); }; if (imageCached.description) { diff --git a/app/containers/message/Video.tsx b/app/containers/message/Video.tsx index 75afd684d..873d25ce4 100644 --- a/app/containers/message/Video.tsx +++ b/app/containers/message/Video.tsx @@ -22,7 +22,7 @@ import { cancelDownload, downloadMediaFile, isDownloadActive, - searchMediaFileAsync + getMediaCache } from '../../lib/methods/handleMediaDownload'; import { fetchAutoDownloadEnabled } from '../../lib/methods/autoDownloadPreference'; import sharedStyles from '../../views/Styles'; @@ -84,20 +84,20 @@ const Video = React.memo( useEffect(() => { const handleVideoSearchAndDownload = async () => { if (video) { - const cachedVideoResult = await searchMediaFileAsync({ + const cachedVideoResult = await getMediaCache({ type: 'video', mimeType: file.video_type, urlToCache: video }); filePath.current = cachedVideoResult.filePath; - const downloadActive = isDownloadActive('video', video); + const downloadActive = isDownloadActive(video); if (cachedVideoResult.file?.exists) { setVideoCached(prev => ({ ...prev, video_url: cachedVideoResult.file?.uri })); if (downloadActive) { - cancelDownload('video', video); + cancelDownload(video); } return; } @@ -125,7 +125,6 @@ const Video = React.memo( try { const videoUri = await downloadMediaFile({ downloadUrl: video, - mediaType: 'video', path: filePath.current }); setVideoCached(prev => ({ @@ -154,7 +153,7 @@ const Video = React.memo( const handleCancelDownload = () => { if (loading) { - cancelDownload('video', video); + cancelDownload(video); return setLoading(false); } }; diff --git a/app/lib/methods/autoDownloadPreference.ts b/app/lib/methods/autoDownloadPreference.ts index 5c6cd89e5..71078b161 100644 --- a/app/lib/methods/autoDownloadPreference.ts +++ b/app/lib/methods/autoDownloadPreference.ts @@ -15,21 +15,22 @@ export const fetchAutoDownloadEnabled = (mediaType: TMediaType) => { const { netInfoState } = store.getState().app; const mediaDownloadPreference = userPreferences.getString(mediaType) as MediaDownloadOption; - let defaultValueByMediaType = false; + if (mediaDownloadPreference === 'wifi_mobile_data') { + return true; + } + + if (mediaDownloadPreference === 'wifi' && netInfoState === NetInfoStateType.wifi) { + return true; + } + if (mediaDownloadPreference === null) { if (mediaType === 'imagesPreferenceDownload') { - // The same as 'wifi_mobile_data' - defaultValueByMediaType = true; + return true; } if (mediaType === 'audioPreferenceDownload' || mediaType === 'videoPreferenceDownload') { - // The same as 'wifi' - defaultValueByMediaType = netInfoState === NetInfoStateType.wifi; + return netInfoState === NetInfoStateType.wifi; } } - return ( - (mediaDownloadPreference === 'wifi' && netInfoState === NetInfoStateType.wifi) || - mediaDownloadPreference === 'wifi_mobile_data' || - defaultValueByMediaType - ); + return false; }; diff --git a/app/lib/methods/handleMediaDownload.ts b/app/lib/methods/handleMediaDownload.ts index b4983d495..243170398 100644 --- a/app/lib/methods/handleMediaDownload.ts +++ b/app/lib/methods/handleMediaDownload.ts @@ -22,14 +22,14 @@ const defaultType = { const downloadQueue: { [index: string]: FileSystem.DownloadResumable } = {}; -export const mediaDownloadKey = (mediaType: MediaTypes, downloadUrl: string) => `${mediaType}-${sanitizeString(downloadUrl)}`; +export const mediaDownloadKey = (messageUrl: string) => `${sanitizeString(messageUrl)}`; -export function isDownloadActive(mediaType: MediaTypes, messageId: string): boolean { - return !!downloadQueue[mediaDownloadKey(mediaType, messageId)]; +export function isDownloadActive(messageUrl: string): boolean { + return !!downloadQueue[mediaDownloadKey(messageUrl)]; } -export async function cancelDownload(mediaType: MediaTypes, messageId: string): Promise { - const downloadKey = mediaDownloadKey(mediaType, messageId); +export async function cancelDownload(messageUrl: string): Promise { + const downloadKey = mediaDownloadKey(messageUrl); if (!isEmpty(downloadQueue[downloadKey])) { try { await downloadQueue[downloadKey].cancelAsync(); @@ -40,18 +40,10 @@ export async function cancelDownload(mediaType: MediaTypes, messageId: string): } } -export function downloadMediaFile({ - mediaType, - downloadUrl, - path -}: { - mediaType: MediaTypes; - downloadUrl: string; - path: string; -}): Promise { +export function downloadMediaFile({ downloadUrl, path }: { downloadUrl: string; path: string }): Promise { return new Promise(async (resolve, reject) => { try { - const downloadKey = mediaDownloadKey(mediaType, downloadUrl); + const downloadKey = mediaDownloadKey(downloadUrl); downloadQueue[downloadKey] = FileSystem.createDownloadResumable(downloadUrl, path); const result = await downloadQueue[downloadKey].downloadAsync(); if (result?.uri) { @@ -101,15 +93,18 @@ const ensureDirAsync = async (dir: string, intermediates = true): Promise return ensureDirAsync(dir, intermediates); }; -export const searchMediaFileAsync = async ({ +export const getMediaCache = async ({ type, mimeType, urlToCache }: { type: MediaTypes; mimeType?: string; - urlToCache: string; + urlToCache?: string; }) => { + if (!urlToCache) { + return { file: null, filePath: '' }; + } try { const serverUrl = store.getState().server.server; const serverUrlParsed = serverUrlParsedAsPath(serverUrl);