Implemented PWA

This commit is contained in:
thepaperpilot 2022-06-26 15:22:22 -05:00
parent cde5e6d737
commit a2b5820906
15 changed files with 4495 additions and 157 deletions

View file

@ -12,11 +12,12 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Icons|Material+Icons+Outlined" rel="stylesheet">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="alternate icon" type="image/png" sizes="48x48" href="/favicon.ico">
<meta name="theme-color" content="#2E3440">
<title>Profectus</title>
<meta name="description" content="A project made in Profectus"/>
</head>
<body>

4531
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -19,6 +19,7 @@
"nanoevents": "^6.0.2",
"pixi.js": "^6.3.0",
"vite": "^2.9.12",
"vite-plugin-pwa": "^0.12.0",
"vite-tsconfig-paths": "^3.5.0",
"vue": "^3.2.26",
"vue-next-select": "^2.10.2",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 873 B

24
public/favicon.svg Normal file
View file

@ -0,0 +1,24 @@
<svg width="656" height="649" viewBox="0 0 656 649" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_65_3)">
<rect x="26" y="21" width="600" height="600" rx="30" fill="#2E3440"/>
</g>
<path d="M313 572.877C295.453 567.525 262.205 562.614 233 572.877C243.737 355.447 238.724 271.878 233 107.877C233 107.877 279.614 70.7611 313 65.8775C346.386 60.9938 399.025 76.3369 433 115.877C438 145.877 428.647 222.534 389 271.878C354.851 314.378 259 310.358 259 364.877C259 466.877 313 572.877 313 572.877Z" stroke="#A3BE8C" stroke-width="10" stroke-miterlimit="16" stroke-linecap="round"/>
<path d="M433 115.878C421.023 186.453 397.39 226.835 370.997 251.5C305.783 312.444 223.719 277.436 259 364.877" stroke="#A3BE8C" stroke-width="5" stroke-miterlimit="16" stroke-linecap="round"/>
<path d="M406.5 248C395.275 252.447 387.434 253.134 370.997 251.5" stroke="#A3BE8C" stroke-width="5" stroke-miterlimit="16" stroke-linecap="round"/>
<path d="M285.5 306.5C323.145 305.626 339.011 298.775 368.5 288" stroke="#A3BE8C" stroke-width="5" stroke-miterlimit="16" stroke-linecap="round"/>
<path d="M433 115.877C381.5 77.8262 298.094 104.947 259 167C254.257 174.528 251.896 182.373 250.674 191C247.146 215.91 253.117 247.34 238.673 296.5" stroke="#A3BE8C" stroke-width="5" stroke-miterlimit="16" stroke-linecap="round"/>
<path d="M233 107.878L250.674 191" stroke="#A3BE8C" stroke-width="5" stroke-miterlimit="16" stroke-linecap="round"/>
<path d="M215 386.5C228.178 408.708 231.486 429.334 236.7 467.5" stroke="#A3BE8C" stroke-width="5" stroke-miterlimit="16" stroke-linecap="round"/>
<defs>
<filter id="filter0_d_65_3" x="22" y="21" width="608" height="608" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_65_3"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_65_3" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

2
public/robots.txt Normal file
View file

@ -0,0 +1,2 @@
User-agent: *
Allow: /

View file

@ -1 +0,0 @@
{"name":"Profectus","short_name":"Profectus","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#2E3440","background_color":"#2E3440","display":"standalone"}

View file

@ -1,5 +1,6 @@
{
"title": "Profectus",
"description": "A project made in Profectus",
"id": "profectus",
"author": "thepaperpilot",
"discordName": "The Paper Pilot Community",

17
src/lib/pwa-register.d.ts vendored Normal file
View file

@ -0,0 +1,17 @@
declare module 'virtual:pwa-register/vue' {
import type { Ref } from 'vue'
export interface RegisterSWOptions {
immediate?: boolean
onNeedRefresh?: () => void
onOfflineReady?: () => void
onRegistered?: (registration: ServiceWorkerRegistration | undefined) => void
onRegisterError?: (error: any) => void
}
export function useRegisterSW(options?: RegisterSWOptions): {
needRefresh: Ref<boolean>
offlineReady: Ref<boolean>
updateServiceWorker: (reloadPage?: boolean) => Promise<void>
}
}

View file

@ -1,4 +1,6 @@
import { App as VueApp, createApp } from "vue";
import { useRegisterSW } from "virtual:pwa-register/vue";
import { App as VueApp, createApp, nextTick } from "vue";
import { useToast } from "vue-toastification";
import App from "./App.vue";
import projInfo from "./data/projInfo.json";
import { GenericLayer } from "./game/layers";
@ -7,6 +9,7 @@ import { Settings } from "./game/settings";
import { Transient } from "./game/state";
import Decimal, { DecimalSource } from "./util/bignum";
import { load } from "./util/save";
import "./game/notifications";
document.title = projInfo.title;
if (projInfo.id === "") {
@ -51,6 +54,38 @@ requestAnimationFrame(async () => {
globalBus.emit("setupVue", vue);
vue.mount("#app");
// Setup PWA update prompt
nextTick(() => {
const toast = useToast();
const { updateServiceWorker } = useRegisterSW({
onNeedRefresh() {
toast.info("New content available, click or reload to update.", {
timeout: false,
closeOnClick: false,
draggable: false,
icon: {
iconClass: "material-icons",
iconChildren: "refresh",
iconTag: "i"
},
rtl: false,
onClick() {
updateServiceWorker();
}
});
},
onOfflineReady() {
toast.info("App ready to work offline");
},
onRegisterError: console.warn,
onRegistered(r) {
if (r) {
setInterval(r.update, 60 * 60 * 1000);
}
}
});
});
startGameLoop();
});

View file

@ -1,7 +1,9 @@
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";
import { defineConfig } from "vite";
import { VitePWA } from "vite-plugin-pwa";
import tsconfigPaths from "vite-tsconfig-paths";
import projInfo from "./src/data/projInfo.json";
// https://vitejs.dev/config/
export default defineConfig({
@ -10,6 +12,33 @@ export default defineConfig({
vueJsx({
// options are passed on to @vue/babel-plugin-jsx
}),
tsconfigPaths()
tsconfigPaths(),
VitePWA({
includeAssets: ["Logo.svg", "favicon.ico", "robots.txt", "apple-touch-icon.png"],
manifest: {
name: projInfo.title,
short_name: projInfo.title,
description: projInfo.description,
theme_color: "#2E3440",
icons: [
{
src: "pwa-192x192.png",
sizes: "192x192",
type: "image/png"
},
{
src: "pwa-512x512.png",
sizes: "512x512",
type: "image/png"
},
{
src: "pwa-512x512.png",
sizes: "512x512",
type: "image/png",
purpose: "any maskable"
}
]
}
})
]
});