Steven
Steven9 phút đọc

Một biến CSS, năm vòng review, và một chuỗi công cụ Swift đã nói dối

GeekBye v2.0.7 làm cho toàn bộ overlay có thể điều chỉnh độ trong suốt — nghe như một thay đổi CSS một dòng và hoàn toàn không phải vậy. Câu chuyện thực sự là những gì mà quá trình review đã bắt được: hai bề mặt nhất quyết không chịu mờ đi, một thanh ghi âm trông sai dù cùng độ mờ, và một tệp binary đã biên dịch lật qua lật lại 672 byte vì chính tài liệu của chúng tôi báo cho reviewer sai phiên bản Swift.

Kỹ thuật
Thiết kế
Build
Phát hành GeekBye
Một biến CSS, năm vòng review, và một chuỗi công cụ Swift đã nói dối

"Làm cho overlay trong suốt" là kiểu công việc nghe như chỉ cần một thanh trượt và một thuộc tính CSS opacity. GeekBye v2.0.7 đã phát hành đúng cái kết quả mà người dùng thấy được ấy — một "chế độ sáng" có thể điều chỉnh, cho phép bạn nhìn xuyên qua các panel của trợ lý xuống bất cứ thứ gì phía sau. Nhưng phần thú vị của bản phát hành này không phải là tính năng. Đó là năm vòng review cần thiết để làm cho nó đúng, và một câu chuyện chiến trường về một tệp binary đã biên dịch thay đổi kích thước vì chính tài liệu của chúng tôi đã nói dối một reviewer.

Cách đúng để làm cho toàn bộ UI trở nên trong suốt

Phiên bản ngây thơ của việc này là rải một giá trị opacity vào mọi component panel rồi gọi là xong. Đó là một cái bẫy bảo trì: cả tá giá trị nhồi cứng trôi dạt khỏi nhau ngay khoảnh khắc có ai đó chạm vào một cái.

Thay vào đó, v2.0.7 dùng một tiện ích CSS dùng chung và một token riêng cho từng bề mặt. Có một class overlay-surface duy nhất tính nền của một panel từ hai custom property: một độ mờ cơ sở mà mỗi bề mặt tự khai báo cho chính mình (thanh điều khiển, chat, bong bóng transcript, khối code, v.v. mỗi cái tự chọn cho mình), và một hệ số nhân alpha toàn cục nằm trên gốc overlay và đại diện cho thiết lập thanh trượt của người dùng. Mỗi bề mặt đọc cùng một hệ số nhân; mỗi cái vẫn giữ cá tính riêng. Điều then chốt là chỉ có nền panel được co giãn — chữ, biểu tượng, và backdrop-blur vẫn được render đầy đủ, nên "trong suốt" không bao giờ đồng nghĩa với "không đọc được."

Hai quyết định trong thiết kế đó đáng được nêu ra, bởi chúng là sự khác biệt giữa một tính năng giúp ích và một tính năng sinh ra vé hỗ trợ:

  • Mặc định là hoàn toàn đục. Thiết lập opacity xuất xưởng ở mức 100% — một no-op. Overlay của không ai bỗng dưng trở nên nhìn xuyên qua được khi cập nhật; độ trong suốt có sẵn ở đó khi bạn với tới nó và vô hình cho tới khi ấy.
  • Thiết lập được kiểm tra một cách phòng thủ. Có một nguồn sự thật duy nhất cho giá trị nhỏ nhất, lớn nhất, mặc định và bước nhảy, cùng một bộ chuẩn hóa canh chừng trường hợp rỗng/thiếu. Điều đó quan trọng vì một cái bẫy của JavaScript: Number(null)0, nên một thiết lập bị thiếu mà bị ép kiểu một cách ngây thơ sẽ đẩy overlay về trạng thái trong suốt nhất của nó thay vì về mặc định. Bộ chuẩn hóa bắt được điều đó trước khi nó có thể xảy ra.

Kéo thanh trượt và toàn bộ overlay đổi sắc trực tiếp, ngay giữa lúc ghi âm, vì mỗi bề mặt đều đăng ký cùng một thiết lập. Không khởi động lại, không tải lại.

Những gì review bắt được (và một lần test trên một màn hình đơn sẽ không bao giờ bắt được)

Đây là chỗ mà "một biến CSS" hết còn đơn giản. Ba lỗi nổi lên trong review, và hai trong số đó là cùng một bài học đội những chiếc mũ khác nhau.

Một panel không chịu mờ đi. Overlay phím tắt vẫn cứng đầu ở dạng đặc trong khi mọi thứ khác trở nên trong suốt. Nguyên nhân: nó render bên ngoài nhánh cây con DOM mang biến opacity, nên nó không bao giờ kế thừa giá trị đang lan xuống từ gốc overlay. Các custom property CSS kế thừa xuyên qua cây DOM — và nếu một node thực chất không phải là hậu duệ của nơi bạn đặt biến, nó lặng lẽ nhận được con số không. Cách sửa là đặt biến đó cục bộ trên chính panel ấy nữa.

