Add Progressive Web App functionality
- Add web app manifest for home screen installation - Implement service worker with offline caching strategy - Create offline fallback page with auto-reconnect - Generate PWA icons in multiple sizes (72px-512px) - Add PWA meta tags and Apple Touch icons to all pages - Register service worker with graceful degradation - Update documentation with PWA installation instructions - Add browserconfig.xml for Windows tile support Features: - Installable on mobile and desktop - Offline functionality with cached resources - App-like experience in standalone mode - Automatic updates when online - Works seamlessly with existing progressive enhancement 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
10c6e54062
commit
c13b61cd03
21 changed files with 940 additions and 15 deletions
|
@ -4,8 +4,26 @@
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Great Lakes Ice Report</title>
|
||||
<link rel="icon" type="image/svg+xml" href="https://iceymi.b-cdn.net/favicon.svg">
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="description" content="Community-driven winter road conditions and icy hazards tracker for the Great Lakes region">
|
||||
<meta name="theme-color" content="#2196F3">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||
<meta name="apple-mobile-web-app-title" content="Ice Report">
|
||||
<meta name="msapplication-TileColor" content="#2196F3">
|
||||
<meta name="msapplication-config" content="/browserconfig.xml">
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
|
||||
<!-- Icons -->
|
||||
<link rel="icon" type="image/svg+xml" href="/icons/favicon.svg">
|
||||
<link rel="icon" type="image/x-icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIj4KICA8ZGVmcz4KICAgIDxzdHlsZT4KICAgICAgLnNub3dmbGFrZSB7IGZpbGw6ICMyMTk2RjM7IH0KICAgICAgLmNlbnRlciB7IGZpbGw6ICMxOTc2RDI7IH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIAogIDxnIGNsYXNzPSJzbm93Zmxha2UiPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiAvPgogICAgPHJlY3QgeD0iMiIgeT0iMTUiIHdpZHRoPSIyOCIgaGVpZ2h0PSIyIiAvPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cmVjdCB4PSIxNSIgeT0iMiIgd2lkdGg9IjIiIGhlaWdodD0iMjgiIHRyYW5zZm9ybT0icm90YXRlKC00NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjE2LDIgMTQsNiAxOCw2IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSIxNiwzMCAxNCwyNiAxOCwyNiIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMiwxNiA2LDE0IDYsMTgiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjMwLDE2IDI2LDE0IDI2LDE4IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSI2LjMsNi4zIDguNiw0IDkuOSw3LjciIHRyYW5zZm9ybT0icm90YXRlKDQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNywyNS43IDIzLjQsMjggMjIuMSwyNC4zIiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjYuMywyNS43IDguNiwyOCA5LjksMjQuMyIgdHJhbnNmb3JtPSJyb3RhdGUoLTQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNyw2LjMgMjMuNCw0IDIyLjEsNy43IiB0cmFuc2Zvcm09InJvdGF0ZSgtNDUgMTYgMTYpIiAvPgogIDwvZz4KICA8Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIzIiBjbGFzcz0iY2VudGVyIiAvPgo8L3N2Zz4K">
|
||||
|
||||
<!-- Apple Touch Icons -->
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/icons/icon-152.svg">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/icons/icon-192.svg">
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script>
|
||||
|
@ -154,5 +172,58 @@ placeholder="Enter address, intersection (e.g., Main St & Second St, City), or l
|
|||
<script src="theme-utils.js"></script>
|
||||
<script src="utils.js"></script>
|
||||
<script src="app-mapbox.js"></script>
|
||||
|
||||
<!-- PWA Service Worker Registration -->
|
||||
<script>
|
||||
// Register service worker for PWA functionality
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => {
|
||||
navigator.serviceWorker.register('/sw.js')
|
||||
.then((registration) => {
|
||||
console.log('✅ Service Worker registered successfully:', registration.scope);
|
||||
|
||||
// Check for updates
|
||||
registration.addEventListener('updatefound', () => {
|
||||
const newWorker = registration.installing;
|
||||
if (newWorker) {
|
||||
newWorker.addEventListener('statechange', () => {
|
||||
if (newWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// New content available, notify user
|
||||
console.log('🔄 New content available! Please refresh.');
|
||||
// Could show a notification here
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('❌ Service Worker registration failed:', error);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.log('Service Worker not supported in this browser');
|
||||
}
|
||||
|
||||
// PWA Install Prompt
|
||||
let deferredPrompt;
|
||||
|
||||
window.addEventListener('beforeinstallprompt', (e) => {
|
||||
console.log('💾 PWA install prompt available');
|
||||
// Prevent Chrome 67 and earlier from automatically showing the prompt
|
||||
e.preventDefault();
|
||||
// Stash the event so it can be triggered later
|
||||
deferredPrompt = e;
|
||||
|
||||
// Could show custom install button here
|
||||
// For now, let the browser handle it naturally
|
||||
});
|
||||
|
||||
window.addEventListener('appinstalled', (evt) => {
|
||||
console.log('🎉 PWA was installed successfully!');
|
||||
deferredPrompt = null;
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue