dsh-folia 4.10.1 → 4.12.3
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/cordis.patch.yml +28 -11
- package/lib/client.js +160 -15
- package/lib/routes/skins.js +3 -0
- package/package.json +2 -1
package/cordis.patch.yml
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
# dsh-plugin-folia bundle patch
|
|
1
|
+
# dsh-plugin-folia bundle patch.
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
# subpackage rows: about-notice / mascot-avatar / media-bridge / fonts / fx /
|
|
5
|
-
# parallax / pet-link). Those seven now live in this package under
|
|
6
|
-
# `lib/components/` and are mounted from `apply()` in `lib/index.js`, so the row
|
|
7
|
-
# set is exactly one row: this bundle.
|
|
3
|
+
# Row set: this bundle + the skin centre it brings along.
|
|
8
4
|
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
5
|
+
# ── 为什么这里有第二条 row ──────────────────────────────────────────────────
|
|
6
|
+
# 我们不再自己实现皮肤渲染:皮肤包(`skin.json` + `skin.css` + 可选 `hooks.mjs`)由
|
|
7
|
+
# `@linxin666/dsh-client-ui-skin-center` 加载与启用,我们的「助手皮肤」页签只负责把站点 zip
|
|
8
|
+
# 解到它读的那个目录(`$DSH_HOME/skins`)。所以它必须是**装得上的**:本包把它列为
|
|
9
|
+
# `dependencies`,并在下面插一条 row —— 用户装 dsh-folia 就同时得到两件套,不用再单独装。
|
|
10
|
+
#
|
|
11
|
+
# ── 重复 row 为什么不会打起来(实测依据,不是猜测)────────────────────────
|
|
12
|
+
# 1) 宿主半边:它的 `apply` 走 `mountOnce('@linxin666/dsh-client-ui-skin-center', …)`,
|
|
13
|
+
# 以 `globalThis[Symbol.for('dsh-web.mounted-plugins')]` 记账 ⇒ 第二次挂载是空操作,
|
|
14
|
+
# 不会重复注册 webserver 路由。
|
|
15
|
+
# 2) 客户端半边:它的设置分区注册包在 `try { ctx.slots.register(...) } catch { return () => {} }`,
|
|
16
|
+
# 重复注册被吞掉 ⇒ 不会出现两张「皮肤」设置页。
|
|
17
|
+
# 于是「用户已有 dsh-web-all(它也插了一条 row)」与「只用我们」两种情形都成立。
|
|
18
|
+
#
|
|
19
|
+
# 版本:依赖写 `^0.4.8`(本仓实测过的版本线);它若大改 v1alpha1 契约,我们跟着升级即可。
|
|
20
|
+
# 判据:test/verify-skin-center-bundle.mjs 会同时钉住「声明了依赖」与「插了唯一 id 的 row」。
|
|
14
21
|
#
|
|
15
22
|
# A patch replaces the targeted row's whole `config`, so only additive `insert`
|
|
16
23
|
# rows appear here (we never override an existing shipped row).
|
|
@@ -18,3 +25,13 @@
|
|
|
18
25
|
- insert:
|
|
19
26
|
- id: folia
|
|
20
27
|
name: 'dsh-folia'
|
|
28
|
+
# 皮肤中心:独立 npm 包(BSD-3-Clause),本包作为依赖携带。
|
|
29
|
+
#
|
|
30
|
+
# ⚠️ row id **不能**以 `folia-` 开头:`lib/subpackage-boot.js#subpackageSpecifiers` 把
|
|
31
|
+
# 「id 以 `folia-` 开头的行」当作**我们自己的子包行**做启动自检(解析不到就抛,因为宿主
|
|
32
|
+
# 对行级失败是静默的)。给第三方行起 `folia-skin-center` 这种 id 会被误判成"我们的子包"
|
|
33
|
+
# ⇒ 自检去仓库 node_modules 里解析它,开发树里没有这个依赖就直接抛,整个 apply 失败。
|
|
34
|
+
# 所以这里用不撞前缀的 `skin-center`(也与 web-all 的 `web-ui-skin-center`、
|
|
35
|
+
# 官方包的 `ui-skin-center` 都不同名)。
|
|
36
|
+
- id: skin-center
|
|
37
|
+
name: '@linxin666/dsh-client-ui-skin-center'
|
package/lib/client.js
CHANGED
|
@@ -808,6 +808,24 @@ window.__ModuleLoader__.load({
|
|
|
808
808
|
"复制失败,请手动选中上面的命令": "Copy failed — select the command above manually",
|
|
809
809
|
"复制命令": "Copy command",
|
|
810
810
|
"先装皮肤中心,否则皮肤装好也没法启用": "Install the skin centre first, or the skin cannot be enabled",
|
|
811
|
+
|
|
812
|
+
// ── 助手皮肤:页签内直接切换(4.12.0)────────────────────────────────
|
|
813
|
+
" · 使用中:{name}": " · active: {name}",
|
|
814
|
+
"✓ ": "✓ ",
|
|
815
|
+
"正在恢复…": "Restoring…",
|
|
816
|
+
"恢复默认外观": "Restore default look",
|
|
817
|
+
"应用": "Apply",
|
|
818
|
+
"切换中…": "Switching…",
|
|
819
|
+
"使用中": "Active",
|
|
820
|
+
"正在使用,先切到别的再卸": "Currently active — switch to another skin before removing",
|
|
821
|
+
"已切换到:{name}": "Switched to: {name}",
|
|
822
|
+
"已恢复官方默认外观": "Restored the default look",
|
|
823
|
+
"这个皮肤不在本机(先安装)": "This skin is not installed locally — install it first",
|
|
824
|
+
"装皮肤中心后才能切换皮肤(见下面的安装命令)": "The skin centre is required to switch skins (install command below)",
|
|
825
|
+
"皮肤 id 不合法": "Invalid skin id",
|
|
826
|
+
"已安装:{name} —— 点「应用」就能切换": "Installed: {name} — press Apply to switch",
|
|
827
|
+
"本页签可以直接切换皮肤:装完点「应用」即可,无需打开设置页。皮肤包落在皮肤中心目录,两边读同一份。":
|
|
828
|
+
"This tab switches skins directly: install, then press Apply — no need to open the settings page. Packs land in the skin centre's folder and both sides read the same files.",
|
|
811
829
|
};
|
|
812
830
|
|
|
813
831
|
// ── 内联模块:src/i18n-copy-picker.js —— 英文词表域:壁纸选择器与快捷面板(picker-* · quick-panel · sidebar-right · theme-follow)(构建期注入;勿手改本段)──
|
|
@@ -18279,6 +18297,16 @@ window.__ModuleLoader__.load({
|
|
|
18279
18297
|
return (v / 1048576).toFixed(1) + " MB";
|
|
18280
18298
|
}
|
|
18281
18299
|
|
|
18300
|
+
/**
|
|
18301
|
+
* 皮肤 id 的归一键:站点上的 slug 是**全站唯一**的,撞名时上传工具会加 `skin-` 前缀
|
|
18302
|
+
* (实测:blue-throated-bee-eater 同时是桌宠 id ⇒ 站上叫 skin-blue-throated-bee-eater),
|
|
18303
|
+
* 而本机目录名用的是 skin.json 里的原始 id。两边比对必须先归一,否则"已安装"会显示成未安装。
|
|
18304
|
+
*/
|
|
18305
|
+
function normSkinId(raw) {
|
|
18306
|
+
const s = String(raw || "").trim().toLowerCase();
|
|
18307
|
+
return s.startsWith("skin-") ? s.slice(5) : s;
|
|
18308
|
+
}
|
|
18309
|
+
|
|
18282
18310
|
function SkinsTabPanel() {
|
|
18283
18311
|
const [state, setState] = React.useState(null);
|
|
18284
18312
|
const [busy, setBusy] = React.useState("");
|
|
@@ -18289,6 +18317,17 @@ window.__ModuleLoader__.load({
|
|
|
18289
18317
|
const resp = await apiJson("/skins/list" + (force ? "?refresh=1" : ""), { parse: "always" });
|
|
18290
18318
|
const doc = (resp && resp.data) || null;
|
|
18291
18319
|
if (resp && resp.ok && doc && doc.ok) {
|
|
18320
|
+
// 读"当前在用哪套皮肤"必须**由浏览器发**,不能走宿主代理:
|
|
18321
|
+
// `/api/skin-center/v2/*` 的读写被 DSH 自己的会话鉴权挡着,宿主 fetch 没有 cookie
|
|
18322
|
+
// ⇒ 代理拿到 401(实测报错「操作失败:skin-center-401」)。
|
|
18323
|
+
// 但**不许裸 fetch**(src/api-client.js 的不变量:业务代码零裸 fetch)——
|
|
18324
|
+
// apiUrl() 对带 scheme 的地址原样放行,而 location.origin 是同源 ⇒ 照旧带会话。
|
|
18325
|
+
if (doc.skinCenter === "present") {
|
|
18326
|
+
try {
|
|
18327
|
+
const a = await apiJson(location.origin + "/api/skin-center/v2/active", { parse: "always" });
|
|
18328
|
+
if (a && a.ok) doc.active = (a.data && a.data.active) || "";
|
|
18329
|
+
} catch { /* 读不到就显示"无使用中" */ }
|
|
18330
|
+
}
|
|
18292
18331
|
setState(doc);
|
|
18293
18332
|
if (doc.siteError && doc.siteError !== "site-off") {
|
|
18294
18333
|
setNote({ ok: false, text: weT("站点清单读不到:{msg}", { msg: String(doc.siteError) }) });
|
|
@@ -18304,10 +18343,47 @@ window.__ModuleLoader__.load({
|
|
|
18304
18343
|
React.useEffect(() => { load(false); }, [load]);
|
|
18305
18344
|
|
|
18306
18345
|
const act = async (kind, payload, label) => {
|
|
18346
|
+
// 结构性操作才锁整块 UI;`activate` 是幂等的、而且要让人能连点换皮肤,所以不锁。
|
|
18307
18347
|
const structural = kind === "install" || kind === "remove";
|
|
18308
18348
|
if (structural) setBusy(kind + ":" + ((payload && payload.id) || ""));
|
|
18349
|
+
if (kind === "activate") setBusy("activate:" + ((payload && payload.id) || ""));
|
|
18309
18350
|
setNote(null);
|
|
18310
18351
|
try {
|
|
18352
|
+
// 切换皮肤**由浏览器直接写**皮肤中心自己的端点(同源请求自带会话);
|
|
18353
|
+
// 走宿主代理会 401 —— DSH 对 `/api/skin-center/v2/*` 的读写都做会话鉴权,宿主 fetch 没有 cookie。
|
|
18354
|
+
if (kind === "activate") {
|
|
18355
|
+
const wantId = (payload && payload.id) || null;
|
|
18356
|
+
// ⚠️ 这里写入的必须是**皮肤中心自己认识的 id**(= skin.json 里的原始 id),
|
|
18357
|
+
// 不能用归一键:归一只是用来"比对",拿去当写值会变成另一个名字 ——
|
|
18358
|
+
// 皮肤中心的 activePostHandler 对解析不到的 id 回 404 skin-not-found(实测报错 skin-center-404)。
|
|
18359
|
+
if (wantId) {
|
|
18360
|
+
const local = ((state && state.installed) || []).find((s) => s.id === wantId);
|
|
18361
|
+
if (!local) {
|
|
18362
|
+
setNote({ ok: false, text: weT("这个皮肤不在本机(先安装)") });
|
|
18363
|
+
return;
|
|
18364
|
+
}
|
|
18365
|
+
}
|
|
18366
|
+
// 切换皮肤**由浏览器直接写**皮肤中心自己的端点(同源、自带会话);
|
|
18367
|
+
// 走宿主代理会 401 —— DSH 对 `/api/skin-center/v2/*` 的读写都做会话鉴权,宿主 fetch 没有 cookie。
|
|
18368
|
+
// 统一走 api-client(不裸 fetch):绝对 URL 原样放行,`location.origin` 是同源 ⇒ 会话照旧带上。
|
|
18369
|
+
const resp = await apiPostJson(location.origin + "/api/skin-center/v2/active", { active: wantId }, { parse: "always" });
|
|
18370
|
+
if (!(resp && resp.ok)) {
|
|
18371
|
+
setNote({ ok: false, text: weT("操作失败:{code}", { code: "skin-center-" + ((resp && resp.status) || 0) }) });
|
|
18372
|
+
return;
|
|
18373
|
+
}
|
|
18374
|
+
// 两条收敛路径:① 广播皮肤中心自己监听的 `dsh-skin-applied`(立即就地切换);
|
|
18375
|
+
// ② 它另外每 2 秒轮询 /api/skin-center/v2/active(事件丢了也会在 2 秒内跟上)。
|
|
18376
|
+
try {
|
|
18377
|
+
window.dispatchEvent(new CustomEvent("dsh-skin-applied", { detail: { id: wantId } }));
|
|
18378
|
+
} catch { /* 老环境没有 CustomEvent 也无所谓,②会兜住 */ }
|
|
18379
|
+
setNote({
|
|
18380
|
+
ok: true,
|
|
18381
|
+
text: wantId ? weT("已切换到:{name}", { name: label || "" }) : weT("已恢复官方默认外观"),
|
|
18382
|
+
});
|
|
18383
|
+
await load(true);
|
|
18384
|
+
return;
|
|
18385
|
+
}
|
|
18386
|
+
|
|
18311
18387
|
const resp = await apiPostJson("/skins/" + kind, payload || {}, { parse: "always" });
|
|
18312
18388
|
const r = (resp && resp.data) || null;
|
|
18313
18389
|
if (resp && resp.ok && r && r.ok) {
|
|
@@ -18316,7 +18392,7 @@ window.__ModuleLoader__.load({
|
|
|
18316
18392
|
ok: true,
|
|
18317
18393
|
text: r.exists
|
|
18318
18394
|
? weT("已安装过:{name}", { name: label || "" })
|
|
18319
|
-
: weT("已安装:{name} ——
|
|
18395
|
+
: weT("已安装:{name} —— 点「应用」就能切换", { name: label || "" }),
|
|
18320
18396
|
});
|
|
18321
18397
|
}
|
|
18322
18398
|
if (kind === "remove") setNote({ ok: true, text: weT("已卸载:{name}", { name: label || "" }) });
|
|
@@ -18330,6 +18406,9 @@ window.__ModuleLoader__.load({
|
|
|
18330
18406
|
'host-not-allowed': weT("下载地址不在白名单里"),
|
|
18331
18407
|
'site-off': weT("站点被关闭了(DSH_FOLIA_SITE=off)"),
|
|
18332
18408
|
'not-a-zip': weT("这个文件不是 zip"),
|
|
18409
|
+
'not-installed': weT("这个皮肤不在本机(先安装)"),
|
|
18410
|
+
'skin-center-missing': weT("装皮肤中心后才能切换皮肤(见下面的安装命令)"),
|
|
18411
|
+
'bad-id': weT("皮肤 id 不合法"),
|
|
18333
18412
|
};
|
|
18334
18413
|
setNote({ ok: false, text: map[code] || weT("操作失败:{code}", { code }) });
|
|
18335
18414
|
}
|
|
@@ -18375,7 +18454,7 @@ window.__ModuleLoader__.load({
|
|
|
18375
18454
|
key: "hint",
|
|
18376
18455
|
className: "we-picker__hint",
|
|
18377
18456
|
style: { margin: "6px 0 4px", opacity: 0.8 },
|
|
18378
|
-
}, weT("
|
|
18457
|
+
}, weT("本页签可以直接切换皮肤:装完点「应用」即可,无需打开设置页。皮肤包落在皮肤中心目录,两边读同一份。")));
|
|
18379
18458
|
}
|
|
18380
18459
|
|
|
18381
18460
|
// 提示行常驻占位(与开机动画/桌宠页签同一条纪律:不因 note 出现/消失让面板跳高度)
|
|
@@ -18390,25 +18469,73 @@ window.__ModuleLoader__.load({
|
|
|
18390
18469
|
}, note ? note.text : "\u00a0"));
|
|
18391
18470
|
|
|
18392
18471
|
const installed = (state && state.installed) || [];
|
|
18472
|
+
const activeId = (state && state.active) || "";
|
|
18473
|
+
/** 这个 id 是不是"正在用"的那套(两边都归一后比,站点 slug 可能带 skin- 前缀)。 */
|
|
18474
|
+
const isActiveSkin = (id) => Boolean(activeId) && normSkinId(activeId) === normSkinId(id);
|
|
18475
|
+
|
|
18476
|
+
/**
|
|
18477
|
+
* 站点条目 → 本机已装皮肤的真实 id(皮肤中心只认这个)。
|
|
18478
|
+
*
|
|
18479
|
+
* 站点 slug 由标题生成、并为"全站唯一"可能被加 `skin-` 前缀;本机目录/皮肤中心用的是
|
|
18480
|
+
* skin.json 里的 id。两者可能不同(实测:站点 windows-xp-luna ↔ 本机 xp)。
|
|
18481
|
+
* 先按归一的 id 比,再按标题兜底;都没有就返回空串(表示"本机没有这一套")。
|
|
18482
|
+
*/
|
|
18483
|
+
const localIdOf = (siteItem) => {
|
|
18484
|
+
const list = (state && state.installed) || [];
|
|
18485
|
+
const byId = list.find((x) => normSkinId(x.id) === normSkinId(siteItem.id));
|
|
18486
|
+
if (byId) return byId.id;
|
|
18487
|
+
const wantTitle = String((siteItem && siteItem.title) || "").trim();
|
|
18488
|
+
if (!wantTitle) return "";
|
|
18489
|
+
const byTitle = list.find((x) => String(x.name || "").trim() === wantTitle);
|
|
18490
|
+
return byTitle ? byTitle.id : "";
|
|
18491
|
+
};
|
|
18393
18492
|
if (state) {
|
|
18394
18493
|
children.push(React.createElement("div", { key: "installed-head", className: "we-picker__hint" },
|
|
18395
|
-
weT("本机已装({n})", { n: installed.length })
|
|
18494
|
+
weT("本机已装({n})", { n: installed.length }),
|
|
18495
|
+
activeId ? weT(" · 使用中:{name}", { name: activeId }) : ""));
|
|
18496
|
+
// 「恢复默认」:清空选择、回到官方外观。只有确实有皮肤在用的时候才有意义。
|
|
18497
|
+
if (activeId) {
|
|
18498
|
+
children.push(React.createElement("button", {
|
|
18499
|
+
key: "clear",
|
|
18500
|
+
className: "we-picker__btn", type: "button",
|
|
18501
|
+
style: { alignSelf: "flex-start", margin: "0 0 6px" },
|
|
18502
|
+
disabled: Boolean(busy),
|
|
18503
|
+
onClick: () => act("activate", { id: "" }, ""),
|
|
18504
|
+
}, busy === "activate:" ? weT("正在恢复…") : weT("恢复默认外观")));
|
|
18505
|
+
}
|
|
18396
18506
|
children.push(React.createElement("div", { key: "installed", style: SKIN_STYLE.grid },
|
|
18397
18507
|
installed.length === 0
|
|
18398
18508
|
? [React.createElement("span", { key: "none", className: "we-picker__hint" }, weT("还没有安装任何皮肤 —— 从下面的站点清单里挑一个。"))]
|
|
18399
|
-
: installed.map((s) =>
|
|
18400
|
-
|
|
18509
|
+
: installed.map((s) => {
|
|
18510
|
+
const isActive = isActiveSkin(s.id);
|
|
18511
|
+
const busyThis = busy === "activate:" + s.id;
|
|
18512
|
+
return React.createElement("div", {
|
|
18513
|
+
key: s.id,
|
|
18514
|
+
style: isActive ? { ...SKIN_STYLE.card, borderColor: "rgba(120,220,150,0.75)" } : SKIN_STYLE.card,
|
|
18515
|
+
},
|
|
18516
|
+
React.createElement("div", { style: { ...SKIN_STYLE.title, color: s.accent || undefined } },
|
|
18517
|
+
(isActive ? weT("✓ ") : "") + (s.name || s.id)),
|
|
18401
18518
|
React.createElement("div", { style: SKIN_STYLE.meta },
|
|
18402
18519
|
[s.version ? "v" + s.version : "", skinFmtBytes(s.bytes), s.hasHooks ? weT("含动效钩子") : ""]
|
|
18403
18520
|
.filter(Boolean).join(" · ")),
|
|
18404
18521
|
React.createElement("div", { style: { display: "flex", gap: "6px", alignItems: "center" } },
|
|
18522
|
+
// 「应用」= 写皮肤中心的 active + 广播 `dsh-skin-applied`,就地切换(不刷新页面)。
|
|
18523
|
+
isActive
|
|
18524
|
+
? React.createElement("span", { style: { ...SKIN_STYLE.badge, background: "rgba(60,160,90,0.55)" } }, weT("使用中"))
|
|
18525
|
+
: React.createElement("button", {
|
|
18526
|
+
className: "we-picker__btn", type: "button",
|
|
18527
|
+
disabled: Boolean(busy),
|
|
18528
|
+
onClick: () => act("activate", { id: s.id }, s.name),
|
|
18529
|
+
}, busyThis ? weT("切换中…") : weT("应用")),
|
|
18405
18530
|
React.createElement("button", {
|
|
18406
18531
|
className: "we-picker__btn", type: "button",
|
|
18407
|
-
disabled: Boolean(busy),
|
|
18532
|
+
disabled: Boolean(busy) || isActive,
|
|
18533
|
+
title: isActive ? weT("正在使用,先切到别的再卸") : undefined,
|
|
18408
18534
|
onClick: () => act("remove", { id: s.id }, s.name),
|
|
18409
18535
|
}, busy === "remove:" + s.id ? weT("卸载中…") : weT("卸载")),
|
|
18410
18536
|
),
|
|
18411
|
-
)
|
|
18537
|
+
);
|
|
18538
|
+
}),
|
|
18412
18539
|
));
|
|
18413
18540
|
}
|
|
18414
18541
|
|
|
@@ -18420,6 +18547,10 @@ window.__ModuleLoader__.load({
|
|
|
18420
18547
|
? [React.createElement("span", { key: "none", className: "we-picker__hint" }, weT("站点上还没有皮肤。"))]
|
|
18421
18548
|
: site.map((s) => {
|
|
18422
18549
|
const busyThis = busy === "install:" + s.id;
|
|
18550
|
+
// 站点条目的 slug 与本机皮肤 id **不一定相同**(站点 slug 由标题生成/为避撞名会加 skin- 前缀),
|
|
18551
|
+
// 而皮肤中心只认 skin.json 里的原始 id ⇒ 写之前必须换成**本机那个 id**,
|
|
18552
|
+
// 否则它的 activePostHandler 会回 404 skin-not-found(实测报错 skin-center-404)。
|
|
18553
|
+
const localId = localIdOf(s);
|
|
18423
18554
|
return React.createElement("div", { key: s.id, style: SKIN_STYLE.card },
|
|
18424
18555
|
s.thumbUrl
|
|
18425
18556
|
? React.createElement("div", {
|
|
@@ -18429,14 +18560,28 @@ window.__ModuleLoader__.load({
|
|
|
18429
18560
|
React.createElement("div", { style: SKIN_STYLE.title, title: s.title }, s.title),
|
|
18430
18561
|
React.createElement("div", { style: SKIN_STYLE.meta },
|
|
18431
18562
|
[skinFmtBytes(s.bytes), (s.tags || []).includes("动态") ? weT("动态") : ""].filter(Boolean).join(" · ")),
|
|
18432
|
-
|
|
18433
|
-
|
|
18434
|
-
|
|
18435
|
-
|
|
18436
|
-
|
|
18437
|
-
|
|
18438
|
-
|
|
18439
|
-
|
|
18563
|
+
React.createElement("div", { style: { display: "flex", gap: "6px", alignItems: "center", flexWrap: "wrap" } },
|
|
18564
|
+
s.installed
|
|
18565
|
+
// 已装的站点卡片也要能**直接应用**:用户是照着站点缩略图挑的,
|
|
18566
|
+
// 让他再滚回上面的「本机已装」区去点一次是多余的一步(实测反馈)。
|
|
18567
|
+
? [
|
|
18568
|
+
localId && isActiveSkin(localId)
|
|
18569
|
+
? React.createElement("span", { key: "on", style: { ...SKIN_STYLE.badge, background: "rgba(60,160,90,0.55)" } }, weT("使用中"))
|
|
18570
|
+
: React.createElement("button", {
|
|
18571
|
+
key: "apply",
|
|
18572
|
+
className: "we-picker__btn", type: "button",
|
|
18573
|
+
disabled: Boolean(busy),
|
|
18574
|
+
onClick: () => act("activate", { id: localId }, s.title),
|
|
18575
|
+
}, busy === "activate:" + localId ? weT("切换中…") : weT("应用")),
|
|
18576
|
+
React.createElement("span", { key: "done", style: SKIN_STYLE.badge }, weT("已安装")),
|
|
18577
|
+
]
|
|
18578
|
+
: React.createElement("button", {
|
|
18579
|
+
className: "we-picker__btn", type: "button",
|
|
18580
|
+
disabled: Boolean(busy),
|
|
18581
|
+
title: skinCenter === "absent" ? weT("先装皮肤中心,否则皮肤装好也没法启用") : undefined,
|
|
18582
|
+
onClick: () => act("install", { id: s.id, url: s.url }, s.title),
|
|
18583
|
+
}, busyThis ? weT("安装中…") : weT("安装")),
|
|
18584
|
+
),
|
|
18440
18585
|
);
|
|
18441
18586
|
}),
|
|
18442
18587
|
));
|
package/lib/routes/skins.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-folia",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.12.3",
|
|
4
4
|
"description": "Folia 壁纸引擎:把本机 Wallpaper Engine 壁纸搬进 DSH 界面(场景实时渲染 / 视频 / 网页),内置液态玻璃与 Folia 吉祥物,并可从自建站点拉取壁纸。单包形态(组件已合并)。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -193,6 +193,7 @@
|
|
|
193
193
|
}
|
|
194
194
|
},
|
|
195
195
|
"dependencies": {
|
|
196
|
+
"@linxin666/dsh-client-ui-skin-center": "^0.4.8",
|
|
196
197
|
"webwallgl": "^3.0.0",
|
|
197
198
|
"x11": "^4.3.1"
|
|
198
199
|
},
|