Steven
Steven4 นาทีที่อ่าน

ออกแบบ Dashboard ใหม่โดยยึด wave chart หนึ่งอันเป็นหัวใจ

GeekBye v1.8.2 เปลี่ยน dashboard จากรีโมตคุมการอัดเสียงให้กลายเป็นหน้าวิเคราะห์แบบอ่านอย่างเดียว — stats strip หนึ่งแถบกับ wave chart 7 วัน สององค์ประกอบเด่นนี้เป็นดราฟต์ที่สองทั้งคู่ ถูก ship ภายใน 20 นาทีหลังดราฟต์แรก ในบ่ายวันเดียวกัน

วิศวกรรม
ดีไซน์
Dashboard
GeekBye รีลีส
ออกแบบ Dashboard ใหม่โดยยึด wave chart หนึ่งอันเป็นหัวใจ

บางรีลีสเพิ่มฟีเจอร์ ส่วน GeekBye v1.8.2 ส่วนใหญ่แล้ว_เอาออก_ไปหนึ่งอย่าง — และการเอาออกนั้นแหละคือเรื่องราว บ่ายวันเดียวในเดือนกุมภาพันธ์ 2026 คอมมิต 18 ตัวเปลี่ยนหน้า dashboard home จากรีโมตคุมการอัดเสียงให้กลายเป็นหน้าวิเคราะห์แบบอ่านอย่างเดียว: สถิติสี่ตัวกับ activity chart หนึ่งอัน ระหว่างทางมันได้ ship bar chart ที่อยู่ได้ 22 นาที, grid การ์ดสถิติที่อยู่ได้ 20 นาที, และ SVG wave เขียนมือที่มาแทนที่ทั้งสองอย่าง การค้นหาทั้งหมดถูกเก็บรักษาไว้ใน timestamp ของคอมมิต ซึ่งเป็นเอกสารการออกแบบชนิดที่ดีที่สุดเท่าที่มี

dashboard เลิกเป็นรีโมต

ก่อนรีลีสนี้ หน้า dashboard home คือ control panel มันนำหน้าด้วย hero card — วิดเจ็ตอัดเสียงตัวใหญ่ พร้อม badge LIVE, ปุ่ม Pause/Resume/Stop, ก้อน gradient, และ hook useSessionState ที่ต่อทุกอย่างเข้ากับตัวอัดเสียง dashboard กำลังพยายามเป็นสองอย่างพร้อมกัน: ที่ที่คุณ_มอง_มีตติงของตัวเอง กับที่ที่คุณ_ควบคุม_ตัวอัดเสียง สองผลิตภัณฑ์ หนึ่งจอ แข่งกันอยู่เงียบ ๆ

v1.8.2 เลือกอย่างเดียว มันลบ hero card กับการต่อสาย useSessionState ทิ้ง — รวมถึง effect ที่พาคุณไปหน้ารายละเอียดของมีตติงโดยอัตโนมัติในวินาทีที่ session จบ ซึ่งเป็นการกระโดดแบบ "หวังดี" ชนิดที่ทำคนตกใจกลางคันเป๊ะ ๆ การเริ่มและซ่อนตัวอัดเสียงถูกย้ายออกไปเป็น toggle เรียบ ๆ บน navbar (ปุ่มที่ถูกเปลี่ยนหน้าที่ หายไปราวร้อยบรรทัดตอนแปลงจากตัวคุม session มาเป็นสวิตช์เปิด/ปิด) โดยมี IPC handler ตัวใหม่ navbar:hide หนุนอยู่ข้างหลัง สิ่งที่เหลืออยู่คือ dashboard ที่ทำอย่างเดียว: โชว์สิ่งที่คุณอัดไว้ให้คุณดู อ่านอย่างเดียว สงบ

ในการเปลี่ยนผ่านนี้มีบั๊กเล็ก ๆ ที่มีความเป็นมนุษย์อยู่ตัวหนึ่งที่ควรพูดถึง เพราะมันคือชนิดที่การ redesign พาเข้ามาอย่างเงียบ ๆ และสายตาดี ๆ จับได้ในชั่วโมงเดียวกัน ปุ่มใหม่บน sidebar สองปุ่ม — Start กับ Hide — ถูก ship มาด้วยไอคอน grid ทั่วไป_ตัวเดียวกัน_ จึงหน้าตาเหมือนกันเป๊ะ 12 นาทีต่อมามีการตามแก้ ให้ Start เป็นไอคอน play, ให้ Hide เป็นไอคอนตาขีดฆ่า, และย้อม Hide เป็นสีเหลืองอำพัน เพื่อให้ "ทำให้แอปหายไป" อ่านเป็นการกระทำที่ตั้งใจ ไม่ใช่ฝาแฝดกลาง ๆ ของ "เริ่ม" ไอคอนก็คือ copy สองปุ่มที่หน้าตาเหมือนกันพูดสิ่งเดียวกัน ส่วนสองปุ่มนี้ไม่ได้หมายถึงสิ่งเดียวกัน

bar chart ที่อยู่ได้ 22 นาที

ตรงนี้แหละคือส่วนที่ผมรัก และมันอ่านออกได้ทั้งหมดจาก git log ที่ 16:29:34 ดราฟต์แรกของการ redesign ลงจอด: activity chart 7 วันที่วาดเป็นแท่ง — คอลัมน์มีอนิเมชัน, ความสูงขั้นต่ำเพื่อให้วันที่จิ๋ว ๆ ยังเห็นได้, ตอเลือน ๆ สูง 2 พิกเซลสำหรับวันที่เป็นศูนย์ สมเหตุสมผล ธรรมดา เป็น chart ชนิดที่คุณคว้ามาใช้โดยไม่ต้องคิด

ที่ 16:51:21 — 22 นาทีต่อมา — มันถูกลบ คอมมิตที่มาแทนบอกสิ่งที่มันทำไว้ตรง ๆ: "replace bar chart with smooth wave area chart for 7-day activity" และที่ 16:52:21 หนึ่งนาทีหลังจากนั้น อีกคอมมิตก็ถอดการ์ดมุมมนกับเส้นขอบรอบ wave ออก "for cleaner look"

ทำไม? คอมมิตบอกแค่ว่า_อะไร_เปลี่ยน ดังนั้น_ทำไม_จึงเป็นการตีความ — แต่รูปทรงของข้อมูลทำให้มันชัดเจน นี่คือเครื่องมือที่ผู้ใช้ทั่วไปมีศูนย์ หนึ่ง หรือสองมีตติงในแต่ละวัน แท่งเจ็ดแท่งที่ส่วนใหญ่สูงแค่ 2 พิกเซล ดูเหมือนลานจอดรถที่ว่างเปล่าเกือบทั้งลาน ตัวเลขเจ็ดตัวชุดเดียวกันวาดเป็นพื้นที่เติมเต็มต่อเนื่องกลับดูเหมือน_เทรนด์_ — คลื่นนุ่ม ๆ ที่ยกตัวขึ้นตรงที่สัปดาห์นั้นวุ่นวาย ไม่มีอะไรถูกปลอม ค่า y เหมือนกันเป๊ะ การ redesign แค่เลือกวิธี encode ที่ทำให้ข้อมูลเบาบางแต่ซื่อตรงถูกอ่านเป็นรูปทรง แทนที่จะเป็นความว่างเปล่า

