diff --git a/.vscode/settings.json b/.vscode/settings.json index 62604942..38041163 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,4 @@ { - "[css]": { - "editor.suggest.insertMode": "replace", - "editor.formatOnSave": true - }, "[json]": { "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode" @@ -11,6 +7,10 @@ "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode" }, + "[scss]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, diff --git a/package.json b/package.json index 353b949a..aacb4eff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@pybricks/pybricks-code", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.5", "license": "MIT", "author": "The Pybricks Authors", "repository": { @@ -11,7 +11,7 @@ "@blueprintjs/core": "^3.38.1", "@craco/craco": "^6.0.0", "@pybricks/firmware": "4.5.0", - "@pybricks/ide-docs": "1.0.0", + "@pybricks/ide-docs": "1.1.0", "@pybricks/mpy-cross-v5": "^2.0.0", "@shopify/react-i18n": "^5.2.1", "@testing-library/dom": "^7.29.2", diff --git a/src/actions/app.ts b/src/actions/app.ts index e4143d25..cd09b533 100644 --- a/src/actions/app.ts +++ b/src/actions/app.ts @@ -4,11 +4,24 @@ // Actions for the app in general. import { Action } from 'redux'; +import { BeforeInstallPromptEvent } from '../utils/dom'; /** App action types. */ export enum AppActionType { /** Reload the app. */ Reload = 'app.action.reload', + /** Checks for an available update. */ + CheckForUpdate = 'app.action.checkForUpdate', + /** Indicates that checking for update finished. */ + DidCheckForUpdate = 'app.action.didCheckForUpdate', + /* Indicates the browser wants to prompt the use to install the app. */ + DidBeforeInstallPrompt = 'app.action.didBeforeInstallPrompt', + /* Requests to prompt the user to install the app. */ + InstallPrompt = 'app.action.installPrompt', + /* Indicates that the user responded to the install prompt. */ + DidInstallPrompt = 'app.action.didInstallPrompt', + /* Indicates that the app was installed. */ + DidInstall = 'app.action.didInstallPrompt', /** The app has just ben started. */ DidStart = 'app.action.didStart', /** Open settings dialog. */ @@ -26,11 +39,73 @@ export enum AppActionType { } /** Action that requests the app to reload. */ -export type AppReloadAction = Action; +export type AppReloadAction = Action & { + registration: ServiceWorkerRegistration; +}; /** Creates an action that requests the app to reload. */ -export function reload(): AppReloadAction { - return { type: AppActionType.Reload }; +export function reload(registration: ServiceWorkerRegistration): AppReloadAction { + return { type: AppActionType.Reload, registration }; +} + +/** Action that requests to check for updates. */ +export type AppCheckForUpdatesAction = Action & { + registration: ServiceWorkerRegistration; +}; + +/** Action that requests to check for updates. */ +export function checkForUpdate( + registration: ServiceWorkerRegistration, +): AppCheckForUpdatesAction { + return { type: AppActionType.CheckForUpdate, registration }; +} + +/** Action that indicates that checking for an update has completed. */ +export type AppDidCheckForUpdateAction = Action & { + updateFound: boolean; +}; + +/** Action that indicates that checking for an update has completed. */ +export function didCheckForUpdate(updateFound: boolean): AppDidCheckForUpdateAction { + return { type: AppActionType.DidCheckForUpdate, updateFound }; +} + +/* Action that indicates the browser wants to prompt the use to install the app. */ +export type AppDidBeforeInstallPromptAction = Action & { + event: BeforeInstallPromptEvent; +}; + +/* Action that indicates the browser wants to prompt the use to install the app. */ +export function didBeforeInstallPrompt( + event: BeforeInstallPromptEvent, +): AppDidBeforeInstallPromptAction { + return { type: AppActionType.DidBeforeInstallPrompt, event }; +} + +/* Action that requests to prompt the user to install the app. */ +export type AppInstallPromptAction = Action & { + event: BeforeInstallPromptEvent; +}; + +/* Action that requests to prompt the user to install the app. */ +export function installPrompt(event: BeforeInstallPromptEvent): AppInstallPromptAction { + return { type: AppActionType.InstallPrompt, event }; +} + +/* Action that indicates that the user responded to the install prompt. */ +export type AppDidInstallPromptAction = Action; + +/* Action that indicates that the user responded to the install prompt. */ +export function didInstallPrompt(): AppDidInstallPromptAction { + return { type: AppActionType.DidInstallPrompt }; +} + +/* Action that indicates app was installed. */ +export type AppDidInstallAction = Action; + +/* Action that indicates app was installed. */ +export function didInstall(): AppDidInstallAction { + return { type: AppActionType.DidInstall }; } /** Action that indicates the app has just started. */ @@ -92,6 +167,12 @@ export function closeLicenseDialog(): AppCloseLicenseDialogAction { /** common type for all app actions. */ export type AppAction = | AppReloadAction + | AppCheckForUpdatesAction + | AppDidCheckForUpdateAction + | AppDidBeforeInstallPromptAction + | AppInstallPromptAction + | AppDidInstallPromptAction + | AppDidInstallAction | AppDidStartAction | AppOpenSettingsAction | AppCloseSettingsAction diff --git a/src/actions/ble.ts b/src/actions/ble.ts index d6ad1ec1..19f4785d 100644 --- a/src/actions/ble.ts +++ b/src/actions/ble.ts @@ -51,6 +51,7 @@ export function didConnect(): BleDeviceDidConnectAction { export enum BleDeviceFailToConnectReasonType { NoWebBluetooth = 'ble.device.didFailToConnect.noWebBluetooth', + NoBluetooth = 'ble.device.didFailToConnect.noBluetooth', Canceled = 'ble.device.didFailToConnect.canceled', NoGatt = 'ble.device.didFailToConnect.noGatt', NoService = 'ble.device.didFailToConnect.noService', @@ -63,6 +64,8 @@ type Reason = { export type BleDeviceFailToConnectNoWebBluetoothReason = Reason; +export type BleDeviceFailToConnectNoBluetoothReason = Reason; + export type BleDeviceFailToConnectCanceledReason = Reason; export type BleDeviceFailToConnectNoGattReason = Reason; @@ -75,6 +78,7 @@ export type BleDeviceFailToConnectUnknownReason = Reason = { export type BootloaderConnectionFailToConnectNoWebBluetoothReason = Reason; +export type BootloaderConnectionFailToConnectNoBluetoothReason = Reason; + export type BootloaderConnectionFailToConnectGattServiceNotFoundReason = Reason; export type BootloaderConnectionFailToConnectCanceledReason = Reason; @@ -103,6 +107,7 @@ export type BootloaderConnectionFailToConnectUnknownReason = Reason & { + id: SettingId; +}; + +/** Creates an action to toggle a setting. */ +export function toggleBoolean(id: SettingId): SettingsToggleBooleanAction { + return { type: SettingsActionType.ToggleBoolean, id }; +} + /** Action that indicates setting/storing a setting failed. */ export type SettingsDidFailToSetBooleanAction = Action & { id: SettingId; @@ -56,5 +67,6 @@ export function didBooleanChange( /** Common type for all settings actions. */ export type SettingsAction = | SettingsSetBooleanAction + | SettingsToggleBooleanAction | SettingsDidFailToSetBooleanAction | SettingsDidBooleanChangeAction; diff --git a/src/components/ActionButton.tsx b/src/components/ActionButton.tsx index 7377dcb6..4b21ecde 100644 --- a/src/components/ActionButton.tsx +++ b/src/components/ActionButton.tsx @@ -51,6 +51,7 @@ class ActionButton extends React.Component {