2022-01-11 20:02:46 +00:00
|
|
|
// Copyright 2022 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2023-01-13 20:07:26 +00:00
|
|
|
import type { ReadonlyDeep } from 'type-fest';
|
2022-01-11 20:02:46 +00:00
|
|
|
import * as log from '../../logging/log';
|
|
|
|
import { showToast } from '../../util/showToast';
|
|
|
|
import * as Errors from '../../types/errors';
|
|
|
|
import { ToastLinkCopied } from '../../components/ToastLinkCopied';
|
|
|
|
import { ToastDebugLogError } from '../../components/ToastDebugLogError';
|
2022-10-18 17:12:02 +00:00
|
|
|
import type { PromiseAction } from '../util';
|
2022-01-11 20:02:46 +00:00
|
|
|
|
|
|
|
// State
|
|
|
|
|
2023-01-13 20:07:26 +00:00
|
|
|
export type CrashReportsStateType = ReadonlyDeep<{
|
2022-01-11 20:02:46 +00:00
|
|
|
count: number;
|
|
|
|
isPending: boolean;
|
2023-01-13 20:07:26 +00:00
|
|
|
}>;
|
2022-01-11 20:02:46 +00:00
|
|
|
|
|
|
|
// Actions
|
|
|
|
|
|
|
|
const SET_COUNT = 'crashReports/SET_COUNT';
|
|
|
|
const UPLOAD = 'crashReports/UPLOAD';
|
|
|
|
const ERASE = 'crashReports/ERASE';
|
|
|
|
|
2023-01-13 20:07:26 +00:00
|
|
|
type SetCrashReportCountActionType = ReadonlyDeep<{
|
2022-01-11 20:02:46 +00:00
|
|
|
type: typeof SET_COUNT;
|
|
|
|
payload: number;
|
2023-01-13 20:07:26 +00:00
|
|
|
}>;
|
2022-01-11 20:02:46 +00:00
|
|
|
|
2023-01-13 20:07:26 +00:00
|
|
|
type CrashReportsActionType = ReadonlyDeep<
|
2022-01-11 20:02:46 +00:00
|
|
|
| SetCrashReportCountActionType
|
|
|
|
| PromiseAction<typeof UPLOAD>
|
2023-01-13 20:07:26 +00:00
|
|
|
| PromiseAction<typeof ERASE>
|
|
|
|
>;
|
2022-01-11 20:02:46 +00:00
|
|
|
|
|
|
|
// Action Creators
|
|
|
|
|
|
|
|
export const actions = {
|
|
|
|
setCrashReportCount,
|
|
|
|
uploadCrashReports,
|
|
|
|
eraseCrashReports,
|
|
|
|
};
|
|
|
|
|
|
|
|
function setCrashReportCount(count: number): SetCrashReportCountActionType {
|
|
|
|
return { type: SET_COUNT, payload: count };
|
|
|
|
}
|
|
|
|
|
|
|
|
function uploadCrashReports(): PromiseAction<typeof UPLOAD> {
|
2023-01-13 00:24:59 +00:00
|
|
|
return { type: UPLOAD, payload: window.IPC.crashReports.upload() };
|
2022-01-11 20:02:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function eraseCrashReports(): PromiseAction<typeof ERASE> {
|
2023-01-13 00:24:59 +00:00
|
|
|
return { type: ERASE, payload: window.IPC.crashReports.erase() };
|
2022-01-11 20:02:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Reducer
|
|
|
|
|
|
|
|
export function getEmptyState(): CrashReportsStateType {
|
|
|
|
return {
|
|
|
|
count: 0,
|
|
|
|
isPending: false,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export function reducer(
|
|
|
|
state: Readonly<CrashReportsStateType> = getEmptyState(),
|
|
|
|
action: Readonly<CrashReportsActionType>
|
|
|
|
): CrashReportsStateType {
|
|
|
|
if (action.type === SET_COUNT) {
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
count: action.payload,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
action.type === `${UPLOAD}_PENDING` ||
|
|
|
|
action.type === `${ERASE}_PENDING`
|
|
|
|
) {
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
isPending: true,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
action.type === `${UPLOAD}_FULFILLED` ||
|
|
|
|
action.type === `${ERASE}_FULFILLED`
|
|
|
|
) {
|
|
|
|
if (action.type === `${UPLOAD}_FULFILLED`) {
|
|
|
|
showToast(ToastLinkCopied);
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
count: 0,
|
|
|
|
isPending: false,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
action.type === (`${UPLOAD}_REJECTED` as const) ||
|
|
|
|
action.type === (`${ERASE}_REJECTED` as const)
|
|
|
|
) {
|
|
|
|
const { error } = action;
|
|
|
|
|
|
|
|
log.error(
|
|
|
|
`Failed to upload crash report due to error ${Errors.toLogFormat(error)}`
|
|
|
|
);
|
|
|
|
|
|
|
|
showToast(ToastDebugLogError);
|
|
|
|
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
count: 0,
|
|
|
|
isPending: false,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return state;
|
|
|
|
}
|