refactor audioFile to handleMediaDownload and fixed the audio download
This commit is contained in:
parent
d138a74d9d
commit
27eacaad9f
|
@ -19,7 +19,7 @@ import { withDimensions } from '../../dimensions';
|
||||||
import { TGetCustomEmoji } from '../../definitions/IEmoji';
|
import { TGetCustomEmoji } from '../../definitions/IEmoji';
|
||||||
import { IAttachment, IUserMessage } from '../../definitions';
|
import { IAttachment, IUserMessage } from '../../definitions';
|
||||||
import { TSupportedThemes } from '../../theme';
|
import { TSupportedThemes } from '../../theme';
|
||||||
import { downloadAudioFile, searchAudioFileAsync } from '../../lib/methods/audioFile';
|
import { MediaTypes, downloadMediaFile, searchMediaFileAsync } from '../../lib/methods/handleMediaDownload';
|
||||||
import EventEmitter from '../../lib/methods/helpers/events';
|
import EventEmitter from '../../lib/methods/helpers/events';
|
||||||
import { PAUSE_AUDIO } from './constants';
|
import { PAUSE_AUDIO } from './constants';
|
||||||
import { isAutoDownloadEnabled } from './helpers/mediaDownload/autoDownloadPreference';
|
import { isAutoDownloadEnabled } from './helpers/mediaDownload/autoDownloadPreference';
|
||||||
|
@ -161,12 +161,16 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
};
|
};
|
||||||
|
|
||||||
handleAutoDownload = async () => {
|
handleAutoDownload = async () => {
|
||||||
const { messageId, author } = this.props;
|
const { messageId, author, file } = 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 searchAudioFileAsync(url, messageId);
|
const fileSearch = await searchMediaFileAsync({
|
||||||
|
type: MediaTypes.audio,
|
||||||
|
mimeType: file.audio_type,
|
||||||
|
messageId
|
||||||
|
});
|
||||||
if (fileSearch?.file?.exists) {
|
if (fileSearch?.file?.exists) {
|
||||||
await this.sound.loadAsync({ uri: fileSearch.file.uri });
|
await this.sound.loadAsync({ uri: fileSearch.file.uri });
|
||||||
return this.setState({ loading: false });
|
return this.setState({ loading: false });
|
||||||
|
@ -277,15 +281,19 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
};
|
};
|
||||||
|
|
||||||
startDownload = async () => {
|
startDownload = async () => {
|
||||||
const { messageId } = this.props;
|
const { messageId, file } = 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) {
|
if (url) {
|
||||||
const fileSearch = await searchAudioFileAsync(url, messageId);
|
const fileSearch = await searchMediaFileAsync({
|
||||||
const audio = await downloadAudioFile(`${url}?rc_uid=${user.id}&rc_token=${user.token}`, fileSearch.filePath);
|
type: MediaTypes.audio,
|
||||||
|
mimeType: file.audio_type,
|
||||||
|
messageId
|
||||||
|
});
|
||||||
|
const audio = await downloadMediaFile(`${url}?rc_uid=${user.id}&rc_token=${user.token}`, fileSearch.filePath);
|
||||||
await this.sound.loadAsync({ uri: audio });
|
await this.sound.loadAsync({ uri: audio });
|
||||||
return this.setState({ loading: false, toDownload: false });
|
return this.setState({ loading: false, toDownload: false });
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ export interface IAttachment {
|
||||||
color?: string;
|
color?: string;
|
||||||
thumb_url?: string;
|
thumb_url?: string;
|
||||||
collapsed?: boolean;
|
collapsed?: boolean;
|
||||||
|
audio_type?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IServerAttachment {
|
export interface IServerAttachment {
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
import * as FileSystem from 'expo-file-system';
|
|
||||||
|
|
||||||
import { sanitizeLikeString } from '../database/utils';
|
|
||||||
import { store } from '../store/auxStore';
|
|
||||||
import log from './helpers/log';
|
|
||||||
|
|
||||||
const DEFAULT_EXTENSION = 'mp3';
|
|
||||||
|
|
||||||
const sanitizeString = (value: string) => sanitizeLikeString(value.substring(value.lastIndexOf('/') + 1));
|
|
||||||
|
|
||||||
const getExtension = (value: string) => {
|
|
||||||
let extension = DEFAULT_EXTENSION;
|
|
||||||
const filename = value.split('/').pop();
|
|
||||||
if (filename?.includes('.')) {
|
|
||||||
extension = value.substring(value.lastIndexOf('.') + 1);
|
|
||||||
}
|
|
||||||
return extension;
|
|
||||||
};
|
|
||||||
|
|
||||||
const ensureDirAsync = async (dir: string, intermediates = true): Promise<void> => {
|
|
||||||
const info = await FileSystem.getInfoAsync(dir);
|
|
||||||
if (info.exists && info.isDirectory) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await FileSystem.makeDirectoryAsync(dir, { intermediates });
|
|
||||||
return ensureDirAsync(dir, intermediates);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const searchAudioFileAsync = async (fileUrl: string, messageId: string) => {
|
|
||||||
let file;
|
|
||||||
let filePath = '';
|
|
||||||
try {
|
|
||||||
const serverUrl = store.getState().server.server;
|
|
||||||
const serverUrlParsed = sanitizeString(serverUrl);
|
|
||||||
const folderPath = `${FileSystem.documentDirectory}audios/${serverUrlParsed}`;
|
|
||||||
const filename = `${messageId}.${getExtension(fileUrl)}`;
|
|
||||||
filePath = `${folderPath}/${filename}`;
|
|
||||||
await ensureDirAsync(folderPath);
|
|
||||||
file = await FileSystem.getInfoAsync(filePath);
|
|
||||||
} catch (e) {
|
|
||||||
log(e);
|
|
||||||
}
|
|
||||||
return { file, filePath };
|
|
||||||
};
|
|
||||||
|
|
||||||
export const downloadAudioFile = async (url: string, filePath: string) => {
|
|
||||||
let uri = '';
|
|
||||||
try {
|
|
||||||
const downloadedFile = await FileSystem.downloadAsync(url, filePath);
|
|
||||||
uri = downloadedFile.uri;
|
|
||||||
} catch (error) {
|
|
||||||
log(error);
|
|
||||||
}
|
|
||||||
return uri;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const deleteAllAudioFiles = async (serverUrl: string): Promise<void> => {
|
|
||||||
try {
|
|
||||||
const serverUrlParsed = sanitizeString(serverUrl);
|
|
||||||
const path = `${FileSystem.documentDirectory}audios/${serverUrlParsed}`;
|
|
||||||
await FileSystem.deleteAsync(path, { idempotent: true });
|
|
||||||
} catch (error) {
|
|
||||||
log(error);
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
import * as FileSystem from 'expo-file-system';
|
||||||
|
import * as mime from 'react-native-mime-types';
|
||||||
|
|
||||||
|
import { sanitizeLikeString } from '../database/utils';
|
||||||
|
import { store } from '../store/auxStore';
|
||||||
|
import log from './helpers/log';
|
||||||
|
|
||||||
|
export enum MediaTypes {
|
||||||
|
audio = 'audio',
|
||||||
|
image = 'image',
|
||||||
|
video = 'video'
|
||||||
|
}
|
||||||
|
const typeString = {
|
||||||
|
[MediaTypes.audio]: 'audios/',
|
||||||
|
[MediaTypes.image]: 'images/',
|
||||||
|
[MediaTypes.video]: 'videos/'
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultType = {
|
||||||
|
[MediaTypes.audio]: 'mp3',
|
||||||
|
[MediaTypes.image]: 'jpg',
|
||||||
|
[MediaTypes.video]: 'mp4'
|
||||||
|
};
|
||||||
|
|
||||||
|
const sanitizeString = (value: string) => sanitizeLikeString(value.substring(value.lastIndexOf('/') + 1));
|
||||||
|
|
||||||
|
const getExtension = (type: MediaTypes, mimeType?: string) => {
|
||||||
|
if (!mimeType) {
|
||||||
|
return defaultType[type];
|
||||||
|
}
|
||||||
|
// The library is returning mpag instead of mp3 for audio/mpeg
|
||||||
|
const extensionFromMime = mimeType === 'audio/mpeg' ? 'mp3' : mime.extension(mimeType);
|
||||||
|
return extensionFromMime;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ensureDirAsync = async (dir: string, intermediates = true): Promise<void> => {
|
||||||
|
const info = await FileSystem.getInfoAsync(dir);
|
||||||
|
if (info.exists && info.isDirectory) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await FileSystem.makeDirectoryAsync(dir, { intermediates });
|
||||||
|
return ensureDirAsync(dir, intermediates);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const searchMediaFileAsync = async ({
|
||||||
|
type,
|
||||||
|
mimeType,
|
||||||
|
messageId
|
||||||
|
}: {
|
||||||
|
type: MediaTypes;
|
||||||
|
mimeType?: string;
|
||||||
|
messageId: string;
|
||||||
|
}) => {
|
||||||
|
let file;
|
||||||
|
let filePath = '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const serverUrl = store.getState().server.server;
|
||||||
|
const serverUrlParsed = sanitizeString(serverUrl);
|
||||||
|
const folderPath = `${FileSystem.documentDirectory}${typeString[type]}${serverUrlParsed}`;
|
||||||
|
const filename = `${messageId}.${getExtension(type, mimeType)}`;
|
||||||
|
filePath = `${folderPath}/${filename}`;
|
||||||
|
await ensureDirAsync(folderPath);
|
||||||
|
file = await FileSystem.getInfoAsync(filePath);
|
||||||
|
} catch (e) {
|
||||||
|
log(e);
|
||||||
|
}
|
||||||
|
return { file, filePath };
|
||||||
|
};
|
||||||
|
|
||||||
|
export const downloadMediaFile = async (url: string, filePath: string, downloadResumable?: FileSystem.DownloadResumable) => {
|
||||||
|
let uri = '';
|
||||||
|
try {
|
||||||
|
if (downloadResumable) {
|
||||||
|
const downloadFile = await downloadResumable.downloadAsync();
|
||||||
|
uri = downloadFile?.uri || '';
|
||||||
|
} else {
|
||||||
|
const downloadedFile = await FileSystem.downloadAsync(url, filePath);
|
||||||
|
uri = downloadedFile.uri;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
log(error);
|
||||||
|
}
|
||||||
|
return uri;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteAllSpecificMediaFiles = async (type: MediaTypes, serverUrl: string): Promise<void> => {
|
||||||
|
try {
|
||||||
|
const serverUrlParsed = sanitizeString(serverUrl);
|
||||||
|
const path = `${FileSystem.documentDirectory}${typeString[type]}${serverUrlParsed}`;
|
||||||
|
await FileSystem.deleteAsync(path, { idempotent: true });
|
||||||
|
} catch (error) {
|
||||||
|
log(error);
|
||||||
|
}
|
||||||
|
};
|
|
@ -21,7 +21,7 @@ import { APP_STORE_LINK, FDROID_MARKET_LINK, isFDroidBuild, LICENSE_LINK, PLAY_M
|
||||||
import database from '../../lib/database';
|
import database from '../../lib/database';
|
||||||
import { useAppSelector } from '../../lib/hooks';
|
import { useAppSelector } from '../../lib/hooks';
|
||||||
import { clearCache } from '../../lib/methods';
|
import { clearCache } from '../../lib/methods';
|
||||||
import { deleteAllAudioFiles } from '../../lib/methods/audioFile';
|
import { deleteAllSpecificMediaFiles, MediaTypes } from '../../lib/methods/handleMediaDownload';
|
||||||
import { getDeviceModel, getReadableVersion, isAndroid } from '../../lib/methods/helpers';
|
import { getDeviceModel, getReadableVersion, isAndroid } from '../../lib/methods/helpers';
|
||||||
import EventEmitter from '../../lib/methods/helpers/events';
|
import EventEmitter from '../../lib/methods/helpers/events';
|
||||||
import { showConfirmationAlert, showErrorAlert } from '../../lib/methods/helpers/info';
|
import { showConfirmationAlert, showErrorAlert } from '../../lib/methods/helpers/info';
|
||||||
|
@ -99,7 +99,7 @@ const SettingsView = (): React.ReactElement => {
|
||||||
confirmationText: I18n.t('Clear'),
|
confirmationText: I18n.t('Clear'),
|
||||||
onPress: async () => {
|
onPress: async () => {
|
||||||
dispatch(appStart({ root: RootEnum.ROOT_LOADING, text: I18n.t('Clear_cache_loading') }));
|
dispatch(appStart({ root: RootEnum.ROOT_LOADING, text: I18n.t('Clear_cache_loading') }));
|
||||||
await deleteAllAudioFiles(server);
|
await deleteAllSpecificMediaFiles(MediaTypes.audio, server);
|
||||||
await clearCache({ server });
|
await clearCache({ server });
|
||||||
await FastImage.clearMemoryCache();
|
await FastImage.clearMemoryCache();
|
||||||
await FastImage.clearDiskCache();
|
await FastImage.clearDiskCache();
|
||||||
|
|
Loading…
Reference in New Issue