done for image and audio
This commit is contained in:
parent
aa2c2886a0
commit
02ba6e9961
|
@ -124,11 +124,12 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
static contextType = MessageContext;
|
static contextType = MessageContext;
|
||||||
|
|
||||||
private sound: Sound;
|
private sound: Sound;
|
||||||
|
private filePath?: string;
|
||||||
|
|
||||||
constructor(props: IMessageAudioProps) {
|
constructor(props: IMessageAudioProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
loading: false,
|
loading: true,
|
||||||
currentTime: 0,
|
currentTime: 0,
|
||||||
duration: 0,
|
duration: 0,
|
||||||
paused: true,
|
paused: true,
|
||||||
|
@ -145,7 +146,29 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
};
|
};
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
this.setState({ loading: true });
|
const { messageId, file } = this.props;
|
||||||
|
const fileSearch = await searchMediaFileAsync({
|
||||||
|
type: MediaTypes.audio,
|
||||||
|
mimeType: file.audio_type,
|
||||||
|
messageId
|
||||||
|
});
|
||||||
|
this.filePath = fileSearch.filePath;
|
||||||
|
if (fileSearch?.file?.exists) {
|
||||||
|
console.log(
|
||||||
|
'🚀 ~ file: Audio.tsx:157 ~ MessageAudio ~ componentDidMount ~ fileSearch?.file?.exists:',
|
||||||
|
fileSearch?.file?.exists
|
||||||
|
);
|
||||||
|
console.log('🚀 ~ file: Audio.tsx:163 ~ MessageAudio ~ componentDidMount ~ fileSearch.file.uri:', fileSearch.file.uri);
|
||||||
|
await this.sound
|
||||||
|
.loadAsync({ uri: fileSearch.file.uri })
|
||||||
|
.then(value => {
|
||||||
|
console.log('🚀 ~ file: Audio.tsx:162 ~ MessageAudio ~ awaitthis.sound.loadAsync ~ value:', value);
|
||||||
|
})
|
||||||
|
.catch(er => {
|
||||||
|
console.log('🚀 ~ file: Audio.tsx:158 ~ MessageAudio ~ awaitthis.sound.loadAsync ~ er:', er);
|
||||||
|
});
|
||||||
|
return this.setState({ loading: false });
|
||||||
|
}
|
||||||
await this.handleAutoDownload();
|
await this.handleAutoDownload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,24 +184,14 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
};
|
};
|
||||||
|
|
||||||
handleAutoDownload = async () => {
|
handleAutoDownload = async () => {
|
||||||
const { messageId, author, file } = this.props;
|
const { author } = this.props;
|
||||||
const { user } = this.context;
|
const { user } = this.context;
|
||||||
const url = this.getUrl();
|
const url = this.getUrl();
|
||||||
try {
|
try {
|
||||||
if (url) {
|
if (url) {
|
||||||
const fileSearch = await searchMediaFileAsync({
|
|
||||||
type: MediaTypes.audio,
|
|
||||||
mimeType: file.audio_type,
|
|
||||||
messageId
|
|
||||||
});
|
|
||||||
if (fileSearch?.file?.exists) {
|
|
||||||
await this.sound.loadAsync({ uri: fileSearch.file.uri });
|
|
||||||
return this.setState({ loading: false });
|
|
||||||
}
|
|
||||||
|
|
||||||
const autoDownload = await isAutoDownloadEnabled('audioPreferenceDownload', { author, user });
|
const autoDownload = await isAutoDownloadEnabled('audioPreferenceDownload', { author, user });
|
||||||
if (autoDownload) {
|
if (autoDownload) {
|
||||||
await this.startDownload();
|
return await this.startDownload();
|
||||||
}
|
}
|
||||||
|
|
||||||
// MediaDownloadOption.NEVER or MediaDownloadOption.WIFI and the mobile is using mobile data
|
// MediaDownloadOption.NEVER or MediaDownloadOption.WIFI and the mobile is using mobile data
|
||||||
|
@ -190,7 +203,7 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
};
|
};
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps: IMessageAudioProps, nextState: IMessageAudioState) {
|
shouldComponentUpdate(nextProps: IMessageAudioProps, nextState: IMessageAudioState) {
|
||||||
const { currentTime, duration, paused, loading } = this.state;
|
const { currentTime, duration, paused, loading, toDownload } = this.state;
|
||||||
const { file, theme } = this.props;
|
const { file, theme } = this.props;
|
||||||
if (nextProps.theme !== theme) {
|
if (nextProps.theme !== theme) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -210,6 +223,9 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
if (nextState.loading !== loading) {
|
if (nextState.loading !== loading) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (nextState.toDownload !== toDownload) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,23 +297,21 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
};
|
};
|
||||||
|
|
||||||
startDownload = async () => {
|
startDownload = async () => {
|
||||||
const { messageId, file } = this.props;
|
const { messageId } = this.props;
|
||||||
const { user } = this.context;
|
const { user } = this.context;
|
||||||
this.setState({ loading: true });
|
this.setState({ loading: true });
|
||||||
|
|
||||||
const url = this.getUrl();
|
const url = this.getUrl();
|
||||||
|
if (url && this.filePath) {
|
||||||
if (url) {
|
|
||||||
const fileSearch = await searchMediaFileAsync({
|
|
||||||
type: MediaTypes.audio,
|
|
||||||
mimeType: file.audio_type,
|
|
||||||
messageId
|
|
||||||
});
|
|
||||||
const audio = await downloadMediaFile({
|
const audio = await downloadMediaFile({
|
||||||
url: `${url}?rc_uid=${user.id}&rc_token=${user.token}`,
|
downloadUrl: `${url}?rc_uid=${user.id}&rc_token=${user.token}`,
|
||||||
filePath: fileSearch.filePath
|
mediaType: MediaTypes.audio,
|
||||||
|
messageId,
|
||||||
|
path: this.filePath
|
||||||
});
|
});
|
||||||
await this.sound.loadAsync({ uri: audio });
|
if (!audio) {
|
||||||
|
return this.setState({ loading: false, toDownload: true });
|
||||||
|
}
|
||||||
|
await this.sound.loadAsync({ uri: this.filePath });
|
||||||
return this.setState({ loading: false, toDownload: false });
|
return this.setState({ loading: false, toDownload: false });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,6 @@ import FastImage from 'react-native-fast-image';
|
||||||
import { dequal } from 'dequal';
|
import { dequal } from 'dequal';
|
||||||
import { createImageProgress } from 'react-native-image-progress';
|
import { createImageProgress } from 'react-native-image-progress';
|
||||||
import * as Progress from 'react-native-progress';
|
import * as Progress from 'react-native-progress';
|
||||||
import * as FileSystem from 'expo-file-system';
|
|
||||||
import { BlurView } from '@react-native-community/blur';
|
import { BlurView } from '@react-native-community/blur';
|
||||||
|
|
||||||
import Touchable from './Touchable';
|
import Touchable from './Touchable';
|
||||||
|
@ -16,7 +15,13 @@ import { TGetCustomEmoji } from '../../definitions/IEmoji';
|
||||||
import { IAttachment, IUserMessage } from '../../definitions';
|
import { IAttachment, IUserMessage } from '../../definitions';
|
||||||
import { TSupportedThemes, useTheme } from '../../theme';
|
import { TSupportedThemes, useTheme } from '../../theme';
|
||||||
import { formatAttachmentUrl } from '../../lib/methods/helpers/formatAttachmentUrl';
|
import { formatAttachmentUrl } from '../../lib/methods/helpers/formatAttachmentUrl';
|
||||||
import { MediaTypes, downloadMediaFile, searchMediaFileAsync } from '../../lib/methods/handleMediaDownload';
|
import {
|
||||||
|
MediaTypes,
|
||||||
|
cancelDownload,
|
||||||
|
downloadMediaFile,
|
||||||
|
isDownloadActive,
|
||||||
|
searchMediaFileAsync
|
||||||
|
} from '../../lib/methods/handleMediaDownload';
|
||||||
import { isAutoDownloadEnabled } from './helpers/mediaDownload/autoDownloadPreference';
|
import { isAutoDownloadEnabled } from './helpers/mediaDownload/autoDownloadPreference';
|
||||||
import RCActivityIndicator from '../ActivityIndicator';
|
import RCActivityIndicator from '../ActivityIndicator';
|
||||||
import { CustomIcon } from '../CustomIcon';
|
import { CustomIcon } from '../CustomIcon';
|
||||||
|
@ -93,28 +98,35 @@ export const MessageImage = React.memo(
|
||||||
|
|
||||||
const ImageContainer = React.memo(
|
const ImageContainer = React.memo(
|
||||||
({ file, imageUrl, showAttachment, getCustomEmoji, style, isReply, author, messageId }: IMessageImage) => {
|
({ file, imageUrl, showAttachment, getCustomEmoji, style, isReply, author, messageId }: IMessageImage) => {
|
||||||
|
const [newFile, setNewFile] = useState(file);
|
||||||
const [toDownload, setToDownload] = useState(true);
|
const [toDownload, setToDownload] = useState(true);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const { baseUrl, user } = useContext(MessageContext);
|
const { baseUrl, user } = useContext(MessageContext);
|
||||||
const img = imageUrl || formatAttachmentUrl(file.image_url, user.id, user.token, baseUrl);
|
const img = imageUrl || formatAttachmentUrl(newFile.image_url, user.id, user.token, baseUrl);
|
||||||
const filePath = useRef('');
|
const filePath = useRef('');
|
||||||
const downloadResumable = useRef<FileSystem.DownloadResumable | null>(null);
|
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const handleAutoDownload = async () => {
|
const handleAutoDownload = async () => {
|
||||||
if (img) {
|
if (img) {
|
||||||
const searchImageBestQuality = await searchMediaFileAsync({
|
const searchImageCached = await searchMediaFileAsync({
|
||||||
type: MediaTypes.image,
|
type: MediaTypes.image,
|
||||||
mimeType: file.image_type,
|
mimeType: newFile.image_type,
|
||||||
messageId
|
messageId
|
||||||
});
|
});
|
||||||
filePath.current = searchImageBestQuality.filePath;
|
filePath.current = searchImageCached.filePath;
|
||||||
if (searchImageBestQuality.file?.exists) {
|
if (searchImageCached.file?.exists) {
|
||||||
file.title_link = searchImageBestQuality.file.uri;
|
setNewFile(prev => ({
|
||||||
|
...prev,
|
||||||
|
title_link: searchImageCached.file?.uri
|
||||||
|
}));
|
||||||
return setToDownload(false);
|
return setToDownload(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isDownloadActive(MediaTypes.image, messageId)) {
|
||||||
|
return setLoading(true);
|
||||||
|
}
|
||||||
|
|
||||||
const autoDownload = await isAutoDownloadEnabled('imagesPreferenceDownload', { user, author });
|
const autoDownload = await isAutoDownloadEnabled('imagesPreferenceDownload', { user, author });
|
||||||
if (autoDownload) {
|
if (autoDownload) {
|
||||||
await handleDownload();
|
await handleDownload();
|
||||||
|
@ -130,25 +142,32 @@ const ImageContainer = React.memo(
|
||||||
|
|
||||||
const handleDownload = async () => {
|
const handleDownload = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const imgUrl = imageUrl || formatAttachmentUrl(file.title_link || file.image_url, user.id, user.token, baseUrl);
|
// The param file.title_link is the one that point to image with best quality, however we still need to test the imageUrl
|
||||||
downloadResumable.current = FileSystem.createDownloadResumable(imgUrl, filePath.current);
|
// And we don't have sure that exists the file.title_link
|
||||||
|
const imgUrl = imageUrl || formatAttachmentUrl(newFile.title_link || newFile.image_url, user.id, user.token, baseUrl);
|
||||||
const imageUri = await downloadMediaFile({
|
const imageUri = await downloadMediaFile({
|
||||||
url: imgUrl,
|
downloadUrl: imgUrl,
|
||||||
filePath: filePath.current,
|
mediaType: MediaTypes.image,
|
||||||
downloadResumable: downloadResumable.current
|
messageId,
|
||||||
|
path: filePath.current
|
||||||
});
|
});
|
||||||
if (!imageUri) {
|
if (!imageUri) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
return setToDownload(true);
|
return setToDownload(true);
|
||||||
}
|
}
|
||||||
file.title_link = imageUri;
|
setNewFile(prev => ({
|
||||||
|
...prev,
|
||||||
|
title_link: filePath.current
|
||||||
|
}));
|
||||||
setToDownload(false);
|
setToDownload(false);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPress = () => {
|
const onPress = () => {
|
||||||
if (loading && downloadResumable.current) {
|
if (loading && isDownloadActive(MediaTypes.image, messageId)) {
|
||||||
return downloadResumable.current.cancelAsync();
|
cancelDownload(MediaTypes.image, messageId);
|
||||||
|
setLoading(false);
|
||||||
|
return setToDownload(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toDownload && !loading) {
|
if (toDownload && !loading) {
|
||||||
|
@ -159,15 +178,15 @@ const ImageContainer = React.memo(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return showAttachment(file);
|
return showAttachment(newFile);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (file.description) {
|
if (newFile.description) {
|
||||||
return (
|
return (
|
||||||
<Button disabled={isReply} theme={theme} onPress={onPress}>
|
<Button disabled={isReply} theme={theme} onPress={onPress}>
|
||||||
<View>
|
<View>
|
||||||
<Markdown
|
<Markdown
|
||||||
msg={file.description}
|
msg={newFile.description}
|
||||||
style={[isReply && style]}
|
style={[isReply && style]}
|
||||||
username={user.username}
|
username={user.username}
|
||||||
getCustomEmoji={getCustomEmoji}
|
getCustomEmoji={getCustomEmoji}
|
||||||
|
|
|
@ -56,7 +56,7 @@ export function downloadMediaFile({
|
||||||
messageId: string;
|
messageId: string;
|
||||||
downloadUrl: string;
|
downloadUrl: string;
|
||||||
path: string;
|
path: string;
|
||||||
}): Promise<string | null> {
|
}): Promise<string | void> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const downloadKey = mediaDownloadKey(mediaType, messageId);
|
const downloadKey = mediaDownloadKey(mediaType, messageId);
|
||||||
const options = {
|
const options = {
|
||||||
|
@ -70,20 +70,21 @@ export function downloadMediaFile({
|
||||||
if (response.respInfo.status >= 200 && response.respInfo.status < 400) {
|
if (response.respInfo.status >= 200 && response.respInfo.status < 400) {
|
||||||
// If response is all good...
|
// If response is all good...
|
||||||
try {
|
try {
|
||||||
console.log('🚀 ~ file: handleMediaDownload.ts:71 ~ returnnewPromise ~ response:', response, response.path());
|
resolve(path);
|
||||||
resolve(response.data);
|
|
||||||
delete downloadQueue[downloadKey];
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
reject();
|
||||||
log(e);
|
log(e);
|
||||||
|
} finally {
|
||||||
|
delete downloadQueue[downloadKey];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reject(null);
|
delete downloadQueue[downloadKey];
|
||||||
|
reject();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
downloadQueue[downloadKey].catch(error => {
|
downloadQueue[downloadKey].catch(() => {
|
||||||
console.log('🚀 ~ file: handleMediaDownload.ts:82 ~ returnnewPromise ~ error:', error);
|
|
||||||
delete downloadQueue[downloadKey];
|
delete downloadQueue[downloadKey];
|
||||||
reject(null);
|
reject();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -96,9 +97,19 @@ const getExtension = (type: MediaTypes, mimeType?: string) => {
|
||||||
if (!mimeType) {
|
if (!mimeType) {
|
||||||
return defaultType[type];
|
return defaultType[type];
|
||||||
}
|
}
|
||||||
|
const extensionFromMime = () => {
|
||||||
// The library is returning mpag instead of mp3 for audio/mpeg
|
// The library is returning mpag instead of mp3 for audio/mpeg
|
||||||
const extensionFromMime = mimeType === 'audio/mpeg' ? 'mp3' : mime.extension(mimeType);
|
if (mimeType === 'audio/mpeg') {
|
||||||
return extensionFromMime;
|
return 'mp3';
|
||||||
|
}
|
||||||
|
const extension = mime.extension(mimeType);
|
||||||
|
// The mime.extension can return false when there aren't any extension
|
||||||
|
if (!extension) {
|
||||||
|
return defaultType[type];
|
||||||
|
}
|
||||||
|
return extension;
|
||||||
|
};
|
||||||
|
return extensionFromMime();
|
||||||
};
|
};
|
||||||
|
|
||||||
const ensureDirAsync = async (dir: string, intermediates = true): Promise<void> => {
|
const ensureDirAsync = async (dir: string, intermediates = true): Promise<void> => {
|
||||||
|
|
Loading…
Reference in New Issue