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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
- 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>
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>
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>
- 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>
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>
- 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>
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>
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>
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>
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>
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>
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>
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>
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>
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>