Flipper as PWA

Summary:
^

Reference: https://docs.google.com/document/d/1flQJUzTe4AuQz3QCpvbloQycenHsu7ZxbKScov7K7ao

Reviewed By: passy

Differential Revision: D45693382

fbshipit-source-id: 5a2e6c213a7e7e2cf9cd5f3033cff3e5291a2a92
This commit is contained in:
Lorenzo Blasa
2023-05-16 04:32:47 -07:00
committed by Facebook GitHub Bot
parent 47a4c10c67
commit c6d5eb3334
13 changed files with 556 additions and 70 deletions

View File

@@ -0,0 +1,122 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import React from 'react';
import {Modal, Button} from 'antd';
import {Layout, _NuxManagerContext} from 'flipper-plugin';
type Props = {
onHide: () => void;
};
const lastShownTimestampKey = 'flipper-pwa-wizard-last-shown-timestamp';
export function shouldShowPWAInstallationWizard(): boolean {
if (window.matchMedia('(display-mode: standalone)').matches) {
return false;
}
let lastShownTimestampFromStorage = undefined;
try {
lastShownTimestampFromStorage = window.localStorage.getItem(
lastShownTimestampKey,
);
} catch (e) {}
if (lastShownTimestampFromStorage) {
const withinOneDay = (timestamp: number) => {
const Day = 1 * 24 * 60 * 60 * 1000;
const DayAgo = Date.now() - Day;
return timestamp > DayAgo;
};
const lastShownTimestamp = Number(lastShownTimestampFromStorage);
return !withinOneDay(lastShownTimestamp);
}
const lastShownTimestamp = Date.now();
try {
window.localStorage.setItem(
lastShownTimestampKey,
String(lastShownTimestamp),
);
} catch (e) {}
return true;
}
async function install(event: any) {
event.prompt();
(event.userChoice as any)
.then((choiceResult: any) => {
if (choiceResult.outcome === 'accepted') {
console.log('PWA installation, user accepted the prompt.');
} else {
console.log('PWA installation, user dismissed the prompt.');
}
(globalThis as any).PWAppInstallationEvent = null;
})
.catch((e: Error) => {
console.error('PWA failed to install with error', e);
});
}
export default function PWAInstallationWizard(props: Props) {
const contents = (
<Layout.Container gap>
<Layout.Container style={{width: '100%', paddingBottom: 15}}>
<>
Please install Flipper as a PWA. Installed Progressive Web Apps run in
a standalone window instead of a browser tab. They're launchable from
your home screen, dock, taskbar, or shelf. It's possible to search for
and jump between them with the app switcher, making them feel like
part of the device they're installed on. New capabilities open up
after a web app is installed. Keyboard shortcuts, usually reserved
when running in the browser, become available too.
</>
</Layout.Container>
</Layout.Container>
);
const footer = (
<>
<Button
type="ghost"
onClick={async () => {
props.onHide();
}}>
Not now
</Button>
<Button
type="primary"
onClick={async () => {
const installEvent = (globalThis as any).PWAppInstallationEvent;
if (installEvent) {
await install(installEvent).then(props.onHide);
}
}}>
Install
</Button>
</>
);
return (
<Modal
visible
centered
onCancel={() => {
props.onHide();
}}
width={570}
title="Install Flipper to Desktop"
footer={footer}>
{contents}
</Modal>
);
}

View File

@@ -33,6 +33,9 @@ import {showChangelog} from '../chrome/ChangelogSheet';
import PlatformSelectWizard, {
hasPlatformWizardBeenDone,
} from '../chrome/PlatformSelectWizard';
import PWAInstallationWizard, {
shouldShowPWAInstallationWizard,
} from '../chrome/PWAppInstallationWizard';
import {getVersionString} from '../utils/versionString';
import config from '../fb-stubs/config';
import {WelcomeScreenStaticView} from './WelcomeScreen';
@@ -110,6 +113,11 @@ export function SandyApp() {
));
}
if (shouldShowPWAInstallationWizard()) {
console.info('Attempt to install PWA, launch installation wizard.');
Dialog.showModal((onHide) => <PWAInstallationWizard onHide={onHide} />);
}
showChangelog(true);
// don't warn about logger, even with a new logger we don't want to re-register