Steven
Steven6 perc olvasás

A login oldal MAGA a demó

A GeekBye v1.7.5 termék-screenshotot tett a login oldalra, majd még aznap törölte — és valódi komponensekből építette újra. Ráadásként: a felhasználó, aki gyorsabb volt az OCR-nél, és hogy néz ki valójában 25 style commit egyetlen nap alatt.

Mérnöki munka
Design
UX
GeekBye kiadások
A login oldal MAGA a demó

A GeekBye v1.7.5 egyhetes kiadás kettős személyiséggel: 37 commit, ebből 28 a login oldal újratervezése — és ezek közül 25 style(login) mikro-finomítás, mind egyetlen napon landolt. Ez az a kiadás is, amely a kódbázis egyik legtanulságosabb versenyhelyzetét javította. Mindkét történetet érdemes elmesélni, és ugyanabban a gondolatban találkoznak: a login oldal az első dolog, amit egy be nem jelentkezett felhasználó lát, úgyhogy jobb, ha maga a termék, nem pedig egy kép róla.

Egy screenshot, körülbelül öt órán át

Az újratervezés konvencionálisan indult. Átszervezés két oszlopra, a bejelentkezés balra, a termék bemutatása jobbra — képként. A késő délelőtti commitok pontosan ezt teszik: 11:57-kor egy valódi előnézeti screenshot landol a repóban, egy 114 KB-os PNG, amelyet hat perccel később egyszer frissítettünk.

17:04-kor már nem volt sehol. A fordulat-commit a statikus képet 344 sornyi valódi komponensre cseréli — egy LoginDemo panelre, amely nyolc kis darabból áll össze, és a tényleges overlay UI-t másolja le: a felvétel navigációs pillje a pulzáló EQ-sávjaival és stop gombjával, a chat panel a Chat/Transcript fülekkel, egy lerenderelt asszisztensi válasz (találóan épp a React useEffect-jét magyarázza), a „Tell me more / Simplify / Show example" (mondj többet / egyszerűsítsd / mutass példát) gyorsműveletek, az élő promptok sora, és a ⌘⏎ Assist beviteli mező.

Legyünk pontosak a „demó" szóval, mert könnyű túlígérni: a gomboknak valódi hover state-jeik vannak — ragyogások, csillanások, átmenetek —, de semmi nincs kattintásra bekötve, és a beviteli mező read-only. Nem sandbox. Ami viszont: a termék tényleges UI-szókincse, élőben renderelve: ugyanaz a logó-asset, ugyanaz a gradient-border és backdrop-blur kezelés, ugyanaz a productName import, amit a white-label rendszer használ — így a demó automatikusan átbrandeli magát minden termékhez, amely ebből a kódbázisból épül. Egy screenshot ebből semmire sem képes. Egy screenshot már a készítése napján elavult, a rossz kijelzőn elmosódott, és örökre annak a terméknek a brandjét viseli, amelyiket épp lencsevégre kaptad. A komponensek minden DPI-n élesek, mindig naprakészek, és minden brandhez helyesek — mert nem a design systemről készült kép, hanem ők maguk a design system.

A törölt PNG egyébként a release tagnél még mindig a repóban van — elárvultan, semmi sem hivatkozik rá. Minden kódbázis hordoz néhány kövületet a vesztes megközelítésből.

Hogy néz ki 25 style commit egy nap alatt

Annak az egyetlen napnak a commit logja egy designer vázlatfüzete, szokatlan őszinteséggel megőrizve. Az oszlopok aránya 40/60 volt, aztán 45/55. Egy „Works with" (ezekkel működik) felirat a platform-logók fölé délben került be, át lett pozicionálva, majd el lett távolítva — körülbelül fél napot élt. Maga a platform-logó sor (Google Meet, Teams, Zoom, Slack, Webex), amely délelőtt 10:59-kor került be, aznap este 22:08-kor teljes egészében törölve lett. A footer pedig négyfelvonásos szágát igényelt az igazításhoz: egyetlen wrapper konténer, aztán a középre igazító osztályok eltávolítása, aztán flexbox-középre igazítás, aztán egyszerűen csak közelebb tolás az aljához.

Könnyű lenne ezt kapkodásnak olvasni. Mi a designmunka tényleges alakjának olvassuk: úgy konvergálsz, hogy renderelsz, ránézel és igazítasz — és ha ezt 25 kis commitban teszed egyetlen squashelt „redesign login page" helyett, akkor maga a keresés is rögzítve marad. Amikor valaki megkérdezi: „nem próbáltunk mi egyszer egy logósort?", a válasz ott van a historyban, időbélyegekkel.

A felhasználó, aki gyorsabb volt az OCR-nél

A kiadás mérnöki története öt nappal korábban játszódott, egy háromcommitos javítási láncban. A v1.5.12 óta a Cmd+H lenyomása azonnali visszajelzéssel állítja sorba a screenshotot: a bélyegkép rögtön megjelenik a sorban, a szövegkinyerés — helyi Apple Vision OCR, nagyjából ~1-2 másodperc — pedig a háttérben fut. A sor-esemény szó szerint ocrText: ''-vel megy ki, és egy komment ígéri, hogy később kitöltődik.

Ez jó optimalizáció, és versenyhelyzetet szült. Egy gyors felhasználó lenyomja a Cmd+H-t, és azonnal elküldi a kérdését. A screenshot szövegmezője még üres. A kérés képernyőtartalom nélkül megy ki, a modell pedig — őszintén, dühítően — azt válaszolja: „I cannot see images" (nem látok képeket). A naiv útvonal nem hibával bukott el; helyes válasszal bukott el a rossz kérdésre, ami a legzavarbaejtőbb mód, ahogyan szoftver elbukhat.

A javítás azon az async munkán zárja le a küldési utat, amit az optimalizáció elhalasztott: ha bármely sorban álló screenshotnak még üres az OCR-szövege, a kérés parkolópályára kerül, és a UI egy „Reading screen..." (képernyő olvasása...) jelzőt mutat; egy useEffect abban a pillanatban elsül, amikor a szöveg megérkezik, és a teljes kinyert tartalommal küldi el a kérést. A diffben két React-specifikus részletet érdemes ellopni: a screenshot-sor egy render közben szinkronizált refbe van tükrözve, mert az eseménykezelők closure-lánca elavult state-et fogott be; a parkoltatott kérés pedig közvetlenül megy ki, nem az általános sorba állított kéréseket kezelő hookon át — ugyanabból a stale-closure okból.

És van egy becsületes bibi, magába a commit-üzenetbe rögzítve: az ennek a versenyhelyzetnek a levadászásához hozzáadott tracing logok egy második, backend-oldali bugot fedtek fel — a prompt-összeállítás az egyik kódúton teljesen eldobta a screenshot szövegét. Egy tünet, két bug, úgy megtalálva, hogy az egész láncot műszereztük fel, és néztük, hol tűnik el a szöveg. A lánc egy termékdöntéssel zárult, kilenc perccel a versenyhelyzet javítása után: a Cmd+H kötegelt elemzéshez állítja sorba a screenshotokat, míg a Cmd+Enter mindig friss képet készít az aktuális képernyőről — két külön munkafolyamat egyetlen kétértelmű helyett. (Hogy a Cmd+Enter Assistje valójában mit csinál, az külön cikk: azonnali AI-segítség bármihez, amit épp nézel.)

Egy apró kóda ugyanabból a hétből, a white-label fejezet olvasóinak: a Product/version (platform) User-Agent dev módra kapott javítást, mert az app.getVersion() csomagolatlan Electronban az Electron verzióját adja vissza, nem a termékét. Az identitás-stringek, mint mindig, a csövekben szivárognak.

Három dolog, amit ez a kiadás tanított nekünk

  1. Rendereld a terméket, ne fényképezd. A valódi komponensekből épített login-oldali demó automatikusan átbrandeli magát, túlél minden kijelzősűrűséget, és nem tud elavulni. A screenshotos megközelítést kipróbáltuk és egy munkanapon belül töröltük — olcsó kísérlet, egyértelmű ítélet.
  2. Minden async optimalizációnak kapu kell a felhasználás pontján. Az „azonnali visszajelzés üres OCR-szöveggel" helyes UX-döntés volt, de a küldési útnak meg kellett tanulnia megvárni azt, amit az optimalizáció elhalasztott. Ha munkát halasztasz el, keresd meg az eredményének minden fogyasztóját, és tanítsd meg nekik a különbséget az „üres" és a „még nincs kész" között.
  3. A láncot műszerezd fel, ne a gyanúsítottat. A tracing logok a screenshot szövegét követték végig — a shortcut handlertől az IPC-n át az API kliensig —, és ezért zárt le egyetlen nyomozás két bugot, az egyiket a hálózat túloldalán.

A v1-történet előző fejezetéért lásd meetingek, amiket tényleg megtalálsz újra (v1.7.3); a teljes ívért pedig a szoftver tökéletesre szállításának anatómiája.