diff --git a/public/apple-icon.svg b/public/apple-icon.svg new file mode 100644 index 0000000..12669d0 --- /dev/null +++ b/public/apple-icon.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/public/favicon.svg b/public/favicon.svg index 7b4d24c..73a0a9f 100644 --- a/public/favicon.svg +++ b/public/favicon.svg @@ -1,16 +1,21 @@ - - + + - + - - + + \ No newline at end of file diff --git a/public/images/icons/apple-icon-152x152.png b/public/images/icons/apple-icon-152x152.png new file mode 100644 index 0000000..d425dc7 Binary files /dev/null and b/public/images/icons/apple-icon-152x152.png differ diff --git a/public/images/icons/apple-icon-167x167.png b/public/images/icons/apple-icon-167x167.png new file mode 100644 index 0000000..669523f Binary files /dev/null and b/public/images/icons/apple-icon-167x167.png differ diff --git a/public/images/icons/apple-icon-180x180.png b/public/images/icons/apple-icon-180x180.png new file mode 100644 index 0000000..7c505c2 Binary files /dev/null and b/public/images/icons/apple-icon-180x180.png differ diff --git a/public/images/icons/icon-128x128.png b/public/images/icons/icon-128x128.png index 77789fa..6fa0e3a 100644 Binary files a/public/images/icons/icon-128x128.png and b/public/images/icons/icon-128x128.png differ diff --git a/public/images/icons/icon-144x144.png b/public/images/icons/icon-144x144.png index 266cadd..44887ed 100644 Binary files a/public/images/icons/icon-144x144.png and b/public/images/icons/icon-144x144.png differ diff --git a/public/images/icons/icon-152x152.png b/public/images/icons/icon-152x152.png index a438c33..87efe17 100644 Binary files a/public/images/icons/icon-152x152.png and b/public/images/icons/icon-152x152.png differ diff --git a/public/images/icons/icon-192x192.png b/public/images/icons/icon-192x192.png index 1df2ca0..d01b207 100644 Binary files a/public/images/icons/icon-192x192.png and b/public/images/icons/icon-192x192.png differ diff --git a/public/images/icons/icon-384x384.png b/public/images/icons/icon-384x384.png index beb271f..62b582e 100644 Binary files a/public/images/icons/icon-384x384.png and b/public/images/icons/icon-384x384.png differ diff --git a/public/images/icons/icon-512x512.png b/public/images/icons/icon-512x512.png index 90ccb41..9f3ef11 100644 Binary files a/public/images/icons/icon-512x512.png and b/public/images/icons/icon-512x512.png differ diff --git a/public/images/icons/icon-72x72.png b/public/images/icons/icon-72x72.png index 3e26ccc..ef877b4 100644 Binary files a/public/images/icons/icon-72x72.png and b/public/images/icons/icon-72x72.png differ diff --git a/public/images/icons/icon-96x96.png b/public/images/icons/icon-96x96.png index bf276ac..4d32cba 100644 Binary files a/public/images/icons/icon-96x96.png and b/public/images/icons/icon-96x96.png differ diff --git a/public/sw.js b/public/sw.js index 7c68057..fa470ab 100644 --- a/public/sw.js +++ b/public/sw.js @@ -36,72 +36,72 @@ self.addEventListener("activate", (event) => { self.addEventListener("fetch", (event) => { // Pour les requêtes API, on utilise "Network First" avec un timeout if (event.request.url.includes("/api/")) { - event.respondWith( - Promise.race([ - fetch(event.request.clone()) - .then((response) => { - // Ne mettre en cache que les réponses réussies - if (response.ok) { - const responseToCache = response.clone(); - caches.open(CACHE_NAME).then((cache) => { - cache.put(event.request, responseToCache); - }); - } - return response; - }) - .catch(() => { - // En cas d'erreur réseau, essayer le cache - return caches.match(event.request).then((cachedResponse) => { - if (cachedResponse) { - return cachedResponse; - } - // Si pas de cache, renvoyer une erreur appropriée - return new Response(JSON.stringify({ error: "Hors ligne" }), { - status: 503, - headers: { "Content-Type": "application/json" }, - }); - }); - }), - // Timeout après 5 secondes - new Promise((_, reject) => setTimeout(() => reject(new Error("Timeout")), 5000)).catch( - () => { - return caches.match(event.request).then((cachedResponse) => { - if (cachedResponse) { - return cachedResponse; - } - return new Response(JSON.stringify({ error: "Timeout" }), { - status: 504, - headers: { "Content-Type": "application/json" }, - }); - }); - } - ), - ]) - ); + // event.respondWith( + // Promise.race([ + // fetch(event.request.clone()) + // .then((response) => { + // // Ne mettre en cache que les réponses réussies + // if (response.ok) { + // const responseToCache = response.clone(); + // caches.open(CACHE_NAME).then((cache) => { + // cache.put(event.request, responseToCache); + // }); + // } + // return response; + // }) + // .catch(() => { + // // En cas d'erreur réseau, essayer le cache + // return caches.match(event.request).then((cachedResponse) => { + // if (cachedResponse) { + // return cachedResponse; + // } + // // Si pas de cache, renvoyer une erreur appropriée + // return new Response(JSON.stringify({ error: "Hors ligne" }), { + // status: 503, + // headers: { "Content-Type": "application/json" }, + // }); + // }); + // }), + // // Timeout après 5 secondes + // new Promise((_, reject) => setTimeout(() => reject(new Error("Timeout")), 5000)).catch( + // () => { + // return caches.match(event.request).then((cachedResponse) => { + // if (cachedResponse) { + // return cachedResponse; + // } + // return new Response(JSON.stringify({ error: "Timeout" }), { + // status: 504, + // headers: { "Content-Type": "application/json" }, + // }); + // }); + // } + // ), + // ]) + // ); } else { // Pour les autres ressources, on garde la stratégie "Cache First" - event.respondWith( - caches.match(event.request).then((cachedResponse) => { - if (cachedResponse) { - return cachedResponse; - } - return fetch(event.request) - .then((response) => { - // Mettre en cache la nouvelle réponse - const responseToCache = response.clone(); - caches.open(CACHE_NAME).then((cache) => { - cache.put(event.request, responseToCache); - }); - return response; - }) - .catch(() => { - // Si la requête échoue et que c'est une page, renvoyer la page hors ligne - if (event.request.mode === "navigate") { - return caches.match(OFFLINE_PAGE); - } - return new Response("Hors ligne", { status: 503 }); - }); - }) - ); + // event.respondWith( + // caches.match(event.request).then((cachedResponse) => { + // if (cachedResponse) { + // return cachedResponse; + // } + // return fetch(event.request) + // .then((response) => { + // // Mettre en cache la nouvelle réponse + // const responseToCache = response.clone(); + // caches.open(CACHE_NAME).then((cache) => { + // cache.put(event.request, responseToCache); + // }); + // return response; + // }) + // .catch(() => { + // // Si la requête échoue et que c'est une page, renvoyer la page hors ligne + // if (event.request.mode === "navigate") { + // return caches.match(OFFLINE_PAGE); + // } + // return new Response("Hors ligne", { status: 503 }); + // }); + // }) + // ); } }); diff --git a/scripts/generate-icons.js b/scripts/generate-icons.js index c307daf..79500da 100644 --- a/scripts/generate-icons.js +++ b/scripts/generate-icons.js @@ -4,6 +4,7 @@ const path = require("path"); const sizes = [72, 96, 128, 144, 152, 192, 384, 512]; const inputSvg = path.join(__dirname, "../public/favicon.svg"); +const inputAppleSvg = path.join(__dirname, "../public/apple-icon.svg"); const outputDir = path.join(__dirname, "../public/images/icons"); async function generateIcons() { @@ -11,13 +12,41 @@ async function generateIcons() { // Créer le dossier de sortie s'il n'existe pas await fs.mkdir(outputDir, { recursive: true }); - // Générer les icônes pour chaque taille + // Générer les icônes Android (avec bords arrondis) for (const size of sizes) { const outputPath = path.join(outputDir, `icon-${size}x${size}.png`); - await sharp(inputSvg).resize(size, size).png().toFile(outputPath); + await sharp(inputSvg) + .resize(size, size, { + fit: "contain", + background: { r: 0, g: 0, b: 0, alpha: 0 }, // Fond transparent + }) + .png({ + compressionLevel: 9, + palette: true, + }) + .toFile(outputPath); - console.log(`✓ Icône ${size}x${size} générée`); + console.log(`✓ Icône Android ${size}x${size} générée`); + } + + // Générer les icônes Apple (carrées) + const appleSizes = [152, 167, 180]; + for (const size of appleSizes) { + const outputPath = path.join(outputDir, `apple-icon-${size}x${size}.png`); + + await sharp(inputAppleSvg) + .resize(size, size, { + fit: "contain", + background: { r: 0, g: 0, b: 0, alpha: 0 }, // Fond transparent + }) + .png({ + compressionLevel: 9, + palette: true, + }) + .toFile(outputPath); + + console.log(`✓ Icône Apple ${size}x${size} générée`); } console.log("\n✨ Toutes les icônes ont été générées avec succès !"); diff --git a/src/app/layout.tsx b/src/app/layout.tsx index b03b8f6..78c5a23 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -16,12 +16,28 @@ export const metadata: Metadata = { ], apple: [ { - url: "/favicon.svg", - type: "image/svg+xml", + url: "/images/icons/apple-icon-180x180.png", + sizes: "180x180", + type: "image/png", + }, + { + url: "/images/icons/apple-icon-167x167.png", + sizes: "167x167", + type: "image/png", + }, + { + url: "/images/icons/apple-icon-152x152.png", + sizes: "152x152", + type: "image/png", }, ], }, manifest: "/manifest.json", + appleWebApp: { + capable: true, + statusBarStyle: "default", + title: "StripStream", + }, }; // Composant client séparé pour le layout