remove mediaType and refactor audio and image

This commit is contained in:
Reinaldo Neto 2023-07-03 14:28:22 -03:00
parent 1be2326686
commit b6ae55e57f
5 changed files with 99 additions and 92 deletions

View File

@ -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<IMessageAudioProps, IMessageAudioStat
currentTime: 0,
duration: 0,
paused: true,
cached: true
cached: false
};
this.sound = new Audio.Sound();
@ -144,7 +144,7 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
async componentDidMount() {
const { file, isReply } = this.props;
const cachedAudioResult = await searchMediaFileAsync({
const cachedAudioResult = await getMediaCache({
type: 'audio',
mimeType: file.audio_type,
urlToCache: this.getUrl()
@ -152,44 +152,15 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
this.filePath = cachedAudioResult.filePath;
if (cachedAudioResult?.file?.exists) {
await this.sound.loadAsync({ uri: cachedAudioResult.file.uri });
return this.setState({ loading: false });
}
if (isReply) return;
await this.handleAutoDownload();
}
getUrl = () => {
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();
this.setState({ loading: false, cached: true });
return;
}
return this.setState({ loading: false, cached: false });
if (isReply) {
this.setState({ loading: false });
return;
}
} catch {
// Do nothing
await this.handleAutoDownload();
}
};
shouldComponentUpdate(nextProps: IMessageAudioProps, nextState: IMessageAudioState) {
const { currentTime, duration, paused, loading, cached } = this.state;
@ -236,6 +207,39 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
}
}
getUrl = () => {
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<IMessageAudioProps, IMessageAudioStat
if (url && this.filePath) {
const audio = await downloadMediaFile({
downloadUrl: `${url}?rc_uid=${user.id}&rc_token=${user.token}`,
mediaType: 'audio',
path: this.filePath
});
await this.sound.loadAsync({ uri: audio });
return this.setState({ loading: false, cached: true });
this.setState({ loading: false, cached: true });
}
} catch {
return this.setState({ loading: false, cached: false });
this.setState({ loading: false, cached: false });
}
};
onPress = () => {
const { cached } = this.state;
return cached ? this.togglePlayPause() : this.handleDownload();
if (cached) {
this.togglePlayPause();
return;
}
this.handleDownload();
};
playPause = async () => {

View File

@ -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) {

View File

@ -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);
}
};

View File

@ -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;
};

View File

@ -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<void> {
const downloadKey = mediaDownloadKey(mediaType, messageId);
export async function cancelDownload(messageUrl: string): Promise<void> {
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<string> {
export function downloadMediaFile({ downloadUrl, path }: { downloadUrl: string; path: string }): Promise<string> {
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<void>
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);