signal-desktop/ts/state/ducks/updates.ts

210 lines
4.3 KiB
TypeScript
Raw Normal View History

2020-10-30 20:34:04 +00:00
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { ThunkAction } from 'redux-thunk';
import type { ReadonlyDeep } from 'type-fest';
2023-03-20 20:42:00 +00:00
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
import { useBoundActions } from '../../hooks/useBoundActions';
import * as updateIpc from '../../shims/updateIpc';
import { DialogType } from '../../types/Dialogs';
2021-10-06 21:59:34 +00:00
import { DAY } from '../../util/durations';
import type { StateType as RootStateType } from '../reducer';
// State
export type UpdatesStateType = ReadonlyDeep<{
dialogType: DialogType;
2020-02-21 00:09:50 +00:00
didSnooze: boolean;
downloadSize?: number;
downloadedSize?: number;
2020-02-21 00:09:50 +00:00
showEventsCount: number;
version?: string;
}>;
// Actions
const DISMISS_DIALOG = 'updates/DISMISS_DIALOG';
const SHOW_UPDATE_DIALOG = 'updates/SHOW_UPDATE_DIALOG';
2020-02-21 00:09:50 +00:00
const SNOOZE_UPDATE = 'updates/SNOOZE_UPDATE';
const START_UPDATE = 'updates/START_UPDATE';
const UNSNOOZE_UPDATE = 'updates/UNSNOOZE_UPDATE';
export type UpdateDialogOptionsType = ReadonlyDeep<{
downloadSize?: number;
downloadedSize?: number;
version?: string;
}>;
type DismissDialogActionType = ReadonlyDeep<{
type: typeof DISMISS_DIALOG;
}>;
export type ShowUpdateDialogActionType = ReadonlyDeep<{
type: typeof SHOW_UPDATE_DIALOG;
payload: {
dialogType: DialogType;
otherState: UpdateDialogOptionsType;
};
}>;
type SnoozeUpdateActionType = ReadonlyDeep<{
type: typeof SNOOZE_UPDATE;
}>;
2020-02-21 00:09:50 +00:00
type StartUpdateActionType = ReadonlyDeep<{
type: typeof START_UPDATE;
}>;
type UnsnoozeUpdateActionType = ReadonlyDeep<{
type: typeof UNSNOOZE_UPDATE;
payload: DialogType;
}>;
export type UpdatesActionType = ReadonlyDeep<
2022-03-04 19:59:47 +00:00
| DismissDialogActionType
| ShowUpdateDialogActionType
2020-02-21 00:09:50 +00:00
| SnoozeUpdateActionType
2022-03-04 19:59:47 +00:00
| StartUpdateActionType
| UnsnoozeUpdateActionType
>;
// Action Creators
2022-03-04 19:59:47 +00:00
function dismissDialog(): DismissDialogActionType {
return {
type: DISMISS_DIALOG,
};
}
function showUpdateDialog(
dialogType: DialogType,
updateDialogOptions: UpdateDialogOptionsType = {}
2022-03-04 19:59:47 +00:00
): ShowUpdateDialogActionType {
return {
type: SHOW_UPDATE_DIALOG,
payload: {
dialogType,
otherState: updateDialogOptions,
},
};
}
function snoozeUpdate(): ThunkAction<
void,
RootStateType,
unknown,
SnoozeUpdateActionType | UnsnoozeUpdateActionType
> {
return (dispatch, getState) => {
const { dialogType } = getState().updates;
2021-10-06 21:59:34 +00:00
setTimeout(() => {
dispatch({
type: UNSNOOZE_UPDATE,
payload: dialogType,
});
2021-10-06 21:59:34 +00:00
}, DAY);
dispatch({
type: SNOOZE_UPDATE,
});
2020-02-21 00:09:50 +00:00
};
}
2022-03-04 19:59:47 +00:00
function startUpdate(): ThunkAction<
void,
RootStateType,
unknown,
StartUpdateActionType | ShowUpdateDialogActionType
> {
return async dispatch => {
dispatch({
type: START_UPDATE,
});
2022-03-04 19:59:47 +00:00
try {
await updateIpc.startUpdate();
} catch (_) {
dispatch({
type: SHOW_UPDATE_DIALOG,
payload: {
dialogType: DialogType.Cannot_Update,
otherState: {},
},
});
}
};
}
export const actions = {
dismissDialog,
showUpdateDialog,
2020-02-21 00:09:50 +00:00
snoozeUpdate,
startUpdate,
};
2023-03-20 20:42:00 +00:00
export const useUpdatesActions = (): BoundActionCreatorsMapObject<
typeof actions
> => useBoundActions(actions);
// Reducer
export function getEmptyState(): UpdatesStateType {
return {
dialogType: DialogType.None,
2020-02-21 00:09:50 +00:00
didSnooze: false,
showEventsCount: 0,
};
}
export function reducer(
state: Readonly<UpdatesStateType> = getEmptyState(),
action: Readonly<UpdatesActionType>
): UpdatesStateType {
if (action.type === SHOW_UPDATE_DIALOG) {
const { dialogType, otherState } = action.payload;
return {
...state,
...otherState,
dialogType,
2020-02-21 00:09:50 +00:00
showEventsCount: state.showEventsCount + 1,
};
}
if (action.type === SNOOZE_UPDATE) {
return {
...state,
dialogType: DialogType.None,
2020-02-21 00:09:50 +00:00
didSnooze: true,
};
}
if (action.type === START_UPDATE) {
return {
...state,
dialogType: DialogType.None,
2022-12-13 22:55:52 +00:00
didSnooze: false,
};
}
if (
action.type === DISMISS_DIALOG &&
state.dialogType === DialogType.MacOS_Read_Only
) {
return {
...state,
dialogType: DialogType.None,
};
}
if (action.type === UNSNOOZE_UPDATE) {
return {
...state,
dialogType: action.payload,
didSnooze: false,
};
}
return state;
}