Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support PWA #806

Merged
merged 3 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions apps/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,14 @@
</script>

<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Bridge stablecoin and native tokens on HelixBridge</title>
<title>Bridge Stablecoins and Native Tokens on HelixBridge</title>
<meta name="description" content="Secure, fast, and low-cost cross-chain crypto transfers" />
<link rel="manifest" href="manifest.json" />
<script defer data-domain="helixbridge.app" src="https://plausible.io/js/script.hash.outbound-links.tagged-events.js"></script>
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
</head>
<body style="background-color: #00141d; color: white; line-height: 1.5rem; font-size: 1rem; font-weight: 400">
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<script type="module" src="src/main.tsx"></script>
</body>
</html>
6 changes: 5 additions & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"@types/react-transition-group": "^4.4.10",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"@vite-pwa/assets-generator": "^0.2.4",
"@vitejs/plugin-react-swc": "^3.5.0",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
Expand All @@ -55,7 +56,10 @@
"tailwindcss": "^3.4.3",
"typescript": "^5.2.2",
"vite": "^5.2.0",
"vitest": "^1.6.0"
"vite-plugin-pwa": "^0.20.1",
"vitest": "^1.6.0",
"workbox-core": "^7.1.0",
"workbox-window": "^7.1.0"
},
"packageManager": "pnpm@9.4.0"
}
Binary file removed apps/web/public/favicon.ico
Binary file not shown.
6 changes: 6 additions & 0 deletions apps/web/public/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 0 additions & 5 deletions apps/web/public/manifest.json

This file was deleted.

3 changes: 3 additions & 0 deletions apps/web/public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Allow: /
19 changes: 19 additions & 0 deletions apps/web/pwa-assets.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { defineConfig } from "@vite-pwa/assets-generator/config";

export default defineConfig({
headLinkOptions: {
preset: "2023",
},
preset: {
transparent: { sizes: [64, 192, 512], favicons: [[48, "favicon.ico"]] },
maskable: {
sizes: [512],
resizeOptions: { fit: "contain", background: "#00141D" },
},
apple: {
sizes: [180],
resizeOptions: { fit: "contain", background: "#00141D" },
},
},
images: ["public/favicon.svg"],
});
74 changes: 74 additions & 0 deletions apps/web/src/components/pwa-badge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { useRegisterSW } from "virtual:pwa-register/react";
import Button from "../ui/button";

export default function PWABadge() {
// Periodic sync is disabled, change the value to enable it, the period is in milliseconds
// You can remove onRegisteredSW callback and registerPeriodicSync function
const period = 0;

const {
needRefresh: [needRefresh, setNeedRefresh],
updateServiceWorker,
} = useRegisterSW({
onRegisteredSW(swUrl, r) {
if (period <= 0) return;
if (r?.active?.state === "activated") {
registerPeriodicSync(period, swUrl, r);
} else if (r?.installing) {
r.installing.addEventListener("statechange", (e) => {
const sw = e.target as ServiceWorker;
if (sw.state === "activated") registerPeriodicSync(period, swUrl, r);
});
}
},
});

function close() {
setNeedRefresh(false);
}

return (
<div role="alert" aria-labelledby="toast-message">
{needRefresh && (
<div className="bg-background fixed bottom-0 right-0 z-10 m-4 flex flex-col gap-y-3 rounded-xl border border-white/20 p-3 text-left">
<span id="toast-message" className="text-sm font-bold text-white">
New content available, click on reload button to update.
</span>
<div className="flex items-center justify-end gap-x-3">
<Button className="rounded-lg px-3 py-[0.125rem] text-sm font-bold" onClick={() => close()}>
Close
</Button>
<Button
className="rounded-lg px-3 py-[0.125rem] text-sm font-bold"
onClick={() => updateServiceWorker(true)}
kind="primary"
>
Reload
</Button>
</div>
</div>
)}
</div>
);
}

/**
* This function will register a periodic sync check every hour, you can modify the interval as needed.
*/
function registerPeriodicSync(period: number, swUrl: string, r: ServiceWorkerRegistration) {
if (period <= 0) return;

setInterval(async () => {
if ("onLine" in navigator && !navigator.onLine) return;

const resp = await fetch(swUrl, {
cache: "no-store",
headers: {
cache: "no-store",
"cache-control": "no-cache",
},
});

if (resp?.status === 200) await r.update();
}, period);
}
2 changes: 2 additions & 0 deletions apps/web/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import ReactDOM from "react-dom/client";
import "./index.css";
import { RouterProvider } from "react-router-dom";
import { router } from "./router.tsx";
import PWABadge from "./components/pwa-badge.tsx";

ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<RouterProvider router={router} />
<PWABadge />
</React.StrictMode>,
);
1 change: 1 addition & 0 deletions apps/web/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/// <reference types="vite/client" />
/// <reference types="vite-plugin-pwa/react" />
31 changes: 30 additions & 1 deletion apps/web/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,38 @@

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
import { VitePWA } from "vite-plugin-pwa";

// https://vitejs.dev/config/
export default defineConfig({
base: "",
plugins: [react()],
plugins: [
react(),
VitePWA({
registerType: "prompt",
injectRegister: false,
manifestFilename: "manifest.json",
pwaAssets: {
disabled: false,
config: true,
},
manifest: {
name: "Helix Bridge",
short_name: "HelixBridge",
description: "Secure, fast, and low-cost cross-chain crypto transfers",
theme_color: "#00141D",
},
workbox: {
globPatterns: ["**/*.{js,css,html,svg,png,ico}"],
cleanupOutdatedCaches: true,
clientsClaim: true,
},
devOptions: {
enabled: false,
navigateFallback: "index.html",
suppressWarnings: true,
type: "module",
},
}),
],
});
Loading
Loading