Files
arcrun-collector/cmd/arcrun-app/check-render.sh
T
Leo 3d13e5a54e t193 二修:側邊欄版面+共用 CSS+App 內更新+兩支視覺機械閘
leo 08-04 看過 v0.17.0 後的四點,逐條回應:

## ① 「不會這裡又寫了一個新的 CSS?」——是,我又寫了一份
真兇:portal 的樣式內嵌在 HTML 裡,沒有獨立檔 ⇒ 四個站各抄一份、本來就在漂移。
解:抽出 InkStoneCo/arcrun-cis/css/arcrun-cis.css 當唯一真相源。
    daemon 的 style.css 現在**一個 hex 都沒有**,顏色全走 var(--...)。

## ② 「完全模仿 gdrive,左方側邊欄,在右方替換頁面」
底部 nav bar 拿掉(leo:「幾乎沒看過這種 nav bar 在下方的」)。
改成左側邊欄四頁:首頁/同步資料夾/AI 設定/版本與更新,右側換頁。
設定不再開 popup;只有「確認移除資料夾」才用覆蓋層。

## ③ 「既然是 Web,你做的時候無法檢視?」——可以,我之前沒做
新增 check-render.sh:headless Chrome 真的渲染一次並**量像素**。
它抓到一個肉眼容易誤判的真 bug:
  arcrun-lockup-h-paper-on-ink.png **自帶不透明 Ink 底板**(實測左上像素 RGBA=23,24,26,255),
  設計前提是貼在純 Ink 表面;我們背景有紙張紋理 ⇒ 出現突兀方塊。
  修:深色模式把品牌區做成純 Ink。實測落差 4(原本會是一個明顯方塊)。
過程中也發現自己對著**舊的 dist**除錯,浪費一輪——這支閘同時防這個。

## ④ 「檢查更新連到 docs,不正確,是直接在這裡進行」
新增「版本與更新」頁:顯示**現在版本 vs 最新版本**,
三段式全在 App 內完成——檢查/下載並安裝/重新啟動套用。
selfupdate 邏輯逐字沿用 arcrun-tray(含 t186 走 raw、t184 蓋正在跑的 .app),不重寫。

## 交貨閘(leo:「你做為檢查有嗎?沒有怎麼交貨?」)
check-cis.sh 擴充:版面檔不准出現任何 hex + 共用底層色票逐項比對。
兩支閘實跑全過。
2026-08-04 23:09:54 +08:00

72 lines
3.6 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# check-render.sh — **看得見的驗收**:用 headless Chrome 真的渲染一次並量像素(t193)
#
# 🔴 leo 2026-08-04:「既然是 Web,你做的時候**無法檢視**?例如用 chrome dev tool mcp?」
# ⇒ 對,可以。以後改完 UI 就跑這支,不要再拿沒看過的畫面交件。
#
# 它驗兩件肉眼容易漏、但機器一量就知道的事:
# ① lockup 底板與品牌區背景是否接合(paper-on-ink.png 自帶不透明 Ink 底板,
# 背景不對就會出現一個突兀方塊——leo 截圖裡看到的就是它)
# ② 深色模式的規則有沒有真的進到 build(曾發生 dist 是舊的、我卻對著舊圖除錯)
set -uo pipefail
cd "$(dirname "$0")"
CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
[ -x "$CHROME" ] || { echo "❌ 找不到 Chrome,跳過渲染檢查"; exit 0; }
[ -d frontend/dist ] || { echo "❌ 沒有 frontend/dist——先 wails build"; exit 1; }
W=$(mktemp -d); trap 'rm -rf "$W"; kill %1 2>/dev/null' EXIT
cp -R frontend/dist/* "$W/"
cat > "$W/mock.js" <<'JS'
window.go={main:{App:{GetState:async()=>({version:'v0',statusBig:'看守中',statusSub:'',
syncing:false,engine:'workers-ai',geminiKey:'',extractedOK:0,accounts:[]}),
SyncNow:async()=>{},PickFolder:async()=>'',AddFolder:async()=>{},RemoveFolder:async()=>{},
SetAI:async()=>{},OpenURL:()=>{},Connect:async()=>{},CheckUpdate:async()=>({})}}};
JS
python3 - "$W" <<'PY'
import re,sys
p=sys.argv[1]+'/index.html'; s=open(p,encoding='utf-8').read()
s=s.replace('src="/assets/','src="./assets/').replace('href="/assets/','href="./assets/')
s=s.replace('<script type="module"','<script src="./mock.js"></script>\n<script type="module"',1)
s=re.sub(r'<html[^>]*>','<html lang="zh-Hant" data-theme="dark">',s,count=1)
open(p,'w',encoding='utf-8').write(s)
PY
(cd "$W" && python3 -m http.server 8799 >/dev/null 2>&1) &
sleep 2
"$CHROME" --headless --disable-gpu --screenshot="$W/s.png" --window-size=1120,780 \
--hide-scrollbars --virtual-time-budget=3000 "http://localhost:8799/index.html" >/dev/null 2>&1
python3 - "$W/s.png" <<'PY'
import zlib,struct,sys
d=open(sys.argv[1],'rb').read(); pos=8; idat=b''; w=h=ct=0
while pos<len(d):
ln=struct.unpack('>I',d[pos:pos+4])[0]; t=d[pos+4:pos+8]
if t==b'IHDR': w,h,_,ct=struct.unpack('>IIBB',d[pos+8:pos+18])
if t==b'IDAT': idat+=d[pos+8:pos+8+ln]
pos+=12+ln
raw=zlib.decompress(idat); ch=4 if ct==6 else 3; stride=w*ch+1
rows=[]; prev=bytearray(w*ch)
for y in range(h):
f=raw[y*stride]; line=bytearray(raw[y*stride+1:(y+1)*stride])
for i in range(len(line)):
a=line[i-ch] if i>=ch else 0; b=prev[i]; c=prev[i-ch] if i>=ch else 0
if f==1: line[i]=(line[i]+a)&255
elif f==2: line[i]=(line[i]+b)&255
elif f==3: line[i]=(line[i]+(a+b)//2)&255
elif f==4:
pp=a+b-c; pa,pb,pc=abs(pp-a),abs(pp-b),abs(pp-c)
pr=a if (pa<=pb and pa<=pc) else (b if pb<=pc else c)
line[i]=(line[i]+pr)&255
rows.append(bytes(line)); prev=line
px=lambda x,y:tuple(rows[y][x*ch:x*ch+3])
brand=px(10,10); logo=px(60,47)
diff=max(abs(a-b) for a,b in zip(brand,logo))
print(f" 品牌區背景 {brand} logo 底板 {logo} 落差 {diff}")
if diff > 12:
print(" ❌ logo 底板與背景不接合——會出現方塊(leo 截圖裡那個)"); sys.exit(1)
print(" ✅ logo 底板與背景接合,無方塊")
# 深色模式有沒有生效:整體應該偏暗
if sum(px(600,400))/3 > 120:
print(" ❌ 深色模式沒生效(右側內容區偏亮)"); sys.exit(1)
print(" ✅ 深色模式生效")
PY