สถิติได้รับการปฏิบัติแบบเดียวกันบนนาฬิกาเรือนเดียวกัน ดราฟต์แรก (16:29) วางตัวเลขสี่ตัวไว้ใน grid การ์ด 2×4 ที่ 16:49 grid ยุบลงเป็น stats strip แบบ inline หนึ่งแถบ — แถวเดียวมีเส้นขอบ คั่นด้วยเส้นบางเฉียบ, ตัวอักษรเล็กลง, container เดียวแทนที่จะเป็นสี่ กล่องห้ากล่องบนจอ (การ์ดสี่ใบบวกการ์ด chart) กลายเป็นสอง (strip กับ wave) PR ถัดไปเพิ่มสัมผัสที่ซื่อตรงอีกจุด: label "Total Time" กลายเป็น "Time in Meetings" เพราะ "ทั้งหมดของ_อะไร_" เป็นคำถามที่มีเหตุผล ที่ไม่ควรมีใครต้องมาถาม

20 นาที จากดราฟต์แรกถึงตัวสุดท้าย ทั้งหมดอยู่ใน pull request เดียว ถ้าพวกนั้นถูก squash รวมเป็นคอมมิต "redesign dashboard" อันเดียว การค้นหาก็จะมองไม่เห็น เพราะมันไม่ได้ถูกรวม คุณจึงได้เฝ้าดูนักออกแบบลู่เข้าหาคำตอบแบบเรียลไทม์

wave ในเชิงกลไก

ที่นี่ไม่มี chart library wave คือ inline SVG ที่ประกอบขึ้นใน JSX และมันคุ้มค่าที่จะดู เพราะมันเป็นสูตรเล็ก ๆ ที่ซื่อตรง ที่คุณขโมยไปใช้กับ sparkline อะไรก็ได้

smoothing คือเคล็ดลับ สำหรับจุดที่อยู่ติดกันแต่ละคู่ path จะใช้ช่วง cubic-bezier ที่ control point ทั้งสองตัวนั่งอยู่บนจุดกึ่งกลางในแนวนอนระหว่างมัน — cpx = (prev.x + curr.x) / 2 — โดยกด control point ไว้ที่ความสูงของปลายแต่ละข้างเอง นั่นคือ flat-tangent smoothing แบบคลาสสิก: เส้นโค้งค่อย ๆ ผ่านทุกจุดข้อมูลโดยไม่เคยพุ่งเลยค่าสูงสุดขึ้นไปหรือต่ำกว่าค่าต่ำสุดลงมา ซึ่งเป็นสิ่งที่ Catmull-Rom spline แบบไร้เดียงสาจะทำ สำหรับ chart ที่ว่าด้วยจำนวนมีตติง "อย่าวาดโหนกที่บ่งบอกถึงค่าที่ไม่เคยเกิดขึ้น" ไม่ใช่ความสวยงามที่แถมมา มันคือความถูกต้อง พื้นที่ที่เติมเต็มคือเส้นโค้งเดียวกันที่ปิดตามด้านล่างและทาด้วย gradient แนวตั้ง (สีฟ้าคราม, จางจาก 30% ลงไปเกือบไม่เหลือ) และเส้นวาดตัวเองขึ้นมาด้วยอนิเมชัน pathLength ของ framer-motion จากซ้ายไปขวา

ใต้ SVG คือระบบท่อของข้อมูล และมันคือพระเอกเงียบ ๆ เมธอดใหม่ getAggregateStats() บน transcript repository รัน prepared statement สามตัวกับตาราง SQLite transcript_sessions บนเครื่อง: ยอดรวมตลอดกาล (จำนวน, ผลรวมของระยะเวลา, ระยะเวลาเฉลี่ย), ยอดนับแบบ rolling เจ็ดวัน, และ bucket ต่อวันด้วย GROUP BY date(created_at) แล้ว — และนี่คือรายละเอียดที่ทำให้ chart แข็งแรง — loop JavaScript เล็ก ๆ เดินไล่เจ็ดวันตามปฏิทินล่าสุด และเติมย้อนหลังทุกวันที่ query ไม่ได้คืนมา โดยดันค่า 0 ลงไป chart จึงถูก_การันตี_ว่าได้ครบเจ็ดจุดพอดีเสมอ

