Commit Graph

78 Commits

Author SHA1 Message Date
syoul 3dbd8704ff chore: bump version to 1.3.1
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:39:22 +01:00
syoul b0104207c4 fix: retirer la mention Mock de l'InfoPanel (détail interne)
ci/woodpecker/push/woodpecker Pipeline failed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:39:13 +01:00
syoul 4821dab6e6 chore: bump version to 1.3.0
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:35:41 +01:00
syoul eb4e693f3c fix: nom de l'app Ğ1Flux (et non ĞéoFlux) dans InfoPanel
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:32:46 +01:00
syoul 810c815706 feat: bouton ℹ + modale InfoPanel décrivant toutes les fonctionnalités
ci/woodpecker/push/woodpecker Pipeline was successful
- InfoPanel : modale avec overlay, sections Vues / Clusters / Période /
  Animation / Statistiques / Source, composants Section/Feature/Kbd
- PeriodSelector : ajout prop onInfo + bouton ℹ en fin de barre
- App.tsx : état infoOpen, onInfo → setInfoOpen(true), rendu InfoPanel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:28:51 +01:00
syoul 0e040510af fix: bouton Clusters bottom-32 — juste au-dessus de l'AnimationPlayer
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:22:12 +01:00
syoul ac974fb8a0 fix: bouton Clusters z-[1002] — visible au-dessus de l'AnimationPlayer
ci/woodpecker/push/woodpecker Pipeline was successful
AnimationPlayer z-[1001] couvrait le bouton z-[600] sur mobile
(player ~130px, bouton à bottom-20/80px).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:18:51 +01:00
syoul 666dc99989 fix: sbom-generate — version syft hardcodée dans l'URL (env non expansé)
ci/woodpecker/push/woodpecker Pipeline was successful
Les variables environment: Woodpecker ne sont pas expansées dans les
commandes shell YAML. Version v1.42.3 écrite directement dans l'URL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:15:20 +01:00
syoul c02f207b6c fix: sbom-generate — alpine + syft pinné via GitHub releases
ci/woodpecker/push/woodpecker Pipeline failed
anchore/syft:vX est distroless (pas de /bin/sh), incompatible avec
les commands Woodpecker. Retour sur alpine:3.20 avec téléchargement
direct du tarball v1.42.3 depuis GitHub releases (pas install.sh
qui tire latest).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:14:16 +01:00
syoul 77f5f44758 fix: sbom-generate — image anchore/syft officielle + versions pinnées
ci/woodpecker/push/woodpecker Pipeline failed
- anchore/syft:v1.42.3 (remplace alpine:3.20 + curl-install latest)
- aquasec/trivy:0.69.3 (remplace :latest)
- Source explicite docker:g1flux:latest pour éviter le bug
  d'auto-détection Syft dans un container Woodpecker

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:12:58 +01:00
syoul c54e76bb04 chore: ajouter .dockerignore pour accélérer le build Docker
ci/woodpecker/push/woodpecker Pipeline failed
Exclut node_modules, dist et docs du contexte de build.
Sans ce fichier, les 208 répertoires de node_modules étaient
transférés inutilement au démon Docker à chaque build.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:07:42 +01:00
syoul b7e8bade97 fix: bouton Clusters bottom-20 (au-dessus AnimationPlayer) + badge géo en blanc
ci/woodpecker/push/woodpecker Pipeline failed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 11:59:16 +01:00
syoul 64682ea773 fix: déplacer bouton Clusters en bas à gauche (évite zoom + AnimationPlayer)
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 11:56:09 +01:00
syoul 53b1e9b399 fix: remonter le bouton Clusters pour éviter chevauchement avec zoom Leaflet
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 11:53:44 +01:00
syoul c51bb251e3 feat: bouton toggle Clusters / Villes dans la vue Flux
ci/woodpecker/push/woodpecker Pipeline was successful
Permet de basculer entre la vue groupée (clustering glouton, défaut)
et la vue individuelle (une ville = un nœud). Le bouton est positionné
en bas à droite de la carte.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 11:49:06 +01:00
syoul 851dc46394 fix: corriger layout desktop — StatsPanel w-72 fixe, w-full dans drawer mobile
ci/woodpecker/push/woodpecker Pipeline was successful
Remplace w-full lg:w-72 h-full (qui cassait les écrans 640-1023px) par
un prop className : w-72 shrink-0 par défaut (desktop), w-full flex-1
min-h-0 dans le drawer mobile.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 11:44:23 +01:00
syoul 786bf30a7b feat: popup liste des villes + balance au clic sur un cluster
ci/woodpecker/push/woodpecker Pipeline was successful
Affiche un panneau flottant au clic sur un nœud : liste des villes
du cluster triées par |balance|, balance nette colorée (orange/teal).
Se ferme sur déplacement/zoom de la carte ou via ✕.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 11:36:20 +01:00
syoul 839acf8aa8 fix: libellé badge géo → "XX% Tx géoloc."
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 11:26:50 +01:00
syoul ffe09ea44a feat: afficher le % géolocalisé dans la barre de contrôles
ci/woodpecker/push/woodpecker Pipeline was successful
Ajoute un badge "XX% géo" à droite du bouton Flux/Heatmap dans
PeriodSelector, mis à jour à chaque frame d'animation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 11:24:03 +01:00
syoul 8e208d02ab chore: bump version to 1.2.0
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.2.0
2026-03-24 11:11:05 +01:00
syoul 16cebb6ec9 feat: adaptation mobile — drawer bottom + layout responsive
ci/woodpecker/push/woodpecker Pipeline was successful
Sur smartphone (< 640px) : panneau stats masqué par défaut, accessible
via un bottom drawer animé (bouton ☰). PeriodSelector passe en flex-wrap
avec padding tactile 44px. AnimationPlayer s'adapte à la largeur écran.
Badge ville focus affiché directement sur la carte en mode mobile.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 11:07:48 +01:00
syoul b6cb0af722 feat: clustering géographique des villes dans la vue Flux
ci/woodpecker/push/woodpecker Pipeline was successful
Regroupe les villes proches visuellement (CLUSTER_RADIUS = 38px) en un
seul nœud dont la couleur reflète la balance nette agrégée du groupe.
Affiche +N à l'intérieur des cercles multi-villes. Les arcs intra-cluster
sont ignorés. Le clustering se recalcule dynamiquement à chaque zoom/pan.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 01:20:00 +01:00
syoul 78b4762c88 feat: coloration des nœuds par balance nette (orange émetteur / vert récepteur)
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 00:55:08 +01:00
syoul 136571ed53 chore: bump version 1.1.0
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.1.0
2026-03-24 00:32:26 +01:00
syoul b884884a04 fix: heatmap overlay — masque les snapshots pendant zoom/pan, resync après
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 00:28:31 +01:00
syoul 97ff22027c feat: vue flux — arcs dirigés entre villes géolocalisées
ci/woodpecker/push/woodpecker Pipeline was successful
- Nouveau type TransactionArc + buildCorridors + computeFlowStats
- FlowMap : SVG overlay Leaflet, arcs bezier, flèches de direction, nœuds de villes cliquables
- Clic sur une ville : arcs sortants orange, entrants teal, reste grisé
- DataService : résolution géo des destinataires (toId) dans le même appel Cesium+
- useAnimation : expose visibleArcs filtré par frame
- PeriodSelector : bouton toggle Heatmap / Flux
- StatsPanel : stats flux (volume, top émetteurs, top récepteurs, balance nette)
- App : state viewMode + focusCity, FlowMap conditionnel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 00:21:03 +01:00
syoul ab72d8218b merge: sync main → dev (v1.0.0 + version display) 2026-03-24 00:08:32 +01:00
syoul 57c1888346 feat: affiche la version du build dans le header (v1.0.0)
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 00:03:48 +01:00
syoul 7ee3b09f0f release: v1.0.0
ci/woodpecker/push/woodpecker Pipeline was successful
2026-03-23 23:47:47 +01:00
syoul b9bcfa8518 feat: taux de géoloc réel par frame + DU + périodeSélecteur + autoplay anim
ci/woodpecker/push/woodpecker Pipeline was successful
- Affiche l'équivalent en DU pour le volume total et la moyenne par tx
- Taux de géolocalisation réel par frame d'animation (via allTimestamps)
- Sélecteur de période personnalisée inline à côté des boutons 24h/7j/30j
- Clic sur Animer lance la lecture automatique à vitesse ×1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.0.0
2026-03-23 23:41:59 +01:00
syoul 42286a8c0d fix: barre de géoloc toujours visible, basée sur la période complète
ci/woodpecker/push/woodpecker Pipeline was successful
En mode animation, globalGeoStats passe les chiffres de la période entière
(depuis stats global) pour que la barre affiche le vrai taux Cesium+.
Le label indique "(période)" pour rappeler que ce n'est pas par frame.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:33:37 +01:00
syoul ee5e401185 fix: masquer la barre de géolocalisation en mode animation
ci/woodpecker/push/woodpecker Pipeline was successful
En mode animation, visibleTransactions ne contient que les tx géolocalisées
→ geoCount/transactionCount = 100% systématiquement, ce qui est trompeur.
La couverture Cesium+ est une propriété du pipeline global, pas d'une frame.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:30:05 +01:00
syoul f29625c6bc feat: clic Animer démarre la lecture automatiquement en vitesse ×1
ci/woodpecker/push/woodpecker Pipeline was successful
- activate() appelle maintenant setSpeed(1) + setPlaying(true) en plus de setActive(true)
- L'effet de reset ne stoppe playing que lors d'une désactivation (active=false),
  pas lors d'une activation, pour ne pas annuler le setPlaying(true) ci-dessus

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:24:26 +01:00
syoul a2fdad46d4 feat: bouton Personnaliser pour période personnalisée (1–365 jours)
ci/woodpecker/push/woodpecker Pipeline was successful
Clic sur "Personnaliser" → champ inline focusé, pré-rempli si déjà custom.
Valider avec Entrée ou blur, annuler avec Échap. Plage 1–365 jours.
Le bouton affiche la valeur courante (ex. "14 jours") quand une période
custom est active, et reprend la surbrillance dorée comme les autres boutons.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:17:10 +01:00
syoul 45080d83ac feat: afficher l'équivalent DU pour le volume total et la moyenne de transaction
ci/woodpecker/push/woodpecker Pipeline was successful
- SubsquidAdapter : fetchCurrentUD() interroge universalDividends (fallback 11.78 Ğ1)
- DataService : getCurrentUD() avec cache 1h, inclus dans DataResult
- StatsPanel : formatDU() + affichage "≈ X DU" sous le volume total
  et "≈ X Ğ1 / tx · ≈ Y DU / tx" sous le compteur de transactions
