
Login страницата Е демото
GeekBye v1.7.5 добави продуктов скрийншот на login страницата и го изтри същия ден — изграждайки го наново като истински компоненти. Плюс: потребителят, който беше по-бърз от OCR-а, и как всъщност изглеждат 25 стилови комита за един ден.
GeekBye v1.7.5 е едноседмично издание с раздвоена личност: 37 комита, от които 28 са редизайн на login страницата — а 25 от тях са микро-корекции style(login), всичките кацнали в един-единствен ден. Това е и изданието, което поправи една от най-поучителните надпревари в кодовата база. И двете истории си струва да бъдат разказани, и се срещат в една и съща идея: login страницата е първото нещо, което вижда неавтентикиран потребител, така че по-добре да бъде продуктът, а не негова снимка.
Скрийншот, за около пет часа
Редизайнът започна конвенционално. Преструктуриране в две колони, вход отляво, продуктът показан отдясно — като изображение. Късносутрешните комити правят точно това: в 11:57 в репото каца истински preview скрийншот, PNG от 114 KB, обновен веднъж шест минути по-късно.
В 17:04 го нямаше. Комитът на завоя заменя статичното изображение с 344 реда истински компоненти — панел LoginDemo, сглобен от осем малки части, които възпроизвеждат истинския overlay UI: навигационният pill на записа с пулсиращите му EQ ленти и бутон за спиране, чат панелът с табовете Chat/Transcript, рендиран отговор на асистента (обясняващ, съвсем на място, useEffect от React), бързите действия „Tell me more / Simplify / Show example" (разкажи ми повече / опрости / покажи пример), редът с live промптове и полето Assist с ⌘⏎.
Нека сме точни с думата „демо", защото е лесно да се преувеличи: бутоните имат истински hover състояния — сияния, проблясъци, преходи — но нищо не е свързано към клик, а полето за въвеждане е read-only. Не е sandbox. Това, което е, е истинският UI речник на продукта, рендиран на живо: същият логотипен asset, същата обработка с gradient-border и backdrop-blur, същият импорт на productName, който използва white-label системата — така че демото се ребрандира само за всеки продукт, изграден от тази кодова база. Скрийншот не може нищо от това. Скрийншотът е остарял в деня, в който го направиш, размазан на грешния дисплей и завинаги брандиран като продукта, който случайно си заснел. Компонентите са ясни при всяко DPI, винаги актуални и коректни за всеки бранд — защото не са снимка на дизайн системата, те са дизайн системата.
Изтритият PNG, между другото, все още е в репото при release тага — осиротял, нерефериран от нищо. Всяка кодова база носи няколко вкаменелости от подхода, който загуби.
Как изглеждат 25 стилови комита за един ден
Комит логът на този единствен ден е скицник на дизайнер, съхранен с необичайна честност. Съотношението на колоните мина през 40/60, после 45/55. Надпис „Works with" (работи с) над логата на платформите беше добавен по обед, преместен и премахнат — живя около половин ден. Самият ред с лога на платформи (Google Meet, Teams, Zoom, Slack, Webex), добавен в 10:59 сутринта, беше изтрит изцяло в 22:08 същата нощ. А футърът мина през сага от четири подхода, за да се подравни: единичен wrapper контейнер, после махане на центриращите класове, после центриране с flexbox, после просто побутване по-близо до долния ръб.
Лесно би било да се прочете това като суетене. Ние го четем като истинската форма на дизайнерската работа: схождаш се, като рендираш, гледаш и коригираш — а правенето на това в 25 малки комита вместо в един squash-нат „redesign login page" означава, че самото търсене е записано. Когато някой попита „не пробвахме ли веднъж ред с лога?", отговорът е в историята, с времеви печати.
Потребителят, който беше по-бърз от OCR-а
Инженерната история на изданието се случи пет дни по-рано, във верига от три поправящи комита. От v1.5.12 натискането на Cmd+H нарежда скрийншот на опашката с мигновена обратна връзка: миниатюрата се появява в опашката веднага, а извличането на текста — локален OCR с Apple Vision, приблизително ~1-2 секунди — тече на заден план. Събитието на опашката буквално тръгва с ocrText: '' и коментар, обещаващ, че ще се попълни по-късно.
Това е добра оптимизация, и тя изсече една надпревара. Бърз потребител натиска Cmd+H и веднага изпраща въпроса си. Текстовото поле на скрийншота е още празно. Заявката излиза без никакво съдържание от екрана, а моделът отговаря — истинно, вбесяващо — „I cannot see images" (не мога да виждам изображения). Наивният път не се провали с грешка; провали се с верен отговор на грешния въпрос, което е най-объркващият начин, по който софтуерът може да се провали.
Поправката спира пътя на изпращане при async работата, която оптимизацията отложи: ако някой скрийншот в опашката все още има празен OCR текст, заявката изчаква паркирана и UI-ът показва индикатор „Reading screen..." (чете екрана...); един useEffect се задейства в мига, в който текстът пристигне, и изпраща заявката с пълното извлечено съдържание. Две React-специфични подробности в diff-а си струва да се откраднат: опашката със скрийншоти е огледално копирана в ref, синхронизиран по време на рендиране, защото веригата от closure-и на event handler-ите улавяше остаряло състояние; а паркираната заявка се изпраща директно, а не през генеричния hook за заявки на опашка — по същата stale-closure причина.
И има една честна гънка, записана направо в комит съобщението: tracing логовете, добавени за лов на тази надпревара, разкриха втори бъг на бекенда — сглобяването на промпта изпускаше текста на скрийншота изцяло по един от кодовите пътища. Един симптом, два бъга, намерени чрез инструментиране на цялата верига и наблюдение къде изчезва текстът. Веригата завърши с продуктово решение, девет минути след поправката на надпреварата: Cmd+H нарежда скрийншоти на опашката за пакетен анализ, докато Cmd+Enter винаги прави свежа снимка на текущия екран — два отделни работни потока вместо един двусмислен. (Какво всъщност прави Assist на Cmd+Enter е отделна статия: мигновена AI помощ за каквото гледаш в момента.)
Една малка кода от същата седмица, за читателите на главата за white-label: User-Agent-ът Product/version (platform) получи поправка за dev режим, защото app.getVersion() в неопакован Electron връща версията на Electron, а не на продукта. Идентификационните низове, както винаги, изтичат през тръбите.
Три неща, на които ни научи това издание
- Рендирай продукта, не го снимай. Login-демо, изградено от истински компоненти, се ребрандира автоматично, преживява всяка плътност на дисплея и не може да остарее. Подходът със скрийншот беше изпробван и изтрит в рамките на един работен ден — евтин експеримент, ясна присъда.
- Всяка асинхронна оптимизация се нуждае от бариера в точката на употреба. „Мигновена обратна връзка с празен OCR текст" беше правилното UX решение, но пътят на изпращане трябваше да се научи да чака това, което оптимизацията отложи. Ако отлагаш работа, намери всеки консуматор на резултата ѝ и го научи на разликата между „празно" и „още не е готово".
- Инструментирай веригата, не заподозрения. Tracing логовете проследиха текста на скрийншота от край до край — от shortcut handler-а през IPC до API клиента — и затова едно разследване затвори два бъга, единият от тях от другата страна на мрежата.
За предишната глава от историята на v1 — срещи, които наистина можеш да намериш отново (v1.7.3); а за цялата дъга — анатомията на доставянето на софтуер до съвършенство.