From fd7c6e28e136beef943c112954674cd7571d3e80 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 4 Nov 2025 18:50:59 +0000 Subject: [PATCH 1/4] Initial plan From 6334a062d20197ea80f04556c7653fd6fcd1a1d2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 4 Nov 2025 18:57:41 +0000 Subject: [PATCH 2/4] Integrate VitePWA with prompt mode and ReloadPrompt component Co-authored-by: mikebarkmin <2592379+mikebarkmin@users.noreply.github.com> --- platforms/web/src/App.tsx | 2 ++ platforms/web/src/ReloadPrompt.css | 29 ++++++++++++++++++ platforms/web/src/ReloadPrompt.tsx | 49 ++++++++++++++++++++++++++++++ platforms/web/src/vite-env.d.ts | 2 ++ platforms/web/tsconfig.app.json | 2 +- platforms/web/vite.config.ts | 2 +- 6 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 platforms/web/src/ReloadPrompt.css create mode 100644 platforms/web/src/ReloadPrompt.tsx create mode 100644 platforms/web/src/vite-env.d.ts diff --git a/platforms/web/src/App.tsx b/platforms/web/src/App.tsx index 34cbfa8..4fd4371 100644 --- a/platforms/web/src/App.tsx +++ b/platforms/web/src/App.tsx @@ -4,6 +4,7 @@ import { LearningMapEditor } from '@learningmap/learningmap'; import "@learningmap/learningmap/index.css"; import Learn from './Learn'; import Landing from './Landing'; +import ReloadPrompt from './ReloadPrompt'; function App() { return ( @@ -13,6 +14,7 @@ function App() { } /> } /> + ) } diff --git a/platforms/web/src/ReloadPrompt.css b/platforms/web/src/ReloadPrompt.css new file mode 100644 index 0000000..c185f49 --- /dev/null +++ b/platforms/web/src/ReloadPrompt.css @@ -0,0 +1,29 @@ +.ReloadPrompt-container { + padding: 0; + margin: 0; + width: 0; + height: 0; +} +.ReloadPrompt-toast { + position: fixed; + right: 0; + bottom: 0; + margin: 16px; + padding: 12px; + border: 1px solid #8885; + border-radius: 4px; + z-index: 1; + text-align: left; + box-shadow: 3px 4px 5px 0 #8885; + background-color: white; +} +.ReloadPrompt-toast-message { + margin-bottom: 8px; +} +.ReloadPrompt-toast-button { + border: 1px solid #8885; + outline: none; + margin-right: 5px; + border-radius: 2px; + padding: 3px 10px; +} diff --git a/platforms/web/src/ReloadPrompt.tsx b/platforms/web/src/ReloadPrompt.tsx new file mode 100644 index 0000000..5d117ba --- /dev/null +++ b/platforms/web/src/ReloadPrompt.tsx @@ -0,0 +1,49 @@ +import './ReloadPrompt.css' + +import { useRegisterSW } from 'virtual:pwa-register/react' + +function ReloadPrompt() { + const { + offlineReady: [offlineReady, setOfflineReady], + needRefresh: [needRefresh, setNeedRefresh], + updateServiceWorker, + } = useRegisterSW({ + onRegistered(r) { + // eslint-disable-next-line prefer-template + console.log('SW Registered: ' + r) + // Implement periodic SW updates (check every hour) + if (r) { + setInterval(() => { + r.update() + }, 60 * 60 * 1000) + } + }, + onRegisterError(error) { + console.log('SW registration error', error) + }, + }) + + const close = () => { + setOfflineReady(false) + setNeedRefresh(false) + } + + return ( +
+ { (offlineReady || needRefresh) + &&
+
+ { offlineReady + ? App ready to work offline + : New content available, click on reload button to update. + } +
+ { needRefresh && } + +
+ } +
+ ) +} + +export default ReloadPrompt diff --git a/platforms/web/src/vite-env.d.ts b/platforms/web/src/vite-env.d.ts new file mode 100644 index 0000000..ec878b7 --- /dev/null +++ b/platforms/web/src/vite-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/platforms/web/tsconfig.app.json b/platforms/web/tsconfig.app.json index a9b5a59..177d3d7 100644 --- a/platforms/web/tsconfig.app.json +++ b/platforms/web/tsconfig.app.json @@ -5,7 +5,7 @@ "useDefineForClassFields": true, "lib": ["ES2022", "DOM", "DOM.Iterable"], "module": "ESNext", - "types": ["vite/client"], + "types": ["vite/client", "vite-plugin-pwa/react"], "skipLibCheck": true, /* Bundler mode */ diff --git a/platforms/web/vite.config.ts b/platforms/web/vite.config.ts index 223ee57..16f42eb 100644 --- a/platforms/web/vite.config.ts +++ b/platforms/web/vite.config.ts @@ -7,7 +7,7 @@ export default defineConfig({ plugins: [ react(), VitePWA({ - registerType: 'autoUpdate', + registerType: 'prompt', includeAssets: ['logo.svg', 'concert_one_latin.woff2'], manifest: { name: 'Learningmap - Interactive Visual Maps for Teaching and Learning', From f3b498381733abc1e9d6ad69a0e451bb65451108 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 4 Nov 2025 19:01:09 +0000 Subject: [PATCH 3/4] Address code review feedback: fix CSS class name, use template literals, extract magic number Co-authored-by: mikebarkmin <2592379+mikebarkmin@users.noreply.github.com> --- platforms/web/src/ReloadPrompt.css | 2 +- platforms/web/src/ReloadPrompt.tsx | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/platforms/web/src/ReloadPrompt.css b/platforms/web/src/ReloadPrompt.css index c185f49..803725b 100644 --- a/platforms/web/src/ReloadPrompt.css +++ b/platforms/web/src/ReloadPrompt.css @@ -17,7 +17,7 @@ box-shadow: 3px 4px 5px 0 #8885; background-color: white; } -.ReloadPrompt-toast-message { +.ReloadPrompt-message { margin-bottom: 8px; } .ReloadPrompt-toast-button { diff --git a/platforms/web/src/ReloadPrompt.tsx b/platforms/web/src/ReloadPrompt.tsx index 5d117ba..dda6f21 100644 --- a/platforms/web/src/ReloadPrompt.tsx +++ b/platforms/web/src/ReloadPrompt.tsx @@ -2,6 +2,8 @@ import './ReloadPrompt.css' import { useRegisterSW } from 'virtual:pwa-register/react' +const UPDATE_CHECK_INTERVAL_MS = 60 * 60 * 1000 // Check for updates every hour + function ReloadPrompt() { const { offlineReady: [offlineReady, setOfflineReady], @@ -9,13 +11,12 @@ function ReloadPrompt() { updateServiceWorker, } = useRegisterSW({ onRegistered(r) { - // eslint-disable-next-line prefer-template - console.log('SW Registered: ' + r) + console.log(`SW Registered: ${r}`) // Implement periodic SW updates (check every hour) if (r) { setInterval(() => { r.update() - }, 60 * 60 * 1000) + }, UPDATE_CHECK_INTERVAL_MS) } }, onRegisterError(error) { From 8632f09b5451f1e05a1b0aaabae67b7480f50307 Mon Sep 17 00:00:00 2001 From: Mike Barkmin Date: Tue, 4 Nov 2025 20:46:42 +0100 Subject: [PATCH 4/4] fix css of prompt --- platforms/web/src/ReloadPrompt.css | 49 +++++++++++++++++++++++++++--- platforms/web/src/ReloadPrompt.tsx | 22 ++++++++------ pnpm-workspace.yaml | 4 +++ 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/platforms/web/src/ReloadPrompt.css b/platforms/web/src/ReloadPrompt.css index 803725b..7954413 100644 --- a/platforms/web/src/ReloadPrompt.css +++ b/platforms/web/src/ReloadPrompt.css @@ -4,26 +4,65 @@ width: 0; height: 0; } + .ReloadPrompt-toast { position: fixed; + transition: all 0.3s ease; right: 0; bottom: 0; - margin: 16px; + margin: 32px; padding: 12px; border: 1px solid #8885; - border-radius: 4px; + border-radius: 8px; z-index: 1; text-align: left; box-shadow: 3px 4px 5px 0 #8885; - background-color: white; } + +.ReloadPrompt-toast.info { + background-color: #F0FFFF; + border-color: #4682B4; + color: #4682B4; + + button { + transition: all 0.3s ease; + background-color: #4682B4; + color: #F0FFFF; + } + + button:hover { + background-color: #315f7d; + border-color: #315f7d; + } + + button.close { + background-color: transparent; + color: #4682B4; + border: 1px solid #4682B4; + } + + button.close:hover { + background-color: #315f7d; + color: #F0FFFF; + border-color: #315f7d; + } +} + .ReloadPrompt-message { margin-bottom: 8px; } + +.ReloadPrompt-buttons { + display: flex; + justify-content: flex-end; + gap: 8px; +} + .ReloadPrompt-toast-button { border: 1px solid #8885; outline: none; margin-right: 5px; - border-radius: 2px; - padding: 3px 10px; + border-radius: 8px; + padding: 6px 12px; + cursor: pointer; } diff --git a/platforms/web/src/ReloadPrompt.tsx b/platforms/web/src/ReloadPrompt.tsx index dda6f21..555ec9d 100644 --- a/platforms/web/src/ReloadPrompt.tsx +++ b/platforms/web/src/ReloadPrompt.tsx @@ -31,16 +31,18 @@ function ReloadPrompt() { return (
- { (offlineReady || needRefresh) - &&
-
- { offlineReady - ? App ready to work offline - : New content available, click on reload button to update. - } -
- { needRefresh && } - + {(offlineReady || needRefresh) + &&
+
+ {offlineReady + ? App ready to work offline + : New content available, click on reload button to update. + } +
+
+ {needRefresh && } + +
}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 962d171..90599f1 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,3 +2,7 @@ packages: - packages/* - platforms/* - '!**/test/**' + +onlyBuiltDependencies: + - '@vscode/vsce-sign' + - keytar