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:
David Lechner
2021-01-18 18:51:38 -06:00
parent c8d499e979
commit 5a66f041f2
6 changed files with 63 additions and 5 deletions
+11
View File
@@ -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
+4 -1
View File
@@ -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"
}
}
}
+2 -1
View File
@@ -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',
}
+25
View File
@@ -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);
}
+2
View File
@@ -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(),
+19 -3
View File
@@ -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 {