Merge pull request 'Implémentation des fonctionnalités Progressive Web App (PWA)' (#1) from feat-imrove-app into main

Reviewed-on: https://codeberg.org/Ka-Ubuntu/kaubuntu.re/pulls/1
This commit is contained in:
Cédric Famibelle-Pronzola
2025-07-17 18:22:22 +02:00
14 changed files with 692 additions and 130 deletions
+49 -4
View File
@@ -14,6 +14,9 @@ kaubuntu.re est une interface web responsive qui permet de consulter et recherch
- Recherche de contenu - Recherche de contenu
- Interface responsive (mobile et desktop) - Interface responsive (mobile et desktop)
- Intégration avec une instance PeerTube - Intégration avec une instance PeerTube
- **Progressive Web App (PWA)** avec installation native
- Mode hors ligne avec cache intelligent
- Détection automatique d'état de connexion
## Technologies utilisées ## Technologies utilisées
@@ -21,6 +24,8 @@ kaubuntu.re est une interface web responsive qui permet de consulter et recherch
- CSS3 avec Media Queries pour le responsive design - CSS3 avec Media Queries pour le responsive design
- PHP pour le backend - PHP pour le backend
- JavaScript pour les interactions côté client - JavaScript pour les interactions côté client
- **Service Worker** pour le cache offline et PWA
- **Web App Manifest** pour l'installation native
- Bibliothèques externes via CDN: - Bibliothèques externes via CDN:
- Font Awesome (icônes) - Font Awesome (icônes)
- jQuery - jQuery
@@ -45,11 +50,15 @@ kaubuntu.re est une interface web responsive qui permet de consulter et recherch
│ ├── mobile-menu.php │ ├── mobile-menu.php
│ ├── featured-videos.php │ ├── featured-videos.php
│ ├── recent-videos.php │ ├── recent-videos.php
── categories.php ── categories.php
│ └── pwa-init.php
├── index.php ├── index.php
├── video.php ├── video.php
├── categories.php ├── categories.php
├── search.php ├── search.php
├── sw.js # Service Worker pour PWA
├── site.webmanifest # Manifest PWA
├── browserconfig.xml # Configuration Windows
└── README.md └── README.md
``` ```
@@ -57,6 +66,7 @@ kaubuntu.re est une interface web responsive qui permet de consulter et recherch
1. Clonez ce dépôt 1. Clonez ce dépôt
2. Configurez votre serveur web (Apache, Nginx, etc.) pour pointer vers le répertoire racine 2. Configurez votre serveur web (Apache, Nginx, etc.) pour pointer vers le répertoire racine
3. **Important :** Assurez-vous que votre serveur supporte HTTPS (requis pour PWA)
## Configuration ## Configuration
@@ -120,14 +130,49 @@ Les fichiers `sitemap.xml`, `robots.txt` et `site.webmanifest` contiennent le no
Ces fichiers sont listés dans le `.gitignore` afin que vos modifications ne soient pas suivies par Git, ce qui vous permet de personnaliser votre instance sans affecter le code source principal. Ces fichiers sont listés dans le `.gitignore` afin que vos modifications ne soient pas suivies par Git, ce qui vous permet de personnaliser votre instance sans affecter le code source principal.
## Progressive Web App (PWA)
Cette plateforme est une PWA complète offrant :
### Fonctionnalités PWA
- **Installation native** : Bouton d'installation automatique dans l'interface
- **Mode hors ligne** : Cache intelligent des pages et ressources visitées
- **Détection d'état** : Indicateur visuel en cas de perte de connexion
- **Performance** : Chargement instantané des ressources en cache
- **Responsive** : Interface adaptée pour l'utilisation en application mobile
### Comment installer l'application
1. **Automatique** : Un bouton "Installer" apparaît dans le header lors de la première visite
2. **Manuel** :
- **Chrome/Edge** : Menu → "Installer kaubuntu.re"
- **Safari iOS** : Partager → "Ajouter à l'écran d'accueil"
- **Firefox Android** : Menu → "Installer"
### Compatibilité PWA
- ✅ Chrome/Edge (Android/Desktop)
- ✅ Safari (iOS 11.3+)
- ✅ Firefox (Android)
- ✅ Samsung Internet
### Fichiers PWA
- `sw.js` : Service Worker gérant le cache et mode offline
- `site.webmanifest` : Configuration de l'application (nom, icônes, etc.)
- `browserconfig.xml` : Support des tuiles Windows
## Déploiement ## Déploiement
Pour déployer sur un serveur mutualisé: Pour déployer sur un serveur mutualisé:
1. Assurez-vous que votre hébergeur supporte PHP (version 7.0 minimum recommandée) 1. Assurez-vous que votre hébergeur supporte PHP (version 7.0 minimum recommandée)
2. Transférez tous les fichiers via FTP dans le répertoire racine de votre site 2. **Configurez HTTPS** (obligatoire pour les fonctionnalités PWA)
3. Vérifiez que les permissions des fichiers sont correctement définies (644 pour les fichiers, 755 pour les dossiers) 3. Transférez tous les fichiers via FTP dans le répertoire racine de votre site
4. Configurez votre domaine pour pointer vers le dossier où vous avez installé l'application 4. Vérifiez que les permissions des fichiers sont correctement définies (644 pour les fichiers, 755 pour les dossiers)
5. Configurez votre domaine pour pointer vers le dossier où vous avez installé l'application
6. Testez l'installation PWA via les outils de développement du navigateur
## Développement ## Développement
+9
View File
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="img/android-chrome-192x192.png"/>
<TileColor>#FF0000</TileColor>
</tile>
</msapplication>
</browserconfig>
+67 -1
View File
@@ -98,6 +98,64 @@ img {
background-color: rgba(0, 0, 0, 0.05); background-color: rgba(0, 0, 0, 0.05);
} }
/* PWA Install Button */
.install-pwa-button {
background: var(--primary-red);
color: white;
border: none;
padding: 8px 12px;
border-radius: 6px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s ease;
margin-right: 10px;
}
.install-pwa-button:hover {
background: #cc0000;
}
.install-pwa-button:active {
transform: scale(0.95);
}
/* PWA Styles */
@media (display-mode: standalone) {
body {
padding-top: env(safe-area-inset-top);
}
.header {
padding-top: env(safe-area-inset-top);
}
}
/* Offline indicator */
.offline-indicator {
position: fixed;
top: 0;
left: 0;
right: 0;
background: #ff4444;
color: white;
text-align: center;
padding: 10px;
z-index: 1000;
display: none;
}
.offline-indicator.show {
display: block;
}
/* Enhanced mobile experience */
@media (max-width: 768px) {
.install-pwa-button {
padding: 6px 10px;
font-size: 14px;
}
}
/* Styles pour la page active dans la sidebar */ /* Styles pour la page active dans la sidebar */
.nav-item.active { .nav-item.active {
background-color: rgba(255, 0, 0, 0.08); background-color: rgba(255, 0, 0, 0.08);
@@ -307,7 +365,8 @@ img {
.icon-button i.icon-youtube, .icon-button i.icon-youtube,
.icon-button i.icon-instagram, .icon-button i.icon-instagram,
.icon-button i.icon-tiktok, .icon-button i.icon-tiktok,
.icon-button i.icon-twitter { .icon-button i.icon-twitter,
.icon-button i.icon-mastodon {
color: inherit; color: inherit;
} }
@@ -1698,6 +1757,11 @@ i.icon-x,
color: #000000 !important; /* Noir X (anciennement Twitter) */ color: #000000 !important; /* Noir X (anciennement Twitter) */
} }
i.icon-mastodon,
.fab.fa-mastodon.icon-mastodon {
color: #563ACC !important; /* Violet Mastodon */
}
/* Maintenir la couleur par défaut pour les icônes dans le footer */ /* Maintenir la couleur par défaut pour les icônes dans le footer */
.footer-social a { .footer-social a {
margin: 0 10px; margin: 0 10px;
@@ -2298,3 +2362,5 @@ i.icon-x,
height: 4px; height: 4px;
} }
} }
+1
View File
@@ -60,6 +60,7 @@ if (!defined('X_URL')) define('X_URL', '#');
if (!defined('INSTAGRAM_URL')) define('INSTAGRAM_URL', '#'); if (!defined('INSTAGRAM_URL')) define('INSTAGRAM_URL', '#');
if (!defined('YOUTUBE_URL')) define('YOUTUBE_URL', '#'); if (!defined('YOUTUBE_URL')) define('YOUTUBE_URL', '#');
if (!defined('TIKTOK_URL')) define('TIKTOK_URL', '#'); if (!defined('TIKTOK_URL')) define('TIKTOK_URL', '#');
if (!defined('MASTODON_URL')) define('MASTODON_URL', 'https://koze.kaubuntu.re');
// Contacts // Contacts
if (!defined('CONTACT_EMAIL')) define('CONTACT_EMAIL', 'contact@kaubuntu.re'); if (!defined('CONTACT_EMAIL')) define('CONTACT_EMAIL', 'contact@kaubuntu.re');
-1
View File
@@ -623,7 +623,6 @@ function searchVideos($query, $count = COUNT_VIDEO_SEARCH, $start = 0) {
'isLocal' => true, // Uniquement les vidéos locales 'isLocal' => true, // Uniquement les vidéos locales
'sort' => '-publishedAt' // Les plus récentes d'abord 'sort' => '-publishedAt' // Les plus récentes d'abord
]); ]);
return formatVideosData($data['data'] ?? []); return formatVideosData($data['data'] ?? []);
} }
?> ?>
+1
View File
@@ -66,6 +66,7 @@
</div> </div>
<div class="footer-social"> <div class="footer-social">
<a target="_blank" rel="noreferrer" href="<?php echo MASTODON_URL; ?>"><i class="fab fa-mastodon icon-mastodon"></i></a>
<a target="_blank" rel="noreferrer" href="<?php echo FACEBOOK_URL; ?>"><i class="fab fa-facebook icon-facebook"></i></a> <a target="_blank" rel="noreferrer" href="<?php echo FACEBOOK_URL; ?>"><i class="fab fa-facebook icon-facebook"></i></a>
<a target="_blank" rel="noreferrer" href="<?php echo YOUTUBE_URL; ?>"><i class="fab fa-youtube icon-youtube"></i></a> <a target="_blank" rel="noreferrer" href="<?php echo YOUTUBE_URL; ?>"><i class="fab fa-youtube icon-youtube"></i></a>
<a target="_blank" rel="noreferrer" href="<?php echo INSTAGRAM_URL; ?>"><i class="fab fa-instagram icon-instagram"></i></a> <a target="_blank" rel="noreferrer" href="<?php echo INSTAGRAM_URL; ?>"><i class="fab fa-instagram icon-instagram"></i></a>
+4
View File
@@ -8,6 +8,7 @@
</div> </div>
<div class="social-icons"> <div class="social-icons">
<a target="_blank" rel="noreferrer" href="<?php echo MASTODON_URL; ?>" class="icon-button"><i class="fab fa-mastodon icon-mastodon"></i></a>
<a target="_blank" rel="noreferrer" href="<?php echo INSTAGRAM_URL; ?>" class="icon-button"><i class="fab fa-instagram icon-instagram"></i></a> <a target="_blank" rel="noreferrer" href="<?php echo INSTAGRAM_URL; ?>" class="icon-button"><i class="fab fa-instagram icon-instagram"></i></a>
<a target="_blank" rel="noreferrer" href="<?php echo TIKTOK_URL; ?>" class="icon-button"><i class="fab fa-tiktok icon-tiktok"></i></a> <a target="_blank" rel="noreferrer" href="<?php echo TIKTOK_URL; ?>" class="icon-button"><i class="fab fa-tiktok icon-tiktok"></i></a>
<div class="more-social-container"> <div class="more-social-container">
@@ -27,6 +28,9 @@
</div> </div>
<div class="action-icons"> <div class="action-icons">
<button id="install-pwa" class="icon-button install-pwa-button" style="display: none;" title="Installer l'application">
<i class="fas fa-download"></i>
</button>
<button class="mobile-menu-toggle"> <button class="mobile-menu-toggle">
<i class="fas fa-bars"></i> <i class="fas fa-bars"></i>
</button> </button>
+82
View File
@@ -0,0 +1,82 @@
<?php
// Fichier d'initialisation PWA à inclure dans toutes les pages
function addPWAHeaders() {
// Meta tags PWA
echo '<meta name="mobile-web-app-capable" content="yes">' . "\n";
echo '<meta name="apple-mobile-web-app-capable" content="yes">' . "\n";
echo '<meta name="apple-mobile-web-app-status-bar-style" content="default">' . "\n";
echo '<meta name="apple-mobile-web-app-title" content="kaubuntu.re">' . "\n";
echo '<meta name="application-name" content="kaubuntu.re">' . "\n";
echo '<meta name="msapplication-TileColor" content="#FF0000">' . "\n";
echo '<meta name="msapplication-config" content="browserconfig.xml">' . "\n";
echo '<meta name="theme-color" content="#FF0000">' . "\n";
// Manifest
echo '<link rel="manifest" href="site.webmanifest">' . "\n";
}
function addPWAScripts() {
?>
<!-- PWA Service Worker -->
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw.js')
.then(function(registration) {
console.log('Service Worker enregistré avec succès:', registration.scope);
// Écouter les mises à jour
registration.addEventListener('updatefound', function() {
const newWorker = registration.installing;
newWorker.addEventListener('statechange', function() {
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
// Nouvelle version disponible
console.log('Nouvelle version disponible');
if (confirm('Une nouvelle version est disponible. Voulez-vous recharger la page ?')) {
window.location.reload();
}
}
});
});
})
.catch(function(err) {
console.log('Échec de l\'enregistrement du Service Worker:', err);
});
});
}
// Gestion de l'installation PWA
let deferredPrompt;
const installButton = document.getElementById('install-pwa');
window.addEventListener('beforeinstallprompt', function(e) {
e.preventDefault();
deferredPrompt = e;
// Afficher le bouton d'installation s'il existe
if (installButton) {
installButton.style.display = 'block';
installButton.addEventListener('click', function() {
deferredPrompt.prompt();
deferredPrompt.userChoice.then(function(choiceResult) {
if (choiceResult.outcome === 'accepted') {
console.log('PWA installée');
}
deferredPrompt = null;
installButton.style.display = 'none';
});
});
}
});
// Masquer le bouton après installation
window.addEventListener('appinstalled', function() {
console.log('PWA installée avec succès');
if (installButton) {
installButton.style.display = 'none';
}
});
</script>
<?php
}
?>
+71 -1
View File
@@ -21,7 +21,16 @@ setSecurityHeaders();
<link rel="icon" type="image/png" sizes="16x16" href="img/favicon-16x16.png"> <link rel="icon" type="image/png" sizes="16x16" href="img/favicon-16x16.png">
<link rel="manifest" href="site.webmanifest"> <link rel="manifest" href="site.webmanifest">
<link rel="icon" type="image/x-icon" href="img/favicon.ico"> <link rel="icon" type="image/x-icon" href="img/favicon.ico">
<meta name="theme-color" content="#ffffff"> <meta name="theme-color" content="#FF0000">
<!-- PWA Meta Tags -->
<meta name="mobile-web-app-capable" content="yes">
<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="kaubuntu.re">
<meta name="application-name" content="kaubuntu.re">
<meta name="msapplication-TileColor" content="#FF0000">
<meta name="msapplication-config" content="browserconfig.xml">
</head> </head>
<body> <body>
<?php include 'includes/sidebar.php'; ?> <?php include 'includes/sidebar.php'; ?>
@@ -377,5 +386,66 @@ setSecurityHeaders();
<script src="js/main.js"></script> <script src="js/main.js"></script>
<script src="js/mastodon-timeline.umd.js"></script> <script src="js/mastodon-timeline.umd.js"></script>
<script src="js/mastodon-config.php"></script> <script src="js/mastodon-config.php"></script>
<!-- PWA Service Worker -->
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw.js')
.then(function(registration) {
console.log('Service Worker enregistré avec succès:', registration.scope);
// Écouter les mises à jour
registration.addEventListener('updatefound', function() {
const newWorker = registration.installing;
newWorker.addEventListener('statechange', function() {
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
// Nouvelle version disponible
console.log('Nouvelle version disponible');
if (confirm('Une nouvelle version est disponible. Voulez-vous recharger la page ?')) {
window.location.reload();
}
}
});
});
})
.catch(function(err) {
console.log('Échec de l\'enregistrement du Service Worker:', err);
});
});
}
// Gestion de l'installation PWA
let deferredPrompt;
const installButton = document.getElementById('install-pwa');
window.addEventListener('beforeinstallprompt', function(e) {
e.preventDefault();
deferredPrompt = e;
// Afficher le bouton d'installation s'il existe
if (installButton) {
installButton.style.display = 'block';
installButton.addEventListener('click', function() {
deferredPrompt.prompt();
deferredPrompt.userChoice.then(function(choiceResult) {
if (choiceResult.outcome === 'accepted') {
console.log('PWA installée');
}
deferredPrompt = null;
installButton.style.display = 'none';
});
});
}
});
// Masquer le bouton après installation
window.addEventListener('appinstalled', function() {
console.log('PWA installée avec succès');
if (installButton) {
installButton.style.display = 'none';
}
});
</script>
</body> </body>
</html> </html>
+24
View File
@@ -1,4 +1,28 @@
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
// Détection de l'état de connexion
function updateOnlineStatus() {
const offlineIndicator = document.querySelector('.offline-indicator');
if (!navigator.onLine) {
if (!offlineIndicator) {
const indicator = document.createElement('div');
indicator.className = 'offline-indicator show';
indicator.textContent = 'Mode hors ligne - Fonctionnalités limitées';
document.body.insertBefore(indicator, document.body.firstChild);
}
} else {
if (offlineIndicator) {
offlineIndicator.remove();
}
}
}
// Écouter les changements de connexion
window.addEventListener('online', updateOnlineStatus);
window.addEventListener('offline', updateOnlineStatus);
// Vérifier l'état initial
updateOnlineStatus();
// Gestion du menu mobile // Gestion du menu mobile
const mobileMenuToggle = document.querySelector('.mobile-menu-toggle'); const mobileMenuToggle = document.querySelector('.mobile-menu-toggle');
const mobileMenu = document.querySelector('.mobile-menu'); const mobileMenu = document.querySelector('.mobile-menu');
+43
View File
@@ -0,0 +1,43 @@
{
"name": "kaubuntu.re - Plateforme Multimédia",
"short_name": "kaubuntu.re",
"description": "Plateforme multimédia alternative et indépendante",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#FF0000",
"orientation": "portrait-primary",
"icons": [
{
"src": "img/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "img/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "img/apple-touch-icon.png",
"sizes": "180x180",
"type": "image/png"
},
{
"src": "img/favicon-32x32.png",
"sizes": "32x32",
"type": "image/png"
},
{
"src": "img/favicon-16x16.png",
"sizes": "16x16",
"type": "image/png"
}
],
"categories": ["entertainment", "news", "social"],
"lang": "fr",
"scope": "/",
"prefer_related_applications": false
}
-1
View File
@@ -1 +0,0 @@
{"name":"VOTRE-DOMAINE","short_name":"VOTRE-DOMAINE","icons":[{"src":"img/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"img/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
+222
View File
@@ -0,0 +1,222 @@
const CACHE_NAME = 'kaubuntu-v1';
const STATIC_CACHE_NAME = 'kaubuntu-static-v1';
const DYNAMIC_CACHE_NAME = 'kaubuntu-dynamic-v1';
// Ressources à mettre en cache immédiatement
const STATIC_ASSETS = [
'/',
'/index.php',
'/css/styles.css',
'/css/categories.css',
'/css/search.css',
'/css/video-page.css',
'/css/mastodon-timeline.min.css',
'/js/main.js',
'/js/categories.js',
'/js/search.js',
'/js/mastodon-timeline.umd.js',
'/img/logo.png',
'/img/android-chrome-192x192.png',
'/img/android-chrome-512x512.png',
'/img/apple-touch-icon.png',
'/img/favicon-32x32.png',
'/img/favicon-16x16.png',
'/img/favicon.ico',
'/img/play-icon.svg',
'/site.webmanifest',
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css',
'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js'
];
// Pages à mettre en cache
const PAGES_TO_CACHE = [
'/',
'/index.php',
'/categories.php',
'/recherche.php',
'/mentions-legales.php'
];
// Installation du Service Worker
self.addEventListener('install', event => {
console.log('Service Worker: Installation');
event.waitUntil(
caches.open(STATIC_CACHE_NAME)
.then(cache => {
console.log('Service Worker: Mise en cache des assets statiques');
return cache.addAll(STATIC_ASSETS);
})
.then(() => {
return self.skipWaiting();
})
.catch(err => {
console.error('Service Worker: Erreur lors de la mise en cache:', err);
})
);
});
// Activation du Service Worker
self.addEventListener('activate', event => {
console.log('Service Worker: Activation');
event.waitUntil(
caches.keys()
.then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== STATIC_CACHE_NAME && cacheName !== DYNAMIC_CACHE_NAME) {
console.log('Service Worker: Suppression du cache obsolète:', cacheName);
return caches.delete(cacheName);
}
})
);
})
.then(() => {
return self.clients.claim();
})
);
});
// Interception des requêtes
self.addEventListener('fetch', event => {
const { request } = event;
const url = new URL(request.url);
// Ignorer les requêtes non-GET
if (request.method !== 'GET') {
return;
}
// Ignorer les requêtes vers des domaines externes (sauf CDN)
if (url.origin !== location.origin &&
!url.hostname.includes('cdnjs.cloudflare.com')) {
return;
}
// Stratégie Cache First pour les assets statiques
if (isStaticAsset(request.url)) {
event.respondWith(
caches.match(request)
.then(response => {
if (response) {
return response;
}
return fetch(request)
.then(response => {
if (response.status === 200) {
const responseClone = response.clone();
caches.open(STATIC_CACHE_NAME)
.then(cache => cache.put(request, responseClone));
}
return response;
});
})
.catch(() => {
// Fallback pour les images
if (request.destination === 'image') {
return caches.match('/img/logo.png');
}
})
);
return;
}
// Stratégie Network First pour les pages dynamiques
if (isPageRequest(request.url)) {
event.respondWith(
fetch(request)
.then(response => {
if (response.status === 200) {
const responseClone = response.clone();
caches.open(DYNAMIC_CACHE_NAME)
.then(cache => cache.put(request, responseClone));
}
return response;
})
.catch(() => {
return caches.match(request)
.then(response => {
if (response) {
return response;
}
// Fallback vers la page d'accueil
return caches.match('/') || caches.match('/index.php');
});
})
);
return;
}
// Stratégie Network First pour les API et AJAX
if (isApiRequest(request.url)) {
event.respondWith(
fetch(request)
.catch(() => {
return new Response(
JSON.stringify({
error: 'Pas de connexion internet',
offline: true
}),
{
status: 503,
headers: {
'Content-Type': 'application/json'
}
}
);
})
);
return;
}
});
// Fonctions utilitaires
function isStaticAsset(url) {
return url.includes('/css/') ||
url.includes('/js/') ||
url.includes('/img/') ||
url.includes('cdnjs.cloudflare.com') ||
url.endsWith('.css') ||
url.endsWith('.js') ||
url.endsWith('.png') ||
url.endsWith('.jpg') ||
url.endsWith('.jpeg') ||
url.endsWith('.svg') ||
url.endsWith('.ico') ||
url.endsWith('.webmanifest');
}
function isPageRequest(url) {
return url.endsWith('/') ||
url.endsWith('.php') ||
url.includes('index.php') ||
url.includes('categories.php') ||
url.includes('recherche.php') ||
url.includes('video.php') ||
url.includes('mentions-legales.php');
}
function isApiRequest(url) {
return url.includes('/ajax/') ||
url.includes('api') ||
url.includes('mastodon-config.php');
}
// Gestion des messages du client
self.addEventListener('message', event => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
// Notification de mise à jour
self.addEventListener('message', event => {
if (event.data && event.data.type === 'CHECK_UPDATE') {
// Vérifier s'il y a une mise à jour
event.ports[0].postMessage({
type: 'UPDATE_AVAILABLE',
version: CACHE_NAME
});
}
});
+1 -4
View File
@@ -176,10 +176,6 @@ if (empty($videoData) || isset($videoData['error'])) {
</div> </div>
<div class="video-actions"> <div class="video-actions">
<button disabled class="action-button disabled-button" title="Fonctionnalité disponible uniquement sur <?php echo PEERTUBE_DISPLAY_NAME; ?>">
<i class="fas fa-thumbs-up"></i>
<span><?php echo formatViewCount($video['likes']); ?></span>
</button>
<button class="action-button" id="share-btn"> <button class="action-button" id="share-btn">
<i class="fas fa-share"></i> <i class="fas fa-share"></i>
<span>Partager</span> <span>Partager</span>
@@ -621,5 +617,6 @@ if (empty($videoData) || isset($videoData['error'])) {
} }
}); });
</script> </script>
</body> </body>
</html> </html>