diff --git a/app/routes.py b/app/routes.py index e37856d..cbaca4f 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,12 +1,32 @@ import json -from flask import render_template, jsonify +from flask import render_template, jsonify, send_from_directory from app import app from app.config import SCOREBOARD_DATA_FILE from app.games import parse_games +@app.route("/manifest.json") +def manifest(): + return send_from_directory(app.static_folder, "manifest.json") + + +@app.route("/sw.js") +def service_worker(): + response = send_from_directory(app.static_folder, "sw.js") + response.headers["Service-Worker-Allowed"] = "/" + response.headers["Cache-Control"] = "no-cache" + return response + + +@app.route("/favicon.ico") +def favicon(): + return send_from_directory( + app.static_folder, "icon-32x32.png", mimetype="image/png" + ) + + @app.route("/") def index(): return render_template("index.html") diff --git a/app/static/icon-180x180.png b/app/static/icon-180x180.png new file mode 100644 index 0000000..2510949 Binary files /dev/null and b/app/static/icon-180x180.png differ diff --git a/app/static/icon-192x192.png b/app/static/icon-192x192.png new file mode 100644 index 0000000..412217b Binary files /dev/null and b/app/static/icon-192x192.png differ diff --git a/app/static/icon-32x32.png b/app/static/icon-32x32.png new file mode 100644 index 0000000..4772f8d Binary files /dev/null and b/app/static/icon-32x32.png differ diff --git a/app/static/icon-512x512.png b/app/static/icon-512x512.png new file mode 100644 index 0000000..72cff75 Binary files /dev/null and b/app/static/icon-512x512.png differ diff --git a/app/static/manifest.json b/app/static/manifest.json new file mode 100644 index 0000000..dfe5dcb --- /dev/null +++ b/app/static/manifest.json @@ -0,0 +1,24 @@ +{ + "name": "NHL Scoreboard", + "short_name": "NHL Scores", + "description": "Live NHL game scores ranked by hype", + "start_url": "/", + "display": "standalone", + "background_color": "#0f172a", + "theme_color": "#0f172a", + "orientation": "portrait-primary", + "icons": [ + { + "src": "/static/icon-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any maskable" + }, + { + "src": "/static/icon-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any maskable" + } + ] +} diff --git a/app/static/script.js b/app/static/script.js index 9d48ecf..2204992 100644 --- a/app/static/script.js +++ b/app/static/script.js @@ -240,4 +240,9 @@ function autoRefresh() { window.addEventListener('load', () => { autoRefresh(); setInterval(tickClocks, 1000); + if ('serviceWorker' in navigator) { + navigator.serviceWorker.register('/sw.js').catch(err => { + console.warn('Service worker registration failed:', err); + }); + } }); diff --git a/app/static/sw.js b/app/static/sw.js new file mode 100644 index 0000000..9b4034a --- /dev/null +++ b/app/static/sw.js @@ -0,0 +1,49 @@ +const CACHE = 'nhl-scoreboard-v1'; +const PRECACHE = [ + '/', + '/static/styles.css', + '/static/script.js', + '/static/icon-192x192.png', + '/static/icon-512x512.png', + '/manifest.json', +]; + +self.addEventListener('install', event => { + event.waitUntil(caches.open(CACHE).then(c => c.addAll(PRECACHE))); + self.skipWaiting(); +}); + +self.addEventListener('activate', event => { + event.waitUntil( + caches.keys().then(keys => + Promise.all(keys.filter(k => k !== CACHE).map(k => caches.delete(k))) + ) + ); + self.clients.claim(); +}); + +self.addEventListener('fetch', event => { + const { pathname } = new URL(event.request.url); + + // Network-first for the live scoreboard API — stale data is useless + if (pathname === '/scoreboard') { + event.respondWith( + fetch(event.request).catch(() => caches.match(event.request)) + ); + return; + } + + // Cache-first for everything else (static assets, shell) + event.respondWith( + caches.match(event.request).then(cached => { + if (cached) return cached; + return fetch(event.request).then(response => { + if (response.ok) { + const clone = response.clone(); + caches.open(CACHE).then(c => c.put(event.request, clone)); + } + return response; + }); + }) + ); +}); diff --git a/app/templates/index.html b/app/templates/index.html index 815a3e3..9d31530 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -3,6 +3,13 @@ NHL Scoreboard + + + + + + +