dsh-folia 4.12.2 → 4.12.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +45 -17
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -18318,13 +18318,13 @@ window.__ModuleLoader__.load({
|
|
|
18318
18318
|
const doc = (resp && resp.data) || null;
|
|
18319
18319
|
if (resp && resp.ok && doc && doc.ok) {
|
|
18320
18320
|
// 读"当前在用哪套皮肤"必须**由浏览器发**,不能走宿主代理:
|
|
18321
|
-
// `/api/skin-center/v2/*` 的读写被 DSH 自己的会话鉴权挡着,宿主 fetch 没有 cookie
|
|
18322
|
-
//
|
|
18323
|
-
//
|
|
18324
|
-
//
|
|
18321
|
+
// `/api/skin-center/v2/*` 的读写被 DSH 自己的会话鉴权挡着,宿主 fetch 没有 cookie ⇒ 401。
|
|
18322
|
+
// 路径用**相对 `/api/...`**:不要拼 `location.origin` —— 我们跑在宿主页面里,origin 不一定
|
|
18323
|
+
// 等于宿主 HTTP API 的源;拼错会得到一个不存在的地址,而它的 404 还会被误读成业务 404。
|
|
18324
|
+
// api-client 对 `/api/**` 原样放行(不补 /folia 前缀)。
|
|
18325
18325
|
if (doc.skinCenter === "present") {
|
|
18326
18326
|
try {
|
|
18327
|
-
const a = await apiJson(
|
|
18327
|
+
const a = await apiJson("/api/skin-center/v2/active", { parse: "always" });
|
|
18328
18328
|
if (a && a.ok) doc.active = (a.data && a.data.active) || "";
|
|
18329
18329
|
} catch { /* 读不到就显示"无使用中" */ }
|
|
18330
18330
|
}
|
|
@@ -18349,24 +18349,28 @@ window.__ModuleLoader__.load({
|
|
|
18349
18349
|
if (kind === "activate") setBusy("activate:" + ((payload && payload.id) || ""));
|
|
18350
18350
|
setNote(null);
|
|
18351
18351
|
try {
|
|
18352
|
-
// 切换皮肤**由浏览器直接写**皮肤中心自己的端点(同源请求自带会话);
|
|
18353
|
-
// 走宿主代理会 401 —— DSH 对 `/api/skin-center/v2/*` 的读写都做会话鉴权,宿主 fetch 没有 cookie。
|
|
18354
18352
|
if (kind === "activate") {
|
|
18355
18353
|
const wantId = (payload && payload.id) || null;
|
|
18356
|
-
//
|
|
18354
|
+
// ⚠️ 这里写入的必须是**皮肤中心自己认识的 id**(= skin.json 里的原始 id),
|
|
18355
|
+
// 不能用归一键:归一只是用来"比对",拿去当写值会变成另一个名字 ——
|
|
18356
|
+
// 皮肤中心的 activePostHandler 对解析不到的 id 回 404 skin-not-found(实测报错 skin-center-404)。
|
|
18357
18357
|
if (wantId) {
|
|
18358
|
-
const
|
|
18359
|
-
if (!
|
|
18358
|
+
const local = ((state && state.installed) || []).find((s) => s.id === wantId);
|
|
18359
|
+
if (!local) {
|
|
18360
18360
|
setNote({ ok: false, text: weT("这个皮肤不在本机(先安装)") });
|
|
18361
18361
|
return;
|
|
18362
18362
|
}
|
|
18363
18363
|
}
|
|
18364
18364
|
// 切换皮肤**由浏览器直接写**皮肤中心自己的端点(同源、自带会话);
|
|
18365
18365
|
// 走宿主代理会 401 —— DSH 对 `/api/skin-center/v2/*` 的读写都做会话鉴权,宿主 fetch 没有 cookie。
|
|
18366
|
-
// 统一走 api-client(不裸 fetch
|
|
18367
|
-
|
|
18366
|
+
// 统一走 api-client(不裸 fetch),路径用相对 `/api/...`(不拼 location.origin ——
|
|
18367
|
+
// 拼错会得到一个不存在的地址,404 又会被误读成业务 404)。
|
|
18368
|
+
const resp = await apiPostJson("/api/skin-center/v2/active", { active: wantId }, { parse: "always" });
|
|
18368
18369
|
if (!(resp && resp.ok)) {
|
|
18369
|
-
|
|
18370
|
+
// 把响应体里的 error 一起显示:`skin-not-found`(它的 catalog 不收)与"路径不对"
|
|
18371
|
+
// 从状态码上看都是 404,只有 body 能分开(实测踩过:把 URL 拼错当成了业务 404)。
|
|
18372
|
+
const detail = (resp && resp.data && resp.data.error) ? ":" + resp.data.error : "";
|
|
18373
|
+
setNote({ ok: false, text: weT("操作失败:{code}", { code: "skin-center-" + ((resp && resp.status) || 0) + detail }) });
|
|
18370
18374
|
return;
|
|
18371
18375
|
}
|
|
18372
18376
|
// 两条收敛路径:① 广播皮肤中心自己监听的 `dsh-skin-applied`(立即就地切换);
|
|
@@ -18470,6 +18474,23 @@ window.__ModuleLoader__.load({
|
|
|
18470
18474
|
const activeId = (state && state.active) || "";
|
|
18471
18475
|
/** 这个 id 是不是"正在用"的那套(两边都归一后比,站点 slug 可能带 skin- 前缀)。 */
|
|
18472
18476
|
const isActiveSkin = (id) => Boolean(activeId) && normSkinId(activeId) === normSkinId(id);
|
|
18477
|
+
|
|
18478
|
+
/**
|
|
18479
|
+
* 站点条目 → 本机已装皮肤的真实 id(皮肤中心只认这个)。
|
|
18480
|
+
*
|
|
18481
|
+
* 站点 slug 由标题生成、并为"全站唯一"可能被加 `skin-` 前缀;本机目录/皮肤中心用的是
|
|
18482
|
+
* skin.json 里的 id。两者可能不同(实测:站点 windows-xp-luna ↔ 本机 xp)。
|
|
18483
|
+
* 先按归一的 id 比,再按标题兜底;都没有就返回空串(表示"本机没有这一套")。
|
|
18484
|
+
*/
|
|
18485
|
+
const localIdOf = (siteItem) => {
|
|
18486
|
+
const list = (state && state.installed) || [];
|
|
18487
|
+
const byId = list.find((x) => normSkinId(x.id) === normSkinId(siteItem.id));
|
|
18488
|
+
if (byId) return byId.id;
|
|
18489
|
+
const wantTitle = String((siteItem && siteItem.title) || "").trim();
|
|
18490
|
+
if (!wantTitle) return "";
|
|
18491
|
+
const byTitle = list.find((x) => String(x.name || "").trim() === wantTitle);
|
|
18492
|
+
return byTitle ? byTitle.id : "";
|
|
18493
|
+
};
|
|
18473
18494
|
if (state) {
|
|
18474
18495
|
children.push(React.createElement("div", { key: "installed-head", className: "we-picker__hint" },
|
|
18475
18496
|
weT("本机已装({n})", { n: installed.length }),
|
|
@@ -18528,6 +18549,10 @@ window.__ModuleLoader__.load({
|
|
|
18528
18549
|
? [React.createElement("span", { key: "none", className: "we-picker__hint" }, weT("站点上还没有皮肤。"))]
|
|
18529
18550
|
: site.map((s) => {
|
|
18530
18551
|
const busyThis = busy === "install:" + s.id;
|
|
18552
|
+
// 站点条目的 slug 与本机皮肤 id **不一定相同**(站点 slug 由标题生成/为避撞名会加 skin- 前缀),
|
|
18553
|
+
// 而皮肤中心只认 skin.json 里的原始 id ⇒ 写之前必须换成**本机那个 id**,
|
|
18554
|
+
// 否则它的 activePostHandler 会回 404 skin-not-found(实测报错 skin-center-404)。
|
|
18555
|
+
const localId = localIdOf(s);
|
|
18531
18556
|
return React.createElement("div", { key: s.id, style: SKIN_STYLE.card },
|
|
18532
18557
|
s.thumbUrl
|
|
18533
18558
|
? React.createElement("div", {
|
|
@@ -18541,16 +18566,15 @@ window.__ModuleLoader__.load({
|
|
|
18541
18566
|
s.installed
|
|
18542
18567
|
// 已装的站点卡片也要能**直接应用**:用户是照着站点缩略图挑的,
|
|
18543
18568
|
// 让他再滚回上面的「本机已装」区去点一次是多余的一步(实测反馈)。
|
|
18544
|
-
// 站点 slug 与本机目录名可能差一个 `skin-` 前缀 ⇒ 用归一后的比较。
|
|
18545
18569
|
? [
|
|
18546
|
-
isActiveSkin(
|
|
18570
|
+
localId && isActiveSkin(localId)
|
|
18547
18571
|
? React.createElement("span", { key: "on", style: { ...SKIN_STYLE.badge, background: "rgba(60,160,90,0.55)" } }, weT("使用中"))
|
|
18548
18572
|
: React.createElement("button", {
|
|
18549
18573
|
key: "apply",
|
|
18550
18574
|
className: "we-picker__btn", type: "button",
|
|
18551
18575
|
disabled: Boolean(busy),
|
|
18552
|
-
onClick: () => act("activate", { id:
|
|
18553
|
-
}, busy === "activate:" +
|
|
18576
|
+
onClick: () => act("activate", { id: localId }, s.title),
|
|
18577
|
+
}, busy === "activate:" + localId ? weT("切换中…") : weT("应用")),
|
|
18554
18578
|
React.createElement("span", { key: "done", style: SKIN_STYLE.badge }, weT("已安装")),
|
|
18555
18579
|
]
|
|
18556
18580
|
: React.createElement("button", {
|
|
@@ -23826,6 +23850,10 @@ window.__ModuleLoader__.load({
|
|
|
23826
23850
|
// 应用侧封面恒 404,而同路径 curl 200)。
|
|
23827
23851
|
if (/^[a-z][a-z0-9+.-]*:/i.test(p) || p.startsWith('data:') || p.startsWith('blob:')) return p;
|
|
23828
23852
|
if (p.startsWith(BASE)) return p;
|
|
23853
|
+
// **宿主自己的 HTTP API** 挂在 `/api/**`(我们的是 `/folia/**`):这类绝对路径必须原样放行。
|
|
23854
|
+
// 补成 `/folia/api/...` 会得到一个不存在的路径 —— 那个 404 还会被调用方误读成"业务侧返回 404"
|
|
23855
|
+
// (实测:皮肤切换报 `skin-center-404`,真因是 URL 被我们拼错,不是皮肤中心说没这套皮肤)。
|
|
23856
|
+
if (p === '/api' || p.startsWith('/api/')) return p;
|
|
23829
23857
|
return BASE + (p.startsWith('/') ? p : '/' + p);
|
|
23830
23858
|
}
|
|
23831
23859
|
|