Commit Graph

29 Commits

Author SHA1 Message Date
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 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 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>
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 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 7975abc619 feat: animation temporelle des flux Ğ1
ci/woodpecker/push/woodpecker Pipeline was successful
Nouveau mode animation accessible via "▶ Animer" dans le sélecteur de période.
- useAnimation : hook gérant frames, lecture, vitesse, filtrage client
- AnimationPlayer : barre de contrôle (play/pause, slider, ×1/×2/×4)
- Granularité auto : 24 frames/h (24h), 7 frames/jour (7j), ~4 frames/semaine (30j)
- Stats et heatmap mis à jour sur la fenêtre courante, zéro requête réseau supplémentaire

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 20:29:25 +01:00
syoul 03f63aec46 feat: ajoute un descriptif de l'application dans le panneau latéral
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 20:09:08 +01:00
syoul ec06c4e35c style: footer dépôt et licence en jaune Ğ1
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 19:56:24 +01:00
syoul aa1f3d5f2f feat: ajoute dépôt et licence AGPLv3 dans le footer
ci/woodpecker/push/woodpecker Pipeline was successful
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 19:53:27 +01:00
syoul d99ad3707d fix: show full city name with postal code and country in top villes
Restore full Cesium+ city field (including postal code), restructure
the city card so name wraps on two lines with country badge + tx count
+ volume all readable without truncation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 18:55:37 +01:00
syoul 55d2b50cd3 fix: replace emoji flags with text badges, clean city names from postal codes
Emoji flags render as boxes on Linux. Replace with a small FR/BE/CH
badge. Also strip postal codes from Cesium+ city names (e.g.
"Saint-Jean-de-Laur, 46260" → "Saint-Jean-de-Laur").

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 18:53:42 +01:00
syoul 8d9a9a3c07 feat: show country flag next to city names in top villes
Determine country from geoPoint coordinates using bounding boxes
for the main Ğ1 community countries (FR, BE, CH, ES, DE, IT, ...).
Display the emoji flag before each city name in the top villes panel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 18:52:00 +01:00
syoul a8792641ab feat: show up/down delta indicators on stats after each refresh
Volume total, transaction count, and top city volumes now display
↑ (green) or ↓ (red) arrows compared to the previous refresh,
making it visible that data is actually updating.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 18:47:53 +01:00
syoul c6cb990b40 chore: rename app from ĞéoFlux to Ğ1Flux
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 18:18:32 +01:00
syoul 93daec7631 fix: géolocalisation Cesium+ et tests déterministes
- CesiumAdapter : utilise le champ `title` (analysé ES) au lieu de `title.keyword`
  qui retournait 0 résultats ; coerce lat/lon en number (certains profils stockent des strings)
- DataService : sépare totalVolume (all tx blockchain) de geoCount (tx heatmap)
- StatsPanel : barre de couverture géo uniquement en mode live
- App : badge source "● live Ğ1v2" ou "○ mock"
- DataService.test.ts : mock SubsquidAdapter + CesiumAdapter directement (vi.mock hoistés)
  pour que les tests soient déterministes quel que soit VITE_USE_LIVE_API dans .env.local
- tsconfig.app.json : exclude src/test pour éviter les erreurs de build prod

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 16:32:23 +01:00
syoul d20d042bca feat: initialisation de ĞéoFlux — visualisation géographique Ğ1
- Carte Leaflet plein écran avec heatmap (OpenStreetMap, dark mode)
- Sélecteur de période 24h / 7j / 30j
- Panneau latéral : volume total, compteur de transactions, top 3 villes
- mockData.ts : 2 400 transactions simulées sur 24 villes FR/EU
- DataService.ts : abstraction prête pour branchement Subsquid/Ğ1v2
- Schémas Zod (g1.schema.ts) : validation runtime Duniter GVA + Cesium+
- Adaptateurs DuniterAdapter et CesiumAdapter (Ğ1v1, à migrer v2)
- Suite de tests Vitest : 43 tests, conformité schéma Ğ1 vérifiée

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