From bb7208223085927128850f35b989d9e8952e4fc2 Mon Sep 17 00:00:00 2001 From: BlackAngelTVdev Date: Thu, 28 May 2026 19:03:23 +0200 Subject: [PATCH] feat(dl): charger les releases GitHub pour les downloads --- p/assets/js/downloads.js | 309 +++++++++++---------------------------- p/assets/styles/main.css | 22 ++- p/dl/index.html | 86 ++--------- 3 files changed, 112 insertions(+), 305 deletions(-) diff --git a/p/assets/js/downloads.js b/p/assets/js/downloads.js index 63dd7c1..7a94276 100644 --- a/p/assets/js/downloads.js +++ b/p/assets/js/downloads.js @@ -1,249 +1,116 @@ -document.addEventListener("DOMContentLoaded", () => { - const cards = Array.from(document.querySelectorAll(".download-card")); - const currentVersionLabel = document.querySelector("[data-current-version]"); - const archiveToggle = document.querySelector("[data-action-toggle-archive]"); - const versionsArchive = document.querySelector("[data-versions-archive]"); +(() => { + const OWNER = "You-re-like-Windows-a-bitch"; + const REPO = "ISO"; + const API_URL = `https://api.github.com/repos/${OWNER}/${REPO}/releases?per_page=6`; + const REPO_URL = `https://github.com/${OWNER}/${REPO}`; + + const currentVersionNode = document.querySelector("[data-current-version]"); + const currentVersionDateNode = document.querySelector("[data-current-version-date]"); + const currentReleaseNoteNode = document.querySelector("[data-current-release-note]"); + const latestDownloadNode = document.querySelector("[data-latest-download]"); const versionsListNode = document.querySelector("[data-versions-list]"); - const actionAdd = document.querySelector("[data-action-add]"); - const actionEdit = document.querySelector("[data-action-edit]"); - const VERSIONS_KEY = "fws:versions"; - - const defaultVersions = [ - { label: "1.0.2", url: "https://download.example.org/fws-1.0.2.iso", date: "2026-05-10" }, - { label: "1.0.1", url: "https://download.example.org/fws-1.0.1.iso", date: "2026-03-22" }, - { label: "0.9.8", url: "https://download.example.org/fws-0.9.8.iso", date: "2025-12-05" }, - ]; - - function loadVersions() { - try { - const raw = localStorage.getItem(VERSIONS_KEY); - if (!raw) return defaultVersions.slice(); - const parsed = JSON.parse(raw); - if (!Array.isArray(parsed) || !parsed.length) return defaultVersions.slice(); - return parsed; - } catch (e) { - return defaultVersions.slice(); - } + function formatDate(value) { + if (!value) return ""; + const date = new Date(value); + if (Number.isNaN(date.getTime())) return ""; + return date.toLocaleDateString("fr-FR", { + year: "numeric", + month: "long", + day: "numeric", + }); } - function saveVersions(list) { - localStorage.setItem(VERSIONS_KEY, JSON.stringify(list)); + function getDirectDownloadUrl(release) { + if (release?.assets?.length) { + return release.assets[0].browser_download_url || release.assets[0].url || release.html_url || "#"; + } + return release?.html_url || "#"; } - let versions = loadVersions(); - let currentVersion = versions[0]; - - function renderVersionsBar() { - if (currentVersionLabel) { - currentVersionLabel.textContent = `${currentVersion.label} ${currentVersion.date ? '— ' + currentVersion.date : ''}`.trim(); - } - // update prominent latest download button - const latestBtn = document.querySelector('[data-latest-download]'); - if (latestBtn) { - latestBtn.href = currentVersion.url || '#'; - } + function getReleaseLabel(release) { + return release.name || release.tag_name || "Sans nom"; } - function renderArchive() { + function renderReleaseList(releases) { if (!versionsListNode) return; versionsListNode.innerHTML = ""; - versions.forEach((v, idx) => { + + releases.slice(1, 6).forEach((release) => { const li = document.createElement("li"); li.className = "version-item"; + + const versionLabel = getReleaseLabel(release); + const downloadUrl = getDirectDownloadUrl(release); + const published = formatDate(release.published_at); + li.innerHTML = ` - ${v.label} ${v.date || ''} -
- Télécharger - - - +
+ ${versionLabel} + ${published ? `Publié le ${published}` : "Date inconnue"} +
+ `; + versionsListNode.appendChild(li); }); } - function setCurrentToIndex(idx) { - const v = versions[idx]; - if (!v) return; - versions.splice(idx, 1); - versions.unshift(v); - currentVersion = versions[0]; - saveVersions(versions); - renderVersionsBar(); - renderArchive(); - applyLinksToCards(); - } + async function loadReleases() { + if (currentVersionNode) currentVersionNode.textContent = "Chargement..."; - function applyLinksToCards() { - cards.forEach((card) => { - const key = `fws:download:${card.dataset.key}`; - const btn = card.querySelector(".download-btn"); - const copyBtn = card.querySelector(".copy-btn"); - const stored = localStorage.getItem(key); - const finalUrl = stored || (currentVersion && currentVersion.url) || "#"; - if (btn) btn.href = finalUrl; - if (btn) btn.dataset.link = finalUrl; - if (copyBtn) copyBtn.dataset.link = finalUrl; - }); - } + try { + const response = await fetch(API_URL, { + headers: { + Accept: "application/vnd.github+json", + }, + }); - function toast(message) { - const t = document.createElement("div"); - t.className = "dl-toast"; - t.textContent = message; - Object.assign(t.style, { - position: "fixed", - right: "1rem", - bottom: "1rem", - background: "rgba(2,6,23,0.9)", - color: "#fff", - padding: "0.6rem 0.9rem", - borderRadius: "6px", - boxShadow: "0 6px 20px rgba(2,6,23,0.5)", - zIndex: 9999, - }); - document.body.appendChild(t); - setTimeout(() => t.remove(), 2200); - } + if (!response.ok) { + throw new Error(`GitHub API ${response.status}`); + } - cards.forEach((card) => { - const key = `fws:download:${card.dataset.key}`; - const btn = card.querySelector(".download-btn"); - const copyBtn = card.querySelector(".copy-btn"); - const editBtn = card.querySelector(".edit-btn"); + const releases = await response.json(); + if (!Array.isArray(releases) || releases.length === 0) { + throw new Error("Aucune release trouvée"); + } - function setLink(url) { - if (!url) url = "#"; - btn.href = url; - btn.dataset.link = url; - copyBtn.dataset.link = url; - localStorage.setItem(key, url); - } + const latest = releases[0]; + const latestLabel = getReleaseLabel(latest); + const latestDownloadUrl = getDirectDownloadUrl(latest); + const latestDate = formatDate(latest.published_at); - const stored = localStorage.getItem(key); - if (stored) { - setLink(stored); - } else { - // apply global current version by default - if (currentVersion && currentVersion.url) { - setLink(currentVersion.url); + if (currentVersionNode) currentVersionNode.textContent = latestLabel; + if (currentVersionDateNode) currentVersionDateNode.textContent = latestDate ? ` · ${latestDate}` : ""; + if (currentReleaseNoteNode) currentReleaseNoteNode.textContent = latest.body || "Release GitHub la plus récente."; + if (latestDownloadNode) latestDownloadNode.href = latestDownloadUrl; + + renderReleaseList(releases); + } catch (error) { + if (currentVersionNode) currentVersionNode.textContent = "Impossible de charger les releases"; + if (currentReleaseNoteNode) { + currentReleaseNoteNode.textContent = `Erreur: ${error.message}. Vérifie que le repo GitHub est public et qu'il expose des releases.`; + } + if (latestDownloadNode) { + latestDownloadNode.href = REPO_URL; + } + if (versionsListNode) { + versionsListNode.innerHTML = ` +
  • +
    + Impossible de charger les anciennes versions + Ouvre le repo GitHub pour voir les releases. +
    + +
  • + `; } } - - editBtn.addEventListener("click", () => { - const current = localStorage.getItem(key) || (currentVersion && currentVersion.url) || ""; - const value = window.prompt("Collez l'URL de téléchargement pour ce fichier:", current); - if (value === null) return; - const trimmed = value.trim(); - setLink(trimmed); - toast("Lien enregistré"); - }); - - copyBtn.addEventListener("click", async () => { - const link = copyBtn.dataset.link || btn.href || ""; - if (!link || link === "#") { - toast("Aucun lien défini — utilisez 'Modifier le lien'"); - return; - } - try { - await navigator.clipboard.writeText(link); - toast("Lien copié dans le presse-papiers"); - } catch (e) { - window.prompt("Copiez manuellement ce lien:", link); - } - }); - - btn.addEventListener("click", (ev) => { - const href = btn.getAttribute("href") || ""; - if (!href || href === "#") { - ev.preventDefault(); - toast("Aucun lien configuré — cliquez sur 'Modifier le lien' pour en ajouter un"); - } - }); - }); - - // render versions UI - function toggleArchive() { - const expanded = archiveToggle.getAttribute("aria-expanded") === "true"; - archiveToggle.setAttribute("aria-expanded", String(!expanded)); - if (versionsArchive) versionsArchive.hidden = expanded; } - if (archiveToggle) { - archiveToggle.addEventListener("click", () => { - toggleArchive(); - }); - } - - if (actionAdd) { - actionAdd.addEventListener("click", () => { - const label = window.prompt("Nom de la version (ex: 1.0.3):", ""); - if (!label) return; - const url = window.prompt("URL de téléchargement pour cette version:", ""); - if (!url) return; - const date = new Date().toISOString().slice(0, 10); - versions.unshift({ label: label.trim(), url: url.trim(), date }); - saveVersions(versions); - currentVersion = versions[0]; - renderVersionsBar(); - renderArchive(); - applyLinksToCards(); - toast("Version ajoutée"); - }); - } - - if (actionEdit) { - actionEdit.addEventListener("click", () => { - const url = window.prompt("Nouvelle URL pour la version actuelle:", currentVersion.url || ""); - if (url === null) return; - currentVersion.url = url.trim(); - versions[0] = currentVersion; - saveVersions(versions); - renderVersionsBar(); - applyLinksToCards(); - toast("Version mise à jour"); - }); - } - - // delegated events for archive list - if (versionsListNode) { - versionsListNode.addEventListener("click", (ev) => { - const copyBtn = ev.target.closest(".copy-version"); - const makeBtn = ev.target.closest(".make-latest"); - const editBtn = ev.target.closest(".edit-version"); - if (copyBtn) { - const idx = Number(copyBtn.dataset.idx); - const v = versions[idx]; - if (v && v.url) { - navigator.clipboard.writeText(v.url).then(() => toast("Lien copié"), () => window.prompt("Copiez le lien:", v.url)); - } - return; - } - if (makeBtn) { - const idx = Number(makeBtn.dataset.idx); - setCurrentToIndex(idx); - toast("Version définie comme dernière"); - return; - } - if (editBtn) { - const idx = Number(editBtn.dataset.idx); - const v = versions[idx]; - if (!v) return; - const newUrl = window.prompt(`Nouvelle URL pour ${v.label}:`, v.url || ""); - if (newUrl === null) return; - v.url = newUrl.trim(); - versions[idx] = v; - saveVersions(versions); - renderArchive(); - applyLinksToCards(); - toast("Version modifiée"); - } - }); - } - - renderVersionsBar(); - renderArchive(); - applyLinksToCards(); -}); + loadReleases(); +})(); \ No newline at end of file diff --git a/p/assets/styles/main.css b/p/assets/styles/main.css index 7fdcabd..50ebbd2 100644 --- a/p/assets/styles/main.css +++ b/p/assets/styles/main.css @@ -1,16 +1,22 @@ -.versions-panel { margin-top: 1rem; padding: 0.9rem; border-radius: 0.75rem; background: rgba(255,255,255,0.02); border: 1px solid rgba(148,163,184,0.04); } +.versions-panel { margin-top: 1rem; padding: 1rem; border-radius: 1rem; background: rgba(255,255,255,0.03); border: 1px solid rgba(148,163,184,0.08); } .latest-version h2 { margin: 0 0 0.35rem; } .latest-row { display:flex; justify-content: space-between; align-items:center; gap:1rem; } -.latest-meta { color: var(--muted); } -.latest-actions { display:flex; gap:0.6rem; } +.latest-meta { color: var(--muted); font-size: 1.05rem; } +.latest-actions { display:flex; gap:0.6rem; flex-wrap: wrap; } +.latest-note { margin: 0.85rem 0 0; color: var(--muted); line-height: 1.6; } -.versions-archive { margin-top: 0.8rem; } -.versions-list { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:0.6rem; } -.version-item { display:flex; justify-content:space-between; align-items:center; padding:0.45rem 0.6rem; border-radius:0.45rem; background: rgba(2,6,23,0.02); } -.version-item .version-actions { display:flex; gap:0.4rem; } +.versions-archive { margin-top: 1rem; } +.versions-list { list-style:none; margin:0; padding:0; display:grid; gap:0.75rem; } +.version-item { display:flex; justify-content:space-between; align-items:center; gap:1rem; padding:0.8rem 0.9rem; border-radius:0.8rem; background: rgba(2,6,23,0.24); border: 1px solid rgba(148,163,184,0.08); } +.version-item-empty { opacity: 0.8; } +.version-main { display:flex; flex-direction:column; gap:0.2rem; } +.version-main a { color: #7dd3fc; text-decoration: none; width: fit-content; } +.version-main a:hover { text-decoration: underline; } +.version-side { display:flex; gap:0.5rem; flex-wrap: wrap; } @media (max-width: 880px) { - .latest-row { flex-direction: column; align-items: flex-start; gap:0.5rem; } + .latest-row, .version-item { flex-direction: column; align-items: flex-start; } + .version-side { width: 100%; } } @import "./var.css"; diff --git a/p/dl/index.html b/p/dl/index.html index 364e2a5..4dcc3c3 100644 --- a/p/dl/index.html +++ b/p/dl/index.html @@ -11,96 +11,30 @@

    Téléchargements

    -

    Choisissez votre image et collez le lien de téléchargement (ou utilisez ceux fournis). Les liens sont sauvegardés localement pour faciliter la gestion.

    - +

    Dernière release GitHub en haut, les 5 précédentes dessous, avec un lien direct sur le premier fichier de chaque release.

    Dernière version

    -
    Version
    +
    + Chargement... + +
    - Télécharger la dernière - + Télécharger + Voir plus
    +

    -
    -

    Versions précédentes

    +
    +

    5 versions précédentes

      -
      - -
      -
      -
      -
      CLI
      -
      -

      CLI (Minimal)

      -

      Image minimale sans environnement graphique, pour les installations serveur ou avancées.

      -
      - Télécharger - - -
      -
      -
      - -
      -
      KDE Plasma
      -
      -

      KDE Plasma

      -

      Environnement complet, riche en fonctionnalités et personnalisable.

      -
      - Télécharger - - -
      -
      -
      - -
      -
      GNOME
      -
      -

      GNOME

      -

      Expérience épurée et orientée productivité, simple à prendre en main.

      -
      - Télécharger - - -
      -
      -
      - -
      -
      XFCE
      -
      -

      XFCE

      -

      Environnement léger et stable, adapté aux machines modestes.

      -
      - Télécharger - - -
      -
      -
      - -
      -
      Hyprland
      -
      -

      Hyprland

      -

      Tiling Wayland moderne, pensé pour les workflows clavier avancés.

      -
      - Télécharger - - -
      -
      -
      -