From 5aaf8cfaa48b955d6e90b4f39931ceefc7c582fe Mon Sep 17 00:00:00 2001 From: PathGao <42336971+PathGao@users.noreply.github.com> Date: Sat, 14 Nov 2026 14:49:12 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=86=E8=A7=89=E5=B0=8F=E8=B0=83=E6=95=B4?= =?UTF-8?q?=EF=BC=9A=E5=AF=B9=E9=BD=90=E8=BE=B9=E7=BC=98=E3=80=81=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E5=8F=A0=E5=9C=A8=E4=B8=80=E8=B5=B7=E7=9A=84=E7=BA=BF?= =?UTF-8?q?=E5=92=8C=E9=98=B4=E5=BD=B1=E3=80=81=E7=BB=9F=E4=B8=80=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E9=AB=98=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 侧边栏、设置页、弹窗、分拣台、摘读记录、关注、专注模式和 B站页面标记的一批小调整,逐条由用户看过前后截图后选定。 - 对齐:侧边栏内容左右对到 12px;分拣台头部四行右边缘、卡片底部「✎ 备注」左边缘对齐;设置页右栏三种块的文字对到 24px;专注模式按钮组右边缘对齐字幕栏。 - 少线少阴影:侧边栏回答里「复制」上面的分割线、历史对话每行的静止边框、只有错误时外面那层灰气泡;分拣台和摘读记录头部白卡的常驻阴影、当前卡片的阴影;设置页指引灰块下面和页签条上面的线;关注普通提示的线框;弹窗「详情」的边框。 - 统一尺寸:设置页控件 32px;专注模式圆按钮 36×36、面板控件 28px;分拣台内置播放框圆角和胶囊高度走 token;关注卡片间距同收藏夹。 - 照 DESIGN 的颜色表:设置页目录当前项改粉线;视频页那一行和动态筛选条的紫线改 2px 直线。 - 信息层级:分拣台封面去掉 AI 判断角标(判断行和按钮已经在说);专注模式字幕时间戳压轻;摘读记录状态行改成弹窗那一套(绿点、转圈、红框),「删除 AI 对话」缩到和同行一样大。 - 设置页 Obsidian 的「测试连接」挪到 Key 输入框右边,结果写在 Key 名字下面;MCP 的「安装」「Agent 最近的修改」两行改整宽。 - 修一处残留:窗口窄于 899px 时分拣台封面图只有 96×54,填不满 128×80 的封面框。 --- docs/DESIGN.md | 17 ++++++++-- extension/badges.css | 8 ++--- extension/content.css | 41 +++++++++++------------- extension/history/history.css | 16 +++++---- extension/history/history.js | 10 +++--- extension/options.css | 57 ++++++++++++++++++++++++--------- extension/options.html | 19 ++++++----- extension/popup.css | 1 - extension/sidepanel.css | 25 +++++++++------ extension/triage/fav-folders.js | 5 +-- extension/triage/follow.css | 12 +++---- extension/triage/triage.css | 37 ++++++++------------- 12 files changed, 139 insertions(+), 109 deletions(-) diff --git a/docs/DESIGN.md b/docs/DESIGN.md index e87db404..1fd51994 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -257,6 +257,12 @@ AI 打标签的建议在应用或放弃前一直存着,刷新或重开分拣 - 内置播放框的 UP 标签行只给关注数据里有的 UP:在关注的可以加标签;已取消关注的只显示原来的标签、没有「+ 标签」;从没关注过的整行不显示。为什么:UP 标签挂在关注列表的 UP 上,没关注的人没有地方挂;另存一份「打了标签但没关注的 UP」会多出一套看不见、不跟着刷新的数据。视频投稿同理反过来:那些视频不在收藏夹,只能给 UP 打标签,不能给视频打。 - B站 自动连播到下一个视频时,两种模式的内置播放框都跟着它:粉色卡片、标签行和 T 都换到新视频。关注里认不出新视频的 UP(不在视频投稿、也不在 UP 卡片的最近投稿里)时,UP 标签行不显示,T 不做事。为什么:留在前一个视频上,T 会给前一个 UP 打标签。 +### 专注模式 + +- 右上角的图标按钮是 36×36 的正圆,按钮组的右边缘和字幕栏的右边缘对齐。 +- 字幕行的时间戳比正文轻:`--mdg-faint`、常规字重、等宽数字。 +- 设置面板里的控件都是 28px 高;「跟随」「章节」是勾选框加文字,外面不套框。 + ### B站 页面上的标记 #### 定下来的决定(改之前先问用户) @@ -359,6 +365,9 @@ B站 页面上的 AI 判断照上表:值得留绿、可清理红、拿不准 - 设置页各节按这个顺序排:读字幕、笔记格式、观看进度、AI 平台、分拣台、MCP、Obsidian、数据与存储、高级。用到 AI 的三节(AI 平台、分拣台、MCP)挨在一起,和 AI 无关的观看进度排在它们前面;MCP 排在分拣台后面,因为它的开关管分拣台和收藏。为什么:按和 AI 有没有关系分组,找 AI 相关的设置不用跳着看(2026-11-10 用户定)。 - 设置页「AI 平台」的「视频」「网页」是页签,照 B站 空间页的页签:16px,当前的加粗、下面 3px 粉线,旁边小灰字写用在哪(「B站 · YouTube」「其他网站」),一次只显示一组;左右方向键切换。每次打开设置页在「视频」。为什么:两组的项同名,摆在一起分不清在改哪一组(2026-10-22 用户定)。 +- 设置页的输入框、下拉框和同一行里的按钮都是 32px 高(`--control-h`)。左侧目录的当前项照「颜色」表:灰底、左边一道粉线、字是 `--text`。 +- 设置页 Obsidian 的「测试连接」在 Key 输入框右边,结果写在「Local REST API Key」名字下面(成功绿字、失败红字),没测过时不占位置。2026-11-14 用户定:填完 Key 手就在那里,也和 Obsidian 插件自己「左名字右输入框」的设置页对得上。 +- 弹窗里能滚动的框(字幕预览)有边框,不能滚动的(「详情」)只有底色。2026-11-14 用户定:边框表示这里可以滚动。 #### 定下来的决定(改之前先问用户) @@ -374,12 +383,15 @@ B站 页面上的 AI 判断照上表:值得留绿、可清理红、拿不准 - 1024 宽时,第 2 行的搜索框和按钮换到页签下面一行。720 宽时没有左栏:左栏变成顶栏的下拉框(选项带数量),⚙ 放到第 2 行最后。 - 头部收起:第 2 行最前面有一个按钮,展开时是 ▴「收起头部」,收起时是 ▾「展开头部」,只有它收起和展开头部。收起后是一条细栏,只剩「名字 · 数量」、第 2 行的页签和右边的搜索 / 刷新 / 导出,没有封面,细栏自己是一张圆角白卡,上面留的空和展开时一样。滚动、回到顶上、焦点进到头部都不改它;切换收藏夹、页签和模式也不改。两种模式各记各的,重开分拣台后照旧;切到另一种模式时,它的收起状态当场生效,和重开分拣台一样不播动画。列表滚动后头部下沿出现阴影(展开时在第 4 行下面,收起时在细栏下面),滚回顶上就消失,说明卡片在头部底下;阴影不改收起状态。列表从头部底下穿过,收起和展开只是平移和淡出,卡片不跳;内置播放框的上沿跟着头部的下沿走。收起和展开用 0.15 秒,系统设了减少动态效果就不动画。760 及以下一样。选中栏和弹窗不管头部收没收,窗口矮也不特殊处理。不设快捷键:它是偶尔才改的布局开关,不是分拣时一直要按的。 - 内置播放框(点卡片后在右边打开的 B站 页面)没有顶栏。从上往下是:收藏夹的「视频标签」行、「UP 标签」行,然后是 B站 页面。关闭是播放框右上角骑在边框上的圆形 ×(`#viewerCloseBtn`,一半在框外,tooltip「关闭播放(Esc)」),或者按 Esc。标签行右边留出空,× 不压住标签。760 及以下内置播放框占掉列表的位置,× 还在同一个角上。 +- 封面上只放时长、观看进度和「看完了」,不放 AI 判断。2026-11-14 用户定:判断行的徽标和右边按钮的颜色已经在说同一个结论。 +- 当前卡片(键盘和鼠标所在的那张)只有 2px 深色框,没有阴影,和选中、播放两种状态一样只靠框。AI 没给判断时「保留」和「取消收藏」是同一种按钮样子。 +- 关注的 UP 卡片和收藏夹卡片同一套间距(卡片之间 12px、内边距 12px)。关注列表上面的普通提示只有灰字和按钮,没有框;警告才有琥珀框。 #### 定下来的决定(改之前先问用户) - 第 3、4 行开头有灰色大字「状态」「标签」,行与行之间有间距和细线。为什么:宽屏下一行两头离得太远,两行胶囊容易看混。 - 第 3 行「全部」后面有竖线,组和组之间也有竖线。 -- 卡片上不放勾选框:蓝框加蓝底已经够看出选中,圆勾在小封面上会压住 AI 判断标签和「看到 X%」标签(2026-10-09 去掉)。 +- 卡片上不放勾选框:蓝框加蓝底已经够看出选中,圆勾在小封面上会压住 AI 判断标签和「看到 X%」标签(2026-10-09 去掉;封面上的 AI 判断标签 2026-11-14 也去掉了)。 - 头部只由按钮收起和展开,不随滚动变(2026-10-14 用户定);封面不缩,静态排版不变。为什么:屏幕高度留给卡片,同时随时能操作筛选。头部放的是排序、筛选、标签这些长期设置,收不收由你定,跟着滚动自己变反而打断你。 - 内置播放框的关闭是右上角骑在边框上的圆形 ×,不放在标签行末尾(会像关闭那一行)。 @@ -389,7 +401,8 @@ B站 页面上的 AI 判断照上表:值得留绿、可清理红、拿不准 - 头部三行是一张白卡,和分拣台的一样(`--surface` 底、`--border` 描边、`--radius-lg` 圆角),上面留 14px、左右 16px(600 及以下都是 8px),行与行之间一道 `--border` 细线。第 2、3 行开头的行名、筛选片、右边的按钮和分拣台第 3、4 行一样。 - 卡片是分拣台的卡片:`--radius-lg` 圆角,卡片之间 12px,选中是蓝框加蓝底。标题 15px、字重 500,信息行 `--faint` 12px。星标单独一列,标题、信息行和正文左边对齐;★ 用 `--star` 黄,对着标题第一行居中。 -- 卡片右上角的按钮是两列一样宽的网格,继续问是灰底;「删除 AI 对话」是 `.quiet` 红字。 +- 卡片右上角的按钮是两列一样宽的网格,继续问是灰底;「删除 AI 对话」是 `.quiet` 红字,12px、22px 高,和同一行的「查看 N 轮问答」一样大。 +- 第 1 行的状态文字和弹窗的状态行是同一套:进行中是转圈,失败是红框,其余是绿点加粗。2026-11-14 用户定。 - 「全选」跟在第 2 行的状态片后面、同一行最右,放不下才换到下一行靠右。为什么:分拣台 760 及以下让状态片占满一行、按钮另起一行,是因为它的状态片多;摘读记录只有两三个,另起一行会空出一条。2026-10-22 用户定 - 760 及以下:两行按钮挪到正文和问答那一行下面,从正文左边开始,标题占满整行;「删除 AI 对话」照旧在问答那一行最右。第 1 行放不下时,搜索框和「清空全部 AI 对话」一起换到下一行,搜索框占满剩下的宽度。 diff --git a/extension/badges.css b/extension/badges.css index 22ef60bf..55d57152 100644 --- a/extension/badges.css +++ b/extension/badges.css @@ -65,8 +65,8 @@ span.mdg-badge.mdg-above { display: flex !important; max-width: 100%; margin: 0 gap: 8px; margin-top: 8px; padding: 6px 10px; - border-left: 3px solid #7c3ed1; - border-radius: 6px; + border-left: 2px solid #7c3ed1; + border-radius: 0 6px 6px 0; background: rgba(124, 62, 209, 0.07); font-size: 15px; line-height: 22px; @@ -186,8 +186,8 @@ span.mdg-ups.mdg-ups-line[data-mid] { display: flex !important; max-width: 100%; gap: 6px; margin-bottom: 8px; padding: 8px 12px; - border-left: 3px solid #7c3ed1; - border-radius: 6px; + border-left: 2px solid #7c3ed1; + border-radius: 0 6px 6px 0; background: var(--bg1, #fff); color: var(--text2, #61666d); font: 13px/18px -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif; diff --git a/extension/content.css b/extension/content.css index 0edb01e9..bacc387d 100644 --- a/extension/content.css +++ b/extension/content.css @@ -262,7 +262,7 @@ html[data-mdg-reader-mode="1"][data-mdg-reader-theme="dark"] { display: flex; inset: 0; justify-content: center; - padding: 18px; + padding: var(--mdg-space-4); position: fixed; z-index: 2147483647; } @@ -271,17 +271,17 @@ html[data-mdg-reader-mode="1"][data-mdg-reader-theme="dark"] { background: var(--mdg-surface); border: 1px solid var(--mdg-border); border-radius: var(--mdg-radius-lg); - box-shadow: 0 20px 60px rgba(15, 23, 42, 0.22); + box-shadow: var(--mdg-lift); color: var(--mdg-text); font-family: var(--mdg-font-sans); max-width: 360px; - padding: 18px; - width: calc(100vw - 36px); + padding: var(--mdg-space-4); + width: calc(100vw - 32px); } .mdg-confirm-title { font-size: var(--mdg-fs-lg); - font-weight: 700; + font-weight: 600; margin-bottom: var(--mdg-space-2); } @@ -300,7 +300,7 @@ html[data-mdg-reader-mode="1"][data-mdg-reader-theme="dark"] { line-height: 1.45; max-height: 96px; overflow: auto; - padding: 9px 10px; + padding: var(--mdg-space-2) var(--mdg-space-3); word-break: break-all; } @@ -308,11 +308,11 @@ html[data-mdg-reader-mode="1"][data-mdg-reader-theme="dark"] { display: flex; gap: var(--mdg-space-2); justify-content: flex-end; - margin-top: 14px; + margin-top: var(--mdg-space-4); } .mdg-confirm-actions button { - height: 34px; + height: 32px; padding: 0 14px; } @@ -388,7 +388,7 @@ html[data-mdg-reader-mode="1"][data-mdg-reader-theme="dark"] { background: var(--mdg-warn-bg); border: 1px solid var(--mdg-warn-border); border-radius: var(--mdg-radius-md); - box-shadow: 0 12px 32px rgba(15, 23, 42, 0.18); + box-shadow: var(--mdg-shadow-float); color: var(--mdg-warn); font-family: var(--mdg-font-sans); font-size: var(--mdg-fs-sm); @@ -581,7 +581,6 @@ body[data-mdg-reader-mode="1"] .mdg-reading-actions { gap: 10px; flex-wrap: wrap; justify-content: flex-end; - margin-right: -20px; margin-top: -8px; pointer-events: auto; transition: opacity 0.2s ease; @@ -606,10 +605,9 @@ body[data-mdg-reader-mode="1"] .mdg-reading-icon-btn { display: inline-flex; align-items: center; justify-content: center; - width: 34px; - height: 34px; - min-height: 36px; - padding: 0 14px; + width: 36px; + height: 36px; + padding: 0; border: 1px solid var(--mdg-border); border-radius: 999px; background: var(--mdg-surface); @@ -747,11 +745,7 @@ body[data-mdg-reader-mode="1"] .mdg-reading-toggle { align-items: center; gap: 6px; width: fit-content; - min-height: 32px; - padding: 0 11px; - border: 1px solid var(--mdg-border); - border-radius: 999px; - background: var(--mdg-surface); + min-height: 28px; color: var(--mdg-text); font-size: var(--mdg-fs-xs); box-sizing: border-box; @@ -765,11 +759,11 @@ body[data-mdg-reader-mode="1"] .mdg-reading-toggle input { body[data-mdg-reader-mode="1"] .mdg-reading-select { width: auto; min-width: 118px; - min-height: 36px; + min-height: 28px; margin: 0; padding: 0 12px; border: 1px solid var(--mdg-border); - border-radius: 999px; + border-radius: var(--mdg-radius-md); background: var(--mdg-surface); color: var(--mdg-text); font-size: var(--mdg-fs-xs); @@ -935,8 +929,9 @@ body[data-mdg-reader-mode="1"] .mdg-reading-item.is-active { body[data-mdg-reader-mode="1"] .mdg-reading-time { font-size: var(--mdg-reader-transcript-font-size); - font-weight: 600; - color: var(--mdg-text) !important; + font-weight: 400; + font-variant-numeric: tabular-nums; + color: var(--mdg-faint) !important; padding-top: 2px; line-height: 1.4; } diff --git a/extension/history/history.css b/extension/history/history.css index 320424d7..00322ddc 100644 --- a/extension/history/history.css +++ b/extension/history/history.css @@ -4,15 +4,19 @@ body { padding: 14px 16px 0; } .rec-head, .records { max-width: 1200px; margin: 0 auto; } /* ---------- the head: one white card as the 分拣台's, rows split by its thin rules (DESIGN 视觉设计 · 分拣台) ---------- */ -.rec-head { border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05); } +.rec-head { border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); } .rec-head > * { padding: 8px 16px; } .rec-head > * + * { border-top: 1px solid var(--border); } .rec-row1 { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding-block: 12px; } /* The search and 清空全部 wrap as one, so the rule never starts a line. */ .rec-find { display: flex; align-items: center; gap: 12px; margin-left: auto; } -.status { color: var(--muted); font-size: var(--fs-xs); } +.status { display: inline-flex; align-items: baseline; gap: 5px; color: var(--ok); font-size: var(--fs-xs); font-weight: 600; } .status:empty { display: none; } -.status.is-error { color: var(--danger); } +.status::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: currentColor; transform: translateY(-1px); } +.status[aria-busy="true"] { border: 0; background: none; font-weight: 400; } +.status[aria-busy="true"]::before { width: 0.9em; height: 0.9em; margin: 0; background: none; transform: translateY(0.1em); } +.status.is-error { padding: 3px var(--space-2); border: 1px solid var(--danger-border); border-radius: var(--radius-sm); background: var(--danger-bg); color: var(--danger); font-weight: 400; } +.status.is-error::before { content: none; } /* 清空全部 AI 对话: red text, no frame, a thin rule between it and the search. */ .rec-row1 .danger { position: relative; margin-left: 9px; border-color: transparent; background: none; color: var(--danger); } .rec-row1 .danger:hover { background: var(--danger-bg); } @@ -70,13 +74,13 @@ summary { cursor: pointer; color: var(--text-2); font-size: var(--fs-xs); } /* Two rows of two equal columns, right-aligned: 继续问 and 复制 Markdown beside the title, 下载 .md and 写入 Obsidian beside the meta line. */ -.entry-acts { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-left: 8px; } +.entry-acts { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); margin-left: 8px; } .entry-acts button { width: 100%; } /* The 「查看 N 轮问答」 line under the body and the buttons, 删除 AI 对话 at its right end (red text, no frame) and staying on that line when the 问答 open. */ .entry > .qa { grid-row: 2; grid-column: 2 / -1; display: flex; align-items: flex-start; gap: 8px; } .qa > details { flex: 1; min-width: 0; } -.qa > [data-act="delete"] { margin-top: -1px; color: var(--danger); } +.qa > [data-act="delete"] { height: 22px; color: var(--danger); font-size: var(--fs-xs); } .qa > [data-act="delete"]:hover { background: var(--danger-bg); color: var(--danger); } /* 继续问 is each card's main action: a gray fill with plain text (buttons never use blue text, DESIGN 视觉设计 · 颜色). */ button.ask { background: var(--field-bg); } @@ -91,7 +95,7 @@ button:disabled:has(> .write-label [aria-busy="true"]) { opacity: 0.7; cursor: p .rec-find { flex: 1 1 320px; min-width: 0; } .rec-find .search { flex: 1 1 auto; width: auto; min-width: 0; } /* The buttons go under the body, from its left edge, so nothing squeezes the title. */ - .entry-acts { grid-row: 3; grid-column: 2; justify-self: start; margin: 10px 0 0; } + .entry-acts { grid-row: 3; grid-column: 2; justify-self: start; margin: var(--space-2) 0 0; } } @media (max-width: 600px) { body { padding: 8px 8px 0; } diff --git a/extension/history/history.js b/extension/history/history.js index b92e4594..63e043a1 100644 --- a/extension/history/history.js +++ b/extension/history/history.js @@ -299,7 +299,8 @@ function aiProviderId() { } } const RECENT_CHECK = "在记录上逐个看,不对的按 T 或点「+ 标签」改"; -const aiProgress = (text) => (TagDialogs.ai.progress(aiTags, text), setStatus(text)); +// A batch's line (「AI 正在处理第 1 批…」, a wait) does not start with 正在 but is still in progress. +const aiProgress = (text) => (TagDialogs.ai.progress(aiTags, text), setStatus(text, false, null, true)); const aiTags = { who: "记录", sees: `标题、是视频还是网页、现有标签和你与 AI 的对话(问和答,每条记录最多 ${UI.READING_AI_CHARS} 字);没有对话的记录看分拣台的 AI 总结和备注`, @@ -385,7 +386,8 @@ async function runAi({ instruction, scope, allowRemove }) { const last = r.errors.at(-1); // A stop for a setup or access error says so with its remedy, the dialog open or not, as the 分拣台's banner. if (r.error) setStatus(r.proposal ? last : UI.aiTagsFailed(last), true, aiRemedy(r)); - else if (open) return; + // The dialog shows the result; the last batch's line is over. + else if (open) return setStatus(""); else if (r.proposal) setStatus("AI 打标签已完成,按 I 或点「✦ AI 打标签」确认建议"); else setStatus(UI.aiTagsFailed(last), true); } @@ -642,14 +644,14 @@ function render() { // 「正在…」 lines are in progress: aria-busy grays them (tokens.css) until the result replaces them. // error: a failure the user must handle (red); action: { label, run }, its remedy button after the text. -function setStatus(text, error = false, action = null) { +function setStatus(text, error = false, action = null, busy = text.startsWith("正在")) { els.status.textContent = text; if (action) { const btn = Object.assign(document.createElement("button"), { type: "button", className: "act-btn", textContent: action.label, onclick: action.run }); els.status.append(" ", btn); } els.status.classList.toggle("is-error", error); - if (text.startsWith("正在")) els.status.setAttribute("aria-busy", "true"); + if (busy) els.status.setAttribute("aria-busy", "true"); else els.status.removeAttribute("aria-busy"); } diff --git a/extension/options.css b/extension/options.css index bc6dd912..af285be8 100644 --- a/extension/options.css +++ b/extension/options.css @@ -58,7 +58,7 @@ input[type="password"], select { width: 100%; min-width: 0; - height: 34px; + height: var(--control-h); padding: 0 10px; } @@ -68,7 +68,7 @@ select { input[type="number"] { width: 72px; - height: 34px; + height: var(--control-h); padding: 0 8px; } @@ -275,10 +275,10 @@ h1 .brand-mark { text-decoration: none; } -.toc a[aria-current="true"], -.toc a[aria-current="true"] .ico { - background: var(--action-bg); - color: var(--link); +.toc a[aria-current="true"] { + background: var(--surface-muted); + box-shadow: inset 3px 0 0 var(--accent); + color: var(--text); font-weight: 600; } @@ -308,9 +308,9 @@ main { align-items: center; gap: 10px; margin: 0; - padding: 6px 10px; + padding: 6px 23px; border: 1px solid var(--danger-border); - border-radius: var(--radius-sm); + border-radius: var(--radius-lg); background: var(--danger-bg); color: var(--danger); font-size: var(--fs-sm); @@ -322,7 +322,7 @@ main { .noai { margin: 0; - padding: 12px 16px; + padding: 12px 24px; border-radius: var(--radius-lg); background: var(--surface); color: var(--text-2); @@ -456,8 +456,7 @@ input.switch:disabled { .kind-tabs { display: flex; gap: 32px; - margin-top: 8px; - border-top: 1px solid var(--border); + margin-top: var(--space-4); border-bottom: 1px solid var(--border); } @@ -676,7 +675,8 @@ details.adv[open] > summary::before { margin-bottom: 8px; } -.ai-provider-row :is(input, select) { +.ai-provider-row :is(input, select), +.ai-provider-test { height: var(--control-h); font-size: var(--fs-sm); } @@ -855,8 +855,12 @@ details.adv[open] > summary::before { } /* Obsidian */ +.guide-box + .row { + border-top: 0; +} + .guide-box { - margin: 4px 0 8px; + margin: 4px 0 var(--space-3); padding: 10px 16px; border-radius: var(--radius-md); background: var(--bg); @@ -916,15 +920,31 @@ details.adv[open] > summary::before { color: var(--text); } +/* The Obsidian key with 测试连接 beside it; the answer goes under the key's name. */ .test-line { display: flex; align-items: center; - gap: 12px; - font-size: var(--fs-sm); + gap: var(--space-2); +} + +.test-line .key { + flex: 1; + min-width: 0; +} + +.test-line button { + height: var(--control-h); +} + +.test-result { color: var(--ok); } -.test-line [data-error="true"] { +.test-result:empty { + display: none; +} + +.test-result[data-error="true"] { color: var(--danger); } @@ -954,6 +974,11 @@ button.var .mono { } /* Data */ +/* In a row the row's own padding is the gap below. */ +.row table.data { + margin-bottom: 0; +} + table.data { width: 100%; margin: 4px 0 20px; diff --git a/extension/options.html b/extension/options.html index 20dd8537..10104bde 100644 --- a/extension/options.html +++ b/extension/options.html @@ -279,12 +279,12 @@
打开后,Claude Code、Cursor、Codex 等 Agent 能通过本机的 MCP 服务用你的登录:搜索和读视频(字幕、评论、画面);读你的 B站收藏夹、关注、历史和稍后再看,以及 YouTube 的稍后观看、赞过的视频、订阅、历史记录和 YouTube 播放列表;改它们:移动、复制、移出收藏夹,新建、改名、删除收藏夹,写分拣台的 AI 判断、保留、备注和标签。把视频加进或移出稍后再看和 YouTube 播放列表。每次修改都记在下面,可以撤销。不含 API Key 和 AI 对话。开着时插件每分钟试连一次本机 127.0.0.1:47823,连上后插件后台会一直运行,不用时关掉。
在 Agent 里添加 MCP 服务,要先装好 Node 20 或更高版本。这样装的服务每次随 Agent 启动取最新版。Agent 说 MCP 服务比插件旧时(以前按本地文件夹装的会这样),用这里的命令重新添加一次,再重启 Agent。
B站和 YouTube 上的修改留最近 100 次,分拣台里的修改另留最近 100 次。撤销 B站上的修改会在 B站改回去:移走的移回去,移出收藏夹的加回原收藏夹。