diff --git a/CHANGELOG.md b/CHANGELOG.md index 34e36f9..cbfde0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,9 @@ `ui/components/ProgressPanel.tsx`,整理與關注都用它;讀數欄位由各頁自己決定。 - `npm run ui-preview` 一支腳本把四個頁面都走一遍(含互斥狀態與手機寬度、設定六章、時間軸播放頭的拖動), `npm run gen-icons` 由 SVG 原稿產生工具列圖示。 +- 整理的審核表可以**下載這一輪的 CSV**(作業列右段):BV 號、標題、來源夾、AI 建議、你最後選的、也留在原位、 + 低信心、已失效、理由、依據、狀態。整張表都寫出去——失效影片與你決定不搬的列一起留著才是完整紀錄。 + 關注那半邊本來就有 UID 與 CSV。 ### Changed @@ -64,6 +67,13 @@ ### Fixed +- **工具列圖示不會再變成點不開。** App 分頁一旦被導去別的網站(表格裡每個帳號與影片都可以點開,很容易發生), + 圖示就只會把那個分頁叫到前面,**點幾次都開不出 App 而且不說為什麼**——它記的是分頁 id,不看那個分頁現在是什麼。 + 現在改用 `runtime.getContexts()` 現場問,被導走或關掉都會重新開一個。副作用:這支 API 要 Chrome 116, + **最低瀏覽器版本從 114 提到 116**(相差三個月,且瀏覽器自動更新)。 +- **門檻欄位說得出自己收什麼。** 填 `9999` 或 `0` 會被彈回上一個合法值,之前畫面上一個字都沒有, + 看起來就像數字被吃掉;現在單位旁邊常駐寫著收得的範圍 `1–3,650`。同一行的說明也講清楚天數是 + **從最新一支影片**算起——圖文與動態不算,所以只發圖文的帳號會顯示「從未投稿」。 - **窄視窗下的勾選框與圖示按鈕點得到了。** 把分頁縮成半個螢幕(並排看 B 站是很自然的用法)之後, 勾選框只有 15×15、頂列的「重新檢查」只有 13×13,觸控筆電上幾乎點不中。現在這個寬度下撐到 24×24, 也就是 WCAG 2.2 AA 的下限;設定用的開關維持原樣。 diff --git a/PRODUCT.md b/PRODUCT.md index be1f197..4e64b33 100644 --- a/PRODUCT.md +++ b/PRODUCT.md @@ -42,7 +42,7 @@ Chrome MV3 擴充功能:WXT + React 19 + TypeScript,建置鏈與前身相同 ## Operating Context -- 執行環境:Chrome/Edge 114+,`chrome://extensions` 載入未封裝項目(是否上架商店未決定)。 +- 執行環境:Chrome/Edge 116+,`chrome://extensions` 載入未封裝項目(是否上架商店未決定)。 - 整個流程在擴充功能自己的分頁跑(App 分頁),service worker 只做 DNR header 規則、開分頁、影片頁「智慧收藏」的單支往返。 - 資料來源全部是 B 站公開 API(`api.bilibili.com`,由 `declarativeNetRequest` 補 Referer/Origin)與使用者自己填的 OpenAI 相容端點(只申請那一個 origin 的 optional host permission)。收藏夾端點見 `docs/design.md` 2,關注端點見 `docs/design.md` 11。 diff --git a/README.md b/README.md index 6d3f574..2f2c9ab 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ can be undone.

CI License: MIT - Chrome 114+ + Chrome 116+

**English** · [繁體中文](README.zh-Hant.md) @@ -28,7 +28,7 @@ nobody is unfollowed until you press the button. ## Install -Requires Node.js 20+ and Chrome or Edge 114+. +Requires Node.js 20+ and Chrome or Edge 116+. ```bash npm install @@ -114,6 +114,8 @@ Favourites: will make; the Organise page recomputes it for the actual number of videos. - **Deleting a folder is not implemented.** On Bilibili that destroys the videos inside it and cannot be undone. +- **Download the run as a CSV** — every row, with what the model suggested next + to what you chose, its reason and the fields it used. Follows: diff --git a/README.zh-Hant.md b/README.zh-Hant.md index 6ede960..59f07d9 100644 --- a/README.zh-Hant.md +++ b/README.zh-Hant.md @@ -6,7 +6,7 @@

CI License: MIT - Chrome 114+ + Chrome 116+

[English](README.md) · **繁體中文** @@ -22,7 +22,7 @@ B 站資料,攤成一張每一列都帶著證據的審核表,讓你勾選、 ## 安裝 -需要 Node.js 20+ 與 Chrome 或 Edge 114+。 +需要 Node.js 20+ 與 Chrome 或 Edge 116+。 ```bash npm install @@ -75,6 +75,7 @@ npm run build # 產出 .output/chrome-mv3 所以模型回答的是「這支最後該在哪些收藏夾」,可以同時建議留著*和*複製一份到別處(「也留在原位」)。 - **成本透明。** 設定頁算出這份設定會打哪些請求;整理頁再依這次實際的影片數算一次。 - **沒有刪除收藏夾。** 在 B 站那會連影片一起消失且不可復原。 +- **這一輪可以下載成 CSV**:每一列都寫出去,AI 建議了什麼與你最後選了什麼各佔一欄,還有理由與它用了哪些欄位。 關注: diff --git a/docs/design.md b/docs/design.md index e8a6c91..0ea3a39 100644 --- a/docs/design.md +++ b/docs/design.md @@ -429,6 +429,22 @@ DOM 依實測(2026-08):`.video-toolbar-left-main` 底下每個功能是一 | `resource/clean`(一次清掉整夾失效內容) | [2](#2-bilibili-api-查證)、[6.3](#63-失效影片) | | 逐夾打 `folder/info` 取簡介與封面 | [2](#2-bilibili-api-查證)(`folder/created/list` 一個請求就有) | +### 9.5 用記下來的 tab id 找 App 分頁 + +點工具列圖示要「已經開著就聚焦、沒開就新建」,第一版把 `tabs.create()` 回傳的 id 存進 `storage.session`, +下次用 `tabs.get(id)` 確認分頁還在不在。**這個判斷是錯的**:使用者在 App 分頁裡打開 B 站(很自然—— +表格裡每個帳號與影片都可以點開)之後,那個分頁的 id 還在、`tabs.get()` 照樣成功,於是圖示只是把一個 +B 站分頁叫到前面,**點幾次都開不出 App,而且完全不說為什麼**。 + +要修就得知道那個分頁現在的網址,而 `Tab.url` 在 MV3 需要 `tabs` 權限或相符的 host permission +(`chrome-extension://` 不可能出現在 host permission 裡)。加 `tabs` 權限會在安裝時跳出「讀取瀏覽記錄」的警告, +和本專案刻意選 `declarativeNetRequestWithHostAccess` 的理由(§8)互相牴觸,為了一個單例判斷不值得。 + +改用 `runtime.getContexts({ contextTypes: ['TAB'] })`:它就是為了回答「本擴充功能現在有哪些 context、在哪個分頁」 +而存在的,**不需要任何權限**(只回報自己的 context),`documentUrl` 直接可比。代價是它要 Chrome 116 +(`minimum_chrome_version` 從 114 提上去;114 與 116 只差三個月,且瀏覽器自動更新)。 +session storage 那份 id 一併刪掉,不留 fallback。 + ## 10. 未解決 還沒驗證、還沒決定的事。做到相關區域時順手收掉。 diff --git a/docs/how-it-works.md b/docs/how-it-works.md index 2b23215..cc3b867 100644 --- a/docs/how-it-works.md +++ b/docs/how-it-works.md @@ -31,6 +31,7 @@ 另一頁的主按鈕與寫入按鈕變灰,旁邊寫著「另一個任務還在跑——等它跑完,或到那一頁停止它」。 分頁之間切換不會打斷任務,切回來畫面接得上。目前在哪一頁寫在網址裡(`app.html#/follows`), 所以誤按上一頁(側鍵、`Alt+←`、觸控板兩指滑動)退回的是上一個分頁,不是離開整個工具。 +工具列圖示只會開**一個** App 分頁:已經開著就把它叫到前面,被你導去別的網站或關掉了就重新開一個。 --- @@ -72,7 +73,7 @@ | 狀態 | 意思 | 畫面上 | 能不能勾選 | |---|---|---|---| | 有影片 | B 站回了 `code 0` 且有影片清單 | 顯示最後一支影片的標題、日期、安靜天數 | 可以 | -| 確認無影片 | B 站回了 `code 0` 但清單是空的 | 「沒有影片」、天數欄顯示「從未投稿」並排在最不活躍的那端 | 可以(它比任何門檻都不活躍) | +| 確認無影片 | B 站回了 `code 0` 但影片清單是空的(**只算影片**,圖文與動態不算) | 「沒有影片」、天數欄顯示「從未投稿」並排在最不活躍的那端 | 可以(它比任何門檻都不活躍) | | 未知 | 請求失敗、B 站回非 0 code、或風控 | 「查不到」+原因,整列變淡、勾選框鎖著 | **不行**,也不會進匯出 | 還有一種「還沒查」——這一輪被你停掉或被風控停下時剩下的帳號。它們跟「未知」一樣鎖著,左邊分面裡都算在「查不到」, @@ -223,6 +224,9 @@ relation/whispers ×⌈M/50⌉ →(勾了「包含悄悄關注」才會) 有快取且還新鮮(30 天內、而且不是「未知」)的直接沿用。畫面上是儀表:目前階段、`done / total`、已用與預估剩餘、 實際速率、快取命中、查不到的數量,加上最近幾筆請求(端點、參數、狀態碼與耗時)。 +**這支端點只回影片。** 只發圖文、專欄或動態的帳號會被算成「從未投稿」,即使 B 站個人空間的「投稿」頁籤有東西。 +這是刻意的——活躍度看的是「還在不在產出影片」;審核表門檻下面那一行也寫著。 + 遇到 `-352`/`-412`/`-799` 或 HTTP 412:等 60 秒重試、再 120、再 240,還是不行就**整輪停下**, 把已經查到的帶進審核表,剩下的標成「還沒查」。按「停止」也是一樣的結果。 @@ -275,6 +279,10 @@ relation/whispers ×⌈M/50⌉ →(勾了「包含悄悄關注」才會) 沒有剪貼簿權限時改成下載 `.txt`);「下載 CSV」給名稱、分組、安靜天數、最新投稿、影片連結、個人空間。 兩者都再排除一次「未知」——不管畫面上勾了什麼,未能確認的帳號不會出現在檔案裡。 +整理那半邊的作業列也有一顆「下載 CSV」,存的是這一輪的分類結果:BV 號、標題、來源夾、**AI 建議了什麼**、 +**你最後選了什麼**、也留在原位、低信心、已失效、理由、依據、狀態。這裡**不**過濾:失效影片與你決定不搬的列 +一起留著才是完整紀錄——它不會被拿去執行任何寫入。 + ### 結果快照 跑完會把整張表(含勾選)存進 `chrome.storage.local`,關掉分頁再開會直接回到審核;「清除結果」才會丟掉。 diff --git a/docs/reviews/2026-09-06-full/report.md b/docs/reviews/2026-09-06-full/report.md index 20ed2b4..17d6c3a 100644 --- a/docs/reviews/2026-09-06-full/report.md +++ b/docs/reviews/2026-09-06-full/report.md @@ -402,6 +402,14 @@ T1 從 README 到能開始用、T2 把一個塞滿的收藏夾分類進正確的 - **改法**:確認 `.app` 或 `.app-body` 沒有多餘的 `tabindex="0"`/`tabindex="-1"` 造成的落點;當前分頁按鈕改成 `aria-current="page"` 而不是 `disabled`,讓它留在 Tab 順序裡。 - **工作量**:S +- **2026-09-08 覆查:一半修掉、另一半是誤判。** 分頁按鈕已加上 `aria-current="page"`(F08 那一批)。 + `` 那一站則不是缺陷:`scripts/ui-preview.mjs` 現在會在審核畫面從第一個分頁按鈕開始按 Tab 走完一整圈 + (回到起點才停),量到 **42 站、其中恰好 1 站在 body**,位置在作業列最後一顆「Clear results」與頂列 + 「Organise」之間——那是「文件最後一個可聚焦元素之後」的瀏覽器預設落點,任何網頁都有。 + 另外「當前分頁按鈕不在 Tab 順序裡」也不成立:它是普通 ` )} +