mirror of
https://github.com/ourongxing/newsnow.git
synced 2025-01-18 10:56:26 +08:00
feat: better way to update PWA site
This commit is contained in:
parent
9fb5f6eb83
commit
3f4bdde790
@ -3,7 +3,7 @@ import { ourongxing, react } from "@ourongxing/eslint-config"
|
||||
export default ourongxing({
|
||||
type: "app",
|
||||
// 貌似不能 ./ 开头,
|
||||
ignores: ["src/routeTree.gen.ts", "imports.app.d.ts"],
|
||||
ignores: ["src/routeTree.gen.ts", "imports.app.d.ts", "public/"],
|
||||
}).append(react({
|
||||
files: ["src/**"],
|
||||
}))
|
||||
|
23
public/sw.js
Normal file
23
public/sw.js
Normal file
@ -0,0 +1,23 @@
|
||||
self.addEventListener("install", (e) => {
|
||||
self.skipWaiting()
|
||||
})
|
||||
self.addEventListener("activate", (e) => {
|
||||
self.registration
|
||||
.unregister()
|
||||
.then(() => self.clients.matchAll())
|
||||
.then((clients) => {
|
||||
clients.forEach((client) => {
|
||||
if (client instanceof WindowClient) client.navigate(client.url)
|
||||
})
|
||||
return Promise.resolve()
|
||||
})
|
||||
.then(() => {
|
||||
self.caches.keys().then((cacheNames) => {
|
||||
Promise.all(
|
||||
cacheNames.map((cacheName) => {
|
||||
return self.caches.delete(cacheName)
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
@ -4,6 +4,7 @@ import { VitePWA } from "vite-plugin-pwa"
|
||||
|
||||
const pwaOption: Partial<VitePWAOptions> = {
|
||||
includeAssets: ["icon.svg", "apple-touch-icon.png"],
|
||||
filename: "swx.js",
|
||||
manifest: {
|
||||
name: "NewsNow",
|
||||
short_name: "NewsNow",
|
||||
@ -42,7 +43,6 @@ const pwaOption: Partial<VitePWAOptions> = {
|
||||
type: "module",
|
||||
navigateFallback: "index.html",
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
export default function pwa() {
|
||||
|
5
server/api/latest.ts
Normal file
5
server/api/latest.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export default defineEventHandler(async () => {
|
||||
return {
|
||||
v: Version,
|
||||
}
|
||||
})
|
@ -6,7 +6,7 @@ export default defineEventHandler(async (event) => {
|
||||
if (!url.pathname.startsWith("/api")) return
|
||||
if (["JWT_SECRET", "G_CLIENT_ID", "G_CLIENT_SECRET"].find(k => !process.env[k])) {
|
||||
event.context.disabledLogin = true
|
||||
if (["/api/s", "/api/proxy"].every(p => !url.pathname.startsWith(p)))
|
||||
if (["/api/s", "/api/proxy", "/api/latest"].every(p => !url.pathname.startsWith(p)))
|
||||
throw createError({ statusCode: 506, message: "Server not configured, disable login" })
|
||||
} else {
|
||||
if (["/api/s", "/api/me"].find(p => url.pathname.startsWith(p))) {
|
||||
|
@ -20,7 +20,7 @@ export function Toast() {
|
||||
width: WIDTH,
|
||||
left: center,
|
||||
}}
|
||||
className="absolute top-0 z-99 flex flex-col gap-2"
|
||||
className="absolute top-4 z-99 flex flex-col gap-2"
|
||||
>
|
||||
{
|
||||
toastItems.map(k => <Item key={k.id} info={k} />)
|
||||
|
@ -1,45 +1,42 @@
|
||||
import { useEffect } from "react"
|
||||
import { useRegisterSW } from "virtual:pwa-register/react"
|
||||
import { useMount } from "react-use"
|
||||
import { useToast } from "./useToast"
|
||||
|
||||
const intervalMS = 60 * 60 * 1000
|
||||
export function usePWA() {
|
||||
const {
|
||||
needRefresh: [needRefresh, setNeedRefresh],
|
||||
updateServiceWorker,
|
||||
}
|
||||
= useRegisterSW({
|
||||
onRegisteredSW(swUrl, r) {
|
||||
if (r) {
|
||||
setInterval(async () => {
|
||||
if (r.installing || !navigator) return
|
||||
|
||||
if ("connection" 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()
|
||||
}, intervalMS)
|
||||
}
|
||||
},
|
||||
})
|
||||
const toaster = useToast()
|
||||
const { updateServiceWorker } = useRegisterSW()
|
||||
|
||||
useEffect(() => {
|
||||
if (needRefresh) {
|
||||
toaster("网站有更新,点击更新", {
|
||||
action: {
|
||||
label: "更新",
|
||||
onClick: () => updateServiceWorker(true),
|
||||
},
|
||||
onDismiss: () => updateServiceWorker(true),
|
||||
})
|
||||
useMount(async () => {
|
||||
const update = () => {
|
||||
updateServiceWorker().then(() => localStorage.setItem("updated", "1"))
|
||||
}
|
||||
}, [needRefresh, updateServiceWorker, setNeedRefresh, toaster])
|
||||
await delay(1000)
|
||||
if (localStorage.getItem("updated")) {
|
||||
localStorage.removeItem("updated")
|
||||
toaster("更新成功,赶快体验吧", {
|
||||
action: {
|
||||
label: "查看更新",
|
||||
onClick: () => {
|
||||
window.open(`${Homepage}/releases/tag/v${Version}`)
|
||||
},
|
||||
},
|
||||
})
|
||||
} else {
|
||||
if (!navigator) return
|
||||
|
||||
if ("connection" in navigator && !navigator.onLine) return
|
||||
|
||||
const resp = await myFetch("/latest")
|
||||
|
||||
if (resp.v && resp.v !== Version) {
|
||||
toaster("有更新,5 秒后自动更新", {
|
||||
action: {
|
||||
label: "立刻更新",
|
||||
onClick: update,
|
||||
},
|
||||
onDismiss: update,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user