Steven
Steven6 хв читання

Спокійне програмне забезпечення: як ми прибрали миготливий перемикач і навчили чат казати, у якому він режимі

Два невеликі релізи GeekBye без гучних функцій — лише перемикач у налаштуваннях, який перестав миготіти, і чат-асистент, який нарешті каже, чи відповів він у режимі зустрічі, чи в режимі кодування. Ось скільки насправді коштує «спокійне програмне забезпечення», по одній деталі за раз.

Продукт
Дизайн
Інженерія
Релізи GeekBye
Спокійне програмне забезпечення: як ми прибрали миготливий перемикач і навчили чат казати, у якому він режимі

Не кожен реліз — це воєнна історія. Деякі — це просто перелік дрібних, майже невидимих речей, які тихенько працювали неправильно — таких, що нічого не ламають, але змушують застосунок здаватися трохи ненадійним, трохи смиканим, трохи не-вашим. GeekBye v2.0.3 і v2.0.5 були саме такими. Жодних нових функцій. Лише спокій.

«Спокійне програмне забезпечення» звучить як настрій. Насправді це купа конкретних рішень. Ось три з них.

Перемикач, який не міг визначитися

Був один перемикач у налаштуваннях — той, що керує відновленням аудіо, — який миготів, коли ви його натискали. Вмикаєте його, і на частку секунди він показує увімкнено, потім різко повертається до вимкнено, а тоді врешті визначається. Крихітне візуальне заїкання, але око його ловить, і воно читається як застосунок не впевнений, що він робить.

Причина — класична гонитва в інтерфейсі, яку називають оптимістичним оновленням. Коли ви натискаєте перемикач, у застосунку є два варіанти: дочекатися, поки налаштування справді збережеться, і тоді оновити перемикач (правильно, але здається повільним), або перемкнути миттєво і зберегти у фоні (здається миттєвим). GeekBye робив друге — перемикав одразу — але також перечитував збережене значення, коли те поверталося. Тож послідовність була така: ви натискаєте, перемикач оптимістично вмикається, реальне збережене значення приходить трохи згодом, і протягом одного кадру ці двоє не збігаються, а перемикач помітно стрибає.

Виправлення полягає в тому, щоб оптимістичне значення й підтверджене значення чисто узгоджувалися — перемикач фіксується на стані, який ви обрали, і перестає сумніватися в собі, коли збереження підтверджується. Разом із цим v2.0.3 зробив непоказний прохід по текстах: опис відновлення аудіо було скорочено, щоб він вирівнявся зі своїми сусідніми рядками, а формулювання налаштувань — олюднено. Ніщо з цього не є функцією. Усе це разом — різниця між панеллю налаштувань, яка здається зконструйованою, і тією, над якою попіклувалися.

Тур, який не хотів іти геть

Тури для нових користувачів корисні рівно один раз. Проблема — саме в цій одноразовості: після того як ви його побачили, ознайомчий шар, який неможливо закрити, стає безладом, що сигналить цей застосунок і досі вважає вас новачком. v2.0.3 виправив обидва кінці цього — тур продуктом тепер можна сховати, а якщо ви справді захочете його повернути, є кнопка Відтворити тур знову. Показуйте його, коли він допомагає, ідіть з дороги, коли ні, і дайте користувачеві викликати його на його власних умовах. Поважати те, що користувач більше не новачок, — це своя маленька форма спокою.

Асистент, який не хотів казати, як він думає

Ось те, що справді мало значення, і це пов'язано з глибшою проблемою, яку ми переслідували.

Асистент GeekBye відповідає по-різному залежно від контексту. На зустрічі «що ти про це думаєш?» має отримати розмовну, орієнтовану на зустріч відповідь. Під час сесії кодування ті самі слова мають отримати технічну. Тож бекенд проганяє запитання через правильну рамку — назвімо це режимом зустрічі або режимом кодування — і ця рамка справді змінює відповідь, яку ви отримуєте.

Проблема: застосунок ніколи не казав вам, який режим відповів. Тож коли асистент давав вам відповідь із кодерським присмаком на розмовне запитання — або відповідав на запитання про код так, ніби ви просто спілкуєтеся, — це виглядало так, ніби ШІ просто помилявся. Він не помилявся; він був в іншому режимі, а ви не мали способу цього побачити. Прихований стан змушував правильну поведінку виглядати зламаною. (Сама логіка режимів — це більший обсяг роботи: оркестратор, який вирішує, як відповідати на некодові запитання під час сесії кодування, — але все це вам ні до чого, якщо ви не можете побачити рішення, яке він ухвалив.)

v2.0.5 додав до чату індикатор режиму лише для читання: невеличку позначку, що показує, чи асистент відповів у режимі зустрічі, чи в режимі кодування. Лише для читання — у цьому вся суть: це не елемент керування, який ви налаштовуєте, а вікно в рішення, яке система вже ухвалила. Ви перестаєте гадати, чому відповідь здається дивною; ви бачите рамку, з якої вона прийшла.

