remove all the redux stuff and do the same as file upload
This commit is contained in:
parent
f136dfb03c
commit
95cbe25ae7
|
@ -84,4 +84,3 @@ export const ENCRYPTION = createRequestTypes('ENCRYPTION', ['INIT', 'STOP', 'DEC
|
||||||
|
|
||||||
export const PERMISSIONS = createRequestTypes('PERMISSIONS', ['SET', 'UPDATE']);
|
export const PERMISSIONS = createRequestTypes('PERMISSIONS', ['SET', 'UPDATE']);
|
||||||
export const ROLES = createRequestTypes('ROLES', ['SET', 'UPDATE', 'REMOVE']);
|
export const ROLES = createRequestTypes('ROLES', ['SET', 'UPDATE', 'REMOVE']);
|
||||||
export const MEDIA_DOWNLOAD = createRequestTypes('MEDIA_DOWNLOAD', ['IN_PROGRESS', 'REMOVE']);
|
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
import { Action } from 'redux';
|
|
||||||
import { DownloadResumable } from 'expo-file-system';
|
|
||||||
|
|
||||||
import { MEDIA_DOWNLOAD } from './actionsTypes';
|
|
||||||
import { MediaTypes, mediaDownloadKey } from '../lib/methods/handleMediaDownload';
|
|
||||||
|
|
||||||
interface IMediaDownloadInProgressAction extends Action {
|
|
||||||
key: string;
|
|
||||||
downloadResumable: DownloadResumable;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IMediaDownloadRemoveAction extends Action {
|
|
||||||
key: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TActionMediaDownload = IMediaDownloadInProgressAction & IMediaDownloadRemoveAction;
|
|
||||||
|
|
||||||
interface IMediaDownloadInprogress {
|
|
||||||
mediaType: MediaTypes;
|
|
||||||
messageId: string;
|
|
||||||
downloadResumable: DownloadResumable;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IMediaDownloadRemove {
|
|
||||||
mediaType: MediaTypes;
|
|
||||||
messageId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const mediaDownloadInProgress = ({
|
|
||||||
mediaType,
|
|
||||||
messageId,
|
|
||||||
downloadResumable
|
|
||||||
}: IMediaDownloadInprogress): IMediaDownloadInProgressAction => {
|
|
||||||
const key = mediaDownloadKey(mediaType, messageId);
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: MEDIA_DOWNLOAD.IN_PROGRESS,
|
|
||||||
key,
|
|
||||||
downloadResumable
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const mediaDownloadRemove = ({ mediaType, messageId }: IMediaDownloadRemove): IMediaDownloadRemoveAction => {
|
|
||||||
const key = mediaDownloadKey(mediaType, messageId);
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: MEDIA_DOWNLOAD.REMOVE,
|
|
||||||
key
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React, { useContext, useLayoutEffect, useRef, useState } from 'react';
|
import React, { useContext, useEffect, useRef, useState } from 'react';
|
||||||
import { StyleProp, StyleSheet, TextStyle, View, Text } from 'react-native';
|
import { StyleProp, StyleSheet, TextStyle, View, Text } from 'react-native';
|
||||||
import { dequal } from 'dequal';
|
import { dequal } from 'dequal';
|
||||||
import * as FileSystem from 'expo-file-system';
|
|
||||||
|
|
||||||
import Touchable from './Touchable';
|
import Touchable from './Touchable';
|
||||||
import Markdown from '../markdown';
|
import Markdown from '../markdown';
|
||||||
|
@ -18,10 +17,16 @@ import RCActivityIndicator from '../ActivityIndicator';
|
||||||
import { TGetCustomEmoji } from '../../definitions/IEmoji';
|
import { TGetCustomEmoji } from '../../definitions/IEmoji';
|
||||||
import { useTheme } from '../../theme';
|
import { 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 {
|
||||||
|
LOCAL_DOCUMENT_PATH,
|
||||||
|
MediaTypes,
|
||||||
|
cancelDownload,
|
||||||
|
downloadMediaFile,
|
||||||
|
isDownloadActive,
|
||||||
|
searchMediaFileAsync
|
||||||
|
} from '../../lib/methods/handleMediaDownload';
|
||||||
import { isAutoDownloadEnabled } from './helpers/mediaDownload/autoDownloadPreference';
|
import { isAutoDownloadEnabled } from './helpers/mediaDownload/autoDownloadPreference';
|
||||||
import sharedStyles from '../../views/Styles';
|
import sharedStyles from '../../views/Styles';
|
||||||
import userPreferences from '../../lib/methods/userPreferences';
|
|
||||||
|
|
||||||
const SUPPORTED_TYPES = ['video/quicktime', 'video/mp4', ...(isIOS ? [] : ['video/3gp', 'video/mkv'])];
|
const SUPPORTED_TYPES = ['video/quicktime', 'video/mp4', ...(isIOS ? [] : ['video/3gp', 'video/mkv'])];
|
||||||
const isTypeSupported = (type: string) => SUPPORTED_TYPES.indexOf(type) !== -1;
|
const isTypeSupported = (type: string) => SUPPORTED_TYPES.indexOf(type) !== -1;
|
||||||
|
@ -70,18 +75,16 @@ const DownloadIndicator = ({ handleCancelDownload }: { handleCancelDownload(): v
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const downloadResumableKey = (video: string) => `DownloadResumable${video}`;
|
|
||||||
|
|
||||||
const Video = React.memo(
|
const Video = React.memo(
|
||||||
({ file, showAttachment, getCustomEmoji, style, isReply, messageId }: IMessageVideo) => {
|
({ file, showAttachment, getCustomEmoji, style, isReply, messageId }: IMessageVideo) => {
|
||||||
|
const [newFile, setNewFile] = useState(file);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const { baseUrl, user } = useContext(MessageContext);
|
const { baseUrl, user } = useContext(MessageContext);
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const filePath = useRef('');
|
const filePath = useRef('');
|
||||||
const downloadResumable = useRef<FileSystem.DownloadResumable | null>(null);
|
|
||||||
const video = formatAttachmentUrl(file.video_url, user.id, user.token, baseUrl);
|
const video = formatAttachmentUrl(file.video_url, user.id, user.token, baseUrl);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useEffect(() => {
|
||||||
const handleAutoDownload = async () => {
|
const handleAutoDownload = async () => {
|
||||||
if (video) {
|
if (video) {
|
||||||
const searchVideoCached = await searchMediaFileAsync({
|
const searchVideoCached = await searchMediaFileAsync({
|
||||||
|
@ -89,16 +92,25 @@ const Video = React.memo(
|
||||||
mimeType: file.video_type,
|
mimeType: file.video_type,
|
||||||
messageId
|
messageId
|
||||||
});
|
});
|
||||||
|
console.log('🚀 ~ file: Video.tsx:100 ~ handleAutoDownload ~ searchVideoCached:', searchVideoCached);
|
||||||
filePath.current = searchVideoCached.filePath;
|
filePath.current = searchVideoCached.filePath;
|
||||||
handleDownloadResumableSnapshot();
|
const downloadActive = isDownloadActive(MediaTypes.video, messageId);
|
||||||
if (searchVideoCached.file?.exists) {
|
if (searchVideoCached.file?.exists) {
|
||||||
file.video_url = searchVideoCached.file.uri;
|
setNewFile(prev => ({
|
||||||
|
...prev,
|
||||||
|
video_url: searchVideoCached.file?.uri
|
||||||
|
}));
|
||||||
|
if (downloadActive) {
|
||||||
|
cancelDownload(MediaTypes.video, messageId);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (downloadActive) return setLoading(true);
|
||||||
|
|
||||||
// We don't pass the author to avoid auto-download what the user sent
|
// We don't pass the author to avoid auto-download what the user sent
|
||||||
const autoDownload = await isAutoDownloadEnabled('imagesPreferenceDownload', { user });
|
const autoDownload = await isAutoDownloadEnabled('imagesPreferenceDownload', { user });
|
||||||
if (autoDownload && !downloadResumable.current) {
|
if (autoDownload) {
|
||||||
await handleDownload();
|
await handleDownload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,44 +122,31 @@ const Video = React.memo(
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDownloadResumableSnapshot = () => {
|
|
||||||
if (video) {
|
|
||||||
const result = userPreferences.getString(downloadResumableKey(video));
|
|
||||||
if (result) {
|
|
||||||
const snapshot = JSON.parse(result);
|
|
||||||
downloadResumable.current = new FileSystem.DownloadResumable(
|
|
||||||
video,
|
|
||||||
filePath.current,
|
|
||||||
{},
|
|
||||||
() => {},
|
|
||||||
snapshot.resumeData
|
|
||||||
);
|
|
||||||
setLoading(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDownload = async () => {
|
const handleDownload = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
downloadResumable.current = FileSystem.createDownloadResumable(video, filePath.current);
|
|
||||||
userPreferences.setString(downloadResumableKey(video), JSON.stringify(downloadResumable.current.savable()));
|
|
||||||
const videoUri = await downloadMediaFile({
|
const videoUri = await downloadMediaFile({
|
||||||
url: video,
|
downloadUrl: video,
|
||||||
filePath: filePath.current,
|
mediaType: MediaTypes.video,
|
||||||
downloadResumable: downloadResumable.current
|
messageId,
|
||||||
|
path: filePath.current
|
||||||
});
|
});
|
||||||
userPreferences.removeItem(downloadResumableKey(video));
|
console.log('🚀 ~ file: Video.tsx:137 ~ handleDownload ~ videoUri:', videoUri);
|
||||||
if (videoUri) {
|
if (videoUri) {
|
||||||
file.video_url = videoUri;
|
setNewFile(prev => ({
|
||||||
|
...prev,
|
||||||
|
video_url: videoUri
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPress = async () => {
|
const onPress = async () => {
|
||||||
if (file.video_type && isTypeSupported(file.video_type) && showAttachment) {
|
if (file.video_type && isTypeSupported(file.video_type) && showAttachment) {
|
||||||
|
if (!newFile.video_url?.startsWith(LOCAL_DOCUMENT_PATH) && !loading) {
|
||||||
// Keep the video downloading while showing the video buffering
|
// Keep the video downloading while showing the video buffering
|
||||||
handleDownload();
|
handleDownload();
|
||||||
return showAttachment(file);
|
}
|
||||||
|
return showAttachment(newFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isIOS && file.video_url) {
|
if (!isIOS && file.video_url) {
|
||||||
|
@ -158,9 +157,8 @@ const Video = React.memo(
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancelDownload = () => {
|
const handleCancelDownload = () => {
|
||||||
if (loading && downloadResumable.current) {
|
if (loading) {
|
||||||
downloadResumable.current.cancelAsync();
|
cancelDownload(MediaTypes.video, messageId);
|
||||||
userPreferences.removeItem(downloadResumableKey(video));
|
|
||||||
return setLoading(false);
|
return setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,7 +16,6 @@ import { TActionSortPreferences } from '../../actions/sortPreferences';
|
||||||
import { TActionUserTyping } from '../../actions/usersTyping';
|
import { TActionUserTyping } from '../../actions/usersTyping';
|
||||||
import { TActionPermissions } from '../../actions/permissions';
|
import { TActionPermissions } from '../../actions/permissions';
|
||||||
import { TActionEnterpriseModules } from '../../actions/enterpriseModules';
|
import { TActionEnterpriseModules } from '../../actions/enterpriseModules';
|
||||||
import { TActionMediaDownload } from '../../actions/mediaDownload';
|
|
||||||
// REDUCERS
|
// REDUCERS
|
||||||
import { IActiveUsers } from '../../reducers/activeUsers';
|
import { IActiveUsers } from '../../reducers/activeUsers';
|
||||||
import { IApp } from '../../reducers/app';
|
import { IApp } from '../../reducers/app';
|
||||||
|
@ -35,7 +34,6 @@ import { IShare } from '../../reducers/share';
|
||||||
import { IInquiry } from '../../ee/omnichannel/reducers/inquiry';
|
import { IInquiry } from '../../ee/omnichannel/reducers/inquiry';
|
||||||
import { IPermissionsState } from '../../reducers/permissions';
|
import { IPermissionsState } from '../../reducers/permissions';
|
||||||
import { IEnterpriseModules } from '../../reducers/enterpriseModules';
|
import { IEnterpriseModules } from '../../reducers/enterpriseModules';
|
||||||
import { IDownloads } from '../../reducers/mediaDownload';
|
|
||||||
|
|
||||||
export interface IApplicationState {
|
export interface IApplicationState {
|
||||||
settings: TSettingsState;
|
settings: TSettingsState;
|
||||||
|
@ -59,7 +57,6 @@ export interface IApplicationState {
|
||||||
encryption: IEncryption;
|
encryption: IEncryption;
|
||||||
permissions: IPermissionsState;
|
permissions: IPermissionsState;
|
||||||
roles: IRoles;
|
roles: IRoles;
|
||||||
mediaDownload: IDownloads;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TApplicationActions = TActionActiveUsers &
|
export type TApplicationActions = TActionActiveUsers &
|
||||||
|
@ -78,5 +75,4 @@ export type TApplicationActions = TActionActiveUsers &
|
||||||
TActionApp &
|
TActionApp &
|
||||||
TActionInquiry &
|
TActionInquiry &
|
||||||
TActionPermissions &
|
TActionPermissions &
|
||||||
TActionEnterpriseModules &
|
TActionEnterpriseModules;
|
||||||
TActionMediaDownload;
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import * as FileSystem from 'expo-file-system';
|
import * as FileSystem from 'expo-file-system';
|
||||||
import * as mime from 'react-native-mime-types';
|
import * as mime from 'react-native-mime-types';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
import RNFetchBlob, { FetchBlobResponse, StatefulPromise } from 'rn-fetch-blob';
|
||||||
|
|
||||||
import { sanitizeLikeString } from '../database/utils';
|
import { sanitizeLikeString } from '../database/utils';
|
||||||
import { store } from '../store/auxStore';
|
import { store } from '../store/auxStore';
|
||||||
|
@ -22,8 +24,70 @@ const defaultType = {
|
||||||
[MediaTypes.video]: 'mp4'
|
[MediaTypes.video]: 'mp4'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const downloadQueue: { [index: string]: StatefulPromise<FetchBlobResponse> } = {};
|
||||||
|
|
||||||
export const mediaDownloadKey = (mediaType: MediaTypes, messageId: string) => `${mediaType}-${messageId}`;
|
export const mediaDownloadKey = (mediaType: MediaTypes, messageId: string) => `${mediaType}-${messageId}`;
|
||||||
|
|
||||||
|
export function isDownloadActive(mediaType: MediaTypes, messageId: string): boolean {
|
||||||
|
return !!downloadQueue[mediaDownloadKey(mediaType, messageId)];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function cancelDownload(mediaType: MediaTypes, messageId: string): Promise<void> {
|
||||||
|
const downloadKey = mediaDownloadKey(mediaType, messageId);
|
||||||
|
if (!isEmpty(downloadQueue[downloadKey])) {
|
||||||
|
console.log('🚀 ~ file: handleMediaDownload.ts:38 ~ cancelDownload ~ downloadQueue:', downloadQueue);
|
||||||
|
try {
|
||||||
|
await downloadQueue[downloadKey].cancel();
|
||||||
|
} catch {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
delete downloadQueue[downloadKey];
|
||||||
|
console.log('🚀 ~ file: handleMediaDownload.ts:47 ~ cancelDownload ~ downloadQueue:', downloadQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function downloadMediaFile({
|
||||||
|
mediaType,
|
||||||
|
messageId,
|
||||||
|
downloadUrl,
|
||||||
|
path
|
||||||
|
}: {
|
||||||
|
mediaType: MediaTypes;
|
||||||
|
messageId: string;
|
||||||
|
downloadUrl: string;
|
||||||
|
path: string;
|
||||||
|
}): Promise<string | null> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const downloadKey = mediaDownloadKey(mediaType, messageId);
|
||||||
|
const options = {
|
||||||
|
timeout: 10000,
|
||||||
|
indicator: true,
|
||||||
|
overwrite: true,
|
||||||
|
path: path.replace('file://', '')
|
||||||
|
};
|
||||||
|
downloadQueue[downloadKey] = RNFetchBlob.config(options).fetch('GET', downloadUrl);
|
||||||
|
downloadQueue[downloadKey].then(response => {
|
||||||
|
if (response.respInfo.status >= 200 && response.respInfo.status < 400) {
|
||||||
|
// If response is all good...
|
||||||
|
try {
|
||||||
|
console.log('🚀 ~ file: handleMediaDownload.ts:71 ~ returnnewPromise ~ response:', response, response.path());
|
||||||
|
resolve(response.data);
|
||||||
|
delete downloadQueue[downloadKey];
|
||||||
|
} catch (e) {
|
||||||
|
log(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reject(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
downloadQueue[downloadKey].catch(error => {
|
||||||
|
console.log('🚀 ~ file: handleMediaDownload.ts:82 ~ returnnewPromise ~ error:', error);
|
||||||
|
delete downloadQueue[downloadKey];
|
||||||
|
reject(null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export const LOCAL_DOCUMENT_PATH = `${FileSystem.documentDirectory}`;
|
export const LOCAL_DOCUMENT_PATH = `${FileSystem.documentDirectory}`;
|
||||||
|
|
||||||
const sanitizeString = (value: string) => sanitizeLikeString(value.substring(value.lastIndexOf('/') + 1));
|
const sanitizeString = (value: string) => sanitizeLikeString(value.substring(value.lastIndexOf('/') + 1));
|
||||||
|
@ -72,30 +136,6 @@ export const searchMediaFileAsync = async ({
|
||||||
return { file, filePath };
|
return { file, filePath };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const downloadMediaFile = async ({
|
|
||||||
url,
|
|
||||||
filePath,
|
|
||||||
downloadResumable
|
|
||||||
}: {
|
|
||||||
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> => {
|
export const deleteAllSpecificMediaFiles = async (type: MediaTypes, serverUrl: string): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
const serverUrlParsed = sanitizeString(serverUrl);
|
const serverUrlParsed = sanitizeString(serverUrl);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as FileSystem from 'expo-file-system';
|
import { LOCAL_DOCUMENT_PATH } from '../handleMediaDownload';
|
||||||
|
|
||||||
export const formatAttachmentUrl = (attachmentUrl: string | undefined, userId: string, token: string, server: string): string => {
|
export const formatAttachmentUrl = (attachmentUrl: string | undefined, userId: string, token: string, server: string): string => {
|
||||||
if (attachmentUrl?.startsWith(`${FileSystem.documentDirectory}`)) {
|
if (attachmentUrl?.startsWith(LOCAL_DOCUMENT_PATH)) {
|
||||||
return attachmentUrl;
|
return attachmentUrl;
|
||||||
}
|
}
|
||||||
if (attachmentUrl && attachmentUrl.startsWith('http')) {
|
if (attachmentUrl && attachmentUrl.startsWith('http')) {
|
||||||
|
|
|
@ -21,7 +21,6 @@ import enterpriseModules from './enterpriseModules';
|
||||||
import encryption from './encryption';
|
import encryption from './encryption';
|
||||||
import permissions from './permissions';
|
import permissions from './permissions';
|
||||||
import roles from './roles';
|
import roles from './roles';
|
||||||
import mediaDownload from './mediaDownload';
|
|
||||||
|
|
||||||
export default combineReducers({
|
export default combineReducers({
|
||||||
settings,
|
settings,
|
||||||
|
@ -44,6 +43,5 @@ export default combineReducers({
|
||||||
enterpriseModules,
|
enterpriseModules,
|
||||||
encryption,
|
encryption,
|
||||||
permissions,
|
permissions,
|
||||||
roles,
|
roles
|
||||||
mediaDownload
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
import { DownloadResumable } from 'expo-file-system';
|
|
||||||
|
|
||||||
import { mediaDownloadInProgress, mediaDownloadRemove } from '../actions/mediaDownload';
|
|
||||||
import { IDownloads, initialState } from './mediaDownload';
|
|
||||||
import { mockedStore } from './mockedStore';
|
|
||||||
import { MediaTypes } from '../lib/methods/handleMediaDownload';
|
|
||||||
|
|
||||||
describe('test reducer', () => {
|
|
||||||
const downloadResumable = 'downloadResumable' as unknown as DownloadResumable;
|
|
||||||
const downloadResumableTwo = 'downloadResumableTwo' as unknown as DownloadResumable;
|
|
||||||
|
|
||||||
it('should return initial state', () => {
|
|
||||||
const state = mockedStore.getState().mediaDownload;
|
|
||||||
expect(state).toEqual(initialState);
|
|
||||||
});
|
|
||||||
it('should return modified store after action', () => {
|
|
||||||
const expectState: IDownloads = { [`${MediaTypes.video}-id`]: downloadResumable };
|
|
||||||
mockedStore.dispatch(mediaDownloadInProgress({ mediaType: MediaTypes.video, messageId: 'id', downloadResumable }));
|
|
||||||
const state = mockedStore.getState().mediaDownload;
|
|
||||||
expect(state).toEqual({ ...expectState });
|
|
||||||
});
|
|
||||||
it('should return the state correct after add second download', () => {
|
|
||||||
mockedStore.dispatch(
|
|
||||||
mediaDownloadInProgress({ mediaType: MediaTypes.audio, messageId: 'id', downloadResumable: downloadResumableTwo })
|
|
||||||
);
|
|
||||||
const expectState = {
|
|
||||||
[`${MediaTypes.video}-id`]: downloadResumable,
|
|
||||||
[`${MediaTypes.audio}-id`]: downloadResumableTwo
|
|
||||||
};
|
|
||||||
const state = mockedStore.getState().mediaDownload;
|
|
||||||
expect(state).toEqual({ ...expectState });
|
|
||||||
});
|
|
||||||
it('should remove one download', () => {
|
|
||||||
mockedStore.dispatch(mediaDownloadRemove({ mediaType: MediaTypes.video, messageId: 'id' }));
|
|
||||||
const expectState = {
|
|
||||||
[`${MediaTypes.audio}-id`]: downloadResumableTwo
|
|
||||||
};
|
|
||||||
const state = mockedStore.getState().mediaDownload;
|
|
||||||
expect(state).toEqual({ ...expectState });
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,26 +0,0 @@
|
||||||
import { DownloadResumable } from 'expo-file-system';
|
|
||||||
|
|
||||||
import { MEDIA_DOWNLOAD } from '../actions/actionsTypes';
|
|
||||||
import { TApplicationActions } from '../definitions';
|
|
||||||
|
|
||||||
export interface IDownloads {
|
|
||||||
[key: string]: DownloadResumable;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const initialState: IDownloads = {};
|
|
||||||
|
|
||||||
export default function mediaDownload(state = initialState, action: TApplicationActions): IDownloads {
|
|
||||||
switch (action.type) {
|
|
||||||
case MEDIA_DOWNLOAD.IN_PROGRESS:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
[action.key]: action.downloadResumable
|
|
||||||
};
|
|
||||||
case MEDIA_DOWNLOAD.REMOVE:
|
|
||||||
const newState = { ...state };
|
|
||||||
delete newState[action.key];
|
|
||||||
return newState;
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
import { createSelector } from 'reselect';
|
|
||||||
|
|
||||||
import { IApplicationState } from '../definitions';
|
|
||||||
import { MediaTypes, mediaDownloadKey } from '../lib/methods/handleMediaDownload';
|
|
||||||
import { IDownloads } from '../reducers/mediaDownload';
|
|
||||||
|
|
||||||
const selectMediaDownload = (state: IApplicationState) => state.mediaDownload;
|
|
||||||
|
|
||||||
const getMediaDownload = (mediaDownload: IDownloads, { mediaType, messageId }: { mediaType: MediaTypes; messageId: string }) => {
|
|
||||||
console.log('🚀 ~ file: mediaDownload.ts:10 ~ getMediaDownload ~ { mediaType, messageId }:', { mediaType, messageId });
|
|
||||||
console.log('🚀 ~ file: mediaDownload.ts:10 ~ getMediaDownload ~ mediaDownload:', mediaDownload);
|
|
||||||
const key = mediaDownloadKey(mediaType, messageId);
|
|
||||||
if (mediaDownload[key]) return mediaDownload[key];
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getDownloadResumable = createSelector(
|
|
||||||
[
|
|
||||||
selectMediaDownload,
|
|
||||||
(_state: IApplicationState, { mediaType, messageId }: { mediaType: MediaTypes; messageId: string }) => ({
|
|
||||||
mediaType,
|
|
||||||
messageId
|
|
||||||
})
|
|
||||||
],
|
|
||||||
getMediaDownload
|
|
||||||
);
|
|
Loading…
Reference in New Issue