wip: reload page if version different

This commit is contained in:
Siyuan Miao 2025-09-11 12:02:26 +02:00
parent c8dd84c6b7
commit b2337af0e8
4 changed files with 87 additions and 10 deletions

18
ui/package-lock.json generated
View File

@ -48,6 +48,7 @@
"@tailwindcss/postcss": "^4.1.12", "@tailwindcss/postcss": "^4.1.12",
"@tailwindcss/typography": "^0.5.16", "@tailwindcss/typography": "^0.5.16",
"@tailwindcss/vite": "^4.1.12", "@tailwindcss/vite": "^4.1.12",
"@types/node": "^22.18.1",
"@types/react": "^19.1.12", "@types/react": "^19.1.12",
"@types/react-dom": "^19.1.9", "@types/react-dom": "^19.1.9",
"@types/semver": "^7.7.1", "@types/semver": "^7.7.1",
@ -1980,6 +1981,16 @@
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": {
"version": "22.18.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.1.tgz",
"integrity": "sha512-rzSDyhn4cYznVG+PCzGe1lwuMYJrcBS1fc3JqSa2PvtABwWo+dZ1ij5OVok3tqfpEBCBoaR4d7upFJk73HRJDw==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
}
},
"node_modules/@types/react": { "node_modules/@types/react": {
"version": "19.1.12", "version": "19.1.12",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz",
@ -6790,6 +6801,13 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"devOptional": true,
"license": "MIT"
},
"node_modules/update-browserslist-db": { "node_modules/update-browserslist-db": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",

View File

@ -59,6 +59,7 @@
"@tailwindcss/postcss": "^4.1.12", "@tailwindcss/postcss": "^4.1.12",
"@tailwindcss/typography": "^0.5.16", "@tailwindcss/typography": "^0.5.16",
"@tailwindcss/vite": "^4.1.12", "@tailwindcss/vite": "^4.1.12",
"@types/node": "^22.18.1",
"@types/react": "^19.1.12", "@types/react": "^19.1.12",
"@types/react-dom": "^19.1.9", "@types/react-dom": "^19.1.9",
"@types/semver": "^7.7.1", "@types/semver": "^7.7.1",

View File

@ -0,0 +1,24 @@
import { useCallback, useEffect, useState } from "react";
const isOnDevice = import.meta.env.MODE === "device";
export function useReloadPage() {
const [pageHash, setPageHash] = useState("");
const fetchPageHash = useCallback(async () => {
const response = await fetch("/static-hash.json");
const data = await response.json();
setPageHash(data.hash);
}, [setPageHash]);
useEffect(() => {
if (!isOnDevice) return ;
const interval = setInterval(() => fetchPageHash(), 1000);
return () => clearInterval(interval);
}, [fetchPageHash]);
useEffect(() => {
if (!isOnDevice) return ;
}, [pageHash]);
}

View File

@ -1,8 +1,10 @@
import { defineConfig } from "vite"; import { defineConfig, type Plugin } from "vite";
import type { OutputAsset } from "rollup";
import react from "@vitejs/plugin-react-swc"; import react from "@vitejs/plugin-react-swc";
import tailwindcss from "@tailwindcss/vite"; import tailwindcss from "@tailwindcss/vite";
import tsconfigPaths from "vite-tsconfig-paths"; import tsconfigPaths from "vite-tsconfig-paths";
import basicSsl from "@vitejs/plugin-basic-ssl"; import basicSsl from "@vitejs/plugin-basic-ssl";
import crypto from "node:crypto";
declare const process: { declare const process: {
env: { env: {
@ -11,6 +13,37 @@ declare const process: {
}; };
}; };
const toHash = (str: string | Uint8Array<ArrayBufferLike>) => {
return crypto.createHash("sha256").update(str).digest("hex");
}
const indexHtmlHashPlugin = (): Plugin => ({
name: "index-html-hash",
enforce: "post",
generateBundle(options, bundle) {
const indexHtml = bundle["index.html"];
for (const key in bundle) {
if (key.includes("index-")) {
console.log(bundle[key].originalFileNames);
}
}
if (indexHtml) {
bundle["static-hash.json"] = {
type: "asset",
source: JSON.stringify({
hash: toHash((indexHtml as OutputAsset).source),
}),
fileName: "static-hash.json",
needsCodeReference: false,
name: undefined,
names: ["static-hash.json"],
originalFileName: null,
originalFileNames: ["static-hash.json"],
};
}
}
})
export default defineConfig(({ mode, command }) => { export default defineConfig(({ mode, command }) => {
const isCloud = mode.indexOf("cloud") !== -1; const isCloud = mode.indexOf("cloud") !== -1;
const onDevice = mode === "device"; const onDevice = mode === "device";
@ -20,7 +53,8 @@ export default defineConfig(({ mode, command }) => {
const plugins = [ const plugins = [
tailwindcss(), tailwindcss(),
tsconfigPaths(), tsconfigPaths(),
react() react(),
indexHtmlHashPlugin(),
]; ];
if (useSSL) { if (useSSL) {
plugins.push(basicSsl()); plugins.push(basicSsl());
@ -37,14 +71,14 @@ export default defineConfig(({ mode, command }) => {
https: useSSL, https: useSSL,
proxy: JETKVM_PROXY_URL proxy: JETKVM_PROXY_URL
? { ? {
"/me": JETKVM_PROXY_URL, "/me": JETKVM_PROXY_URL,
"/device": JETKVM_PROXY_URL, "/device": JETKVM_PROXY_URL,
"/webrtc": JETKVM_PROXY_URL, "/webrtc": JETKVM_PROXY_URL,
"/auth": JETKVM_PROXY_URL, "/auth": JETKVM_PROXY_URL,
"/storage": JETKVM_PROXY_URL, "/storage": JETKVM_PROXY_URL,
"/cloud": JETKVM_PROXY_URL, "/cloud": JETKVM_PROXY_URL,
"/developer": JETKVM_PROXY_URL, "/developer": JETKVM_PROXY_URL,
} }
: undefined, : undefined,
}, },
base: onDevice && command === "build" ? "/static" : "/", base: onDevice && command === "build" ? "/static" : "/",