introducing the reducer to keep the downloads in progress

This commit is contained in:
Reinaldo Neto 2023-05-18 18:36:58 -03:00
parent 370f893e94
commit 154deb62ac
7 changed files with 132 additions and 4 deletions

View File

@ -84,3 +84,4 @@ export const ENCRYPTION = createRequestTypes('ENCRYPTION', ['INIT', 'STOP', 'DEC
export const PERMISSIONS = createRequestTypes('PERMISSIONS', ['SET', 'UPDATE']);
export const ROLES = createRequestTypes('ROLES', ['SET', 'UPDATE', 'REMOVE']);
export const MEDIA_DOWNLOAD = createRequestTypes('MEDIA_DOWNLOAD', ['IN_PROGRESS', 'REMOVE']);

View File

@ -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
};
};

View File

@ -16,6 +16,7 @@ import { TActionSortPreferences } from '../../actions/sortPreferences';
import { TActionUserTyping } from '../../actions/usersTyping';
import { TActionPermissions } from '../../actions/permissions';
import { TActionEnterpriseModules } from '../../actions/enterpriseModules';
import { TActionMediaDownload } from '../../actions/mediaDownload';
// REDUCERS
import { IActiveUsers } from '../../reducers/activeUsers';
import { IApp } from '../../reducers/app';
@ -34,6 +35,7 @@ import { IShare } from '../../reducers/share';
import { IInquiry } from '../../ee/omnichannel/reducers/inquiry';
import { IPermissionsState } from '../../reducers/permissions';
import { IEnterpriseModules } from '../../reducers/enterpriseModules';
import { IDownloads } from '../../reducers/mediaDownload';
export interface IApplicationState {
settings: TSettingsState;
@ -57,6 +59,7 @@ export interface IApplicationState {
encryption: IEncryption;
permissions: IPermissionsState;
roles: IRoles;
mediaDownload: IDownloads;
}
export type TApplicationActions = TActionActiveUsers &
@ -75,4 +78,5 @@ export type TApplicationActions = TActionActiveUsers &
TActionApp &
TActionInquiry &
TActionPermissions &
TActionEnterpriseModules;
TActionEnterpriseModules &
TActionMediaDownload;

View File

@ -22,6 +22,8 @@ const defaultType = {
[MediaTypes.video]: 'mp4'
};
export const LOCAL_DOCUMENT_PATH = `${FileSystem.documentDirectory}`;
const sanitizeString = (value: string) => sanitizeLikeString(value.substring(value.lastIndexOf('/') + 1));
const getExtension = (type: MediaTypes, mimeType?: string) => {
@ -57,7 +59,7 @@ export const searchMediaFileAsync = async ({
try {
const serverUrl = store.getState().server.server;
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)}`;
filePath = `${folderPath}/${filename}`;
await ensureDirAsync(folderPath);
@ -95,7 +97,7 @@ export const downloadMediaFile = async ({
export const deleteAllSpecificMediaFiles = async (type: MediaTypes, serverUrl: string): Promise<void> => {
try {
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 });
} catch (error) {
log(error);

View File

@ -21,6 +21,7 @@ import enterpriseModules from './enterpriseModules';
import encryption from './encryption';
import permissions from './permissions';
import roles from './roles';
import mediaDownload from './mediaDownload';
export default combineReducers({
settings,
@ -43,5 +44,6 @@ export default combineReducers({
enterpriseModules,
encryption,
permissions,
roles
roles,
mediaDownload
});

View File

@ -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 });
});
});

View File

@ -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;
}
}