การันตีตัวนั้นแหละคือสิ่งที่ทำให้เคสขอบหายวับไป แทนที่จะต้องเอา guard ไปโปรยทั่วทั้ง view สัปดาห์ที่ว่างเปล่าน่ะเหรอ? ศูนย์เจ็ดตัว และ Math.max(count, 1) ที่ตัวหารช่วยกดเส้นให้แบนอยู่ล่างสุดแทนที่จะหารด้วยศูนย์ จุดข้อมูลเดียวที่จะทำให้สูตรระยะห่างแกน x อย่าง i / (n − 1) คายค่า NaN ออกมาน่ะเหรอ? เกิดขึ้นไม่ได้ — repository ไม่เคยคายอะไรออกมาน้อยกว่าเจ็ดจุด label วันในสัปดาห์ยัง parse แต่ละ bucket ที่ T12:00:00 แทนที่จะเป็นเที่ยงคืนเปล่า ๆ เพื่อไม่ให้สตริง YYYY-MM-DD ไถลไปเป็นวันก่อนหน้าใน timezone ที่ UTC ติดลบ ซ่อมรูปทรงของข้อมูลที่ต้นทาง แล้วโค้ดที่ render ก็มีสิทธิ์ไร้เดียงสาได้อย่างตั้งใจ

ทั้งหมดนี้อยู่บนเครื่อง query สถิติอ่านฐานข้อมูลในเครื่อง คืนค่าผ่าน IPC channel ที่มี type อย่าง transcript:get-stats และทำอนิเมชันเป็นตัวเลขนับขึ้นสี่ตัวตอน mount ไม่มีอะไรเกี่ยวกับประวัติมีตติงของคุณออกจากแล็ปท็อปไปเพื่อวาด chart นี้ — ซึ่งสำหรับเครื่องมือที่อัดบทสนทนาของคุณ นี่เป็นวิธีเดียวที่ยอมรับได้ในการสร้างหน้าวิเคราะห์

อีกหนึ่งบั๊ก เพราะการ redesign ลากพวกมันออกมาสู่แสงสว่าง

ที่ถูกมัดรวมมากับรีลีสเดียวกันคือตัวแก้ที่ไม่เกี่ยวอะไรกับ dashboard เลย แต่เกี่ยวข้องเต็ม ๆ กับหนี้ชนิดที่การ redesign ไปสะดุดเข้า สไตล์ scrollbar โหมดมืดของแอปได้ไถลไปเป็นนิยาม CSS สองตัวที่แข่งกันของ class เดียวกัน — ตัวสีม่วงที่เก่ากว่ากับตัวขาวบนพื้นดำที่ใหม่กว่า — และตัวไหนชนะขึ้นอยู่กับลำดับ cascade แย่กว่านั้น มีแต่ element ที่จำได้ว่าต้องเติม class เท่านั้นที่ได้ style เลย ส่วนที่เหลือทั้งหมดตกกลับไปที่ scrollbar สีอ่อนแบบ default และ scrollbar แนวนอนไม่เคยถูก style เลย เพราะกฎเก่าตั้งแค่ความกว้าง ไม่เคยตั้งความสูง ตัวแก้ลบนิยามทั้งสองทิ้ง, style scrollbar แบบ_global_บนทุก element, และเอา class ที่ตอนนี้ตายแล้วออกจากสิบคอมโพเนนต์ที่แบกมันไว้ มันคือ diff สองบรรทัดที่ทำซ้ำสิบครั้ง — ภาษีอันไร้ความหรูหราของการ style ของอย่างเดียวกันสองรอบแล้วปล่อยให้ทั้งสองรอด

สามสิ่งที่รีลีสนี้สอนเรา

  1. ลบเพื่อโฟกัส dashboard ดีขึ้นด้วยการทำ_น้อยลง_ — ทิ้งการควบคุมการอัดเสียงที่มันไม่เคยต้องการ แล้วกลายเป็นสิ่งเดียวที่ชัดเจน จอที่เป็นทั้ง viewer และรีโมตคือผลิตภัณฑ์ครึ่ง ๆ สองอัน; เลือกอันเดียว แล้วย้ายอีกอันไปที่ที่มันควรอยู่
  2. เลือก encoding ที่ข้อมูลสมควรได้ จำนวนที่เบาบางจากตัวเลขชุดเดียวกัน อ่านเป็นความว่างเปล่าใน bar chart และอ่านเป็นเทรนด์ใน area chart นี่ไม่ใช่การปั่น — มันคือการเลือกรูปทรงที่ซื่อตรง ที่ปล่อยให้ข้อมูลจริงและบางเบาได้สื่อสาร
  3. การันตีรูปทรงของข้อมูลจากต้นน้ำ loop เติมย้อนหลังจนครบเจ็ดคือเหตุผลที่โค้ด chart ไม่มี null check โปรยกระจาย: หารด้วยศูนย์, NaN จากจุดเดียว, และวันที่ขาด ล้วนหายไป เพราะ query สัญญาว่าได้ครบเจ็ด bucket พอดี การ render ที่แข็งแรงเริ่มจากชั้นล่างลงไปหนึ่งชั้น

สำหรับบทก่อนหน้าของเรื่องยุค v1 ดูสี่รีลีสใน 26 ชั่วโมง (v1.7.6–v1.8.1); และสำหรับภาพรวมทั้งเส้นเรื่อง ดูกายวิภาคของการส่งมอบซอฟต์แวร์ให้สมบูรณ์แบบ

บทความที่เกี่ยวข้อง

หน้า Login นั่นแหละคือ Demo
Steven
Steven3 นาทีที่อ่าน

หน้า Login นั่นแหละคือ Demo

GeekBye v1.7.5 เพิ่ม screenshot ของโปรดักต์ลงหน้า login แล้วลบทิ้งภายในวันเดียวกัน — ก่อนจะสร้างใหม่ด้วยคอมโพเนนต์ของจริงแทน แถมด้วย: ผู้ใช้ที่เร็วกว่า OCR และ style commit 25 ตัวในวันเดียวหน้าตาเป็นยังไงกันแน่

วิศวกรรม
ดีไซน์
UX
เอาการรีลีสใส่ไว้ใน CI, สองครั้ง
Steven
Steven4 นาทีที่อ่าน

เอาการรีลีสใส่ไว้ใน CI, สองครั้ง

GeekBye v1.8.4 ย้าย release build ทั้ง macOS และ Windows เข้าไปใน CI สิ่งที่ changelog ไม่ได้บอกคือ เราเคยลองแบบนี้มาก่อนหนึ่งครั้ง, ลบทิ้งหนึ่งเดือนต่อมาเพราะค่า runner, และเพิ่งทำให้มันอยู่ตัวได้ในครั้งที่สอง — เพราะพอถึงตอนนั้น release script ก็ทำงานด้วยมือได้แล้ว

วิศวกรรม
CI/CD
Desktop
ส่งมอบสามสิบภาษาโดยไม่มีตาข่ายรองรับ
Steven
Steven4 นาทีที่อ่าน

ส่งมอบสามสิบภาษาโดยไม่มีตาข่ายรองรับ

GeekBye v1.8.3 ต่อ react-i18next เข้าไปและแปลทั้งแอปเป็น 30 ภาษา ส่วนที่เป็น library นั้นเป็นงานปกติ ส่วนที่น่าสนใจคือสิ่งที่ขาดหายไป: ไม่มีการเช็ก key parity และไม่มีตัวดึงสตริง — ภาษาอังกฤษที่ hardcode ไว้จึงหลุดออกมา, typo ภาษาเดนมาร์กหลุดขึ้น production, และ changelog เองก็ตกลงกันไม่ได้ว่าแอปพูดได้ 28, 29 หรือ 30 ภาษากันแน่

วิศวกรรม
i18n
Desktop