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

186 lines
4.5 KiB
TypeScript
Raw Normal View History

2023-01-03 19:55:46 +00:00
// Copyright 2019 Signal Messenger, LLC
2020-10-30 20:34:04 +00:00
// SPDX-License-Identifier: AGPL-3.0-only
import type { ReadonlyDeep } from 'type-fest';
import { trigger } from '../../shims/events';
import type { LocaleMessagesType } from '../../types/I18N';
2023-01-13 00:24:59 +00:00
import type { LocalizerType } from '../../types/Util';
import type { MenuOptionsType } from '../../types/menu';
2023-01-13 00:24:59 +00:00
import type { NoopActionType } from './noop';
import type { AciString, PniString } from '../../types/ServiceId';
import OS from '../../util/os/osMain';
2023-01-13 00:24:59 +00:00
import { ThemeType } from '../../types/Util';
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
import { useBoundActions } from '../../hooks/useBoundActions';
2019-01-14 21:49:58 +00:00
// State
// eslint-disable-next-line local-rules/type-alias-readonlydeep
export type UserStateType = Readonly<{
attachmentsPath: string;
2023-01-13 00:24:59 +00:00
i18n: LocalizerType;
interactionMode: 'mouse' | 'keyboard';
isMainWindowFullScreen: boolean;
isMainWindowMaximized: boolean;
localeMessages: LocaleMessagesType;
menuOptions: MenuOptionsType;
osName: 'linux' | 'macos' | 'windows' | undefined;
ourAci: AciString | undefined;
ourConversationId: string | undefined;
ourDeviceId: number | undefined;
ourNumber: string | undefined;
ourPni: PniString | undefined;
2019-11-07 21:36:16 +00:00
platform: string;
regionCode: string | undefined;
2023-01-13 00:24:59 +00:00
stickersPath: string;
tempPath: string;
theme: ThemeType;
2022-01-26 23:05:26 +00:00
version: string;
}>;
2019-01-14 21:49:58 +00:00
// Actions
type UserChangedActionType = ReadonlyDeep<{
2019-01-14 21:49:58 +00:00
type: 'USER_CHANGED';
payload: {
ourConversationId?: string;
ourDeviceId?: number;
ourAci?: AciString;
ourPni?: PniString;
ourNumber?: string;
regionCode?: string;
interactionMode?: 'mouse' | 'keyboard';
theme?: ThemeType;
isMainWindowMaximized?: boolean;
isMainWindowFullScreen?: boolean;
menuOptions?: MenuOptionsType;
2019-01-14 21:49:58 +00:00
};
}>;
2019-01-14 21:49:58 +00:00
export const ERASE_STORAGE_SERVICE = 'user/ERASE_STORAGE_SERVICE_STATE';
export type EraseStorageServiceStateAction = ReadonlyDeep<{
type: typeof ERASE_STORAGE_SERVICE;
}>;
export type UserActionType = ReadonlyDeep<
UserChangedActionType | EraseStorageServiceStateAction
>;
2019-01-14 21:49:58 +00:00
// Action Creators
export const actions = {
eraseStorageServiceState,
2019-01-14 21:49:58 +00:00
userChanged,
manualReconnect,
2019-01-14 21:49:58 +00:00
};
export const useUserActions = (): BoundActionCreatorsMapObject<
typeof actions
> => useBoundActions(actions);
function eraseStorageServiceState(): EraseStorageServiceStateAction {
return {
type: ERASE_STORAGE_SERVICE,
};
}
2019-01-14 21:49:58 +00:00
function userChanged(attributes: {
interactionMode?: 'mouse' | 'keyboard';
ourConversationId?: string;
ourDeviceId?: number;
ourNumber?: string;
ourAci?: AciString;
ourPni?: PniString;
regionCode?: string;
theme?: ThemeType;
isMainWindowMaximized?: boolean;
isMainWindowFullScreen?: boolean;
menuOptions?: MenuOptionsType;
2019-01-14 21:49:58 +00:00
}): UserChangedActionType {
return {
type: 'USER_CHANGED',
payload: attributes,
};
}
function manualReconnect(): NoopActionType {
trigger('manualConnect');
return {
type: 'NOOP',
payload: null,
};
}
const intlNotSetup = () => {
throw new Error('i18n not yet set up');
};
2019-01-14 21:49:58 +00:00
// Reducer
export function getEmptyState(): UserStateType {
2023-01-13 00:24:59 +00:00
let osName: 'windows' | 'macos' | 'linux' | undefined;
if (OS.isWindows()) {
osName = 'windows';
} else if (OS.isMacOS()) {
osName = 'macos';
} else if (OS.isLinux()) {
osName = 'linux';
}
2019-01-14 21:49:58 +00:00
return {
attachmentsPath: 'missing',
2023-01-13 00:24:59 +00:00
i18n: Object.assign(intlNotSetup, {
getLocale: intlNotSetup,
getIntl: intlNotSetup,
getLocaleMessages: intlNotSetup,
2023-04-20 17:03:43 +00:00
getLocaleDirection: intlNotSetup,
getHourCyclePreference: intlNotSetup,
2023-01-13 00:24:59 +00:00
}),
interactionMode: 'mouse',
isMainWindowMaximized: false,
isMainWindowFullScreen: false,
2023-01-13 00:24:59 +00:00
localeMessages: {},
menuOptions: {
development: false,
devTools: false,
includeSetup: false,
isProduction: true,
platform: 'unknown',
},
2023-01-13 00:24:59 +00:00
osName,
ourAci: undefined,
2023-01-13 00:24:59 +00:00
ourConversationId: 'missing',
ourDeviceId: 0,
ourNumber: 'missing',
ourPni: undefined,
2023-01-13 00:24:59 +00:00
platform: 'missing',
regionCode: 'missing',
stickersPath: 'missing',
tempPath: 'missing',
theme: ThemeType.light,
2022-01-26 23:05:26 +00:00
version: '0.0.0',
2019-01-14 21:49:58 +00:00
};
}
export function reducer(
state: Readonly<UserStateType> = getEmptyState(),
action: Readonly<UserActionType>
2019-01-14 21:49:58 +00:00
): UserStateType {
if (!state) {
return getEmptyState();
}
if (action.type === 'USER_CHANGED') {
const { payload } = action;
return {
...state,
...payload,
};
}
return state;
}