introducing the reducer to keep the downloads in progress
This commit is contained in:
parent
370f893e94
commit
154deb62ac
|
@ -84,3 +84,4 @@ 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']);
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
import { DownloadResumable } from 'expo-file-system';
|
||||||
|
|
||||||
|
import { MEDIA_DOWNLOAD } from './actionsTypes';
|
||||||
|
import { MediaTypes } 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
const downloadKey = (mediaType: MediaTypes, messageId: string) => `${mediaType}-${messageId}`;
|
||||||
|
|
||||||
|
export const mediaDownloadInProgress = ({
|
||||||
|
mediaType,
|
||||||
|
messageId,
|
||||||
|
downloadResumable
|
||||||
|
}: IMediaDownloadInprogress): IMediaDownloadInProgressAction => {
|
||||||
|
const key = downloadKey(mediaType, messageId);
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: MEDIA_DOWNLOAD.IN_PROGRESS,
|
||||||
|
key,
|
||||||
|
downloadResumable
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mediaDownloadRemove = ({ mediaType, messageId }: IMediaDownloadRemove): IMediaDownloadRemoveAction => {
|
||||||
|
const key = downloadKey(mediaType, messageId);
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: MEDIA_DOWNLOAD.REMOVE,
|
||||||
|
key
|
||||||
|
};
|
||||||
|
};
|
|
@ -16,6 +16,7 @@ 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';
|
||||||
|
@ -34,6 +35,7 @@ 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;
|
||||||
|
@ -57,6 +59,7 @@ 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 &
|
||||||
|
@ -75,4 +78,5 @@ export type TApplicationActions = TActionActiveUsers &
|
||||||
TActionApp &
|
TActionApp &
|
||||||
TActionInquiry &
|
TActionInquiry &
|
||||||
TActionPermissions &
|
TActionPermissions &
|
||||||
TActionEnterpriseModules;
|
TActionEnterpriseModules &
|
||||||
|
TActionMediaDownload;
|
||||||
|
|
|
@ -22,6 +22,8 @@ const defaultType = {
|
||||||
[MediaTypes.video]: 'mp4'
|
[MediaTypes.video]: 'mp4'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
const getExtension = (type: MediaTypes, mimeType?: string) => {
|
const getExtension = (type: MediaTypes, mimeType?: string) => {
|
||||||
|
@ -57,7 +59,7 @@ export const searchMediaFileAsync = async ({
|
||||||
try {
|
try {
|
||||||
const serverUrl = store.getState().server.server;
|
const serverUrl = store.getState().server.server;
|
||||||
const serverUrlParsed = sanitizeString(serverUrl);
|
const serverUrlParsed = sanitizeString(serverUrl);
|
||||||
const folderPath = `${FileSystem.documentDirectory}${typeString[type]}${serverUrlParsed}`;
|
const folderPath = `${LOCAL_DOCUMENT_PATH}${typeString[type]}${serverUrlParsed}`;
|
||||||
const filename = `${messageId}.${getExtension(type, mimeType)}`;
|
const filename = `${messageId}.${getExtension(type, mimeType)}`;
|
||||||
filePath = `${folderPath}/${filename}`;
|
filePath = `${folderPath}/${filename}`;
|
||||||
await ensureDirAsync(folderPath);
|
await ensureDirAsync(folderPath);
|
||||||
|
@ -95,7 +97,7 @@ export const downloadMediaFile = async ({
|
||||||
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);
|
||||||
const path = `${FileSystem.documentDirectory}${typeString[type]}${serverUrlParsed}`;
|
const path = `${LOCAL_DOCUMENT_PATH}${typeString[type]}${serverUrlParsed}`;
|
||||||
await FileSystem.deleteAsync(path, { idempotent: true });
|
await FileSystem.deleteAsync(path, { idempotent: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log(error);
|
log(error);
|
||||||
|
|
|
@ -21,6 +21,7 @@ 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,
|
||||||
|
@ -43,5 +44,6 @@ export default combineReducers({
|
||||||
enterpriseModules,
|
enterpriseModules,
|
||||||
encryption,
|
encryption,
|
||||||
permissions,
|
permissions,
|
||||||
roles
|
roles,
|
||||||
|
mediaDownload
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
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 });
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,26 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue