- Raccourcis clavier : ←/→ (frames), Espace (play/pause), Échap
(quitter animation/fermer info), H (basculer heatmap↔flux)
- URL partageable : ?period=7&view=flow&city=Paris — état restauré
au chargement et mis à jour sans rechargement (history.replaceState)
- Sparkline : mini bar-chart SVG dans le StatsPanel montrant l'activité
sur la période (données déjà en mémoire, aucune requête)
- Recherche identité : champ flottant (⌕) acceptant un nom Ğ1 ou une
clé g1…, résout via Subsquid + Cesium+, bascule en vue flux et
met la ville en focus
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pour les fromId/toId absents du keyMap WoT, applique ss58ToDuniterKey
directement pour tenter un lookup Cesium+. Les non-membres ayant un
profil géolocalisé (ex: comptes portefeuille avec ville renseignée)
apparaissent désormais dans le flux animé.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sur mobile réel, la police forcée à 16px fait wrapper les contrôles
AnimationPlayer en 2 lignes (~165px). bottom-44 (176px) sur mobile,
bottom-24 (96px) sur sm+ où les contrôles ne wrappent pas.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>