alerts: add alertsHideAlert actions

This is used instead of using toaster.dismiss() directly.
This commit is contained in:
David Lechner
2022-10-19 18:26:37 -05:00
committed by David Lechner
parent 28cf87c356
commit fc4cb8eb78
4 changed files with 94 additions and 36 deletions
+10
View File
@@ -49,3 +49,13 @@ export const alertsDidShowAlert = createAction(
action,
}),
);
/**
* Action that requests to hide an alert.
* @param key The key that matches `<domain>.<specific>.<props>` or the
* overridden key if used.
*/
export const alertsHideAlert = createAction((key: string) => ({
type: 'alters.action.hideAlert',
key,
}));
+8 -1
View File
@@ -6,7 +6,7 @@ import { delay, getContext, put, take, takeEvery } from 'typed-redux-saga/macro'
import { getAlertProps } from '../alerts';
import type { ToasterRef } from '../toasterTypes';
import { defined } from '../utils';
import { alertsDidShowAlert, alertsShowAlert } from './actions';
import { alertsDidShowAlert, alertsHideAlert, alertsShowAlert } from './actions';
export type AlertsSagaContext = { toasterRef: ToasterRef };
@@ -48,7 +48,14 @@ function* handleShowAlert(action: ReturnType<typeof alertsShowAlert>): Generator
chan.close();
}
}
function* handleHideAlert(action: ReturnType<typeof alertsHideAlert>): Generator {
const toaster = (yield* getContext<ToasterRef>('toasterRef')).current;
defined(toaster);
toaster.dismiss(action.key);
}
export default function* (): Generator {
yield* takeEvery(alertsShowAlert, handleShowAlert);
yield* takeEvery(alertsHideAlert, handleHideAlert);
}
+69 -25
View File
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2021-2022 The Pybricks Authors
import type { ToasterInstance } from '@blueprintjs/core';
import {
FirmwareMetadata,
FirmwareMetadataV110,
@@ -9,10 +8,9 @@ import {
FirmwareReaderError,
FirmwareReaderErrorCode,
} from '@pybricks/firmware';
import { mock } from 'jest-mock-extended';
import JSZip from 'jszip';
import { AsyncSaga } from '../../test';
import { alertsShowAlert } from '../alerts/actions';
import { alertsHideAlert, alertsShowAlert } from '../alerts/actions';
import {
BootloaderConnectionFailureReason,
checksumRequest,
@@ -83,7 +81,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -267,7 +264,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -433,7 +429,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -483,7 +478,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -524,6 +518,10 @@ describe('flashFirmware', () => {
// this to happen.
saga.put(didFailToRequest(0, new Error('failed due to disconnect')));
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
await saga.end();
});
@@ -551,7 +549,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -585,6 +582,10 @@ describe('flashFirmware', () => {
// should request to disconnect after failure
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
action = await saga.take();
expect(action).toEqual(disconnect());
@@ -615,7 +616,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -652,6 +652,10 @@ describe('flashFirmware', () => {
// should request to disconnect after failure
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
action = await saga.take();
expect(action).toEqual(disconnect());
@@ -682,7 +686,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -713,6 +716,10 @@ describe('flashFirmware', () => {
// should request to disconnect after failure
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
action = await saga.take();
expect(action).toEqual(disconnect());
@@ -742,7 +749,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -778,6 +784,10 @@ describe('flashFirmware', () => {
// should request to disconnect after failure
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
action = await saga.take();
expect(action).toEqual(disconnect());
@@ -808,7 +818,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -861,6 +870,10 @@ describe('flashFirmware', () => {
// should request to disconnect after failure
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
action = await saga.take();
expect(action).toEqual(disconnect());
@@ -891,7 +904,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -927,6 +939,10 @@ describe('flashFirmware', () => {
// should request to disconnect after failure
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
action = await saga.take();
expect(action).toEqual(disconnect());
@@ -957,7 +973,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -1036,6 +1051,10 @@ describe('flashFirmware', () => {
// should request to disconnect after failure
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
action = await saga.take();
expect(action).toEqual(disconnect());
@@ -1066,7 +1085,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -1154,6 +1172,10 @@ describe('flashFirmware', () => {
// should request to disconnect after failure
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
action = await saga.take();
expect(action).toEqual(disconnect());
@@ -1184,7 +1206,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -1325,6 +1346,10 @@ describe('flashFirmware', () => {
// should request to disconnect after failure
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
action = await saga.take();
expect(action).toEqual(disconnect());
@@ -1355,7 +1380,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -1496,6 +1520,10 @@ describe('flashFirmware', () => {
// should request to disconnect after failure
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
action = await saga.take();
expect(action).toEqual(disconnect());
@@ -1524,7 +1552,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -1712,7 +1739,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -1736,6 +1762,10 @@ describe('flashFirmware', () => {
),
);
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
await saga.end();
});
@@ -1759,7 +1789,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -1782,6 +1811,10 @@ describe('flashFirmware', () => {
),
);
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
await saga.end();
});
@@ -1805,7 +1838,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -1842,6 +1874,10 @@ describe('flashFirmware', () => {
didFailToFinish(FailToFinishReasonType.FailedToCompile),
);
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
await saga.end();
});
@@ -1865,7 +1901,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -1902,6 +1937,10 @@ describe('flashFirmware', () => {
didFailToFinish(FailToFinishReasonType.FirmwareSize),
);
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
await saga.end();
});
@@ -1926,7 +1965,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -1967,6 +2005,10 @@ describe('flashFirmware', () => {
),
);
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
await saga.end();
});
@@ -1990,7 +2032,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
@@ -2048,6 +2089,10 @@ describe('flashFirmware', () => {
// should request to disconnect after failure
await expect(saga.take()).resolves.toEqual(
alertsHideAlert('firmware.ble.progress'),
);
action = await saga.take();
expect(action).toEqual(disconnect());
@@ -2079,7 +2124,6 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, {
nextMessageId: createCountFunc(),
toasterRef: { current: mock<ToasterInstance>() },
});
// saga is triggered by this action
+7 -10
View File
@@ -29,7 +29,11 @@ import {
take,
takeEvery,
} from 'typed-redux-saga/macro';
import { alertsDidShowAlert, alertsShowAlert } from '../alerts/actions';
import {
alertsDidShowAlert,
alertsHideAlert,
alertsShowAlert,
} from '../alerts/actions';
import {
checksumRequest,
checksumResponse,
@@ -55,7 +59,6 @@ import { MaxProgramFlashSize, Result } from '../lwp3-bootloader/protocol';
import { BootloaderConnectionState } from '../lwp3-bootloader/reducers';
import { compile, didCompile, didFailToCompile } from '../mpy/actions';
import { RootState } from '../reducers';
import type { ToasterRef } from '../toasterTypes';
import { LegoUsbProductId, legoUsbVendorId } from '../usb';
import { defined, ensureError, hex, maybe } from '../utils';
import { crc32, fmod, sumComplement32 } from '../utils/math';
@@ -93,10 +96,7 @@ const firmwareBleProgressToastId = 'firmware.ble.progress';
* parent task).
*/
function* disconnectAndCancel(): SagaGenerator<void> {
const toaster = (yield* getContext<ToasterRef>('toasterRef')).current;
defined(toaster);
toaster.dismiss(firmwareBleProgressToastId);
yield* put(alertsHideAlert(firmwareBleProgressToastId));
const connection = yield* select((s: RootState) => s.bootloader.connection);
@@ -749,9 +749,6 @@ function* handleFlashUsbDfu(action: ReturnType<typeof firmwareFlashUsbDfu>): Gen
dfu.dfuseStartAddress = dfuFirmwareStartAddress;
const writeProc = dfu.write(1024, firmware, true);
const toaster = (yield* getContext<ToasterRef>('toasterRef')).current;
defined(toaster);
const eraseProcessChan = eventChannel<{
bytesSent: number;
expectedSize: number;
@@ -813,7 +810,7 @@ function* handleFlashUsbDfu(action: ReturnType<typeof firmwareFlashUsbDfu>): Gen
console.error(error);
}
toaster.dismiss(firmwareDfuProgressToastId);
yield* put(alertsHideAlert(firmwareDfuProgressToastId));
yield* put(firmwareDidFailToFlashUsbDfu());
yield* put(alertsShowAlert('firmware', 'dfuError'));