- DU actuel Ğ1v2 : 11.78 Ğ1 (bloc 225874)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:13:00 +01:00
syoul bea7cbe60f fix: crossfade via deux img overlays — canvas jamais modifié
ci/woodpecker/push/woodpecker Pipeline was successful
Problème racine : modifier l'opacité du canvas Leaflet (qui vit dans un
pane GPU-composité) via CSS causait des désynchronisations non-déterministes.

Nouvelle approche :
- Canvas : jamais touché (opacité Leaflet par défaut)
- Deux <img> overlays se croisent : prev (sortant) et next (entrant)
- Après draw(), on attend le RAF interne de Leaflet, puis on capture
  le canvas via toDataURL() dans le next img
- currentSrcRef garde l'src courante pour initialiser prev au prochain tour

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:04:01 +01:00
syoul bc61527b4e fix: annuler les deux RAFs au cleanup pour éviter la double transition
ci/woodpecker/push/woodpecker Pipeline was successful
Le cleanup n'annulait que raf1. Si raf1 avait déjà tiré avant le cleanup React,
raf2 restait en queue et déclenchait une deuxième transition (l'aller-retour visible
à la fin de chaque frame). Fix : stocker raf2 dans la closure et l'annuler aussi.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:43:12 +01:00
syoul ac2f5bc431 fix: vrai crossfade simultané — canvas fade-in + overlay fade-out en même temps
ci/woodpecker/push/woodpecker Pipeline was successful
Avant : overlay se dissout mais le canvas apparaît instantanément en dessous.
Maintenant : canvas part à opacity 0, les deux transitions démarrent en même temps
→ ancienne frame fade out pendant que la nouvelle fade in simultanément.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:25:26 +01:00
syoul 2debc3587a fix: crossfade simplifié — canvas toujours visible, seul l'overlay se dissout
ci/woodpecker/push/woodpecker Pipeline was successful
Le canvas reste toujours à opacity 1. Quand les transactions changent :
1. Capture le canvas dans l'overlay img (snap à opacity 1 sans transition)
2. Met à jour le canvas en dessous
3. Double rAF pour laisser Leaflet.heat redessiner
4. Dissout l'overlay de 1→0 en 500ms via CSS transition

