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
This commit is contained in:
sebastjanartic 2025-08-31 20:20:49 +00:00
parent 17dbdf81f1
commit 7c02d0310a
5 changed files with 203 additions and 4 deletions

View File

@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no, viewport-fit=cover" />
<title>go4.video Top-Inhalte von Folx TV</title>
<meta name="description" content="go4.video Top-Inhalte von Folx TV. Volksmusik, Schlager & Shows jederzeit online." />
@ -29,7 +29,23 @@
<meta name="apple-mobile-web-app-title" content="go4.video" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="theme-color" content="#3b82f6" />
<meta name="theme-color" content="#6366f1" />
<meta name="mobile-web-app-capable" content="yes" />
<!-- iOS specifične meta oznake -->
<meta name="apple-touch-fullscreen" content="yes" />
<meta name="format-detection" content="telephone=no" />
<!-- iOS ikone za različne velikosti -->
<link rel="apple-touch-icon" sizes="57x57" href="/api/favicon?size=57" />
<link rel="apple-touch-icon" sizes="60x60" href="/api/favicon?size=60" />
<link rel="apple-touch-icon" sizes="72x72" href="/api/favicon?size=72" />
<link rel="apple-touch-icon" sizes="76x76" href="/api/favicon?size=76" />
<link rel="apple-touch-icon" sizes="114x114" href="/api/favicon?size=114" />
<link rel="apple-touch-icon" sizes="120x120" href="/api/favicon?size=120" />
<link rel="apple-touch-icon" sizes="144x144" href="/api/favicon?size=144" />
<link rel="apple-touch-icon" sizes="152x152" href="/api/favicon?size=152" />
<link rel="apple-touch-icon" sizes="180x180" href="/api/favicon?size=180" />
<!-- Favicon -->
<link rel="icon" type="image/svg+xml" href="/api/favicon" />

View File

@ -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"
}
]

67
client/public/sw.js Normal file
View File

@ -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;
});
})
);
});

View File

@ -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: '';

View File

@ -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(<App />);