Một sắc màu hover biến mất. Các nút Fn/Assist mất đi ánh sáng hover màu lục lam. Tiện ích trong suốt đặt nền bằng !important (nó buộc phải thắng các mặc định của bề mặt), và điều đó nghiền nát sắc màu nền hover: trên cùng một phần tử. Va chạm về độ ưu tiên (specificity). Cách sửa là làm cho sắc màu hover cũng mạnh mẽ ngang bằng để nó có thể giành lại khi hover.

Cả hai lỗi đó đều là cùng một sự thật nền tảng: một chuỗi kế thừa biến CSS là một ranh giới về tính đúng đắn thực thụ, chứ không phải một chi tiết tạo kiểu. Sự kế thừa và độ ưu tiên quyết định giá trị của bạn có tới được phần tử hay không, và cả hai đều không hiện ra trong một ảnh chụp màn hình cho tới khi nó đã sai.

Cùng opacity, khác vẻ ngoài. Cái tinh vi nhất: thanh ghi âm và thanh nhàn rỗi được đặt ở độ mờ cơ sở y hệt nhau, mà vẫn trông khác nhau rõ rệt. Vì sao? Viên thuốc ghi âm dùng một backdrop-blur nặng hơn, và một lớp blur mạnh trên nền tối trung bình hóa về phía một kết quả đậm hơn — nên cùng alpha lại tạo ra vẻ ngoài không đồng nhất. Nó cũng có một viền mờ nhạt trong khi thanh nhàn rỗi có một cạnh vòng-gradient sáng. Cách sửa là làm khớp mức blur và cái vòng. Bài học đọng lại: cùng alpha không phải là cùng vẻ ngoài một khi blur bước vào bức tranh. Độ trong suốt là một hệ thống các hiệu ứng tương tác với nhau, chứ không phải một con số đơn lẻ.

Tệp binary thay đổi kích thước vì tài liệu đã nói dối

Giờ đến câu chuyện chiến trường, và đó là kiểu tôi thích nhất — kiểu mà công cụ và tài liệu bất đồng, còn một reviewer cẩn thận thì mắc kẹt giữa làn đạn.

GeekBye phát hành một số tệp binary Swift đã biên dịch sẵn (các helper native cho những việc như phát hiện cuộc họp). Vì một tệp binary đã biên dịch được commit vào repo, mọi lập trình viên phải biên dịch nó với đúng cùng một phiên bản Swift — các toolchain khác nhau tạo ra các byte khác nhau từ cùng một mã nguồn, và điều đó sẽ nghĩa là một xung đột git ma quái mỗi lần có ai đó build lại. Nên có một script thực thi một phiên bản cụ thể: Swift 6.3.x, được kiểm tra tại thời điểm build.

Trong lúc review bản phát hành này, một reviewer đánh dấu rằng một tệp binary nên được build lại để khớp với "toolchain mà repo bắt buộc." Lập trình viên đã làm đúng như vậy — và kích thước của binary thay đổi từ 89,184 byte thành 88,512. Thông điệp commit thậm chí còn nói rằng nó đang "khôi phục đầu ra ổn định theo byte" bằng cách build lại với Swift 6.2.1, "toolchain mà repo bắt buộc."

Có điều 6.2.1 là phiên bản sai. Script thực thi build yêu cầu 6.3.x. Vấn đề là tài liệu văn xuôi — README và hướng dẫn dành cho người đóng góp — vẫn còn ghi 6.2.1 ở một vài chỗ. Thế là một reviewer tận tâm và một lập trình viên tận tâm, cả hai đều cố làm điều đúng, đã đi theo tài liệu thẳng vào việc commit đúng cái artifact mà script thực thi tồn tại để chối bỏ. Một binary 6.2.1 trong một repo 6.3.x chính là kiểu trôi dạt sẽ phá vỡ lần build lại sạch sẽ của mọi lập trình viên khác.

Commit tiếp theo đã sửa nó — và cách sửa mới là điểm mấu chốt. Nó không chỉ build lại binary về dạng 6.3.x của nó (kích thước được khôi phục về 89,184, đúng ngay chỗ nó khởi đầu). Nó còn chỉnh lại các tham chiếu "6.2.1" cũ trong tài liệu để cái bẫy không thể sập lần nữa. Tệp binary lật 672 byte qua lại qua hai commit, và lỗi thực sự chưa bao giờ là tệp binary. Đó là chuyện hai nguồn sự thật — script thực thi và tài liệu viết ra — bất đồng với nhau, và một con người đã tin nhầm nguồn.

