Skip to content

Commit

Permalink
Improve PWA
Browse files Browse the repository at this point in the history
  • Loading branch information
mantou132 committed Nov 29, 2023
1 parent bd5b7c4 commit b0287d1
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 89 deletions.
Binary file modified packages/webapp/public/logo-maskable-144.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
81 changes: 0 additions & 81 deletions packages/webapp/public/manifest.webmanifest

This file was deleted.

31 changes: 26 additions & 5 deletions packages/webapp/public/sw.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
const sw = self;

const cacheName = 'console';
const assetsToCache = [...new Set([sw.location.pathname, '/'])].map((path) => sw.location.origin + path);
const assetsToCache = [...new Set(['/'])].map((path) => location.origin + path);

sw.addEventListener('activate', (event) => {
event.waitUntil(sw.registration.navigationPreload?.enable() || Promise.resolve());
});

sw.addEventListener('install', () => {
sw.skipWaiting();
sw.caches.open(cacheName).then((cache) => {
caches.open(cacheName).then((cache) => {
cache.addAll(assetsToCache);
});
});
Expand All @@ -29,6 +29,7 @@ sw.addEventListener('push', function (event) {
payload = { title: event.data.text() };
}
event.waitUntil(
// 需要在 client 请求权限
sw.registration.showNotification(payload.title, {
icon: '/logo-144.png',
body: payload.body,
Expand All @@ -44,16 +45,36 @@ sw.addEventListener('notificationclick', function (event) {
event.notification.close();
});

/**
*
* @param {FetchEvent} event
*/
function handleShareTarget(event) {
event.respondWith(
(async () => {
const formData = await event.request.formData();
const file = formData.get('file');
// TODO: add to caches -> client open emulator
return Response.redirect('/', 303);
})(),
);
}

sw.addEventListener('fetch', (event) => {
const { request } = event;
const requestUrl = new URL(request.url);
const isSomeOrigin = requestUrl.origin === sw.location.origin;
const isSomeOrigin = requestUrl.origin === location.origin;
const isApiFetch = (isSomeOrigin && requestUrl.pathname.startsWith('/api')) || requestUrl.origin.includes('api.');

if (requestUrl.pathname === '/_share_target') {
handleShareTarget(event);
return;
}

if (request.method !== 'GET') return;
if (!isSomeOrigin && !isApiFetch) return;

const getCache = () => sw.caches.match(request, { ignoreSearch: request.mode === 'navigate' });
const getCache = () => caches.match(request, { ignoreSearch: request.mode === 'navigate' });

event.respondWith(
(async function () {
Expand All @@ -64,7 +85,7 @@ sw.addEventListener('fetch', (event) => {
.then(async (response) => {
if (response.ok) {
const responseCache = response.clone();
sw.caches.open(cacheName).then((cache) => cache.put(request, responseCache));
caches.open(cacheName).then((cache) => cache.put(request, responseCache));
return response;
} else {
const cache = await getCache();
Expand Down
1 change: 1 addition & 0 deletions packages/webapp/src/drop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { setNesFile } from 'src/configure';

window.launchQueue?.setConsumer(async (launchParams: any) => {
if (!launchParams.files.length) return;
// 为啥刷新还是会触发

// https://github.com/WICG/file-system-access/blob/master/EXPLAINER.md#example-code
const files = await Promise.all(launchParams.files.map((h: any) => h.getFile()));
Expand Down
1 change: 0 additions & 1 deletion packages/webapp/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
/>
<title>NESBox</title>
<link type="image/png" sizes="32x32" rel="icon" href="/logo-32.png" />
<link rel="manifest" href="/manifest.webmanifest" />
<link rel="preload" href="/fonts/regular.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<link rel="preload" href="/fonts/medium.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<script async type="module" src="./index.ts"></script>
Expand Down
10 changes: 10 additions & 0 deletions packages/webapp/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,13 @@ if (COMMAND === 'build') {
addEventListener('load', () => {
logger.info('Loaded!');
});

// Installed
matchMedia(mediaQuery.PWA).addEventListener('change', ({ matches }) => {
if (matches) {
const w = 1024;
const h = 640;
resizeTo(w, h);
moveTo((screen.width - w) / 2, (screen.height - h) / 2);
}
});
23 changes: 21 additions & 2 deletions packages/webapp/src/modules/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { mediaQuery } from '@mantou/gem/helper/mediaquery';
import { i18n } from 'src/i18n/basic';
import { themeStore } from 'src/theme';
import { canonicalOrigin, isSafari } from 'src/constants';
import { navStore } from 'src/configure';
import { configure, navStore } from 'src/configure';

import 'duoyun-ui/elements/title';
import 'duoyun-ui/elements/reflect';
Expand All @@ -15,6 +15,10 @@ const style = createCSSSheet(css`
}
`);

type State = {
manifest?: string;
};

/**
* @customElement m-meta
*/
Expand All @@ -24,8 +28,22 @@ const style = createCSSSheet(css`
@connectStore(i18n.store)
@connectStore(history.store)
@adoptedStyle(style)
export class ModuleMetaElement extends GemElement {
export class ModuleMetaElement extends GemElement<State> {
state: State = {};
mounted = () => {
addEventListener('load', async () => {
const { getWebManifestURL } = await import('src/webmanifest');
this.effect(
() => {
this.setState({ manifest: getWebManifestURL() });
},
() => [i18n.currentLanguage, configure.theme],
);
});
};

render = () => {
const { manifest } = this.state;
return html`
<dy-title suffix=${mediaQuery.isPWA ? '' : ` - ${i18n.get('global.title')}`}></dy-title>
<dy-reflect>
Expand All @@ -35,6 +53,7 @@ export class ModuleMetaElement extends GemElement {
/>
<meta name="description" content=${i18n.get('global.sloganDesc')} />
<link rel="canonical" href=${`${canonicalOrigin}${history.getParams().path}`} />
${manifest ? html`<link rel="manifest" href=${manifest} />` : ''}
</dy-reflect>
`;
};
Expand Down
110 changes: 110 additions & 0 deletions packages/webapp/src/webmanifest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { utf8ToB64 } from 'duoyun-ui/lib/encode';
import { routes } from 'src/routes';

import { COMMAND } from 'src/constants';
import { i18n } from 'src/i18n/basic';

export function getWebManifestURL() {
return `data:application/json;base64,${utf8ToB64(
JSON.stringify(genWebManifest(), (_, value) =>
typeof value === 'string' && value.startsWith('/') ? new URL(value, location.origin).href : value,
),
)}`;
}

export function genWebManifest() {
return {
id: 'com.nesbox' + (COMMAND === 'serve' ? '.dev' : ''),
name: i18n.get('global.title') + (COMMAND === 'serve' ? '(DEV)' : ''),
short_name: i18n.get('global.title'),
categories: ['entertainment', 'games'],
description: i18n.get('global.sloganDesc').replaceAll('\n', ','),
scope: '/',
start_url: `${routes.games.pattern}?utm_source=web_app_manifest`,
background_color: 'black',
theme_color: 'black',
display: 'standalone',
orientation: 'landscape',
file_handlers: [
{
action: routes.emulator.pattern,
name: 'Game File',
accept: {
'application/octet-stream': ['.nes'],
},
},
],
share_target: {
action: '/_share_target',
method: 'POST',
enctype: 'multipart/form-data',
params: {
files: [
{
name: 'nes',
accept: ['application/octet-stream', '.nes'],
},
],
},
},
launch_handler: {
client_mode: 'navigate-new',
},
shortcuts: [
{
name: i18n.get('page.games.title'),
url: routes.games.pattern,
},
{
name: i18n.get('page.favorites.title'),
url: routes.favorites.pattern,
},
],
icons: [
{
src: '/logo-32.png',
sizes: '32x32',
type: 'image/png',
},
{
src: '/logo-96.png',
sizes: '96x96',
type: 'image/png',
},
{
src: '/logo-maskable-144.png',
sizes: '144x144',
type: 'image/png',
purpose: 'maskable',
},
{
src: '/logo-144.png',
sizes: '144x144',
type: 'image/png',
},
],
screenshots: [
{
src: 'https://raw.githubusercontent.com/mantou132/nesbox/master/screenshots/homepage.png',
sizes: '1280x861',
type: 'image/png',
form_factor: 'wide',
label: 'HomeScreen of NESBox',
},
{
src: 'https://raw.githubusercontent.com/mantou132/nesbox/master/screenshots/playing.png',
sizes: '1280x861',
type: 'image/png',
form_factor: 'wide',
label: 'Playing game in NESBox',
},
{
src: 'https://raw.githubusercontent.com/mantou132/nesbox/master/screenshots/settings.png',
sizes: '1280x861',
type: 'image/png',
form_factor: 'wide',
label: 'Settings in NESBox',
},
],
};
}

0 comments on commit b0287d1

Please sign in to comment.