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:
parent
17dbdf81f1
commit
7c02d0310a
@ -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" />
|
||||
|
||||
@ -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
67
client/public/sw.js
Normal 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;
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -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: '';
|
||||
|
||||
@ -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 />);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user