Steven
Steven7 min leestijd

Eén CSS-variabele, vijf reviewrondes en een Swift-toolchain die loog

GeekBye v2.0.7 maakte de hele overlay instelbaar doorschijnend — wat klinkt als een eenregelige CSS-wijziging en dat absoluut niet was. Het echte verhaal is wat de code review betrapte: twee oppervlakken die weigerden te vervagen, een opnamebalk die er verkeerd uitzag bij dezelfde opacity, en een gecompileerde binary die 672 bytes heen en weer sprong omdat onze eigen docs een reviewer de verkeerde Swift-versie vertelden.

Engineering
Design
Build
GeekBye Releases
Eén CSS-variabele, vijf reviewrondes en een Swift-toolchain die loog

"Maak de overlay doorschijnend" is het soort taak dat klinkt als een schuifregelaar en een CSS opacity-eigenschap. GeekBye v2.0.7 leverde precies die uitkomst voor de gebruiker — één instelbare "light mode" waarmee je door de panelen van de assistent heen kunt kijken naar wat er achter zit. Maar het interessante aan deze release is niet de feature. Het zijn de vijf reviewrondes die nodig waren om het goed te krijgen, en een oorlogsverhaal over een gecompileerde binary die van grootte veranderde omdat onze eigen documentatie tegen een reviewer loog.

De juiste manier om een hele UI doorschijnend te maken

De naïeve versie hiervan is een opacity-waarde uitstrooien over elke paneelcomponent en het klaar noemen. Dat is een onderhoudsval: een dozijn hardgecodeerde waarden die uit elkaar gaan lopen op het moment dat iemand er één aanraakt.

In plaats daarvan gebruikt v2.0.7 één gedeelde CSS-utility en een per-oppervlak token. Er is één enkele overlay-surface-class die de achtergrond van een paneel berekent uit twee custom properties: een basis-opacity die elk oppervlak voor zichzelf declareert (de bedieningsbalk, chat, transcriptbubbels, codeblokken enzovoort kiezen elk hun eigen waarde), en een globale alpha-vermenigvuldiger die op de overlay-root meerijdt en de schuifregelaarinstelling van de gebruiker vertegenwoordigt. Elk oppervlak leest dezelfde vermenigvuldiger; elk behoudt zijn eigen karakter. Cruciaal is dat alleen de paneelachtergrond schaalt — tekst, iconen en de backdrop-blur blijven volledig gerenderd, zodat "doorschijnend" nooit "onleesbaar" betekent.

Twee beslissingen in dat ontwerp zijn het benoemen waard omdat ze het verschil zijn tussen een feature die helpt en een die supporttickets genereert:

  • De standaardwaarde is volledig ondoorzichtig. De opacity-instelling wordt op 100% geleverd — een no-op. Niemands overlay werd bij een update opeens doorzichtig; de doorschijnendheid is er wanneer je ernaar reikt en onzichtbaar tot dan.
  • De instelling wordt defensief gevalideerd. Er is één bron van waarheid voor het minimum, maximum, de standaardwaarde en de stap, en een normalizer die het lege/ontbrekende geval afdekt. Dat is van belang vanwege een JavaScript-voetzoeker: Number(null) is 0, dus een ontbrekende instelling die naïef wordt gecoerceerd zou de overlay naar zijn meest transparante staat laten schieten in plaats van naar zijn standaardwaarde. De normalizer vangt dat op voordat het kan gebeuren.

Sleep de schuifregelaar en de hele overlay hertint live, midden in een opname, want elk oppervlak is geabonneerd op dezelfde instelling. Geen herstart, geen herladen.

Wat de review betrapte (en een test op één monitor nooit zou)

Hier hield "één CSS-variabele" op simpel te zijn. Drie bugs kwamen boven in review, en twee ervan zijn dezelfde les met een andere hoed op.

Een paneel dat niet wilde vervagen. De overlay met sneltoetsen bleef koppig solide terwijl al het andere doorschijnend werd. De oorzaak: het rendert buiten de DOM-subtree die de opacity-variabele draagt, dus het erfde de waarde die van de overlay-root naar beneden cascadeerde nooit. CSS custom properties erven door de DOM-boom heen — en als een node niet daadwerkelijk een afstammeling is van waar je de variabele instelt, krijgt hij stilletjes niets. De fix was om de variabele ook lokaal op dat paneel in te stellen.

Een hovertint die verdween. De Fn/Assist-knoppen verloren hun cyaan hoverglow. De doorschijnendheids-utility zette de achtergrond met !important (het moet winnen van de oppervlaktestandaarden), en dat walste over de hover:-achtergrondtint op hetzelfde element. Specificiteitsbotsing. De fix was om de hovertint even nadrukkelijk te maken zodat hij bij hover kon terugwinnen.

Beide zijn dezelfde onderliggende waarheid: een CSS-variabele-cascade is een echte correctheidsgrens, geen stylingdetail. Overerving en specificiteit bepalen of je waarde het element überhaupt bereikt, en geen van beide duikt op in een screenshot totdat het fout is.