Élimine le double-affichage et les conflits de transition canvas/overlay.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:18:15 +01:00
syoul 8a31b60716 fix: éliminer le double affichage du crossfade
ci/woodpecker/push/woodpecker Pipeline was successful
Problème : void canvas.offsetWidth forçait un repaint avec canvas ET
overlay potentiellement visibles en même temps.

Fix : flusher uniquement l'overlay (void overlay.offsetWidth), puis
appliquer canvas=0 + overlay=1 dans le même batch de paint — Frame A
passe du canvas à l'overlay en un seul rendu sans doublon.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:07:34 +01:00
syoul a9bf445747 fix: force reflow avant reset des transitions CSS du crossfade
ci/woodpecker/push/woodpecker Pipeline was successful
Sans forcer un reflow, le browser ignore transition:none et applique
encore l'ancienne transition — causant un bug visuel sur la 1ère frame.
void canvas.offsetWidth flush les styles en attente.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:05:37 +01:00
syoul d7fef466f3 fix: vrai crossfade simultané — canvas masqué puis fade in+out en parallèle
ci/woodpecker/push/woodpecker Pipeline was successful
Canvas caché (opacity 0) avant update → overlay (frame A) fade out
et canvas (frame B) fade in simultanément sur 500ms.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:00:42 +01:00
syoul 14d218e4ff feat: vrai fondu enchaîné par overlay image sur le heatmap
ci/woodpecker/push/woodpecker Pipeline was successful
Principe : capture du canvas heatmap actuel dans une <img> superposée
(opacity 1), mise à jour immédiate du heatmap en dessous, puis
dissolution de l'overlay (opacity 0 en 500ms). Les deux frames
coexistent pendant la transition → vrai dissolve sans clignotement.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 21:55:51 +01:00
syoul d50b30666b feat: améliore le fondu enchaîné et recalibre les vitesses
ci/woodpecker/push/woodpecker Pipeline was successful
- Fondu : dip à 0.15 (au lieu de 0) pour un effet dissolve plutôt
  qu'un blink; ease-out 150ms / ease-in 200ms