Ba điều bản phát hành này dạy chúng tôi

  1. Một chuỗi kế thừa biến CSS là một ranh giới về tính đúng đắn. Hai trong ba lỗi review quy về một biến không kế thừa và một !important đè lên một trạng thái hover. Nếu một giá trị phải tới được một phần tử qua kế thừa hoặc phải thắng qua độ ưu tiên, thì đường đi đó là logic — hãy kiểm chứng nó như logic, chứ không phải như tạo kiểu.
  2. Cùng tham số có thể tạo ra kết quả không như nhau. Thanh ghi âm và thanh nhàn rỗi chung một opacity mà vẫn trông khác nhau vì một mức blur khác đã thay đổi kết quả. Khi bạn hợp nhất một hệ thống thị giác quanh một con số, hãy kiểm tra rằng các biến khác quanh mỗi bề mặt không đang lặng lẽ thay đổi ý nghĩa của con số ấy.
  3. Khi tài liệu và script thực thi bất đồng, hãy sửa sự bất đồng — chứ không chỉ triệu chứng. Lỗi không phải là một binary tồi; đó là một tài liệu ghi sai toolchain và một script thực thi nói khác đi. Build lại binary chỉ chữa triệu chứng. Làm cho mọi nguồn sự thật khớp nhau mới là cách sửa thực sự, vì reviewer tiếp theo cũng sẽ tin vào tài liệu.

GeekBye v2.0.7 đã phát hành độ trong suốt đồng nhất, mọi trường hợp biên đã được review và tài liệu toolchain đã được chỉnh lại cho đúng. Đây là bản cuối cùng trong loạt phát hành "thủ công lặng lẽ" trước đợt chạy nước rút về độ tin cậy tiếp theo. Về nền móng bên dưới nó, xem một phiên bản 2 thực sự đòi hỏi những gì (v2.0.0); về bản phát hành đánh bóng song sinh, phần mềm điềm tĩnh: bản sửa nhấp nháy và con chip chế độ trả lời (v2.0.3 + v2.0.5); và về cách overlay ẩn đi trong một cuộc gọi, làm sao để vô hình khi chia sẻ màn hình.

Bài Viết Liên Quan

Phần mềm điềm tĩnh: Loại bỏ nút gạt nhấp nháy và dạy chat nói rõ nó đang ở chế độ nào
Steven
Steven8 phút đọc

Phần mềm điềm tĩnh: Loại bỏ nút gạt nhấp nháy và dạy chat nói rõ nó đang ở chế độ nào

Hai bản phát hành nhỏ của GeekBye, không có tính năng nổi bật nào — chỉ là một nút gạt trong cài đặt hết nhấp nháy và một trợ lý chat cuối cùng cũng cho bạn biết nó trả lời ở chế độ họp hay chế độ lập trình. Đây chính là cái giá thực sự của "phần mềm điềm tĩnh", từng chi tiết một.

Sản phẩm
Thiết kế
Kỹ thuật
Một phiên bản 2 thực sự đòi hỏi những gì: 206 commit cho những trạng thái trung thực
Steven
Steven9 phút đọc

Một phiên bản 2 thực sự đòi hỏi những gì: 206 commit cho những trạng thái trung thực

GeekBye v2 không phải là một bản phát hành tính năng. Nó là 206 commit nhắm tới một ý tưởng duy nhất: ứng dụng không bao giờ được nói dối về trạng thái của chính nó. Đây là cái giá phải trả — bao gồm cả lỗi một dòng trong tệp lock suýt khiến chúng tôi không thể phát hành bất cứ thứ gì.

Độ tin cậy
Kỹ thuật
Phát hành
Giải phẫu quá trình đưa phần mềm đến độ hoàn hảo: Cách đánh giá mã bắt được lỗi mà kiểm thử bỏ sót
Steven
Steven9 phút đọc

Giải phẫu quá trình đưa phần mềm đến độ hoàn hảo: Cách đánh giá mã bắt được lỗi mà kiểm thử bỏ sót

Xuyên suốt loạt bài GeekBye v2, cùng một điều cứ lặp đi lặp lại: một bản sửa lỗi vượt qua mọi bài kiểm thử trên máy của lập trình viên, rồi khâu đánh giá mã chứng minh rằng nó sẽ thất bại với gần như tất cả mọi người. Đây là quy trình đằng sau chín bản phát hành — cửa kiểm soát đánh giá, những phát hiện bắt lỗi ngay từ đầu, và kỷ luật kiểm thử trước khi phát hành đã biến "nó chạy được trên máy tôi" thành "nó chạy được".

Kỹ thuật
Quy trình
Đánh giá mã