remove mediaType and refactor audio and image
This commit is contained in:
parent
1be2326686
commit
b6ae55e57f
|
@ -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 () => {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue