don't need to controle the filepath in the view

This commit is contained in:
Reinaldo Neto 2023-07-04 14:22:20 -03:00
parent c85f98955c
commit b3f460598f
4 changed files with 91 additions and 70 deletions

View File

@ -121,7 +121,6 @@ Button.displayName = 'MessageAudioButton';
class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioState> {
static contextType = MessageContext;
private sound: Sound;
private filePath?: string;
constructor(props: IMessageAudioProps) {
super(props);
@ -149,9 +148,8 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
mimeType: file.audio_type,
urlToCache: this.getUrl()
});
this.filePath = cachedAudioResult.filePath;
if (cachedAudioResult?.file?.exists) {
await this.sound.loadAsync({ uri: cachedAudioResult.file.uri });
if (cachedAudioResult?.exists) {
await this.sound.loadAsync({ uri: cachedAudioResult.uri });
this.setState({ loading: false, cached: true });
return;
}
@ -290,17 +288,18 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
};
handleDownload = async () => {
const { file } = this.props;
// @ts-ignore can't use declare to type this
const { user } = this.context;
this.setState({ loading: true });
try {
const url = this.getUrl();
if (url && this.filePath) {
if (url) {
const audio = await downloadMediaFile({
downloadUrl: `${url}?rc_uid=${user.id}&rc_token=${user.token}`,
path: this.filePath
type: 'audio',
mimeType: file.audio_type
});
await this.sound.loadAsync({ uri: audio });
this.setState({ loading: false, cached: true });
}

View File

@ -1,4 +1,4 @@
import React, { useContext, useLayoutEffect, useRef, useState } from 'react';
import React, { useContext, useLayoutEffect, useState } from 'react';
import { StyleProp, TextStyle, View } from 'react-native';
import FastImage from 'react-native-fast-image';
import { dequal } from 'dequal';
@ -68,7 +68,6 @@ const ImageContainer = React.memo(
const [loading, setLoading] = useState(true);
const { theme } = useTheme();
const { baseUrl, user } = useContext(MessageContext);
const filePath = useRef('');
const getUrl = (link?: string) => imageUrl || formatAttachmentUrl(link, user.id, user.token, baseUrl);
const img = getUrl(file.image_url);
// The param file.title_link is the one that point to image with best quality, however we still need to test the imageUrl
@ -83,11 +82,10 @@ const ImageContainer = React.memo(
mimeType: imageCached.image_type,
urlToCache: imgUrlToCache
});
filePath.current = cachedImageResult.filePath;
if (cachedImageResult.file?.exists) {
if (cachedImageResult?.exists) {
setImageCached(prev => ({
...prev,
title_link: cachedImageResult.file?.uri
title_link: cachedImageResult?.uri
}));
setLoading(false);
setCached(true);
@ -122,7 +120,8 @@ const ImageContainer = React.memo(
try {
const imageUri = await downloadMediaFile({
downloadUrl: imgUrlToCache,
path: filePath.current
type: 'image',
mimeType: imageCached.image_type
});
setImageCached(prev => ({
...prev,

View File

@ -1,4 +1,4 @@
import React, { useContext, useEffect, useRef, useState } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import { StyleProp, StyleSheet, TextStyle, View, Text } from 'react-native';
import { dequal } from 'dequal';
import * as VideoThumbnails from 'expo-video-thumbnails';
@ -106,7 +106,6 @@ const Video = React.memo(
const [cached, setCached] = useState(false);
const { baseUrl, user } = useContext(MessageContext);
const { theme } = useTheme();
const filePath = useRef('');
const video = formatAttachmentUrl(file.video_url, user.id, user.token, baseUrl);
useEffect(() => {
@ -117,12 +116,11 @@ const Video = React.memo(
mimeType: file.video_type,
urlToCache: video
});
filePath.current = cachedVideoResult.filePath;
const downloadActive = isDownloadActive(video);
if (cachedVideoResult.file?.exists) {
if (cachedVideoResult?.exists) {
setVideoCached(prev => ({
...prev,
video_url: cachedVideoResult.file?.uri
video_url: cachedVideoResult?.uri
}));
setLoading(false);
setCached(true);
@ -157,7 +155,8 @@ const Video = React.memo(
try {
const videoUri = await downloadMediaFile({
downloadUrl: video,
path: filePath.current
type: 'video',
mimeType: file.video_type
});
setVideoCached(prev => ({
...prev,

View File

@ -8,54 +8,12 @@ import log from './helpers/log';
export type MediaTypes = 'audio' | 'image' | 'video';
const typeString = {
audio: 'audios/',
image: 'images/',
video: 'videos/'
};
const defaultType = {
audio: 'mp3',
image: 'jpg',
video: 'mp4'
};
const downloadQueue: { [index: string]: FileSystem.DownloadResumable } = {};
export const mediaDownloadKey = (messageUrl: string) => `${sanitizeString(messageUrl)}`;
export function isDownloadActive(messageUrl: string): boolean {
return !!downloadQueue[mediaDownloadKey(messageUrl)];
}
export async function cancelDownload(messageUrl: string): Promise<void> {
const downloadKey = mediaDownloadKey(messageUrl);
if (!isEmpty(downloadQueue[downloadKey])) {
try {
await downloadQueue[downloadKey].cancelAsync();
} catch {
// Do nothing
}
delete downloadQueue[downloadKey];
}
}
export function downloadMediaFile({ downloadUrl, path }: { downloadUrl: string; path: string }): Promise<string> {
return new Promise(async (resolve, reject) => {
try {
const downloadKey = mediaDownloadKey(downloadUrl);
downloadQueue[downloadKey] = FileSystem.createDownloadResumable(downloadUrl, path);
const result = await downloadQueue[downloadKey].downloadAsync();
if (result?.uri) {
return resolve(result.uri);
}
reject();
} catch {
reject();
}
});
}
export const LOCAL_DOCUMENT_DIRECTORY = FileSystem.documentDirectory;
const sanitizeString = (value: string) => {
@ -93,6 +51,24 @@ const ensureDirAsync = async (dir: string, intermediates = true): Promise<void>
return ensureDirAsync(dir, intermediates);
};
const getFilePath = ({ type, mimeType, urlToCache }: { type: MediaTypes; mimeType?: string; urlToCache?: string }) => {
if (!urlToCache) {
return;
}
const folderPath = getFolderPath();
const fileUrlSanitized = sanitizeString(urlToCache);
const filename = `${fileUrlSanitized}.${getExtension(type, mimeType)}`;
const filePath = `${folderPath}${filename}`;
return filePath;
};
const getFolderPath = () => {
const serverUrl = store.getState().server.server;
const serverUrlParsed = serverUrlParsedAsPath(serverUrl);
const folderPath = `${LOCAL_DOCUMENT_DIRECTORY}${serverUrlParsed}`;
return folderPath;
};
export const getMediaCache = async ({
type,
mimeType,
@ -103,21 +79,20 @@ export const getMediaCache = async ({
urlToCache?: string;
}) => {
if (!urlToCache) {
return { file: null, filePath: '' };
return null;
}
try {
const serverUrl = store.getState().server.server;
const serverUrlParsed = serverUrlParsedAsPath(serverUrl);
const folderPath = `${LOCAL_DOCUMENT_DIRECTORY}${serverUrlParsed}${typeString[type]}`;
const fileUrlSanitized = sanitizeString(urlToCache);
const filename = `${fileUrlSanitized}.${getExtension(type, mimeType)}`;
const filePath = `${folderPath}${filename}`;
const folderPath = getFolderPath();
const filePath = getFilePath({ type, mimeType, urlToCache });
if (!filePath) {
return null;
}
await ensureDirAsync(folderPath);
const file = await FileSystem.getInfoAsync(filePath);
return { file, filePath };
return file;
} catch (error) {
log(error);
return { file: null, filePath: '' };
return null;
}
};
@ -130,3 +105,52 @@ export const deleteMediaFiles = async (serverUrl: string): Promise<void> => {
log(error);
}
};
const downloadQueue: { [index: string]: FileSystem.DownloadResumable } = {};
export const mediaDownloadKey = (messageUrl: string) => `${sanitizeString(messageUrl)}`;
export function isDownloadActive(messageUrl: string): boolean {
return !!downloadQueue[mediaDownloadKey(messageUrl)];
}
export async function cancelDownload(messageUrl: string): Promise<void> {
const downloadKey = mediaDownloadKey(messageUrl);
if (!isEmpty(downloadQueue[downloadKey])) {
try {
await downloadQueue[downloadKey].cancelAsync();
} catch {
// Do nothing
}
delete downloadQueue[downloadKey];
}
}
export function downloadMediaFile({
type,
mimeType,
downloadUrl
}: {
type: MediaTypes;
mimeType?: string;
downloadUrl: string;
}): Promise<string> {
return new Promise(async (resolve, reject) => {
try {
const path = getFilePath({ type, mimeType, urlToCache: downloadUrl });
if (!path) {
reject();
return;
}
const downloadKey = mediaDownloadKey(downloadUrl);
downloadQueue[downloadKey] = FileSystem.createDownloadResumable(downloadUrl, path);
const result = await downloadQueue[downloadKey].downloadAsync();
if (result?.uri) {
return resolve(result.uri);
}
reject();
} catch {
reject();
}
});
}