- Délais : 1500ms base (×1=1.5s, ×2=750ms, ×4=375ms)
- Vitesse par défaut : ×2

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 21:52:44 +01:00
syoul 30057a07fb feat: fondu entre les frames de l'animation heatmap
ci/woodpecker/push/woodpecker Pipeline was successful
Fade out 250ms → mise à jour des données → fade in 250ms sur le canvas
Leaflet.heat. Aucun état React supplémentaire — manipulation directe
du canvas interne via _canvas.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 21:47:10 +01:00
syoul 40c09e2e4b feat: ajoute le jour de la semaine dans les labels demi-semaines
ci/woodpecker/push/woodpecker Pipeline was successful
Ex: "lun. 21 févr. – jeu. 24 févr."

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 21:43:13 +01:00
syoul 0aea929b48 feat: animation 30 jours en demi-semaines (3.5j, ~9 frames)
ci/woodpecker/push/woodpecker Pipeline was successful
Remplace les frames hebdomadaires (5 frames) par des demi-semaines
(3.5 jours, ~9-10 frames) pour une animation plus fluide sur 30 jours.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 21:40:48 +01:00
syoul d4cc4fbd3a fix: accepter city/title null dans le schéma Zod Cesium+
ci/woodpecker/push/woodpecker Pipeline was successful
Un profil Cesium+ (clé 2QsNk...) a city:null. La contrainte
.string().optional() accepte undefined mais pas null → ZodError
silencieux dans resolveGeoByKeys → geoMap vide → 0 transactions
affichées en mode 30 jours.

Correction : .string().nullable().optional() pour title et city.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 21:36:47 +01:00
syoul bf2dbd6d35 fix: accepter blockNumber négatif dans le schéma Zod Subsquid
ci/woodpecker/push/woodpecker Pipeline was successful
Les transferts Ğ1v1 migrés (avant le 7 mars 2026) ont des blockNumber
négatifs dans l'indexeur Subsquid. La contrainte .positive() provoquait
un ZodError silencieux qui abandonnait le fetch 30 jours et conservait
les données 7 jours en mémoire — d'où les frames vides en animation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 21:30:00 +01:00
syoul 2fce063703 fix: limite dynamique pour fetchTransfers selon la période
ci/woodpecker/push/woodpecker Pipeline was successful
Hardcoder limit=2000 ne couvrait que ~5 jours (400 tx/jour × 5 = 2000).
La limite est maintenant calculée : max(2000, periodDays × 600).
- 1j  → 2000  (inchangé)
- 7j  → 4200
- 30j → 18000  (couvre ~45 jours de marge)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 20:46:49 +01:00