Resumable backup import

This commit is contained in:
Fedor Indutny 2024-08-27 17:00:41 -04:00 committed by GitHub
parent 3d8aaf0a5a
commit 8ef149e3a8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 498 additions and 33 deletions

View file

@ -15,12 +15,32 @@ export enum AppViewType {
Inbox = 'Inbox',
Installer = 'Installer',
Standalone = 'Standalone',
BackupImport = 'BackupImport',
}
export type AppStateType = ReadonlyDeep<{
appView: AppViewType;
hasInitialLoadCompleted: boolean;
}>;
export type AppStateType = ReadonlyDeep<
{
hasInitialLoadCompleted: boolean;
} & (
| {
appView: AppViewType.Blank;
}
| {
appView: AppViewType.Inbox;
}
| {
appView: AppViewType.Installer;
}
| {
appView: AppViewType.Standalone;
}
| {
appView: AppViewType.BackupImport;
currentBytes?: number;
totalBytes?: number;
}
)
>;
// Actions
@ -28,6 +48,8 @@ const INITIAL_LOAD_COMPLETE = 'app/INITIAL_LOAD_COMPLETE';
const OPEN_INBOX = 'app/OPEN_INBOX';
const OPEN_INSTALLER = 'app/OPEN_INSTALLER';
const OPEN_STANDALONE = 'app/OPEN_STANDALONE';
const OPEN_BACKUP_IMPORT = 'app/OPEN_BACKUP_IMPORT';
const UPDATE_BACKUP_IMPORT_PROGRESS = 'app/UPDATE_BACKUP_IMPORT_PROGRESS';
type InitialLoadCompleteActionType = ReadonlyDeep<{
type: typeof INITIAL_LOAD_COMPLETE;
@ -45,11 +67,25 @@ type OpenStandaloneActionType = ReadonlyDeep<{
type: typeof OPEN_STANDALONE;
}>;
type OpenBackupImportActionType = ReadonlyDeep<{
type: typeof OPEN_BACKUP_IMPORT;
}>;
type UpdateBackupImportProgressActionType = ReadonlyDeep<{
type: typeof UPDATE_BACKUP_IMPORT_PROGRESS;
payload: {
currentBytes: number;
totalBytes: number;
};
}>;
export type AppActionType = ReadonlyDeep<
| InitialLoadCompleteActionType
| OpenInboxActionType
| OpenInstallerActionType
| OpenStandaloneActionType
| OpenBackupImportActionType
| UpdateBackupImportProgressActionType
>;
export const actions = {
@ -57,6 +93,8 @@ export const actions = {
openInbox,
openInstaller,
openStandalone,
openBackupImport,
updateBackupImportProgress,
};
export const useAppActions = (): BoundActionCreatorsMapObject<typeof actions> =>
@ -118,6 +156,16 @@ function openStandalone(): ThunkAction<
};
}
function openBackupImport(): OpenBackupImportActionType {
return { type: OPEN_BACKUP_IMPORT };
}
function updateBackupImportProgress(
payload: UpdateBackupImportProgressActionType['payload']
): UpdateBackupImportProgressActionType {
return { type: UPDATE_BACKUP_IMPORT_PROGRESS, payload };
}
// Reducer
export function getEmptyState(): AppStateType {
@ -159,5 +207,24 @@ export function reducer(
};
}
if (action.type === OPEN_BACKUP_IMPORT) {
return {
...state,
appView: AppViewType.BackupImport,
};
}
if (action.type === UPDATE_BACKUP_IMPORT_PROGRESS) {
if (state.appView !== AppViewType.BackupImport) {
return state;
}
return {
...state,
currentBytes: action.payload.currentBytes,
totalBytes: action.payload.totalBytes,
};
}
return state;
}

View file

@ -18,6 +18,7 @@ import {
getIsMainWindowMaximized,
getIsMainWindowFullScreen,
getTheme,
getIntl,
} from '../selectors/user';
import { hasSelectedStoryData as getHasSelectedStoryData } from '../selectors/stories';
import { useAppActions } from '../ducks/app';
@ -26,7 +27,7 @@ import { useStoriesActions } from '../ducks/stories';
import { ErrorBoundary } from '../../components/ErrorBoundary';
import { ModalContainer } from '../../components/ModalContainer';
import { SmartInbox } from './Inbox';
import { getAppView } from '../selectors/app';
import { getApp } from '../selectors/app';
function renderInbox(): JSX.Element {
return <SmartInbox />;
@ -110,7 +111,8 @@ async function uploadProfile({
}
export const SmartApp = memo(function SmartApp() {
const appView = useSelector(getAppView);
const i18n = useSelector(getIntl);
const state = useSelector(getApp);
const isMaximized = useSelector(getIsMainWindowMaximized);
const isFullScreen = useSelector(getIsMainWindowFullScreen);
const hasSelectedStoryData = useSelector(getHasSelectedStoryData);
@ -124,7 +126,8 @@ export const SmartApp = memo(function SmartApp() {
return (
<App
appView={appView}
i18n={i18n}
state={state}
isMaximized={isMaximized}
isFullScreen={isFullScreen}
getCaptchaToken={getCaptchaToken}