style(copy): fix remaining punctuation violations and make check:copy strict

Auto-fix of 602 string literals across 74 files (half-width punctuation next to
Chinese, parenthesised Chinese, quotes); biome reflow; e2/e6 assertions follow
the new full-width summaries. check:copy now runs with --strict in ci.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-28 21:34:51 +08:00
1 parent 0fccfe257d
commit fb84a71f80
76 files changed
+582 -570

No files matched your search

@@ -136,7 +136,7 @@ export function CredentialFields({
<FormField
label="TOTP 密钥"
htmlFor={id("totp")}
hint="站点开了二次验证时填 base32 密钥,登录时自动生成 6 位码"
hint="站点开了二次验证时填 base32 密钥,登录时自动生成 6 位码"
>
<Input
id={id("totp")}
@@ -157,7 +157,7 @@ export function CredentialFields({
<label htmlFor={id("cookie-only")} className="text-caption">
<span className="block font-medium text-foreground">只换 Cookie</span>
<span className="block text-muted-foreground">
密码加密保存,用于 Cookie 失效后自动重新登录。打开后登录成功只留 Cookie,不保存密码
密码加密保存,用于 Cookie 失效后自动重新登录。打开后登录成功只留 Cookie,不保存密码
</span>
</label>
</div>
@@ -168,7 +168,7 @@ export function CredentialFields({
htmlFor={id("cookie")}
required
error={errors.cookie}
hint="浏览器登录站点后,从开发者工具复制请求头里的整段 Cookie"
hint="浏览器登录站点后,从开发者工具复制请求头里的整段 Cookie"
>
<Textarea
id={id("cookie")}
@@ -198,7 +198,7 @@ export function CredentialFields({
<FormField
label="User-Agent"
htmlFor={id("ua")}
hint={value.kind === "cookie" ? "Cookie 与浏览器 UA 绑定时填写;留空用站点默认" : "留空用站点默认"}
hint={value.kind === "cookie" ? "Cookie 与浏览器 UA 绑定时填写;留空用站点默认" : "留空用站点默认"}
>
<Input
id={id("ua")}
@@ -36,7 +36,7 @@ export function SiteAccountsTab({
<EmptyState
icon={UserRound}
title="还没有账号"
description="填写凭证后,这里显示登录状态和登录历史"
description="填写凭证后,这里显示登录状态和登录历史"
action={
<Button size="sm" onClick={() => onDialog({ kind: "credentials", site })}>
<KeyRound />
@@ -110,8 +110,8 @@ function AccountBlock({
删除账号
</Button>
}
title={`删除账号「${a.label}」?`}
description="账号、凭证和用户数据历史一起删除,不可恢复。站点和资源保留。"
title={`删除账号「${a.label}」?`}
description="账号、凭证和用户数据历史一起删除,不可恢复。站点和资源保留。"
confirmLabel="删除账号"
destructive
onConfirm={async () => {
@@ -241,7 +241,7 @@ function PasskeyForm({ site, label, has }: { site: SiteListItem; label: string;
>
<h2 className="text-lead font-semibold text-foreground">Passkey</h2>
<p className="mb-3 text-caption text-muted-foreground">
用于 RSS 和下载链接,不参与登录。{has ? "已保存;再次保存会替换。" : "还没有保存。"}
用于 RSS 和下载链接,不参与登录。{has ? "已保存;再次保存会替换。" : "还没有保存。"}
</p>
<div className="flex flex-wrap items-start gap-2">
<FormField label="Passkey" htmlFor="pk" error={err} className="min-w-0 flex-1">
@@ -96,9 +96,9 @@ export function SiteAddDialog({ onClose }: { onClose: () => void }) {
const u = new URL(form.baseUrl.trim());
if (!/^https?:$/.test(u.protocol)) throw new Error();
} catch {
fe.baseUrl = "填完整地址,如 https://example.org";
fe.baseUrl = "填完整地址,如 https://example.org";
}
if (custom && !/^[a-z][a-z0-9_-]*$/.test(form.key.trim())) fe.key = "小写字母开头,只含小写字母、数字、- 和 _";
if (custom && !/^[a-z][a-z0-9_-]*$/.test(form.key.trim())) fe.key = "小写字母开头,只含小写字母、数字、- 和 _";
let body = null;
if (kinds.length) {
// 账号标签用站点标识:服务端 secret 名按标签生成且全局唯一,多站都叫 default 会冲突
@@ -258,14 +258,14 @@ export function SiteAddDialog({ onClose }: { onClose: () => void }) {
onClick={() => pick(CUSTOM)}
className="w-full rounded-lg border border-dashed border-border px-3 py-2 text-left text-caption text-muted-foreground hover:border-foreground/40 hover:text-foreground"
>
自定义 RSS 站点:只抓 Feed,不登录
自定义 RSS 站点:只抓 Feed,不登录
</button>
</section>
</>
)}
</div>
<p className="mt-3 text-meta text-muted-foreground">
"未实测"的定义没有在真实站点上验证过,列表和登录可能失败。
"未实测"的定义没有在真实站点上验证过,列表和登录可能失败。
</p>
</div>
) : step === 2 ? (
@@ -343,7 +343,7 @@ export function SiteAddDialog({ onClose }: { onClose: () => void }) {
<div className="min-w-0 space-y-3" data-state={phase ? "running" : "done"} aria-busy={busy}>
<p className="text-caption text-muted-foreground">
{created ? `已添加「${created.name}」。` : ""}
{phase ?? (login?.ok === false ? "可以返回修改凭证后重试,或先保存,之后在站点页处理。" : "")}
{phase ?? (login?.ok === false ? "可以返回修改凭证后重试,或先保存,之后在站点页处理。" : "")}
</p>
{phase ? <LoadingState rows={2} /> : null}
<LoginResultView
+1 -1
View File
@@ -150,7 +150,7 @@ function CheckButtons({ site, checks, compact }: Omit<Props, "onDialog"> & { com
variant="outline"
size="sm"
disabled={h || !site.enabled}
title={site.enabled ? "首页连通 + 登录态,走站点限流" : "站点已停用"}
title={site.enabled ? "首页连通 + 登录态,走站点限流" : "站点已停用"}
onClick={() => void checks.checkHealth(site)}
>
{h ? <LoaderCircle className="animate-spin" /> : <Activity />}
+11 -11
View File
@@ -256,7 +256,7 @@ export function CredentialDialog({
onClose();
}
} else {
toast.success("凭证已保存,刷新登录已排队");
toast.success("凭证已保存,刷新登录已排队");
onClose();
}
} catch (err) {
@@ -271,8 +271,8 @@ export function CredentialDialog({
<DialogTitle>更新凭证 · {site.name}</DialogTitle>
<DialogDescription>
{current
? `当前:${AUTH_KIND_LABEL[current.authKind]}。凭证加密保存,不回显;保存后立即刷新登录`
: "凭证加密保存,不回显;保存后立即刷新登录"}
? `当前:${AUTH_KIND_LABEL[current.authKind]}。凭证加密保存,不回显;保存后立即刷新登录`
: "凭证加密保存,不回显;保存后立即刷新登录"}
</DialogDescription>
</DialogHeader>
<form id="site-cred" onSubmit={submit} noValidate>
@@ -334,12 +334,12 @@ export function SiteEditSheet({ site, onClose }: { site: SiteListItem; onClose:
try {
new URL(v.baseUrl.trim());
} catch {
fe.baseUrl = "填完整地址,如 https://example.org";
fe.baseUrl = "填完整地址,如 https://example.org";
}
const posInt = (s: string, k: string, min = 1) => {
if (!s.trim()) return undefined;
const n = Number(s);
if (!Number.isInteger(n) || n < min) fe[k] = `填不小于 ${min} 的整数,留空用站点默认`;
if (!Number.isInteger(n) || n < min) fe[k] = `填不小于 ${min} 的整数,留空用站点默认`;
return n;
};
const rpm = posInt(v.rpm, "rpm");
@@ -436,7 +436,7 @@ export function SiteEditSheet({ site, onClose }: { site: SiteListItem; onClose:
</label>
</div>
{v.snapshotEnabled ? (
<FormField label="快照周期(分钟)" htmlFor="se-int" error={errors.intervalMin} hint="留空用站点默认">
<FormField label="快照周期(分钟)" htmlFor="se-int" error={errors.intervalMin} hint="留空用站点默认">
<Input
id="se-int"
inputMode="numeric"
@@ -450,10 +450,10 @@ export function SiteEditSheet({ site, onClose }: { site: SiteListItem; onClose:
<Switch id="se-proxy" checked={v.proxy} onCheckedChange={(x) => set("proxy", x)} disabled={busy} />
<label htmlFor="se-proxy" className="text-caption">
<span className="block font-medium text-foreground">使用代理</span>
<span className="block text-muted-foreground">走「站点默认」里的代理地址;没填代理地址时不生效</span>
<span className="block text-muted-foreground">走「站点默认」里的代理地址;没填代理地址时不生效</span>
</label>
</div>
<p className="text-meta text-muted-foreground">User-Agent 随凭证保存,在"更新凭证"里填写。</p>
<p className="text-meta text-muted-foreground">User-Agent 随凭证保存,在"更新凭证"里填写。</p>
</div>
</DetailSheet>
);
@@ -474,7 +474,7 @@ export function DeleteSiteDialog({
<ConfirmDialog
open
onOpenChange={(o) => !o && onClose()}
title={`删除站点「${site.name}」?`}
title={`删除站点「${site.name}」?`}
description="不可恢复。"
confirmLabel="删除站点"
destructive
@@ -491,8 +491,8 @@ export function DeleteSiteDialog({
>
<ul className="list-disc space-y-1 pl-5 text-caption text-muted-foreground">
<li>站点、{site.accounts?.length ?? 0} 个账号和全部凭证删除</li>
<li>已抓到的资源保留,标为"站点已关闭",不再产生新候选</li>
<li>该站 Feed 停用;已有下载任务按原策略继续</li>
<li>已抓到的资源保留,标为"站点已关闭",不再产生新候选</li>
<li>该站 Feed 停用;已有下载任务按原策略继续</li>
<li>同一站点以后可以重新添加</li>
</ul>
</ConfirmDialog>
+6 -6
View File
@@ -150,15 +150,15 @@ export function loginFailureText(
): { text: string; suggestCookie: boolean } {
switch (reason) {
case "captcha":
return { text: "登录失败:站点要求验证码。改用 Cookie,或稍后重试", suggestCookie: true };
return { text: "登录失败:站点要求验证码。改用 Cookie,或稍后重试", suggestCookie: true };
case "two_factor":
return { text: "登录失败:站点要求二次验证。填写 TOTP 密钥后重试,或改用 Cookie", suggestCookie: true };
return { text: "登录失败:站点要求二次验证。填写 TOTP 密钥后重试,或改用 Cookie", suggestCookie: true };
case "challenge":
return { text: "站点返回 Cloudflare 挑战页,无法自动登录。改用 Cookie", suggestCookie: true };
return { text: "站点返回 Cloudflare 挑战页,无法自动登录。改用 Cookie", suggestCookie: true };
case "bad_credentials":
return { text: "登录失败:账号或密码错误", suggestCookie: false };
return { text: "登录失败:账号或密码错误", suggestCookie: false };
case "account_blocked":
return { text: `登录失败:账号被封禁或未确认${message ? `(${message})` : ""}`, suggestCookie: false };
return { text: `登录失败:账号被封禁或未确认${message ? `(${message})` : ""}`, suggestCookie: false };
case "auth_expired":
return {
text:
@@ -172,7 +172,7 @@ export function loginFailureText(
case "unsupported":
return { text: message ?? "这个站点不支持该凭证类型的自动登录", suggestCookie: false };
default:
return { text: message ?? "登录失败,原因未知", suggestCookie: false };
return { text: message ?? "登录失败,原因未知", suggestCookie: false };
}
}
@@ -90,7 +90,7 @@ export function UserDataChart({ points }: { points: SiteUserDataPoint[] }) {
if (rows.length < 2)
return (
<p className="py-6 text-center text-caption text-muted-foreground">
{rows.length ? "只有 1 天的数据,满 2 天后显示趋势" : "还没有历史数据。刷新登录成功后每天记一次"}
{rows.length ? "只有 1 天的数据,满 2 天后显示趋势" : "还没有历史数据。刷新登录成功后每天记一次"}
</p>
);