- Nouveau commentParser.ts : ~80 règles regex multilingues, 11 catégories
- SubsquidAdapter : fetch du champ comment.remark depuis SubSquid
- Transaction et TransactionArc : champs comment et category
- StatsPanel : section Nature des échanges avec barres cliquables (détail inline)
- FlowMap : tooltip au survol des arcs avec répartition catégories + commentaires
- InfoPanel mis à jour
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Dots de statut en temps réel dans le StatsPanel (ok/slow/error + latence)
- Bannière d'alerte si un service est inaccessible
- EndpointPopover : sélection parmi nœuds connus, test de latence live, URL custom
- Rechargement automatique des données après changement d'endpoint
- SubsquidAdapter et CesiumAdapter lisent l'URL active depuis EndpointConfig
- InfoPanel mis à jour (overlay DU + statut des services)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bouton DU (gauche carte) : affiche en overlay des cercles verts
proportionnels au nombre de membres WoT actifs géolocalisés par ville.
Chargement à la demande, mis en cache 1h.
Pipeline :
SubsquidAdapter.fetchActiveMemberKeys() → isMember:true (~7000)
CesiumAdapter.resolveGeoByKeysBatched() → lots de 500 clés
DataService.fetchMemberCities() → agrégation + cache 1h
HeatMap → CircleMarkers Leaflet en overlay
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
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>
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>
- 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>
- 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>
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>
- Extrait le pays depuis le champ city Cesium+ en priorité (ex: "Heusy, 4800, Belgique" → BE)
- Bounding boxes réordonnées : petits pays (LU, BE, CH, NL) avant FR pour éviter les faux positifs
- Affiche l'heure du dernier refresh sur le badge live
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add .catch() so failed background fetches don't silently break the interval
- Add refreshing state with a spinning ↻ on the live badge during background updates
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Au lieu de chercher par nom (title), on résout maintenant par clé :
1. buildIdentityKeyMap() : charge toutes les identités Ğ1v2 depuis Subsquid
avec leur ownerKeyChange → currentSS58 → genesisKey → duniterKey
2. ss58ToDuniterKey() : conversion SS58 v2 (préfixe 2 octets) → base58 Ed25519
= _id Cesium+ (même matériau cryptographique, encodage différent)
3. resolveGeoByKeys() : query Cesium+ par ids{} → résultat exact, pas d'ambiguïté
4. Cache keyMap 10 min : 1 requête Subsquid pour ~8000 identités, pas par refresh
Résultat : les membres migrés v1→v2 avec un profil Cesium+ sont correctement
géolocalisés même si leur nom v2 diffère de leur nom v1.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>