Деталь, що робить індикатор чесним

Ось інженерне рішення, яке варто передати далі, бо це саме той різновид речей, що відрізняє прикручений збоку індикатор від справді надійного.

Інформація про режим приходить з бекенду як частина потокової відповіді — невеликий кадр mode у потоці подій, надісланих сервером. Але старіший клієнт, що з'явився до цієї функції, не знав би, що таке кадр mode; у кращому разі він його проігнорує, у гіршому — відобразить щось спотворене. Тож клієнт оголошує свою здатність: він надсилає заголовок запиту, який каже я вмію показувати індикатор режиму, і бекенд надсилає кадр mode лише тим клієнтам, які його надіслали. Старі клієнти ніколи не отримують сигналу, з яким не можуть впоратися; нові клієнти отримують рівно той кадр, який попросили.

Це рукостискання в один заголовок, і це різниця між «ми додали функцію» та «ми додали функцію, не зламавши нікому, хто ще не оновився». Той самий прохід рецензування підтягнув решту поведінки: індикатор очищається під час скидання і коли змінюється контекст розмови (застаріла позначка режиму — це своя маленька брехня), і показується він лише у виді чату, де йому й місце.

Чого нас навчили два «безфункційні» релізи

  1. Смикання — це сигнал довіри. Миготливий перемикач, стрибучий тумблер, позначка, що затримується на кадр довше, ніж треба, — жодне з цього не є багом у сенсі падіння, але кожне шепоче цей застосунок не зовсім себе контролює. Спокій — це відсутність цього шепоту, і ви заслуговуєте на нього по одній гонитві за раз.
  2. Прихований режим змушує правильну поведінку виглядати як баг. Асистент робив правильну річ і отримував за неї докори — суто тому, що користувач не бачив рамки. Коли ваша система ухвалює невидиме рішення, яке змінює вихід, покажіть це рішення — індикатор лише для читання часто і є всім виправленням.
  3. Нові функції мають бути невидимими для клієнтів, які не можуть ними скористатися. Рукостискання через заголовок здатності означає, що сигнал режиму досягає лише тих клієнтів, які можуть його відобразити. Зворотна сумісність — це не перевірка версії, прикручена пізніше; це клієнт, що каже, що він розуміє, і сервер, що поважає цю відповідь.

Це релізи, про які ніхто не пише заголовків у чейнджлозі, і вони — велика частина того, чому GeekBye v2 відчувається саме так, як відчувається. Про реліз, на якому було збудовано цей спокій, читайте чого насправді вартий другий випуск (v2.0.0). Про роботу над надійністю поруч із ним — день, коли наш застосунок влаштував DDoS сам собі (v2.0.1) і чому ваш ШІ-нотатник припиняє запис посеред зустрічі (v2.0.9).

Схожі статті

Одна CSS-змінна, п'ять раундів рев'ю та ланцюжок інструментів Swift, що збрехав
Steven
Steven6 хв читання

Одна CSS-змінна, п'ять раундів рев'ю та ланцюжок інструментів Swift, що збрехав

GeekBye v2.0.7 зробив увесь оверлей регульовано напівпрозорим — що звучить як однорядкова зміна CSS і абсолютно нею не було. Справжня історія — про те, що виловило код-рев'ю: дві поверхні, які відмовлялися згасати, панель запису, що виглядала неправильно за тієї самої прозорості, і скомпільований бінарник, який стрибнув на 672 байти, бо наша власна документація підказала рецензенту неправильну версію Swift.

Інженерія
Дизайн
Збірка
Ваш застосунок для Mac отримує доступ до мікрофона — і забуває його при кожному запуску
Steven
Steven5 хв читання

Ваш застосунок для Mac отримує доступ до мікрофона — і забуває його при кожному запуску

GeekBye попросив доступ до мікрофона, ви його надали, і все запрацювало. Наступний запуск: доступу немає. А в Системних параметрах → Мікрофон застосунок узагалі не з’явився. Винуватцем виявилася функція безпеки macOS, що тихо запускає застосунок зі шляху, який зникає — ось діагноз і виправлення в одне натискання.

macOS
Дозволи
Інженерія
Транскрипція в реальному часі, коли файрвол блокує WebSocket
Steven
Steven4 хв читання

Транскрипція в реальному часі, коли файрвол блокує WebSocket

Корпоративні мережі обожнюють пропускати HTTPS і тихцем убивати upgrade до WebSocket. Це непомітно ламає транскрипцію в реальному часі. GeekBye v2.0.8 автоматично переходить на чисто-HTTPS транспорт — а його випуск викрив баг, який зробив би всю функцію непотрібною.

Транскрипція
Мережі
Інженерія