dsh-life-pack 0.3.3 → 0.3.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/README.md +38 -0
- package/dist/client.js +29 -9
- package/dist/client.js.map +1 -1
- package/dist/directory-browser-api.d.ts +3 -2
- package/dist/directory-browser-api.d.ts.map +1 -1
- package/dist/directory-browser-api.js +3 -2
- package/dist/directory-browser-api.js.map +1 -1
- package/dist/directory-browser-contract.d.ts +40 -3
- package/dist/directory-browser-contract.d.ts.map +1 -1
- package/dist/directory-browser-contract.js +56 -5
- package/dist/directory-browser-contract.js.map +1 -1
- package/dist/directory-browser-state.d.ts +29 -4
- package/dist/directory-browser-state.d.ts.map +1 -1
- package/dist/directory-browser-state.js +46 -2
- package/dist/directory-browser-state.js.map +1 -1
- package/dist/directory-browser-ui.d.ts +4 -1
- package/dist/directory-browser-ui.d.ts.map +1 -1
- package/dist/directory-browser-ui.js +12 -5
- package/dist/directory-browser-ui.js.map +1 -1
- package/package.json +6 -1
package/README.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# 爱生活(dsh-life-pack)
|
|
2
|
+
|
|
3
|
+
DSH 设置弹窗里的「爱生活」卡:把六个技能(备忘录、卡路里、私家大厨、居家管家、作息管家、饼干记账)的**设置页**收进一排页签,另带**配置体检**与**更新区**。
|
|
4
|
+
|
|
5
|
+
One settings card for the iLife home-life suite: memo, calorie, chef, home, schedule and bill in a tab bar, with a read-only config health check and an update panel.
|
|
6
|
+
|
|
7
|
+
## 装
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
dsh plugin add dsh-life-pack # 只要这张卡
|
|
11
|
+
dsh plugin add dsh-life-pack dsh-calorie # 卡 + 某一个技能(一条命令两个包)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
某个技能没装时,那一个页签的位置会变成**补装提示**,带上该条可直接复制的命令——不需要先装齐六个。
|
|
15
|
+
|
|
16
|
+
## 卡里有什么
|
|
17
|
+
|
|
18
|
+
| 区域 | 做什么 |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| 页签条 | 六个技能的设置页各自注册进「爱生活页签槽」;点谁切谁 |
|
|
21
|
+
| 配置体检 | 点一次,按家取数:顶部一行总账,每家一张表(每条:灯/标题/档/一句话/去哪修)。**只读**——不建目录、不改配置、不自动重置 |
|
|
22
|
+
| 更新区 | 七个包(它自己 + 六家)检查更新、逐个安装;装完按事实给下一步(重启 DSH 生效/重试/重新检查) |
|
|
23
|
+
| 面板入口 | 右上角:检查更新、去仓库点 Star、反馈问题;底部一句「作者其他插件」 |
|
|
24
|
+
|
|
25
|
+
## 它不做什么
|
|
26
|
+
|
|
27
|
+
不 import 任何一个单品包,也不依赖它们——依赖方向是反的(单品硬依赖 `dsh-life-pack`)。总管只做导航与聚合:六家的页面各自注册进槽位,缺席就渲染补装提示,不轮询、不代管。
|
|
28
|
+
|
|
29
|
+
## 配置与数据
|
|
30
|
+
|
|
31
|
+
- 配置:`~/.ilife/<技能>.yaml`(六个技能各一份,在各自的设置页里改)
|
|
32
|
+
- 数据目录:默认 `~/.ilife/data`(可在各技能设置页里改;留空=用默认)
|
|
33
|
+
|
|
34
|
+
## 链接
|
|
35
|
+
|
|
36
|
+
- 仓库与整套插件(六个单品同仓):<https://github.com/FeatherHunter/ilife>
|
|
37
|
+
- 问题与建议:<https://github.com/FeatherHunter/ilife/issues>
|
|
38
|
+
- 许可:MIT
|
package/dist/client.js
CHANGED
|
@@ -1747,10 +1747,15 @@ window.__ModuleLoader__.load({
|
|
|
1747
1747
|
if (typeof raw !== "object" || raw === null) return false;
|
|
1748
1748
|
return typeof raw.pick === "function";
|
|
1749
1749
|
}
|
|
1750
|
-
/**
|
|
1750
|
+
/** 三态判定:**先看两格浏览原语**(都在=应用内浏览器这条路在),再看单独的 `pick`,都没有=`none`。
|
|
1751
|
+
*
|
|
1752
|
+
* 为什么浏览优先:客户端命名空间上三条动词一定都在(由 `TYPERT_REMOTE.descriptors` 生成,
|
|
1753
|
+
* 与组合里服务哪种能力无关),所以两格原语在=这台宿主**可能**给浏览;真调一次才知道给不给,
|
|
1754
|
+
* 不给({@link CAPABILITY_REFUSED})再由调用方换系统对话框。反过来先认 `pick` 就会在
|
|
1755
|
+
* Desktop 这种「只服务 browse」的宿主上每次都去唤一次系统对话框、被拒一次(#744 实测)。 */
|
|
1751
1756
|
function pickerModeOf(raw) {
|
|
1752
|
-
if (
|
|
1753
|
-
return
|
|
1757
|
+
if (isBrowseFace(raw)) return "browse";
|
|
1758
|
+
return hasPickFn(raw) ? "native" : "none";
|
|
1754
1759
|
}
|
|
1755
1760
|
/** 平台回执 → 三态(**永不抛**):成功回的是信封里的 `value` 不是路径;`ok:false` 是「供不了」不是「取消」。
|
|
1756
1761
|
*
|
|
@@ -1771,8 +1776,10 @@ window.__ModuleLoader__.load({
|
|
|
1771
1776
|
} : { kind: "cancelled" };
|
|
1772
1777
|
}
|
|
1773
1778
|
const detail = answer.error?.message?.trim() ?? "";
|
|
1779
|
+
const code = answer.error?.code;
|
|
1774
1780
|
return {
|
|
1775
1781
|
kind: "unavailable",
|
|
1782
|
+
...typeof code === "string" && code !== "" ? { code } : {},
|
|
1776
1783
|
message: "打不开系统文件夹对话框" + (detail === "" ? "" : "(" + detail + ")") + ":请直接在框里填绝对路径。"
|
|
1777
1784
|
};
|
|
1778
1785
|
}
|
|
@@ -1944,7 +1951,15 @@ window.__ModuleLoader__.load({
|
|
|
1944
1951
|
listeners.add(listener);
|
|
1945
1952
|
return () => listeners.delete(listener);
|
|
1946
1953
|
},
|
|
1947
|
-
open
|
|
1954
|
+
async open() {
|
|
1955
|
+
const wanted = deps.initialPath.trim();
|
|
1956
|
+
if (wanted !== "") {
|
|
1957
|
+
await load(wanted);
|
|
1958
|
+
if (state.phase === "ready") return state;
|
|
1959
|
+
}
|
|
1960
|
+
await load(null);
|
|
1961
|
+
return state;
|
|
1962
|
+
},
|
|
1948
1963
|
enter: (path) => load(path),
|
|
1949
1964
|
async up() {
|
|
1950
1965
|
const listing = state.listing;
|
|
@@ -2053,6 +2068,7 @@ window.__ModuleLoader__.load({
|
|
|
2053
2068
|
});
|
|
2054
2069
|
return {
|
|
2055
2070
|
open: () => controller.open(),
|
|
2071
|
+
subscribe: (listener) => controller.subscribe(listener),
|
|
2056
2072
|
state: () => controller.getState(),
|
|
2057
2073
|
summary: () => describe(controller.getState()),
|
|
2058
2074
|
actions: {
|
|
@@ -2225,7 +2241,7 @@ window.__ModuleLoader__.load({
|
|
|
2225
2241
|
},
|
|
2226
2242
|
error: { color: "var(--dsw-alias-label-error, #e66)" }
|
|
2227
2243
|
};
|
|
2228
|
-
function crumbRow(state,
|
|
2244
|
+
function crumbRow(state, onEnter) {
|
|
2229
2245
|
const listing = state.listing;
|
|
2230
2246
|
if (listing === null || listing.crumbs.length === 0) return null;
|
|
2231
2247
|
const parts = [];
|
|
@@ -2244,7 +2260,7 @@ window.__ModuleLoader__.load({
|
|
|
2244
2260
|
},
|
|
2245
2261
|
title: crumb.path,
|
|
2246
2262
|
onClick: () => onEnter(crumb.path)
|
|
2247
|
-
},
|
|
2263
|
+
}, crumb.name));
|
|
2248
2264
|
});
|
|
2249
2265
|
return react.createElement("div", { style: S$1.crumbs }, parts);
|
|
2250
2266
|
}
|
|
@@ -2310,7 +2326,7 @@ window.__ModuleLoader__.load({
|
|
|
2310
2326
|
const listing = state.listing ?? EMPTY_LISTING;
|
|
2311
2327
|
const hidden = hiddenCount(listing);
|
|
2312
2328
|
const body = [];
|
|
2313
|
-
body.push(crumbRow(state,
|
|
2329
|
+
body.push(crumbRow(state, props.onEnter));
|
|
2314
2330
|
body.push(react.createElement("div", { style: S$1.pathRow }, react.createElement("input", {
|
|
2315
2331
|
style: S$1.input,
|
|
2316
2332
|
value: state.draft,
|
|
@@ -2391,11 +2407,15 @@ window.__ModuleLoader__.load({
|
|
|
2391
2407
|
/** 目录行接线的 React 半边:把操作半那组动作直接喂给组件。
|
|
2392
2408
|
*
|
|
2393
2409
|
* 操作半(`directory-browser-state.ts` 的 `createDirectoryRowBrowser`)不碰 React,
|
|
2394
|
-
* 这里只把它的 `actions` 摊进 props —— 于是「进哪一层」那套在 Node 里可测,这里只做接线。
|
|
2410
|
+
* 这里只把它的 `actions` 摊进 props —— 于是「进哪一层」那套在 Node 里可测,这里只做接线。
|
|
2411
|
+
*
|
|
2412
|
+
* `useSyncExternalStore` 是**必需**的:列举是异步落定的,不订阅的话这一帧画完就再没有重画,
|
|
2413
|
+
* 图上会永远停在「正在读取…」(#744 实测)。 */
|
|
2395
2414
|
function DirectoryBrowserFromRow(props) {
|
|
2415
|
+
const state = react.useSyncExternalStore(props.row.subscribe, props.row.state);
|
|
2396
2416
|
return DirectoryBrowser({
|
|
2397
2417
|
open: props.open,
|
|
2398
|
-
state
|
|
2418
|
+
state,
|
|
2399
2419
|
labels: props.labels,
|
|
2400
2420
|
...props.row.actions
|
|
2401
2421
|
});
|