-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathindex.html
More file actions
114 lines (104 loc) · 4.55 KB
/
Copy pathindex.html
File metadata and controls
114 lines (104 loc) · 4.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Best-effort: avoid browsers caching this HTML (so users get latest deploy without Ctrl+R) -->
<meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate, max-age=0" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<!-- GitHub Pages cache-buster: if a newer deploy exists, reload this HTML with ?v=... -->
<script>
(() => {
const LOCAL_VERSION = '%APP_VERSION%'
const IS_PROD_BUILD = '%IS_PROD_BUILD%' === 'true'
// Strip any ?v=… cache-bust param ASAP — runs before anything else so the
// dirty URL after a forced reload is visible for the bare minimum time
// (just the navigation flash). The captured value feeds the version check
// below so a stale-server race (server still serves old HTML for the bumped
// version) doesn't loop.
let arrivedWithV = ''
try {
const params = new URLSearchParams(location.search)
arrivedWithV = params.get('v') || ''
if (params.has('v')) {
params.delete('v')
const next = new URL(location.href)
next.search = params.toString() ? `?${params.toString()}` : ''
history.replaceState(null, '', next.toString())
}
} catch {}
const parseSemver = (v) => {
const s = String(v || '').trim().replace(/^v/i, '')
const core = s.split('-')[0]
const [a, b, c] = core.split('.')
return [Number(a) || 0, Number(b) || 0, Number(c) || 0]
}
const isNewer = (remote, local) => {
const r = parseSemver(remote)
const l = parseSemver(local)
for (let i = 0; i < 3; i++) {
if (r[i] > l[i]) return true
if (r[i] < l[i]) return false
}
return false
}
// Exposed so App.vue / kiosk can re-check on "Refresh data" without duplicating logic.
// Works on any HTTP host (GitHub Pages, internal Apache/nginx, …); skipped on
// file:// (Electron) where there's no remote deploy to compare against.
window.__glvCheckForUpdate = async () => {
try {
const isHttp = location.protocol === 'http:' || location.protocol === 'https:'
if (!IS_PROD_BUILD || !isHttp) return false
const u = new URL('current_version.json', location.href)
u.search = ''
const res = await fetch(u.toString(), { cache: 'no-store' })
if (!res.ok) return false
const remote = await res.json()
// Stamp last successful check (fetch + parse OK, regardless of whether an update is
// needed) so kiosk's daily 3am safety reload knows the auto-update channel is healthy.
window.__glvLastVersionCheckOk = Date.now()
const remoteVersion = remote && remote.version ? String(remote.version) : ''
if (!remoteVersion || !LOCAL_VERSION) return false
// Loop guard: we just arrived from `?v=remoteVersion` but LOCAL_VERSION
// still reads as older. Server is stale — give up rather than reload again.
if (arrivedWithV && arrivedWithV === remoteVersion) return false
if (!isNewer(remoteVersion, LOCAL_VERSION)) return false
const next = new URL(location.href)
next.searchParams.set('v', remoteVersion)
location.replace(next.toString())
return true
} catch {
return false
}
}
// Initial check on page load.
try { window.__glvCheckForUpdate() } catch {}
})()
</script>
<!-- Electron renderer security: avoid "no CSP / unsafe-eval" warnings -->
<meta
http-equiv="Content-Security-Policy"
content="
default-src 'self';
base-uri 'self';
form-action 'self';
object-src 'none';
script-src 'self' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' data: blob:;
font-src 'self' data:;
connect-src 'self' http: https: ws: wss:;
"
/>
<link rel="icon" href="./favicon.ico" />
<title>GitLab Viz</title>
<style>
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }
</style>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>