From 95199e44c12ba000fd71aedd7b214b8d997a7806 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 22 Nov 2022 14:21:05 -0600 Subject: [PATCH] hub/alerts/UserProgramSize: add alert for program too big This finishes the TODO about adding a proper message. Fixes: https://github.com/pybricks/support/issues/810 --- CHANGELOG.md | 2 ++ src/alerts.ts | 2 ++ src/hub/alerts/UserProgramSize.test.tsx | 21 +++++++++++++ src/hub/alerts/UserProgramSize.tsx | 42 +++++++++++++++++++++++++ src/hub/alerts/i18n.ts | 12 +++++++ src/hub/alerts/index.ts | 8 +++++ src/hub/alerts/translations/en.json | 6 ++++ src/hub/sagas.ts | 11 +++++-- 8 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 src/hub/alerts/UserProgramSize.test.tsx create mode 100644 src/hub/alerts/UserProgramSize.tsx create mode 100644 src/hub/alerts/i18n.ts create mode 100644 src/hub/alerts/index.ts create mode 100644 src/hub/alerts/translations/en.json diff --git a/CHANGELOG.md b/CHANGELOG.md index c6aba64f..0415c548 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ### Fixed - Fixed missing warning sign icon. +- Fixed error message for program too big for download ([support#810]). ## [2.0.0-beta.11] - 2022-11-11 @@ -20,6 +21,7 @@ [pybricks-code#1299]: https://github.com/pybricks/pybricks-code/issues/1299 [support#792]: https://github.com/orgs/pybricks/discussions/792 +[support#810]: https://github.com/pybricks/support/issues/810 ## [2.0.0-beta.10] - 2022-11-11 diff --git a/src/alerts.ts b/src/alerts.ts index 3bc2a0e1..192625c5 100644 --- a/src/alerts.ts +++ b/src/alerts.ts @@ -7,6 +7,7 @@ import app from './app/alerts'; import ble from './ble/alerts'; import explorer from './explorer/alerts'; import firmware from './firmware/alerts'; +import hub from './hub/alerts'; import mpy from './mpy/alerts'; import type { CreateToast } from './toasterTypes'; @@ -17,6 +18,7 @@ const alertDomains = { ble, explorer, firmware, + hub, mpy, }; diff --git a/src/hub/alerts/UserProgramSize.test.tsx b/src/hub/alerts/UserProgramSize.test.tsx new file mode 100644 index 00000000..d16b98d6 --- /dev/null +++ b/src/hub/alerts/UserProgramSize.test.tsx @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2022 The Pybricks Authors + +import React from 'react'; +import { testRender } from '../../../test'; +import { userProgramSize } from './UserProgramSize'; + +it('should be valid', () => { + const callback = jest.fn(); + const toast = userProgramSize(callback, { actual: 10000, max: 8000 }); + + // TODO: refactor this to a common function to be used by all alerts + + // it should render + const [, message] = testRender(<>{toast.message}); + expect(message).toBeDefined(); + + // it should have a dismiss callback + toast.onDismiss?.(false); + expect(callback).toHaveBeenCalledWith('dismiss'); +}); diff --git a/src/hub/alerts/UserProgramSize.tsx b/src/hub/alerts/UserProgramSize.tsx new file mode 100644 index 00000000..93584b36 --- /dev/null +++ b/src/hub/alerts/UserProgramSize.tsx @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2022 The Pybricks Authors + +import { Intent } from '@blueprintjs/core'; +import React from 'react'; +import type { CreateToast } from '../../toasterTypes'; +import { useI18n } from './i18n'; + +type UserProgramSizeProps = { + /** The actual size of the program in bytes. */ + actual: number; + /** The maximum allowable size of the program in bytes. */ + max: number; +}; + +const UserProgramSize: React.VoidFunctionComponent = ({ + actual, + max, +}) => { + const i18n = useI18n(); + return ( + <> +

+ {i18n.translate('userProgramSize.message', { + actual: i18n.formatNumber(actual), + max: i18n.formatNumber(max), + })} +

+

{i18n.translate('userProgramSize.suggestion')}

+ + ); +}; + +export const userProgramSize: CreateToast = ( + onAction, + props, +) => ({ + message: , + icon: 'error', + intent: Intent.DANGER, + onDismiss: () => onAction('dismiss'), +}); diff --git a/src/hub/alerts/i18n.ts b/src/hub/alerts/i18n.ts new file mode 100644 index 00000000..eb8dc486 --- /dev/null +++ b/src/hub/alerts/i18n.ts @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2022 The Pybricks Authors + +import { useI18n as useShopifyI18n } from '@shopify/react-i18n'; +import type { TypedI18n } from '../../i18n'; +import type translations from './translations/en.json'; + +export function useI18n(): TypedI18n { + // istanbul ignore next: babel-loader rewrites this line + const [i18n] = useShopifyI18n(); + return i18n; +} diff --git a/src/hub/alerts/index.ts b/src/hub/alerts/index.ts new file mode 100644 index 00000000..eaeb369c --- /dev/null +++ b/src/hub/alerts/index.ts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2022 The Pybricks Authors + +import { userProgramSize } from './UserProgramSize'; + +export default { + userProgramSize, +}; diff --git a/src/hub/alerts/translations/en.json b/src/hub/alerts/translations/en.json new file mode 100644 index 00000000..ad41722a --- /dev/null +++ b/src/hub/alerts/translations/en.json @@ -0,0 +1,6 @@ +{ + "userProgramSize": { + "message": "This program is too big. Compiled size is {actual} bytes but the hub can only fit {max} bytes.", + "suggestion": "Try removing unused code or making names and strings smaller." + } +} diff --git a/src/hub/sagas.ts b/src/hub/sagas.ts index 14b8ed90..ad4a0400 100644 --- a/src/hub/sagas.ts +++ b/src/hub/sagas.ts @@ -225,9 +225,14 @@ function* handleDownloadAndRun(action: ReturnType): Gener console.log(`Downloading ${didCompile.file.size} bytes`); } - if (didCompile.file.size >= maxUserProgramSize) { - // TODO: proper error notification - throw new Error('file too big'); + if (didCompile.file.size > maxUserProgramSize) { + yield* put( + alertsShowAlert('hub', 'userProgramSize', { + actual: didCompile.file.size, + max: maxUserProgramSize, + }), + ); + return; } // let everyone know the runtime is busy loading the program