Dezelfde opacity, andere look. De subtielste: de opnamebalk en de rustbalk waren op identieke basis-opacity ingesteld, en zagen er toch zichtbaar anders uit. Waarom? De opnamepil gebruikte een zwaardere backdrop-blur, en een sterke blur over een donkere achtergrond middelt naar een donkerder resultaat — dus gelijke alpha leverde een ongelijk uiterlijk op. Hij had ook een vage rand waar de rustbalk een heldere gradient-ring-rand had. De fix stemde het blurniveau en de ring op elkaar af. De les bleef hangen: gelijke alpha is geen gelijk uiterlijk zodra blur in het spel komt. Doorschijnendheid is een systeem van op elkaar inwerkende effecten, geen enkel getal.

De binary die van grootte veranderde omdat de docs logen

Nu het oorlogsverhaal, en het is mijn favoriete soort — die waarin de tooling en de docs het oneens zijn en een zorgvuldige reviewer in het kruisvuur belandt.

GeekBye levert een aantal voorgecompileerde Swift-binaries (native helpers voor dingen als meetingdetectie). Omdat een gecompileerde binary in de repo wordt gecheckt, moet elke ontwikkelaar hem compileren met exact dezelfde Swift-versie — verschillende toolchains produceren verschillende bytes uit identieke broncode, en dat zou elke keer dat iemand herbouwt een spookachtig git-conflict betekenen. Dus er is een script dat één specifieke versie afdwingt: Swift 6.3.x, gecontroleerd bij het builden.

Tijdens de review van deze release merkte een reviewer op dat een binary opnieuw gebouwd zou moeten worden om te matchen met "de door de repo verplichte toolchain." De ontwikkelaar deed precies dat — en de grootte van de binary veranderde van 89,184 bytes naar 88,512. De commit-boodschap zei zelfs dat het "byte-stabiele output herstelde" door te herbouwen met Swift 6.2.1, "de door de repo verplichte toolchain."

Behalve dat 6.2.1 de verkeerde versie was. Het build-handhavingsscript vereiste 6.3.x. Het probleem was dat de prozadocumentatie — de README en de bijdragersgids — op een paar plekken nog steeds 6.2.1 zei. Dus een plichtsgetrouwe reviewer en een plichtsgetrouwe ontwikkelaar, beiden proberend het juiste te doen, volgden de docs recht naar het committen van precies het artefact dat het handhavingsscript bestaat om te weigeren. Een 6.2.1-binary in een 6.3.x-repo is precies de drift die de schone herbouw van elke andere ontwikkelaar zou breken.

De volgende commit repareerde het — en de fix is waar het om gaat. Hij bouwde niet alleen de binary terug naar zijn 6.3.x-vorm (grootte hersteld naar 89,184, precies waar hij begon). Hij corrigeerde ook de verouderde "6.2.1"-verwijzingen in de docs zodat de val niet opnieuw kon worden dichtgeklapt. De binary sprong 672 bytes heen en terug over twee commits, en de echte bug was nooit de binary. Het was dat twee bronnen van waarheid — het handhavingsscript en de geschreven docs — het oneens waren, en een mens de verkeerde vertrouwde.

Drie dingen die deze release leerde

  1. Een CSS-variabele-cascade is een correctheidsgrens. Twee van de drie reviewbugs kwamen neer op een variabele die niet erfde en een !important die een hover-state overreed. Als een waarde een element moet bereiken via overerving of moet winnen via specificiteit, dan is dat pad logica — verifieer het als logica, niet als styling.
  2. Gelijke parameters kunnen ongelijke resultaten opleveren. De opnamebalk en de rustbalk deelden een opacity en zagen er toch anders uit omdat een andere blur de uitkomst veranderde. Wanneer je een visueel systeem op één getal verenigt, controleer dan of de andere variabelen rond elk oppervlak niet stilletjes veranderen wat dat getal betekent.
  3. Wanneer docs en handhaving het oneens zijn, repareer de onenigheid — niet alleen het symptoom. De bug was geen slechte binary; het was een doc die de verkeerde toolchain noemde en een handhavingsscript dat iets anders zei. De binary herbouwen behandelt het symptoom. Elke bron van waarheid het eens laten worden is de echte fix, want de volgende reviewer zal de docs ook vertrouwen.

GeekBye v2.0.7 leverde de uniforme doorschijnendheid, alle randgevallen gereviewd en de toolchain-docs rechtgezet. Het is de laatste van de "stille vakmanschap"-releases voor de betrouwbaarheidssprint die volgde. Voor het fundament eronder, zie wat een versie 2 echt kost (v2.0.0); voor de zusterrelease vol polijstwerk, kalme software: de flikkerfix en de antwoordmodus-chip (v2.0.3 + v2.0.5); en voor hoe de overlay verborgen blijft tijdens een gesprek, hoe je onzichtbaar blijft tijdens schermdelen.