forked from ORGANISATION-KA-INTERNATIONALE/FEDIVERSE-OKI
3c0b094e92
Remplace la documentation PHP par celle de la branche svelte (FR/EN) : architecture statique et bake au build, fonctionnalités portées (Funkwhale inclus), référence de src/lib/config.ts, modÚle CSP par page, PWA, structure du projet, prérequis Node + ImageMagick, mesures Lighthouse, déploiement
821 lines
40 KiB
Plaintext
821 lines
40 KiB
Plaintext
= đïž ANNU KUTE CED â Hub multimĂ©dia du podcast (SvelteKit)
|
|
:toc: left
|
|
:toc-title: Sommaire / Contents
|
|
:toclevels: 3
|
|
|
|
[[top]]
|
|
đ *Hub multimĂ©dia du podcast ANNU KUTE CED â version SvelteKit statique* +
|
|
đ *Multimedia hub for the ANNU KUTE CED podcast â static SvelteKit version*
|
|
|
|
[.text-center]
|
|
*Choisissez votre langue / Choose your language :* +
|
|
<<fr,đ«đ· Version française>> · <<en,đŹđ§ English version>>
|
|
|
|
'''
|
|
|
|
[[fr]]
|
|
== đ«đ· Version française
|
|
|
|
=== đ Description
|
|
|
|
*ANNU KUTE CED* est le *hub multimĂ©dia* du podcast du mĂȘme nom. Il regroupe en un seul lieu :
|
|
|
|
- đ„ la chaĂźne *PeerTube* du podcast (vidĂ©os, shorts, directs) ;
|
|
- đïž son compte *Castopod* (derniers Ă©pisodes, lecture audio intĂ©grĂ©e) ;
|
|
- đ” une sĂ©lection alĂ©atoire de morceaux *Funkwhale* (mĂȘme lecteur intĂ©grĂ©) ;
|
|
- đĄ sa timeline *Mastodon* (actualitĂ©s et annonces).
|
|
|
|
Cette version est une *application SvelteKit 100 % statique* (Svelte 5 + TypeScript, `adapter-static`, prerender intĂ©gral) : toutes les donnĂ©es des instances sont *rĂ©cupĂ©rĂ©es au moment du build* (« bake ») et le site gĂ©nĂ©rĂ© peut ĂȘtre servi depuis n'importe quel hĂ©bergement statique â y compris un mutualisĂ© comme o2switch â *sans PHP, sans Node, sans base de donnĂ©es*. C'est aussi une *Progressive Web App* installable, avec mode hors ligne, en français et en anglais.
|
|
|
|
đŻ *Mission* : offrir un point d'entrĂ©e unique, libre et dĂ©centralisĂ©, pour dĂ©couvrir, Ă©couter et suivre le podcast ANNU KUTE CED sans dĂ©pendre des grandes plateformes propriĂ©taires.
|
|
|
|
NOTE : La version historique PHP est conservée sur la branche `main`. Cette documentation décrit la branche `svelte`.
|
|
|
|
=== đł Origine du projet
|
|
|
|
Cette application est un *fork* de https://labola.o-k-i.net/ORGANISATION-KA-INTERNATIONALE/FEDIVERSE-OKI[*FEDIVERSE OKI*^], dĂ©veloppĂ©e par l'https://o-k-i.net[ORGANISATION KA INTERNATIONALE (OKI)^], elle-mĂȘme issue du projet https://codeberg.org/Ka-Ubuntu/kaubuntu.re[kaubuntu.re^] du mouvement https://kaubuntu.com[Ka-Ubuntu^]. La licence d'origine (GNU AGPL v3) est conservĂ©e et respectĂ©e. La refonte SvelteKit applique la https://o-k-i.net[charte OKI] (tokens panafricains, thĂšme sombre par dĂ©faut, iconographie SVG krĂ©yĂČl, cadences de motion « gwoka »).
|
|
|
|
[cols="1,3",options="header"]
|
|
|===
|
|
| ĂlĂ©ment | DĂ©tail
|
|
|
|
| DépÎt upstream
|
|
| https://labola.o-k-i.net/ORGANISATION-KA-INTERNATIONALE/FEDIVERSE-OKI
|
|
|
|
| DépÎt de ce fork
|
|
| `git@labola.o-k-i.net:cedric/annu-kute-ced.git` (branche `svelte`)
|
|
|
|
| Domaine de production
|
|
| https://annukuteced.buzz
|
|
|
|
| Gouvernance
|
|
| Application maintenue par OKI ; fork porté par le propriétaire du dépÎt *cedric* (Cédric Famibelle-Pronzola)
|
|
|
|
| Licence
|
|
| https://www.gnu.org/licenses/agpl-3.0.html[GNU Affero General Public License v3^] (AGPL-V3) ou ultérieure
|
|
|===
|
|
|
|
=== đ Sources et instances utilisĂ©es
|
|
|
|
Le hub agrĂšge au build les sources du podcast ANNU KUTE CED :
|
|
|
|
[cols="1,2,3",options="header"]
|
|
|===
|
|
| Service | Instance | Compte / chaĂźne
|
|
|
|
| đ„ PeerTube (vidĂ©os, lives)
|
|
| GADE â `https://gade.o-k-i.net`
|
|
| https://gade.o-k-i.net/c/annu_kute_ced/videos[`annu_kute_ced`^]
|
|
|
|
| đïž Castopod (Ă©pisodes audio)
|
|
| KUTE â `https://kute.o-k-i.net`
|
|
| https://kute.o-k-i.net/@annu_kute_cedric[`@annu_kute_cedric`^]
|
|
|
|
| đ” Funkwhale (musique)
|
|
| MIZIK â `https://mizik.o-k-i.net`
|
|
| morceaux aléatoires de l'instance
|
|
|
|
| đĄ Mastodon (timeline)
|
|
| BOKANTE â `https://bokante.o-k-i.net`
|
|
| https://bokante.o-k-i.net/@cedric[`@cedric`^]
|
|
|===
|
|
|
|
Toutes ces sources sont modifiables dans `src/lib/config.ts` (voir <<fr-configuration,Configuration>>).
|
|
|
|
=== ⚠Fonctionnalités
|
|
|
|
==== đ„ VidĂ©os PeerTube
|
|
|
|
- Vidéos récentes, tendances et par catégories (configurables)
|
|
- *Shorts* : carrousel dédié aux vidéos portrait de moins de 3 minutes (défilement tactile)
|
|
- Page vidéo complÚte : lecteur PeerTube embarqué, description Markdown, badge de licence Creative Commons, commentaires (lecture seule), vidéos suggérées
|
|
- *Téléchargement* : fichiers directs et playlists HLS, avec résolution et taille
|
|
- *Partage* : copie de lien, code d'intégration, e-mail, Facebook, X, WhatsApp, LinkedIn, Telegram
|
|
- Recherche plein texte et par hashtag (préfixe `#`) sur un index JSON généré au build
|
|
|
|
==== đș Directs et annonces
|
|
|
|
- Page *Direct* (`/direct`) : embed du live PeerTube s'il est en cours, avec autoplay
|
|
- *Annonce du prochain live* : date et heure converties automatiquement pour 5 territoires (Ma'ohi Nui, Martinique/Guadeloupe, Guyane, France, Kanaky), image personnalisable
|
|
- Section *hero* d'accueil configurable : live, vidéo unique, playlist ou masquée
|
|
|
|
==== đïž Podcast et musique
|
|
|
|
- *Castopod* : derniers épisodes via flux RSS, avec *lecteur audio intégré* (lecture/pause, avance automatique à l'épisode suivant, Media Session API)
|
|
- *Funkwhale* : sĂ©lection alĂ©atoire de morceaux de l'instance, avec le mĂȘme lecteur intĂ©grĂ©
|
|
- *Un seul flux à la fois* entre les deux lecteurs (bus audio partagé)
|
|
|
|
==== đĄ RĂ©seaux sociaux
|
|
|
|
- *Timeline Mastodon* : les 10 derniers posts récupérés au build et rendus en HTML sémantique (plus de bibliothÚque JS embarquée)
|
|
|
|
==== đ Internationalisation
|
|
|
|
- Interface en *français* (`/`) et en *anglais* (`/en/`) : routage par paramÚtre optionnel, bundles JSON, `hreflang`, attribut `lang` par route
|
|
- KrĂ©yĂČl en signature : page 404 (« Paj la pa la »), page hors-ligne (« Pa gen koneksyon »), verrou maintenance (« An nou tann ! »)
|
|
|
|
==== đš Charte OKI
|
|
|
|
- *ThÚme sombre par défaut* (identité de marque), thÚme clair en opt-in persisté en `localStorage`, appliqué sans FOUC
|
|
- Tokens panafricains (noir/or/vert/rouge), *flag-bar* de signature, typographies *Archivo* et *Inter* self-hébergées en woff2
|
|
- *ZĂ©ro emoji en interface* : sprite SVG maison (pictos krĂ©yĂČl `ka`, `lambi`, `zetwal`⊠+ icĂŽnes UI), zĂ©ro Font Awesome, zĂ©ro CDN
|
|
- Motion « gwoka » : KineticText au scroll (`animation-timeline: view()`), barre de progression, reveal syncopĂ© (3+3+2), View Transitions â gate unique `prefers-reduced-motion`
|
|
|
|
==== đ± PWA et confort d'utilisation
|
|
|
|
- *Progressive Web App* installable (bouton d'installation automatique)
|
|
- Mode hors ligne : shell et pages en cache via Service Worker (Workbox), page `/offline` dédiée
|
|
- *Indicateur visuel* de perte de connexion
|
|
- Interface entiĂšrement responsive (mobile, tablette, desktop)
|
|
|
|
==== đ Dons, compte Ă rebours et divers
|
|
|
|
- *Page de dons* : LiberaPay, Ko-fi et Stripe (dons ponctuels et mensuels, montants suggérés)
|
|
- *Verrou maintenance* : compte à rebours multi-fuseaux affiché à la place de tout le site quand activé au build, redirection automatique à l'échéance
|
|
- Bloc « à propos » configurable (titre, deux paragraphes, image légendée)
|
|
|
|
==== đ SEO et donnĂ©es structurĂ©es
|
|
|
|
- *JSON-LD* généré automatiquement : `WebSite` (avec `SearchAction`), `VideoObject`, `CollectionPage`, `BreadcrumbList`, `Organization`
|
|
- Balises *Open Graph* complĂštes et *Twitter Cards*, canonical, `hreflang` fr/en/x-default
|
|
- `sitemap.xml` *généré au build* (toutes les pages, vidéos comprises) et `robots.txt`
|
|
|
|
==== đĄïž SĂ©curitĂ©
|
|
|
|
- *CSP stricte* : politique globale en en-tĂȘte (`_headers` Cloudflare / `.htaccess` Apache) + `script-src` dĂ©livrĂ© *par page* en balise `<meta>` avec les empreintes SHA-256 des scripts inline (aucun `'unsafe-inline'` pour les scripts)
|
|
- *ZĂ©ro requĂȘte tierce* au chargement hors instances first-party de l'Ă©cosystĂšme (GADE, KUTE, BOKANTE, MIZIK) : ni Google Fonts, ni CDN, ni analytics
|
|
- HTML distant *sanitisé* au build (posts Mastodon, commentaires) ; descriptions Markdown échappées
|
|
- HSTS, `X-Frame-Options: DENY`, `X-Content-Type-Options: nosniff`, `Referrer-Policy`, `Permissions-Policy` restrictive
|
|
|
|
==== ⥠Performance (mesurée, Lighthouse mobile)
|
|
|
|
- *97 / 100 / 100 / 100* (performance, accessibilité, bonnes pratiques, SEO)
|
|
- JS initial â 66 Ko gzip ; poids total de l'accueil â 900 Ko ; LCP 2,4 s ; TBT 50 ms ; CLS 0
|
|
- Images distantes *optimisées au build* (WebP via ImageMagick) : vignettes PeerTube, avatars, médias Mastodon, pochettes Castopod
|
|
|
|
=== đ ïž Technologies utilisĂ©es
|
|
|
|
- ⥠*SvelteKit 2* + *Svelte 5* (runes) + *TypeScript* strict
|
|
- đŠ `@sveltejs/adapter-static` (prerender intĂ©gral, `trailingSlash: 'always'`)
|
|
- đ± `vite-plugin-pwa` (Workbox, generateSW)
|
|
- đŒïž *ImageMagick* (optimisation des images au prebuild)
|
|
- đš CSS vanilla : tokens OKI + styles scopĂ©s â pas de framework CSS
|
|
- đ€ `@fontsource/archivo` + `@fontsource/inter` (woff2 copiĂ©s dans `static/fonts/`)
|
|
|
|
=== đ Structure du projet
|
|
|
|
[source]
|
|
----
|
|
âââ docs/
|
|
â âââ wireframes/ # Maquettes d'origine (PNG desktop + mobile)
|
|
â âââ DEPLOIEMENT-SVELTEKIT.md # Guide build + dĂ©ploiement (o2switch, Cloudflare)
|
|
â âââ generate-readme-pdf.sh # Export de la doc : README.html / README.pdf
|
|
âââ scripts/
|
|
â âââ fetch-podcast-cover.mjs # Prebuild : pochettes Castopod optimisĂ©es (WebP)
|
|
â âââ optimize-remote-images.mjs # Prebuild : vignettes/avatars/mĂ©dias optimisĂ©s
|
|
â âââ postbuild-csp.mjs # Postbuild : CSP SHA-256 par page (balise meta)
|
|
âââ src/
|
|
â âââ app.html # %lang%, fonts, theme.js, registerSW.js
|
|
â âââ hooks.server.ts # lang fr/en via transformPageChunk
|
|
â âââ params/locale.ts # Matcher du paramĂštre [[locale]]
|
|
â âââ lib/
|
|
â â âââ config.ts # â Toute la configuration d'instance
|
|
â â âââ types.ts # Types partagĂ©s (VideoSummary, Episode, PostâŠ)
|
|
â â âââ audio-bus.svelte.ts # Un seul flux audio Ă la fois
|
|
â â âââ styles/ # oki-tokens.css (charte) + base.css (primitives)
|
|
â â âââ i18n/ # fr.json, en.json + helpers (locale, hrefForâŠ)
|
|
â â âââ server/ # RĂ©cupĂ©ration des donnĂ©es au build :
|
|
â â â âââ http.ts # fetch throttlĂ© (429 â retry), sanitisation
|
|
â â â âââ peertube.ts # API GADE (vidĂ©os, shorts, live, commentaires)
|
|
â â â âââ castopod.ts # Flux RSS KUTE (Ă©pisodes)
|
|
â â â âââ funkwhale.ts # API MIZIK (morceaux alĂ©atoires locaux)
|
|
â â â âââ mastodon.ts # API BOKANTE (timeline)
|
|
â â â âââ image-map.ts # Mapping images optimisĂ©es (mapImage)
|
|
â â â âââ image-map.json # (gĂ©nĂ©rĂ© au prebuild)
|
|
â â âââ motion/ # tokens gwoka, action use:reveal
|
|
â â âââ components/ # Seo, Nav, Sidebar, Footer, VideoCard,
|
|
â â # AudioPlayer, MastodonTimeline, HeroSection,
|
|
â â # CountdownLock, OfflineIndicator, motion/âŠ
|
|
â âââ routes/
|
|
â âââ +layout.ts # prerender = true, trailingSlash
|
|
â âââ +error.svelte # 404 krĂ©yĂČl (« Paj la pa la »)
|
|
â âââ [[locale=locale]]/ # Toutes les pages, FR (/) et EN (/en/) :
|
|
â â âââ +page.svelte # accueil (agrĂ©gateur)
|
|
â â âââ video/[uuid]/ # page vidĂ©o (embed, tĂ©lĂ©chargements, partage)
|
|
â â âââ categories/[id]/ # page catĂ©gorie
|
|
â â âââ recherche/ # recherche (index JSON + filtrage client)
|
|
â â âââ direct/ # live + annonce du prochain live
|
|
â â âââ dons/ # dons (LiberaPay, Ko-fi, Stripe)
|
|
â â âââ mentions-legales/ # mentions lĂ©gales
|
|
â â âââ offline/ # page hors-ligne (fallback du SW)
|
|
â âââ search-index.json/ # Index de recherche (bake)
|
|
â âââ sitemap.xml/ # Sitemap (bake)
|
|
âââ static/
|
|
â âââ fonts/ # Archivo/Inter woff2 + fonts.css
|
|
â âââ images/ # logo, favicons, pochettes, images optimisĂ©es
|
|
â âââ icons.svg # Sprite SVG (pictos krĂ©yĂČl + UI)
|
|
â âââ theme.js # Anti-FOUC (thĂšme sombre dĂ©faut, clair opt-in)
|
|
â âââ registerSW.js # Enregistrement du Service Worker
|
|
â âââ manifest.webmanifest # Manifest PWA
|
|
â âââ _headers / .htaccess # Headers de sĂ©curitĂ© (Cloudflare / Apache)
|
|
â âââ 404.html # 404 statique autonome
|
|
â âââ robots.txt / browserconfig.xml
|
|
âââ uploads/ # Images d'annonces (non versionnĂ©, hors .gitkeep)
|
|
âââ package.json / vite.config.ts # Adapter, PWA, paths.relative: false
|
|
âââ README.adoc
|
|
----
|
|
|
|
=== đ PrĂ©requis
|
|
|
|
- đą *Node.js 20+* (recommandĂ© : 22+)
|
|
- đŒïž *ImageMagick* (`convert`) â optimisation des images au prebuild
|
|
- đ Pour le dĂ©veloppement : un accĂšs rĂ©seau aux instances (les donnĂ©es sont fetchĂ©es au build)
|
|
|
|
.Installation d'ImageMagick
|
|
[source,bash]
|
|
----
|
|
# Ubuntu / Debian
|
|
sudo apt-get install imagemagick
|
|
|
|
# Fedora / RHEL / CentOS
|
|
sudo dnf install ImageMagick
|
|
----
|
|
|
|
=== đ Installation et dĂ©veloppement
|
|
|
|
. đ„ Clonez le dĂ©pĂŽt et basculez sur la branche :
|
|
+
|
|
[source,bash]
|
|
----
|
|
git clone git@labola.o-k-i.net:cedric/annu-kute-ced.git
|
|
cd annu-kute-ced
|
|
git checkout svelte
|
|
----
|
|
. đŠ Installez les dĂ©pendances :
|
|
+
|
|
[source,bash]
|
|
----
|
|
npm ci
|
|
----
|
|
. đ§ Lancez le serveur de dĂ©veloppement :
|
|
+
|
|
[source,bash]
|
|
----
|
|
npm run dev
|
|
----
|
|
. đïž Buildez le site statique :
|
|
+
|
|
[source,bash]
|
|
----
|
|
npm run build # prebuild (images) â prerender (donnĂ©es) â postbuild (CSP)
|
|
npm run preview # vérification locale du build
|
|
----
|
|
|
|
Le dossier `build/` contient le site complet, prĂȘt Ă dĂ©poser sur n'importe quel hĂ©bergement statique.
|
|
|
|
â
*Vérifications qualité* : `npm run check` (svelte-check, 0 erreur / 0 warning exigé).
|
|
|
|
đ *RafraĂźchissement du contenu* : les donnĂ©es Ă©tant bakĂ©es au build, un nouveau build est nĂ©cessaire pour afficher les derniĂšres vidĂ©os/Ă©pisodes/posts â voir `docs/DEPLOIEMENT-SVELTEKIT.md` pour un exemple de cron + rsync.
|
|
|
|
[[fr-configuration]]
|
|
=== âïž Configuration
|
|
|
|
Toute la configuration d'instance vit dans *un seul fichier* : `src/lib/config.ts` (versionnĂ©). C'est l'Ă©quivalent des anciennes constantes PHP â modifiez-le puis rebuildez.
|
|
|
|
[cols="1,3",options="header"]
|
|
|===
|
|
| Export | RĂŽle
|
|
|
|
| `site`
|
|
| Nom, domaine (`baseUrl`), description, e-mail de contact, URLs licence/source, fuseau par défaut
|
|
|
|
| `legal`
|
|
| Coordonnées des mentions légales (webmaster, hébergeur o2Switch)
|
|
|
|
| `peertube`
|
|
| URL de l'instance, chaßne, compte live, durée max des shorts, volumes par section, tag « indépendance »
|
|
|
|
| `hero`
|
|
| BanniÚre d'accueil : `type` (`'live'`, `'video'`, `'playlist'`, `'none'`), vidéo/playlist associée
|
|
|
|
| `castopod`
|
|
| Activation, instance, slug(s) de podcast, nombre d'épisodes
|
|
|
|
| `funkwhale`
|
|
| Activation, instance MIZIK, nombre de morceaux (pool de 50, sélection aléatoire)
|
|
|
|
| `mastodon`
|
|
| Instance, compte, nombre de posts de la timeline
|
|
|
|
| `social`
|
|
| URLs des réseaux sociaux du header/footer (vide = icÎne masquée)
|
|
|
|
| `donations`
|
|
| Activation, URLs LiberaPay/Ko-fi, liens Stripe (ponctuels/mensuels), montants, devise
|
|
|
|
| `nextLive`
|
|
| Annonce du prochain live : activation, titre, description, date, image, 5 fuseaux horaires
|
|
|
|
| `categories` / `categoryNames` / `categoryIcons`
|
|
| Catégories prioritaires (ordre d'affichage), noms FR/EN, pictos du sprite
|
|
|
|
| `importantTags` / `popularTags`
|
|
| Hashtags de la sidebar/footer et de l'accueil
|
|
|
|
| `about`
|
|
| Bloc « à propos » : activation, titre, deux paragraphes, image + légende (masqué tant que `enabled: false`)
|
|
|
|
| `countdown`
|
|
| *Verrou maintenance* : quand `enabled: true`, tout le site buildé affiche le compte à rebours multi-fuseaux + date cible
|
|
|===
|
|
|
|
.Les textes d'interface
|
|
NOTE : Les libellés FR/EN vivent dans `src/lib/i18n/fr.json` et `en.json` (pas dans `config.ts`).
|
|
|
|
=== đ§ Ordre des sections sur la page d'accueil
|
|
|
|
. *Hero* â si `hero.type` â `'none'` (live, vidĂ©o ou playlist)
|
|
. *Derniers Ă©pisodes* (Castopod) â si activĂ© et Ă©pisodes disponibles
|
|
. *Morceaux* (Funkwhale) â si activĂ© et morceaux disponibles
|
|
. *ActualitĂ©s* (timeline Mastodon) â si posts disponibles
|
|
. *Shorts* â carrousel
|
|
. *Vidéos récentes*
|
|
. *Tendances*
|
|
. *Une section par catégorie prioritaire* (seulement si elle contient des vidéos) + lien « Voir plus »
|
|
. *Bloc « à propos »* (si activé) + aside hashtags populaires
|
|
|
|
[[fr-securite]]
|
|
=== đĄïž SĂ©curitĂ©
|
|
|
|
==== ModĂšle CSP
|
|
|
|
- *En-tĂȘte global* (`static/_headers` pour Cloudflare Pages, `static/.htaccess` pour Apache/o2switch) : `style-src`, `img-src`, `font-src 'self'`, `connect-src 'self'`, `media-src`, `frame-src https://gade.o-k-i.net`, `frame-ancestors 'none'`, `base-uri 'self'`, `form-action 'self'`, `object-src 'none'`. Seules origines externes : les instances de l'Ă©cosystĂšme.
|
|
- *`script-src` par page* : `scripts/postbuild-csp.mjs` calcule les empreintes SHA-256 des scripts inline de chaque page (script de démarrage SvelteKit + JSON-LD) et les injecte dans une balise `<meta http-equiv="Content-Security-Policy">` complÚte. Aucun `'unsafe-inline'` pour les scripts.
|
|
- Anti-FOUC, redirection de langue et enregistrement du SW en *fichiers externes* (`theme.js`, `registerSW.js`) : aucun script inline non hashé.
|
|
|
|
==== Redirections des anciennes URLs (Apache)
|
|
|
|
Le `.htaccess` redirige les URLs historiques PHP : `index.php` â `/`, `video.php?uuid=X` â `/video/X/`, `categories.php?id=N` â `/categories/N/`, `recherche.php?q=âŠ` â `/recherche/?q=âŠ`, `direct.php` â `/direct/`, `dons.php` â `/dons/`, `mentions-legales.php` â `/mentions-legales/`. Il force aussi HTTPS, sert `404.html` et met en cache immutable `/_app/` et `/fonts/`.
|
|
|
|
=== đ± Progressive Web App (PWA)
|
|
|
|
- đČ *Installation native* : bouton « Installer » dans le header (Ă©vĂ©nement `beforeinstallprompt`)
|
|
- đ *Mode hors ligne* : prĂ©cache du shell (Workbox `generateSW`), `navigateFallback` vers `/offline/`
|
|
- đĄ *DĂ©tection de connexion* : indicateur visuel en cas de perte rĂ©seau
|
|
- đ *Mise Ă jour* : `autoUpdate` + `skipWaiting` (mise Ă jour silencieuse au prochain chargement)
|
|
- L'enregistrement du SW se fait par le fichier statique `registerSW.js` (chemins absolus), jamais par injection du plugin
|
|
|
|
NOTE : Les flux audio/vidĂ©o des instances ne sont *pas* interceptĂ©s par le SW (requĂȘtes `Range`) â seuls le shell et les assets locaux sont prĂ©cachĂ©s.
|
|
|
|
=== đ DĂ©ploiement
|
|
|
|
Voir le guide complet : *`docs/DEPLOIEMENT-SVELTEKIT.md`*.
|
|
|
|
- *o2switch (Apache)* : déposer `build/` à la racine web ; le `.htaccess` inclus gÚre HTTPS, headers, redirections des anciennes URLs et 404
|
|
- *Cloudflare Pages* : build command `npm run build`, output `build` ; le `_headers` inclus applique la sécurité et le cache
|
|
- *Rafraßchissement* : rebuild planifié (cron + rsync, ou CI avec webhook aprÚs publication d'un épisode)
|
|
|
|
=== đšâđ» DĂ©veloppement et contribution
|
|
|
|
. đż CrĂ©ez une branche : `git checkout -b ma-fonctionnalite`
|
|
. đŸ Committez avec des *messages atomiques*, au format conventionnel :
|
|
* `feat: add âŠ`, `fix: prevent âŠ`, `docs: update âŠ`, `refactor: âŠ`
|
|
. â
Avant tout commit : `npm run check` (0 erreur / 0 warning) et `npm run build` vert
|
|
. đ€ Poussez : `git push origin ma-fonctionnalite`
|
|
. đ Ouvrez une pull request
|
|
|
|
Bonnes pratiques du dépÎt :
|
|
|
|
- Les remontĂ©es de bugs et propositions sont les bienvenues sur le dĂ©pĂŽt du fork ; les amĂ©liorations gĂ©nĂ©riques peuvent ĂȘtre proposĂ©es en upstream (FEDIVERSE OKI)
|
|
- `src/lib/server/image-map.json` et `static/images/remote/` sont régénérés au prebuild : pas d'édition manuelle
|
|
- Conventions Svelte 5 : runes uniquement, `{#each}` à clé unique, `onclick` (jamais `on:click`), durées lues depuis les tokens CSS
|
|
|
|
==== đ Exporter la documentation (HTML / PDF)
|
|
|
|
[source,bash]
|
|
----
|
|
docs/generate-readme-pdf.sh # README.html + README.pdf
|
|
docs/generate-readme-pdf.sh --html # HTML seulement
|
|
docs/generate-readme-pdf.sh --pdf # PDF seulement
|
|
----
|
|
|
|
Prérequis : `asciidoctor`, `chromium` et le paquet `fonts-noto-color-emoji`. La feuille de style `docs/docinfo.html` est injectée automatiquement via le mécanisme `docinfo` d'Asciidoctor.
|
|
|
|
=== đ Licence
|
|
|
|
Copyright (C) 2025 Cédric Famibelle-Pronzola & *ORGANISATION KA INTERNATIONALE*
|
|
|
|
Ce programme est un logiciel libre : vous pouvez le redistribuer et/ou le modifier selon les termes de la licence publique générale GNU Affero publiée par la Free Software Foundation, soit la version 3 de la licence, soit (à votre choix) toute version ultérieure.
|
|
|
|
Ce programme est distribuĂ© dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE ; sans mĂȘme la garantie implicite de COMMERCIALISATION ou d'ADAPTATION Ă UN USAGE PARTICULIER. Voir la https://www.gnu.org/licenses/agpl-3.0.html[licence publique gĂ©nĂ©rale GNU Affero^] pour plus de dĂ©tails (texte intĂ©gral dans `LICENSE`).
|
|
|
|
=== đ Contact
|
|
|
|
Pour toute question ou suggestion concernant cette plateforme : mailto:kontak@o-k-i.net[kontak@o-k-i.net]
|
|
|
|
<<top,⏠Retour au sommaire>>
|
|
|
|
'''
|
|
|
|
[[en]]
|
|
== đŹđ§ English version
|
|
|
|
=== đ Description
|
|
|
|
*ANNU KUTE CED* is the *multimedia hub* of the podcast of the same name. It brings together in a single place:
|
|
|
|
- đ„ the podcast's *PeerTube* channel (videos, shorts, live streams);
|
|
- đïž its *Castopod* account (latest episodes, built-in audio playback);
|
|
- đ” a random selection of *Funkwhale* tracks (same built-in player);
|
|
- đĄ its *Mastodon* timeline (news and announcements).
|
|
|
|
This version is a *100% static SvelteKit application* (Svelte 5 + TypeScript, `adapter-static`, full prerender): all instance data is *fetched at build time* ("baked") and the generated site can be served from any static hosting â including shared hosting like o2switch â *with no PHP, no Node, no database*. It is also an installable *Progressive Web App* with offline support, in French and English.
|
|
|
|
đŻ *Mission*: provide a single, free and decentralized entry point to discover, listen to and follow the ANNU KUTE CED podcast without relying on Big Tech platforms.
|
|
|
|
NOTE: The historical PHP version is kept on the `main` branch. This documentation covers the `svelte` branch.
|
|
|
|
=== đł Project origin
|
|
|
|
This application is a *fork* of https://labola.o-k-i.net/ORGANISATION-KA-INTERNATIONALE/FEDIVERSE-OKI[*FEDIVERSE OKI*^], developed by the https://o-k-i.net[ORGANISATION KA INTERNATIONALE (OKI)^], itself derived from the https://codeberg.org/Ka-Ubuntu/kaubuntu.re[kaubuntu.re^] project by the https://kaubuntu.com[Ka-Ubuntu^] movement. The original license (GNU AGPL v3) is preserved and respected. The SvelteKit rewrite applies the OKI design system (panafrican tokens, dark theme by default, KrĂ©yĂČl SVG iconography, "gwoka" motion cadences).
|
|
|
|
[cols="1,3",options="header"]
|
|
|===
|
|
| Item | Detail
|
|
|
|
| Upstream repository
|
|
| https://labola.o-k-i.net/ORGANISATION-KA-INTERNATIONALE/FEDIVERSE-OKI
|
|
|
|
| This fork's repository
|
|
| `git@labola.o-k-i.net:cedric/annu-kute-ced.git` (`svelte` branch)
|
|
|
|
| Production domain
|
|
| https://annukuteced.buzz
|
|
|
|
| Governance
|
|
| Application maintained by OKI; fork carried by the repository owner *cedric* (Cédric Famibelle-Pronzola)
|
|
|
|
| License
|
|
| https://www.gnu.org/licenses/agpl-3.0.html[GNU Affero General Public License v3^] (AGPL-V3) or later
|
|
|===
|
|
|
|
=== đ Aggregated sources and instances
|
|
|
|
The hub aggregates the ANNU KUTE CED podcast's sources at build time:
|
|
|
|
[cols="1,2,3",options="header"]
|
|
|===
|
|
| Service | Instance | Account / channel
|
|
|
|
| đ„ PeerTube (videos, lives)
|
|
| GADE â `https://gade.o-k-i.net`
|
|
| https://gade.o-k-i.net/c/annu_kute_ced/videos[`annu_kute_ced`^]
|
|
|
|
| đïž Castopod (audio episodes)
|
|
| KUTE â `https://kute.o-k-i.net`
|
|
| https://kute.o-k-i.net/@annu_kute_cedric[`@annu_kute_cedric`^]
|
|
|
|
| đ” Funkwhale (music)
|
|
| MIZIK â `https://mizik.o-k-i.net`
|
|
| random tracks from the instance
|
|
|
|
| đĄ Mastodon (timeline)
|
|
| BOKANTE â `https://bokante.o-k-i.net`
|
|
| https://bokante.o-k-i.net/@cedric[`@cedric`^]
|
|
|===
|
|
|
|
All of these sources can be changed in `src/lib/config.ts` (see <<en-configuration,Configuration>>).
|
|
|
|
=== âš Features
|
|
|
|
==== đ„ PeerTube videos
|
|
|
|
- Recent, trending and per-category videos (configurable)
|
|
- *Shorts*: dedicated carousel for portrait videos under 3 minutes (touch scrolling)
|
|
- Full video page: embedded PeerTube player, Markdown description, Creative Commons licence badge, comments (read-only), suggested videos
|
|
- *Downloads*: direct files and HLS playlists, with resolution and size
|
|
- *Sharing*: copy link, embed code, e-mail, Facebook, X, WhatsApp, LinkedIn, Telegram
|
|
- Full-text search and hashtag search (`#` prefix) over a build-generated JSON index
|
|
|
|
==== đș Live streams and announcements
|
|
|
|
- *Live page* (`/direct`): embeds the PeerTube live stream when one is running, with autoplay
|
|
- *Next live announcement*: date and time automatically converted for 5 territories (Ma'ohi Nui, Martinique/Guadeloupe, French Guiana, France, Kanaky), custom image
|
|
- Configurable homepage *hero section*: live, single video, playlist or hidden
|
|
|
|
==== đïž Podcast and music
|
|
|
|
- *Castopod*: latest episodes via RSS feed, with a *built-in audio player* (play/pause, auto-advance to the next episode, Media Session API)
|
|
- *Funkwhale*: random track selection from the instance, using the same built-in player
|
|
- *One stream at a time* across both players (shared audio bus)
|
|
|
|
==== đĄ Social networks
|
|
|
|
- *Mastodon timeline*: the 10 latest posts fetched at build time and rendered as semantic HTML (no embedded JS library anymore)
|
|
|
|
==== đ Internationalization
|
|
|
|
- Interface in *French* (`/`) and *English* (`/en/`): optional-parameter routing, JSON bundles, `hreflang`, per-route `lang` attribute
|
|
- KrĂ©yĂČl as a signature: 404 page ("Paj la pa la"), offline page ("Pa gen koneksyon"), maintenance lock ("An nou tann !")
|
|
|
|
==== đš OKI design system
|
|
|
|
- *Dark theme by default* (brand identity), light theme as an opt-in persisted in `localStorage`, applied without FOUC
|
|
- Panafrican tokens (black/gold/green/red), signature *flag-bar*, self-hosted *Archivo* and *Inter* woff2 fonts
|
|
- *Zero emoji in the interface*: custom SVG sprite (KrĂ©yĂČl pictograms `ka`, `lambi`, `zetwal`⊠+ UI icons), no Font Awesome, no CDN
|
|
- "Gwoka" motion: scroll-driven KineticText (`animation-timeline: view()`), progress bar, syncopated reveal (3+3+2), View Transitions â single `prefers-reduced-motion` gate
|
|
|
|
==== đ± PWA and user experience
|
|
|
|
- Installable *Progressive Web App* (automatic install button)
|
|
- Offline mode: shell and pages cached via Service Worker (Workbox), dedicated `/offline` page
|
|
- *Visual indicator* when the connection is lost
|
|
- Fully responsive interface (mobile, tablet, desktop)
|
|
|
|
==== đ Donations, countdown and more
|
|
|
|
- *Donation page*: LiberaPay, Ko-fi and Stripe (one-time and monthly donations, suggested amounts)
|
|
- *Maintenance lock*: multi-timezone countdown displayed instead of the whole site when enabled at build time, automatic redirect when it ends
|
|
- Configurable "About" block (title, two paragraphs, captioned image)
|
|
|
|
==== đ SEO and structured data
|
|
|
|
- Automatically generated *JSON-LD*: `WebSite` (with `SearchAction`), `VideoObject`, `CollectionPage`, `BreadcrumbList`, `Organization`
|
|
- Full *Open Graph* and *Twitter Cards* meta tags, canonical, `hreflang` fr/en/x-default
|
|
- Build-generated `sitemap.xml` (every page, including videos) and `robots.txt`
|
|
|
|
==== đĄïž Security
|
|
|
|
- *Strict CSP*: global policy in headers (`_headers` for Cloudflare / `.htaccess` for Apache) + per-page `script-src` delivered in a `<meta>` tag with SHA-256 hashes of inline scripts (no `'unsafe-inline'` for scripts)
|
|
- *Zero third-party requests* at load time outside the first-party ecosystem instances (GADE, KUTE, BOKANTE, MIZIK): no Google Fonts, no CDN, no analytics
|
|
- Remote HTML *sanitized* at build time (Mastodon posts, comments); Markdown descriptions escaped
|
|
- HSTS, `X-Frame-Options: DENY`, `X-Content-Type-Options: nosniff`, `Referrer-Policy`, restrictive `Permissions-Policy`
|
|
|
|
==== ⥠Performance (measured, mobile Lighthouse)
|
|
|
|
- *97 / 100 / 100 / 100* (performance, accessibility, best practices, SEO)
|
|
- Initial JS â 66 KB gzip; homepage total weight â 900 KB; LCP 2.4 s; TBT 50 ms; CLS 0
|
|
- Remote images *optimized at build time* (WebP via ImageMagick): PeerTube thumbnails, avatars, Mastodon media, Castopod covers
|
|
|
|
=== đ ïž Tech stack
|
|
|
|
- ⥠*SvelteKit 2* + *Svelte 5* (runes) + strict *TypeScript*
|
|
- đŠ `@sveltejs/adapter-static` (full prerender, `trailingSlash: 'always'`)
|
|
- đ± `vite-plugin-pwa` (Workbox, generateSW)
|
|
- đŒïž *ImageMagick* (build-time image optimization)
|
|
- đš Vanilla CSS: OKI tokens + scoped styles â no CSS framework
|
|
- đ€ `@fontsource/archivo` + `@fontsource/inter` (woff2 copied to `static/fonts/`)
|
|
|
|
=== đ Project structure
|
|
|
|
[source]
|
|
----
|
|
âââ docs/
|
|
â âââ wireframes/ # Original mockups (desktop + mobile PNGs)
|
|
â âââ DEPLOIEMENT-SVELTEKIT.md # Build + deployment guide (o2switch, Cloudflare)
|
|
â âââ generate-readme-pdf.sh # Docs export: README.html / README.pdf
|
|
âââ scripts/
|
|
â âââ fetch-podcast-cover.mjs # Prebuild: optimized Castopod covers (WebP)
|
|
â âââ optimize-remote-images.mjs # Prebuild: optimized thumbnails/avatars/media
|
|
â âââ postbuild-csp.mjs # Postbuild: per-page SHA-256 CSP (meta tag)
|
|
âââ src/
|
|
â âââ app.html # %lang%, fonts, theme.js, registerSW.js
|
|
â âââ hooks.server.ts # fr/en lang via transformPageChunk
|
|
â âââ params/locale.ts # [[locale]] param matcher
|
|
â âââ lib/
|
|
â â âââ config.ts # â All instance configuration
|
|
â â âââ types.ts # Shared types (VideoSummary, Episode, PostâŠ)
|
|
â â âââ audio-bus.svelte.ts # One audio stream at a time
|
|
â â âââ styles/ # oki-tokens.css (brand) + base.css (primitives)
|
|
â â âââ i18n/ # fr.json, en.json + helpers (locale, hrefForâŠ)
|
|
â â âââ server/ # Build-time data fetching:
|
|
â â â âââ http.ts # throttled fetch (429 â retry), sanitizing
|
|
â â â âââ peertube.ts # GADE API (videos, shorts, live, comments)
|
|
â â â âââ castopod.ts # KUTE RSS feed (episodes)
|
|
â â â âââ funkwhale.ts # MIZIK API (random local tracks)
|
|
â â â âââ mastodon.ts # BOKANTE API (timeline)
|
|
â â â âââ image-map.ts # Optimized images mapping (mapImage)
|
|
â â â âââ image-map.json # (generated at prebuild)
|
|
â â âââ motion/ # gwoka tokens, use:reveal action
|
|
â â âââ components/ # Seo, Nav, Sidebar, Footer, VideoCard,
|
|
â â # AudioPlayer, MastodonTimeline, HeroSection,
|
|
â â # CountdownLock, OfflineIndicator, motion/âŠ
|
|
â âââ routes/
|
|
â âââ +layout.ts # prerender = true, trailingSlash
|
|
â âââ +error.svelte # KrĂ©yĂČl 404 ("Paj la pa la")
|
|
â âââ [[locale=locale]]/ # Every page, FR (/) and EN (/en/):
|
|
â â âââ +page.svelte # home (aggregator)
|
|
â â âââ video/[uuid]/ # video page (embed, downloads, sharing)
|
|
â â âââ categories/[id]/ # category page
|
|
â â âââ recherche/ # search (JSON index + client filtering)
|
|
â â âââ direct/ # live + next-live announcement
|
|
â â âââ dons/ # donations (LiberaPay, Ko-fi, Stripe)
|
|
â â âââ mentions-legales/ # legal notice
|
|
â â âââ offline/ # offline page (SW fallback)
|
|
â âââ search-index.json/ # Search index (baked)
|
|
â âââ sitemap.xml/ # Sitemap (baked)
|
|
âââ static/
|
|
â âââ fonts/ # Archivo/Inter woff2 + fonts.css
|
|
â âââ images/ # logo, favicons, covers, optimized images
|
|
â âââ icons.svg # SVG sprite (KrĂ©yĂČl pictograms + UI)
|
|
â âââ theme.js # Anti-FOUC (dark default, light opt-in)
|
|
â âââ registerSW.js # Service Worker registration
|
|
â âââ manifest.webmanifest # PWA manifest
|
|
â âââ _headers / .htaccess # Security headers (Cloudflare / Apache)
|
|
â âââ 404.html # Self-contained static 404
|
|
â âââ robots.txt / browserconfig.xml
|
|
âââ uploads/ # Announcement images (not versioned, except .gitkeep)
|
|
âââ package.json / vite.config.ts # Adapter, PWA, paths.relative: false
|
|
âââ README.adoc
|
|
----
|
|
|
|
=== đ Requirements
|
|
|
|
- đą *Node.js 20+* (recommended: 22+)
|
|
- đŒïž *ImageMagick* (`convert`) â build-time image optimization
|
|
- đ For development: network access to the instances (data is fetched at build time)
|
|
|
|
.Installing ImageMagick
|
|
[source,bash]
|
|
----
|
|
# Ubuntu / Debian
|
|
sudo apt-get install imagemagick
|
|
|
|
# Fedora / RHEL / CentOS
|
|
sudo dnf install ImageMagick
|
|
----
|
|
|
|
=== đ Installation and development
|
|
|
|
. đ„ Clone the repository and switch to the branch:
|
|
+
|
|
[source,bash]
|
|
----
|
|
git clone git@labola.o-k-i.net:cedric/annu-kute-ced.git
|
|
cd annu-kute-ced
|
|
git checkout svelte
|
|
----
|
|
. đŠ Install dependencies:
|
|
+
|
|
[source,bash]
|
|
----
|
|
npm ci
|
|
----
|
|
. đ§ Start the development server:
|
|
+
|
|
[source,bash]
|
|
----
|
|
npm run dev
|
|
----
|
|
. đïž Build the static site:
|
|
+
|
|
[source,bash]
|
|
----
|
|
npm run build # prebuild (images) â prerender (data) â postbuild (CSP)
|
|
npm run preview # local check of the build
|
|
----
|
|
|
|
The `build/` directory holds the complete site, ready to drop on any static hosting.
|
|
|
|
â
*Quality gates*: `npm run check` (svelte-check, 0 errors / 0 warnings required).
|
|
|
|
đ *Content refresh*: since data is baked at build time, a new build is required to display the latest videos/episodes/posts â see `docs/DEPLOIEMENT-SVELTEKIT.md` for a cron + rsync example.
|
|
|
|
[[en-configuration]]
|
|
=== âïž Configuration
|
|
|
|
All instance configuration lives in *a single file*: `src/lib/config.ts` (versioned). It is the equivalent of the old PHP constants â edit it, then rebuild.
|
|
|
|
[cols="1,3",options="header"]
|
|
|===
|
|
| Export | Role
|
|
|
|
| `site`
|
|
| Name, domain (`baseUrl`), description, contact e-mail, license/source URLs, default timezone
|
|
|
|
| `legal`
|
|
| Legal notice details (webmaster, o2Switch host)
|
|
|
|
| `peertube`
|
|
| Instance URL, channel, live account, max shorts duration, per-section volumes, "independence" tag
|
|
|
|
| `hero`
|
|
| Homepage banner: `type` (`'live'`, `'video'`, `'playlist'`, `'none'`), associated video/playlist
|
|
|
|
| `castopod`
|
|
| Toggle, instance, podcast slug(s), episode count
|
|
|
|
| `funkwhale`
|
|
| Toggle, MIZIK instance, track count (pool of 50, random selection)
|
|
|
|
| `mastodon`
|
|
| Instance, account, timeline post count
|
|
|
|
| `social`
|
|
| Header/footer social network URLs (empty = icon hidden)
|
|
|
|
| `donations`
|
|
| Toggle, LiberaPay/Ko-fi URLs, Stripe links (one-time/monthly), amounts, currency
|
|
|
|
| `nextLive`
|
|
| Next live announcement: toggle, title, description, date, image, 5 timezones
|
|
|
|
| `categories` / `categoryNames` / `categoryIcons`
|
|
| Priority categories (display order), FR/EN names, sprite pictograms
|
|
|
|
| `importantTags` / `popularTags`
|
|
| Sidebar/footer and homepage hashtags
|
|
|
|
| `about`
|
|
| "About" block: toggle, title, two paragraphs, image + caption (hidden while `enabled: false`)
|
|
|
|
| `countdown`
|
|
| *Maintenance lock*: when `enabled: true`, the whole built site shows the multi-timezone countdown + target date
|
|
|===
|
|
|
|
.Interface texts
|
|
NOTE: FR/EN labels live in `src/lib/i18n/fr.json` and `en.json` (not in `config.ts`).
|
|
|
|
=== đ§ Homepage section order
|
|
|
|
. *Hero* â if `hero.type` â `'none'` (live, video or playlist)
|
|
. *Latest episodes* (Castopod) â if enabled and episodes available
|
|
. *Tracks* (Funkwhale) â if enabled and tracks available
|
|
. *News* (Mastodon timeline) â if posts available
|
|
. *Shorts* â carousel
|
|
. *Recent videos*
|
|
. *Trending*
|
|
. *One section per priority category* (only when it has videos) + "See more" link
|
|
. *"About" block* (if enabled) + popular hashtags aside
|
|
|
|
[[en-securite]]
|
|
=== đĄïž Security
|
|
|
|
==== CSP model
|
|
|
|
- *Global header* (`static/_headers` for Cloudflare Pages, `static/.htaccess` for Apache/o2switch): `style-src`, `img-src`, `font-src 'self'`, `connect-src 'self'`, `media-src`, `frame-src https://gade.o-k-i.net`, `frame-ancestors 'none'`, `base-uri 'self'`, `form-action 'self'`, `object-src 'none'`. Only external origins: the ecosystem instances.
|
|
- *Per-page `script-src`*: `scripts/postbuild-csp.mjs` computes SHA-256 hashes of each page's inline scripts (SvelteKit start script + JSON-LD) and injects them into a full `<meta http-equiv="Content-Security-Policy">` tag. No `'unsafe-inline'` for scripts.
|
|
- Anti-FOUC, language redirect and SW registration as *external files* (`theme.js`, `registerSW.js`): no unhashed inline script.
|
|
|
|
==== Legacy URL redirects (Apache)
|
|
|
|
The `.htaccess` redirects historical PHP URLs: `index.php` â `/`, `video.php?uuid=X` â `/video/X/`, `categories.php?id=N` â `/categories/N/`, `recherche.php?q=âŠ` â `/recherche/?q=âŠ`, `direct.php` â `/direct/`, `dons.php` â `/dons/`, `mentions-legales.php` â `/mentions-legales/`. It also forces HTTPS, serves `404.html` and sets immutable caching for `/_app/` and `/fonts/`.
|
|
|
|
=== đ± Progressive Web App (PWA)
|
|
|
|
- đČ *Native installation*: "Install" button in the header (`beforeinstallprompt` event)
|
|
- đ *Offline mode*: shell precache (Workbox `generateSW`), `navigateFallback` to `/offline/`
|
|
- đĄ *Connection detection*: visual indicator when the network is lost
|
|
- đ *Updates*: `autoUpdate` + `skipWaiting` (silent update on next load)
|
|
- SW registration is done by the static `registerSW.js` file (absolute paths), never via plugin injection
|
|
|
|
NOTE: Instance audio/video streams are *not* intercepted by the SW (`Range` requests) â only the shell and local assets are precached.
|
|
|
|
=== đ Deployment
|
|
|
|
See the full guide: *`docs/DEPLOIEMENT-SVELTEKIT.md`*.
|
|
|
|
- *o2switch (Apache)*: drop `build/` at the web root; the bundled `.htaccess` handles HTTPS, headers, legacy URL redirects and 404
|
|
- *Cloudflare Pages*: build command `npm run build`, output `build`; the bundled `_headers` applies security and caching
|
|
- *Refresh*: scheduled rebuild (cron + rsync, or CI with a webhook after an episode is published)
|
|
|
|
=== đšâđ» Development and contribution
|
|
|
|
. đż Create a branch: `git checkout -b my-feature`
|
|
. đŸ Commit with *atomic messages*, conventional format:
|
|
* `feat: add âŠ`, `fix: prevent âŠ`, `docs: update âŠ`, `refactor: âŠ`
|
|
. â
Before any commit: `npm run check` (0 errors / 0 warnings) and a green `npm run build`
|
|
. đ€ Push: `git push origin my-feature`
|
|
. đ Open a pull request
|
|
|
|
Repository best practices:
|
|
|
|
- Bug reports and proposals are welcome on the fork's repository; generic improvements can be proposed upstream (FEDIVERSE OKI)
|
|
- `src/lib/server/image-map.json` and `static/images/remote/` are regenerated at prebuild: no manual editing
|
|
- Svelte 5 conventions: runes only, uniquely keyed `{#each}`, `onclick` (never `on:click`), durations read from CSS tokens
|
|
|
|
==== đ Exporting the documentation (HTML / PDF)
|
|
|
|
[source,bash]
|
|
----
|
|
docs/generate-readme-pdf.sh # README.html + README.pdf
|
|
docs/generate-readme-pdf.sh --html # HTML only
|
|
docs/generate-readme-pdf.sh --pdf # PDF only
|
|
----
|
|
|
|
Requirements: `asciidoctor`, `chromium` and the `fonts-noto-color-emoji` package. The `docs/docinfo.html` stylesheet is automatically injected via Asciidoctor's `docinfo` mechanism.
|
|
|
|
=== đ License
|
|
|
|
Copyright (C) 2025 Cédric Famibelle-Pronzola & *ORGANISATION KA INTERNATIONALE*
|
|
|
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the https://www.gnu.org/licenses/agpl-3.0.html[GNU Affero General Public License^] for more details (full text in `LICENSE`).
|
|
|
|
=== đ Contact
|
|
|
|
For any question or suggestion about this platform: mailto:kontak@o-k-i.net[kontak@o-k-i.net]
|
|
|
|
<<top,⏠Back to top>>
|