ServiceWorker: display loading screen while updating

This commit is contained in:
Alex Gleason 2022-06-24 11:52:57 -05:00
parent 23c37229b8
commit d5ffce844d
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
5 changed files with 35 additions and 0 deletions

15
app/soapbox/actions/sw.ts Normal file
View file

@ -0,0 +1,15 @@
import type { AnyAction } from 'redux';
/** Sets the ServiceWorker updating state. */
const SW_UPDATING = 'SW_UPDATING';
/** Dispatch when the ServiceWorker is being updated to display a loading screen. */
const setSwUpdating = (isUpdating: boolean): AnyAction => ({
type: SW_UPDATING,
isUpdating,
});
export {
SW_UPDATING,
setSwUpdating,
};

View file

@ -78,6 +78,7 @@ const SoapboxMount = () => {
const settings = useSettings(); const settings = useSettings();
const soapboxConfig = useSoapboxConfig(); const soapboxConfig = useSoapboxConfig();
const features = useFeatures(); const features = useFeatures();
const swUpdating = useAppSelector(state => state.meta.swUpdating);
const locale = validLocale(settings.get('locale')) ? settings.get('locale') : 'en'; const locale = validLocale(settings.get('locale')) ? settings.get('locale') : 'en';
@ -120,6 +121,7 @@ const SoapboxMount = () => {
me && !account, me && !account,
!isLoaded, !isLoaded,
localeLoading, localeLoading,
swUpdating,
].some(Boolean); ].some(Boolean);
const bodyClass = classNames('bg-white dark:bg-slate-900 text-base h-full', { const bodyClass = classNames('bg-white dark:bg-slate-900 text-base h-full', {

View file

@ -7,6 +7,7 @@ import ReactDOM from 'react-dom';
import { defineMessages } from 'react-intl'; import { defineMessages } from 'react-intl';
import snackbar from 'soapbox/actions/snackbar'; import snackbar from 'soapbox/actions/snackbar';
import { setSwUpdating } from 'soapbox/actions/sw';
import * as BuildConfig from 'soapbox/build_config'; import * as BuildConfig from 'soapbox/build_config';
import { store } from 'soapbox/store'; import { store } from 'soapbox/store';
import { printConsoleWarning } from 'soapbox/utils/console'; import { printConsoleWarning } from 'soapbox/utils/console';
@ -45,6 +46,7 @@ function main() {
store.dispatch(snackbar.show('info', messages.updateText, { store.dispatch(snackbar.show('info', messages.updateText, {
actionLabel: messages.update, actionLabel: messages.update,
action: () => { action: () => {
store.dispatch(setSwUpdating(true));
OfflinePluginRuntime.applyUpdate(); OfflinePluginRuntime.applyUpdate();
}, },
dismissAfter: false, dismissAfter: false,

View file

@ -1,5 +1,7 @@
import { Record as ImmutableRecord } from 'immutable'; import { Record as ImmutableRecord } from 'immutable';
import { SW_UPDATING, setSwUpdating } from 'soapbox/actions/sw';
import reducer from '../meta'; import reducer from '../meta';
describe('meta reducer', () => { describe('meta reducer', () => {
@ -7,5 +9,13 @@ describe('meta reducer', () => {
const result = reducer(undefined, {}); const result = reducer(undefined, {});
expect(ImmutableRecord.isRecord(result)).toBe(true); expect(ImmutableRecord.isRecord(result)).toBe(true);
expect(result.instance_fetch_failed).toBe(false); expect(result.instance_fetch_failed).toBe(false);
expect(result.swUpdating).toBe(false);
});
describe(SW_UPDATING, () => {
it('sets swUpdating to the provided value', () => {
const result = reducer(undefined, setSwUpdating(true));
expect(result.swUpdating).toBe(true);
});
}); });
}); });

View file

@ -3,11 +3,15 @@
import { Record as ImmutableRecord } from 'immutable'; import { Record as ImmutableRecord } from 'immutable';
import { fetchInstance } from 'soapbox/actions/instance'; import { fetchInstance } from 'soapbox/actions/instance';
import { SW_UPDATING } from 'soapbox/actions/sw';
import type { AnyAction } from 'redux'; import type { AnyAction } from 'redux';
const ReducerRecord = ImmutableRecord({ const ReducerRecord = ImmutableRecord({
/** Whether /api/v1/instance 404'd (and we should display the external auth form). */
instance_fetch_failed: false, instance_fetch_failed: false,
/** Whether the ServiceWorker is currently updating (and we should display a loading screen). */
swUpdating: false,
}); });
export default function meta(state = ReducerRecord(), action: AnyAction) { export default function meta(state = ReducerRecord(), action: AnyAction) {
@ -17,6 +21,8 @@ export default function meta(state = ReducerRecord(), action: AnyAction) {
return state.set('instance_fetch_failed', true); return state.set('instance_fetch_failed', true);
} }
return state; return state;
case SW_UPDATING:
return state.set('swUpdating', action.isUpdating);
default: default:
return state; return state;
} }