From 7c02d0310a30bd6d844a39a2229eda48331f1a23 Mon Sep 17 00:00:00 2001 From: sebastjanartic <45803536-sebastjanartic@users.noreply.replit.com> Date: Sun, 31 Aug 2025 20:20:49 +0000 Subject: [PATCH] Improve the app's experience when added to the iPhone home screen Implement Progressive Web App (PWA) features for enhanced mobile experience, including service worker registration, manifest.json updates for standalone mode, and CSS adjustments for iOS safe area and touch interactions. Replit-Commit-Author: Agent Replit-Commit-Session-Id: ab9cd02a-d0b2-4288-9ceb-1964d0059648 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/ab9cd02a-d0b2-4288-9ceb-1964d0059648/mbX83Mu --- client/index.html | 20 +++++++++-- client/public/manifest.json | 64 +++++++++++++++++++++++++++++++++-- client/public/sw.js | 67 +++++++++++++++++++++++++++++++++++++ client/src/index.css | 43 ++++++++++++++++++++++++ client/src/main.tsx | 13 +++++++ 5 files changed, 203 insertions(+), 4 deletions(-) create mode 100644 client/public/sw.js diff --git a/client/index.html b/client/index.html index 11223db..c23688c 100644 --- a/client/index.html +++ b/client/index.html @@ -2,7 +2,7 @@ - + go4.video – Top-Inhalte von Folx TV @@ -29,7 +29,23 @@ - + + + + + + + + + + + + + + + + + diff --git a/client/public/manifest.json b/client/public/manifest.json index b44927b..c7b172b 100644 --- a/client/public/manifest.json +++ b/client/public/manifest.json @@ -5,18 +5,78 @@ "theme_color": "#6366f1", "background_color": "#2D1B69", "display": "standalone", + "orientation": "portrait-primary", "start_url": "/", + "scope": "/", + "lang": "en", + "dir": "ltr", + "categories": ["entertainment", "multimedia"], + "prefer_related_applications": false, "icons": [ + { + "src": "/api/favicon?size=57", + "sizes": "57x57", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/api/favicon?size=60", + "sizes": "60x60", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/api/favicon?size=72", + "sizes": "72x72", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/api/favicon?size=76", + "sizes": "76x76", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/api/favicon?size=114", + "sizes": "114x114", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/api/favicon?size=120", + "sizes": "120x120", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/api/favicon?size=144", + "sizes": "144x144", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/api/favicon?size=152", + "sizes": "152x152", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/api/favicon?size=180", + "sizes": "180x180", + "type": "image/png", + "purpose": "any" + }, { "src": "/api/favicon?size=192", "sizes": "192x192", - "type": "image/svg+xml", + "type": "image/png", "purpose": "any maskable" }, { "src": "/api/favicon?size=512", "sizes": "512x512", - "type": "image/svg+xml", + "type": "image/png", "purpose": "any maskable" } ] diff --git a/client/public/sw.js b/client/public/sw.js new file mode 100644 index 0000000..31b8148 --- /dev/null +++ b/client/public/sw.js @@ -0,0 +1,67 @@ +// Service Worker za go4.video PWA +const CACHE_NAME = 'go4-video-v1'; +const urlsToCache = [ + '/', + '/manifest.json', + '/api/favicon', + '/api/favicon?size=192', + '/api/favicon?size=512' +]; + +// Instalacija service worker-ja +self.addEventListener('install', (event) => { + event.waitUntil( + caches.open(CACHE_NAME) + .then((cache) => { + console.log('PWA cache opened'); + return cache.addAll(urlsToCache); + }) + ); +}); + +// Aktivacija service worker-ja +self.addEventListener('activate', (event) => { + event.waitUntil( + caches.keys().then((cacheNames) => { + return Promise.all( + cacheNames.map((cacheName) => { + if (cacheName !== CACHE_NAME) { + console.log('Deleting old cache:', cacheName); + return caches.delete(cacheName); + } + }) + ); + }) + ); +}); + +// Prestrezanje omrežnih zahtev +self.addEventListener('fetch', (event) => { + event.respondWith( + caches.match(event.request) + .then((response) => { + // Vrni iz cache-a, če obstaja + if (response) { + return response; + } + + // Sicer povleči iz omrežja + return fetch(event.request).then((response) => { + // Preveri ali je veljaven odgovor + if (!response || response.status !== 200 || response.type !== 'basic') { + return response; + } + + // Kloniraj odgovor + const responseToCache = response.clone(); + + caches.open(CACHE_NAME) + .then((cache) => { + cache.put(event.request, responseToCache); + }); + + return response; + }); + }) + ); +}); \ No newline at end of file diff --git a/client/src/index.css b/client/src/index.css index f0c386a..d5fed7f 100644 --- a/client/src/index.css +++ b/client/src/index.css @@ -65,6 +65,11 @@ background: linear-gradient(135deg, hsl(250, 50%, 15%) 0%, hsl(240, 30%, 25%) 50%, hsl(260, 40%, 20%) 100%); color: hsl(210, 40%, 98%); min-height: 100vh; + /* iOS PWA optimizacije */ + -webkit-touch-callout: none; + -webkit-user-select: none; + -webkit-tap-highlight-color: transparent; + overscroll-behavior: none; } } @@ -365,6 +370,44 @@ input[data-testid*="search"]::placeholder { } } +/* iOS PWA safe area optimizacije */ +@supports (padding: max(0px)) { + .has-fixed-header { + padding-top: max(80px, env(safe-area-inset-top)); + } +} + +/* PWA full screen optimizacije za iOS */ +@media (display-mode: standalone) { + body { + /* Prepreči povlečenje za osvežitev na iOS */ + overscroll-behavior-y: none; + /* Prilagodi safe area */ + padding-top: env(safe-area-inset-top); + padding-bottom: env(safe-area-inset-bottom); + padding-left: env(safe-area-inset-left); + padding-right: env(safe-area-inset-right); + } + + .header-sticky { + top: env(safe-area-inset-top) !important; + } +} + +/* Dodatne mobile optimizacije */ +@media (max-width: 768px) { + /* Prepreči zoom pri fokusiranju input polj */ + input, select, textarea { + font-size: 16px !important; + } + + /* Optimiziraj touch targets za iOS */ + button, a, [role="button"] { + min-height: 44px; + min-width: 44px; + } +} + /* Test grid overlay */ body.show-grid::after { content: ''; diff --git a/client/src/main.tsx b/client/src/main.tsx index 696e0d2..0945fc0 100644 --- a/client/src/main.tsx +++ b/client/src/main.tsx @@ -2,4 +2,17 @@ import { createRoot } from "react-dom/client"; import App from "./App"; import "./index.css"; +// Registracija Service Worker-ja za PWA funkcionalnost +if ('serviceWorker' in navigator) { + window.addEventListener('load', () => { + navigator.serviceWorker.register('/sw.js') + .then((registration) => { + console.log('SW registered: ', registration); + }) + .catch((registrationError) => { + console.log('SW registration failed: ', registrationError); + }); + }); +} + createRoot(document.getElementById("root")!).render();