mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-12 09:36:27 +00:00
update new version experience
This changes the new version message to be more user-friendly and allows using the new version without restarting the browser or clearing the cache.
This commit is contained in:
@@ -7,6 +7,8 @@ import { Action } from 'redux';
|
||||
|
||||
/** App action types. */
|
||||
export enum AppActionType {
|
||||
/** Reload the app. */
|
||||
Reload = 'app.action.reload',
|
||||
/** The app has just ben started. */
|
||||
DidStart = 'app.action.didStart',
|
||||
/** Open settings dialog. */
|
||||
@@ -23,6 +25,14 @@ export enum AppActionType {
|
||||
CloseLicenseDialog = 'app.action.closeLicenseDialog',
|
||||
}
|
||||
|
||||
/** Action that requests the app to reload. */
|
||||
export type AppReloadAction = Action<AppActionType.Reload>;
|
||||
|
||||
/** Creates an action that requests the app to reload. */
|
||||
export function reload(): AppReloadAction {
|
||||
return { type: AppActionType.Reload };
|
||||
}
|
||||
|
||||
/** Action that indicates the app has just started. */
|
||||
export type AppDidStartAction = Action<AppActionType.DidStart>;
|
||||
|
||||
@@ -81,6 +91,7 @@ export function closeLicenseDialog(): AppCloseLicenseDialogAction {
|
||||
|
||||
/** common type for all app actions. */
|
||||
export type AppAction =
|
||||
| AppReloadAction
|
||||
| AppDidStartAction
|
||||
| AppOpenSettingsAction
|
||||
| AppCloseSettingsAction
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
"error": "{errorMessage}"
|
||||
},
|
||||
"serviceWorker": {
|
||||
"update": "New content is available and will be used when all tabs for this page are closed.'"
|
||||
"update": {
|
||||
"message": "A new version of {appName} is available. Click {action} to start using the new version.",
|
||||
"action": "Restart"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ export enum MessageId {
|
||||
BleGattServiceNotFound = 'ble.gattServiceNotFound',
|
||||
BleNoWebBluetooth = 'ble.noWebBluetooth',
|
||||
ProgramChanged = 'editor.programChanged',
|
||||
ServiceWorkerUpdate = 'serviceWorker.update',
|
||||
ServiceWorkerUpdateMessage = 'serviceWorker.update.message',
|
||||
ServiceWorkerUpdateAction = 'serviceWorker.update.action',
|
||||
YesReloadProgram = 'editor.yesReloadProgram',
|
||||
MpyError = 'mpy.error',
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2021 The Pybricks Authors
|
||||
|
||||
import { call, takeEvery } from 'redux-saga/effects';
|
||||
import { AppActionType } from '../actions/app';
|
||||
|
||||
function* reload(): Generator {
|
||||
console.log('reload');
|
||||
|
||||
// unregister the service worker so that when the page reloads, it uses
|
||||
// the new version
|
||||
const registrations = (yield call(() =>
|
||||
navigator.serviceWorker.getRegistrations(),
|
||||
)) as ServiceWorkerRegistration[];
|
||||
|
||||
for (const r of registrations) {
|
||||
yield call(() => r.unregister());
|
||||
}
|
||||
|
||||
location.reload();
|
||||
}
|
||||
|
||||
export default function* app(): Generator {
|
||||
yield takeEvery(AppActionType.Reload, reload);
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
import { all, put } from 'redux-saga/effects';
|
||||
import { didStart } from '../actions/app';
|
||||
import app from './app';
|
||||
import bleUart from './ble-uart';
|
||||
import editor from './editor';
|
||||
import errorLog from './error-log';
|
||||
@@ -19,6 +20,7 @@ import terminal from './terminal';
|
||||
/* istanbul ignore next */
|
||||
export default function* (): Generator {
|
||||
yield all([
|
||||
app(),
|
||||
bleUart(),
|
||||
lwp3BootloaderBle(),
|
||||
lwp3BootloaderProtocol(),
|
||||
|
||||
@@ -14,6 +14,7 @@ import { Replacements } from '@shopify/react-i18n';
|
||||
import React from 'react';
|
||||
import { channel } from 'redux-saga';
|
||||
import { delay, getContext, put, take, takeEvery } from 'redux-saga/effects';
|
||||
import { reload } from '../actions/app';
|
||||
import {
|
||||
BleDeviceActionType,
|
||||
BleDeviceDidFailToConnectAction,
|
||||
@@ -30,6 +31,7 @@ import { NotificationActionType, NotificationAddAction } from '../actions/notifi
|
||||
import { ServiceWorkerActionType } from '../actions/service-worker';
|
||||
import Notification from '../components/Notification';
|
||||
import { MessageId } from '../components/notification-i18n';
|
||||
import { appName } from '../settings/ui';
|
||||
|
||||
type NotificationContext = {
|
||||
toaster: IToaster;
|
||||
@@ -229,12 +231,26 @@ function* addNotification(action: NotificationAddAction): Generator {
|
||||
}
|
||||
|
||||
function* showServiceWorkerUpdate(): Generator {
|
||||
const ch = channel<React.MouseEvent<HTMLElement>>();
|
||||
const action = dispatchAction(
|
||||
MessageId.ServiceWorkerUpdateAction,
|
||||
ch.put,
|
||||
'refresh',
|
||||
);
|
||||
yield* showSingleton(
|
||||
Level.Info,
|
||||
MessageId.ServiceWorkerUpdate,
|
||||
undefined,
|
||||
helpAction('https://github.com/pybricks/pybricks-code/issues/102'),
|
||||
MessageId.ServiceWorkerUpdateMessage,
|
||||
{
|
||||
appName,
|
||||
action: React.createElement('strong', undefined, action.text),
|
||||
},
|
||||
action,
|
||||
ch.close,
|
||||
);
|
||||
|
||||
yield take(ch);
|
||||
|
||||
yield put(reload());
|
||||
}
|
||||
|
||||
export default function* (): Generator {
|
||||
|
||||
Reference in New Issue
Block a user