Steven
Steven7 min citire

Pagina de login ESTE demo-ul

GeekBye v1.7.5 a adăugat un screenshot de produs pe pagina de login și l-a șters în aceeași zi — reconstruindu-l în schimb din componente reale. În plus: utilizatorul care a fost mai rapid decât OCR-ul și cum arată de fapt 25 de commit-uri de stil într-o singură zi.

Inginerie
Design
UX
Lansări GeekBye
Pagina de login ESTE demo-ul

GeekBye v1.7.5 e o lansare de o săptămână cu personalitate dublă: 37 de commit-uri, dintre care 28 sunt un redesign al paginii de login — și 25 dintre acestea sunt micro-ajustări style(login), toate aterizate într-o singură zi. E și lansarea care a reparat una dintre cele mai instructive curse din toată baza de cod. Ambele povești merită spuse, și se întâlnesc în aceeași idee: pagina de login e primul lucru pe care îl vede un utilizator neautentificat, așa că ar face bine să fie produsul, nu o poză a lui.

Un screenshot, timp de vreo cinci ore

Redesign-ul a început convențional. Restructurare pe două coloane, sign-in-ul în stânga, iar produsul arătat în dreapta — ca imagine. Commit-urile de dinaintea prânzului fac exact asta: la 11:57 aterizează în repo un screenshot de previzualizare adevărat, un PNG de 114 KB, actualizat o dată șase minute mai târziu.

La 17:04 dispăruse. Commit-ul de pivot înlocuiește imaginea statică cu 344 de linii de componente reale — un panou LoginDemo asamblat din opt piese mici care replică UI-ul real al overlay-ului: pill-ul de navigare al înregistrării cu barele lui de EQ pulsând și butonul de stop, panoul de chat cu tab-urile Chat/Transcript, un răspuns de asistent randat (care explică, potrivit, useEffect din React), acțiunile rapide „Tell me more / Simplify / Show example" (spune-mi mai mult / simplifică / arată un exemplu), rândul de prompturi live și input-ul Assist cu ⌘⏎.

Să fim preciși cu cuvântul „demo", pentru că e ușor să promiți prea mult: butoanele au hover states reale — glow-uri, shimmer-e, tranziții — dar nimic nu e legat la click, iar input-ul e read-only. Nu e un sandbox. Ce este, în schimb, e vocabularul UI real al produsului, randat live: același asset de logo, același tratament de gradient-border și backdrop-blur, același import productName pe care îl folosește sistemul de white-label — astfel încât demo-ul se rebranduiește singur pentru fiecare produs construit din această bază de cod. Un screenshot nu poate face nimic din toate astea. Un screenshot e învechit din ziua în care îl faci, neclar pe display-ul nepotrivit și branduit pe veci ca produsul pe care s-a nimerit să-l capturezi. Componentele sunt clare la orice DPI, mereu la zi și corecte pentru fiecare brand — pentru că nu sunt o poză a design system-ului, ele sunt design system-ul.

PNG-ul șters, apropo, e încă în repo la tag-ul de release — orfan, nereferențiat de nimic. Fiecare bază de cod poartă câteva fosile ale abordării care a pierdut.

Cum arată 25 de commit-uri de stil într-o zi

Jurnalul de commit-uri al acelei singure zile e caietul de schițe al unui designer, păstrat cu o onestitate neobișnuită. Raportul coloanelor a fost 40/60, apoi 45/55. Un label „Works with" (funcționează cu) deasupra logo-urilor de platforme a fost adăugat la prânz, repoziționat și eliminat — a trăit cam o jumătate de zi. Rândul de logo-uri de platforme în sine (Google Meet, Teams, Zoom, Slack, Webex), adăugat la 10:59 dimineața, a fost șters complet la 22:08 în acea noapte. Iar footer-ul a avut nevoie de o saga în patru abordări ca să se alinieze: un singur container wrapper, apoi eliminarea claselor de centrare, apoi centrare cu flexbox, apoi pur și simplu împins puțin mai aproape de marginea de jos.

Ar fi ușor să citești asta drept agitație inutilă. Noi o citim ca forma reală a muncii de design: convergi randând, privind și ajustând — iar a face asta în 25 de commit-uri mici în loc de un singur „redesign login page" squash-uit înseamnă că însăși căutarea rămâne înregistrată. Când cineva întreabă „n-am încercat noi cândva un rând de logo-uri?", răspunsul e în istoric, cu timestamp-uri.

Utilizatorul care a fost mai rapid decât OCR-ul

Povestea de inginerie a lansării s-a petrecut cu cinci zile mai devreme, într-un lanț de fix-uri de trei commit-uri. Începând cu v1.5.12, apăsarea Cmd+H pune un screenshot în coadă cu feedback instantaneu: thumbnail-ul apare în coadă imediat, iar extragerea textului — OCR local cu Apple Vision, aproximativ ~1-2 secunde — rulează în fundal. Evenimentul de coadă pleacă la propriu cu ocrText: '' și un comentariu care promite că se va completa mai târziu.

E o optimizare bună, și a născut o cursă. Un utilizator rapid apasă Cmd+H și își trimite imediat întrebarea. Câmpul de text al screenshot-ului e încă gol. Cererea pleacă fără niciun conținut de ecran, iar modelul răspunde — sincer, exasperant — „I cannot see images" (nu pot vedea imagini). Calea naivă nu a eșuat cu o eroare; a eșuat cu un răspuns corect la întrebarea greșită, care e cel mai derutant mod în care poate eșua software-ul.

Fix-ul blochează calea de submit pe munca async pe care optimizarea a amânat-o: dacă vreun screenshot din coadă are încă text OCR gol, cererea parchează, iar UI-ul arată un indicator „Reading screen..." (citește ecranul...); un useEffect se declanșează în clipa în care textul sosește și trimite cererea cu întregul conținut extras. Două detalii specifice React din diff merită furate: coada de screenshot-uri e oglindită într-un ref sincronizat în timpul render-ului, pentru că lanțul de closure-uri al event handler-elor captura stare veche; iar cererea parcată e trimisă direct, nu prin hook-ul generic de cereri în coadă, din același motiv de stale closure.

Și mai e o cută onestă consemnată chiar în mesajul de commit: log-urile de trasare adăugate ca să vâneze această cursă au dezvăluit un al doilea bug, pe backend — asamblarea promptului arunca textul screenshot-ului cu totul, pe una dintre căile de cod. Un simptom, două bug-uri, găsite instrumentând întregul lanț și urmărind unde dispărea textul. Lanțul s-a încheiat cu o decizie de produs, nouă minute după fix-ul cursei: Cmd+H pune screenshot-urile în coadă pentru analiză în lot, în timp ce Cmd+Enter face întotdeauna o captură proaspătă a ecranului curent — două fluxuri de lucru distincte în locul unuia ambiguu. (Ce face de fapt Assist-ul lui Cmd+Enter e un articol de sine stătător: ajutor AI instantaneu pentru orice ai pe ecran.)

O mică coda din aceeași săptămână, pentru cititorii capitolului despre white-label: User-Agent-ul Product/version (platform) a primit un fix pentru modul de development, pentru că app.getVersion() în Electron ne-împachetat returnează versiunea Electron-ului, nu a produsului. Șirurile de identitate, ca întotdeauna, se scurg prin instalații.

Trei lucruri pe care ni le-a predat această lansare

  1. Randează produsul, nu-l fotografia. Un demo de pagină de login construit din componente reale se rebranduiește automat, supraviețuiește oricărei densități de display și nu poate rămâne în urmă. Abordarea cu screenshot a fost încercată și ștearsă în aceeași zi de lucru — experiment ieftin, verdict clar.
  2. Fiecare optimizare async are nevoie de o barieră la punctul de utilizare. „Feedback instantaneu cu text OCR gol" a fost decizia de UX corectă, dar calea de submit a trebuit să învețe să aștepte ceea ce optimizarea amânase. Dacă amâni o muncă, găsește fiecare consumator al rezultatului ei și învață-l diferența dintre „gol" și „încă nu e gata".
  3. Instrumentează lanțul, nu suspectul. Log-urile de trasare au urmărit textul screenshot-ului cap-coadă — de la handler-ul de shortcut la IPC la clientul de API — și de aceea o singură investigație a închis două bug-uri, unul dintre ele de cealaltă parte a rețelei.

Pentru capitolul anterior al poveștii v1, ședințe pe care chiar le poți regăsi (v1.7.3); iar pentru întregul arc, anatomia livrării de software până la perfecțiune.