
At redesigne dashboardet omkring ét enkelt bølgediagram
GeekBye v1.8.2 forvandlede dashboardet fra en fjernbetjening til optagelse til en kun læsbar analysevisning — en statistikrække og et bølgediagram over 7 dage. Begge de karakteristiske elementer var andet-udkast, shippet inden for tyve minutter efter deres første udkast, samme eftermiddag.
Nogle releaser tilføjer en feature. GeekBye v1.8.2 fjernede mest én — og fjernelsen er historien. På en enkelt eftermiddag i februar 2026 forvandlede atten commits dashboardets forside fra en fjernbetjening til optagelse til en kun læsbar analysevisning: fire statistiktal og ét aktivitetsdiagram. Undervejs shippede den et søjlediagram, der levede toogtyve minutter, et gitter af statistikkort, der levede tyve, og en håndlavet SVG-bølge, der erstattede begge. Hele søgningen er bevaret i commit-tidsstemplerne, hvilket er den bedste slags designdokumentation, der findes.
Dashboardet holdt op med at være en fjernbetjening
Før denne release var dashboardets forside et kontrolpanel. Den lagde ud med et hero-kort — en stor optagewidget med et LIVE-mærke, Pause/Resume/Stop-knapper, gradientklatter og et useSessionState-hook, der forbandt det hele med optageren. Dashboardet forsøgte at være to ting på én gang: stedet, hvor du kigger på dine møder, og stedet, hvor du styrer optageren. To produkter, én skærm, i stille konkurrence.
v1.8.2 valgte én. Den slettede hero-kortet og useSessionState-forbindelsen — inklusive en effekt, der automatisk navigerede dig til et mødes detaljeside i samme øjeblik en session sluttede, hvilket er præcis den slags "hjælpsomme" spring, der overrasker folk midt i flowet. At starte og skjule optageren flyttede ud til en simpel kontakt i navbaren (en ombygget knap, der tabte omkring hundrede linjer, da den gik fra sessionscontroller til tænd/sluk-kontakt), understøttet af et nyt navbar:hide-IPC-handler. Tilbage stod et dashboard, der gør én ting: viser dig, hvad du har optaget. Kun læsbar. Roligt.
Der er en lille, menneskelig bug i den overgang værd at fremhæve, for det er lige netop den slags, et redesign stille indfører, og et godt øje fanger samme time. De to nye sidebjælkeknapper — Start og Hide — blev shippet med det samme generiske gitterikon, så de var visuelt identiske. Tolv minutter senere gav en opfølgende commit Start et play-ikon, gav Hide et øje-fra-ikon og tonede Hide ravgul, så "få appen til at forsvinde" læses som en bevidst handling snarere end en neutral tvilling til "start". Ikoner er tekst. To knapper, der ser ens ud, siger det samme, og disse betød ikke det samme.
Søjlediagrammet, der levede toogtyve minutter
Her er den del, jeg elsker, og den er fuldt læsbar fra git-loggen. Klokken 16:29:34 landede redesignets første udkast: et aktivitetsdiagram over 7 dage tegnet som søjler — animerede kolonner, en minimumshøjde, så bittesmå dage forblev synlige, en 2-pixel dæmpet stump for nul-dage. Fornuftigt. Konventionelt. Den slags diagram man rækker ud efter uden at tænke.
Klokken 16:51:21 — toogtyve minutter senere — blev det slettet. Erstatningscommiten siger præcis, hvad den gjorde: "replace bar chart with smooth wave area chart for 7-day activity." Og klokken 16:52:21, ét minut efter, skrællede en anden commit det afrundede kort og kanten væk rundt om bølgen, "for cleaner look."
Hvorfor? Commits siger kun hvad der ændrede sig, så hvorfor er en fortolkning — men dataenes form gør det åbenlyst. Det her er et værktøj, hvor en typisk bruger har nul, ét eller to møder på en given dag. Syv søjler, de fleste 2 pixel høje, ser næsten tomme og spredte ud. De samme syv tal tegnet som et sammenhængende udfyldt areal ligner en tendens — en blid bølge, der stiger, hvor ugen var travl. Intet blev forfalsket; y-værdierne er identiske. Redesignet valgte simpelthen den kodning, der lader tynde, ærlige data læses som en form i stedet for som fravær.
Statistikken fik samme behandling på samme ur. Det første udkast (16:29) satte fire tal i et 2×4-gitter af kort. Klokken 16:49 kollapsede gitteret til én inline statistikrække — én indrammet række med hårfine skilletegn, mindre skrift, én container i stedet for fire. Fem kasser på skærmen (fire kort plus et diagramkort) blev til to (en række og en bølge). Den næste PR tilføjede endnu et ærligt strøg: etiketten "Total Time" blev til "Time in Meetings", fordi total-af-hvad var et rimeligt spørgsmål, som ingen burde skulle stille.
Tyve minutter, fra første udkast til endelig, alt sammen inden for én pull request. Hvis de var blevet mast sammen til én "redesign dashboard"-commit, ville søgningen være usynlig. Fordi de ikke var det, kan du se en designer konvergere i realtid.
Bølgen, mekanisk
Der er intet diagrambibliotek her. Bølgen er en inline-SVG bygget i JSX, og den er et kig værd, fordi den er en lille, ærlig opskrift, du kan snuppe til enhver sparkline.
Udjævningen er tricket. For hvert par af nabopunkter bruger stien et kubisk Bézier-segment, hvis to kontrolpunkter sidder i det horisontale midtpunkt mellem dem — cpx = (prev.x + curr.x) / 2 — med kontrolpunkterne holdt i hver endes egen højde. Det er den klassiske flad-tangent-udjævning: kurven glider blødt gennem hvert datapunkt uden nogensinde at skyde over den højeste eller under den laveste værdi, hvilket en naiv Catmull-Rom-spline ville gøre. For et diagram om antal møder er "tegn aldrig en bule, der antyder en værdi, der ikke skete" ikke en finesse; det er korrekthed. Det udfyldte areal er den samme kurve lukket langs bunden og malet med en vertikal gradient (cyan, der falmer fra 30 % til næsten ingenting), og linjen tegner sig selv ind fra venstre mod højre med en framer-motion pathLength-animation.
Under SVG-en ligger data-rørføringen, og den er den stille helt. En ny getAggregateStats()-metode på transkript-repositoryet kører tre forberedte statements mod den lokale SQLite-tabel transcript_sessions: totaler for al tid (antal, summeret varighed, gennemsnitlig varighed), en rullende syvdages-optælling og en GROUP BY date(created_at)-spand per dag. Så — og det er detaljen, der gør diagrammet robust — går en lille JavaScript-løkke gennem de seneste syv kalenderdage og genudfylder hver dag, forespørgslen ikke returnerede, ved at skubbe et nul ind. Diagrammet får derfor garanteret præcis syv punkter, altid.
Den garanti er det, der får kanttilfældene til at forsvinde i stedet for at kræve vagter spredt gennem visningen. En tom uge? Syv nuller, og et Math.max(count, 1) på nævneren holder linjen flad i bunden i stedet for at dividere med nul. Et enkelt datapunkt, der ville få x-afstandsformlen i / (n − 1) til at give NaN? Kan ikke ske — repositoryet udsender aldrig færre end syv. Ugedagsetiketterne parser endda hver spand ved T12:00:00 snarere end nøgen midnat, så en YYYY-MM-DD-streng ikke glider til den foregående dag i en negativ UTC-tidszone. Fiks dataenes form ved kilden, og renderingskoden får lov at være naiv med vilje.
Alt bliver på maskinen. Statistikforespørgslen læser den lokale database, returnerer gennem en typet transcript:get-stats-IPC-kanal og animeres ind i fire optællende tal ved montering. Intet om din mødehistorik forlader laptoppen for at tegne dette diagram — hvilket, for et værktøj, der optager dine samtaler, er den eneste acceptable måde at bygge en analysevisning på.
Endnu en bug, for redesigns trækker dem frem i lyset
Pakket ind i samme release var et fix, der intet havde med dashboardet at gøre og alt at gøre med den slags gæld, et redesign snubler over. Appens mørke scrollbar-styling var drevet ud i to konkurrerende CSS-definitioner af den samme klasse — en ældre lilla og en nyere hvid-på-mørk — og hvilken der vandt, afhang af kaskaderækkefølgen. Værre, kun elementer, der huskede at tilføje klassen, blev overhovedet stylet; alt andet faldt tilbage på den lyse standard-scrollbar, og horisontale scrollbars blev aldrig stylet, fordi de gamle regler kun satte en bredde, aldrig en højde. Fixet slettede begge definitioner, stylede scrollbaren globalt på hvert element og fjernede den nu døde klasse fra de ti komponenter, der havde båret den. Det er en toliniers diff gentaget ti gange — den uglamourøse skat for at have stylet den samme ting to gange og ladet begge overleve.
Tre ting denne release lærte os
- Træk fra for at fokusere. Dashboardet blev bedre af at gøre mindre — ved at miste optagekontrollerne, det aldrig havde brug for, og blive én klar ting. En skærm, der både er en viewer og en fjernbetjening, er to halve produkter; vælg én og flyt den anden derhen, hvor den hører til.
- Vælg den kodning, dine data fortjener. Tynde tal læses som fravær i søjler og som en tendens i et area chart, ud fra identiske tal. Det er ikke spin — det er at vælge den ærlige form, der lader ægte, tynde data kommunicere.
- Garantér dataenes form opstrøms. Genudfyld-til-syv-løkken er grunden til, at diagramkoden ikke har spredte null-tjek: division med nul, NaN ved ét enkelt punkt og manglende dage forsvinder alle sammen, fordi forespørgslen lover præcis syv spande. Robust rendering starter ét lag længere nede.
For det forrige kapitel i v1-historien, fire releaser på seksogtyve timer (v1.7.6–v1.8.1); og for hele buen, anatomien i at shippe software til perfektion.