@nonamelego/dsh-catppuccin 0.2.7-beta.1 → 0.2.7
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 +35 -7
- package/lib/client.js +204 -10
- package/lib/client.js.map +1 -1
- package/lib/index.js +258 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,7 +22,10 @@
|
|
|
22
22
|
|
|
23
23
|
它内置 Catppuccin 的四个主题——**Latte**、**Frappé**、**Macchiato**、**Mocha**——
|
|
24
24
|
把整个界面的配色都换成对应的 Catppuccin 色板;并在 **设置 → 常规 → 外观**
|
|
25
|
-
下方提供一行 **Catppuccin**
|
|
25
|
+
下方提供一行 **Catppuccin** 快捷切换,选择会自动保存、重启自动恢复——
|
|
26
|
+
偏好持久保存在 DSH home 下的 `catppuccin-state.json`(浏览器 localStorage
|
|
27
|
+
作为同机的即时缓存),因此即使在 **DSH Desktop** 里每次启动端口都变化,
|
|
28
|
+
主题和玻璃设置也能跨重启稳定恢复。
|
|
26
29
|
|
|
27
30
|
同时内置一套可开关的**玻璃质感**(Glassmorphism)皮肤:顶栏、侧边栏、
|
|
28
31
|
输入框、统计行、轨迹视图、聊天气泡、新会话按钮都变成磨砂玻璃卡片,
|
|
@@ -88,6 +91,18 @@ dsh plugin --profile web add @nonamelego/dsh-catppuccin
|
|
|
88
91
|
装完重启 `dsh web` 即可,`dsh plugin` 会自动把它加进 profile 的 bundles。
|
|
89
92
|
其他 profile 把命令里的 `web` 换成对应名字即可(如 `headless`)。
|
|
90
93
|
|
|
94
|
+
**[DSH Desktop](https://github.com/anywhere-labs/deepseek-harness-desktop)**:桌面版默认激活的 profile 就叫 `desktop`,把命令里的 `web`
|
|
95
|
+
换成 `desktop` 即可:
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
dsh plugin --profile desktop add @nonamelego/dsh-catppuccin
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
在桌面的 **DSH 终端**里运行即可(终端里的 `dsh plugin` 默认就作用于当前激活的
|
|
102
|
+
profile,也可以直接写 `dsh plugin add @nonamelego/dsh-catppuccin`;若你在托盘里
|
|
103
|
+
选了别的 profile,就把 `desktop` 换成那个名字),装完重启 **[DSH Desktop](https://github.com/anywhere-labs/deepseek-harness-desktop)** 生效。
|
|
104
|
+
从仓库安装的方式同理:`dsh plugin --profile desktop add https://github.com/NoNameLeGo/dsh-catppuccin-theme`。
|
|
105
|
+
|
|
91
106
|
### 方式二:从仓库安装
|
|
92
107
|
|
|
93
108
|
```sh
|
|
@@ -106,11 +121,12 @@ pnpm --dir C:\Users\LeGo\.dsh\profiles\web add link:D:\Vibe-Coding\dsh-catppucci
|
|
|
106
121
|
```
|
|
107
122
|
|
|
108
123
|
然后在 profile 的 `package.json` 中把 `@nonamelego/dsh-catppuccin` 加进 `dsh.profile.bundles`,
|
|
109
|
-
重启 `dsh web`
|
|
124
|
+
重启 `dsh web` 即可。在 [DSH Desktop](https://github.com/anywhere-labs/deepseek-harness-desktop) 中使用时,把上面的路径换成桌面 profile
|
|
125
|
+
(默认 `desktop`,位于 `~/.dsh/profiles/desktop`),装完重启 **[DSH Desktop](https://github.com/anywhere-labs/deepseek-harness-desktop)** 即可。
|
|
110
126
|
|
|
111
127
|
## 使用
|
|
112
128
|
|
|
113
|
-
1. 打开 Web GUI(默认 `http://127.0.0.1:3080
|
|
129
|
+
1. 打开 Web GUI(默认 `http://127.0.0.1:3080`);在 [DSH Desktop](https://github.com/anywhere-labs/deepseek-harness-desktop) 中则直接打开桌面应用即可。
|
|
114
130
|
2. 进入 **设置 → 常规**。
|
|
115
131
|
3. 在 **外观** 区域下方找到 **Catppuccin** 行,选择主题:
|
|
116
132
|
**Latte**(浅色)、**Frappé**、**Macchiato** 或 **Mocha**(深色)。
|
|
@@ -130,7 +146,11 @@ pnpm --dir C:\Users\LeGo\.dsh\profiles\web add link:D:\Vibe-Coding\dsh-catppucci
|
|
|
130
146
|
直接调和进纯色背景。
|
|
131
147
|
|
|
132
148
|
玻璃配色取自当前主题的设计 token,切换 Latte / Frappé / Macchiato / Mocha
|
|
133
|
-
|
|
149
|
+
时玻璃颜色自动跟随;设置最终持久保存在 DSH home 下的
|
|
150
|
+
`catppuccin-state.json`(同主题一起,跨重启、跨端口恢复),浏览器
|
|
151
|
+
localStorage 只作为即时缓存与多标签页同步——**DSH Desktop** 每次启动使用
|
|
152
|
+
不同的随机回环端口,localStorage 因此无法跨重启保留,而 DSH home 下的文件
|
|
153
|
+
不受端口影响,重启后自动恢复。
|
|
134
154
|
|
|
135
155
|
### 检查 Catppuccin 插件更新
|
|
136
156
|
|
|
@@ -149,6 +169,9 @@ pnpm --dir C:\Users\LeGo\.dsh\profiles\web add link:D:\Vibe-Coding\dsh-catppucci
|
|
|
149
169
|
升级到 `@latest`。
|
|
150
170
|
- 检查走宿主进程的 Node fetch(无跨域问题);离线或 registry 不可达时
|
|
151
171
|
显示具体失败原因并支持重试。
|
|
172
|
+
- **环境自适配**:在 [DSH Desktop](https://github.com/anywhere-labs/deepseek-harness-desktop) 中运行时,目标 profile 直接取桌面版的
|
|
173
|
+
当前 profile(不靠扫描猜测),提示与重启文案也切换为 Desktop 口径
|
|
174
|
+
(DSH 终端);普通 dsh web / CLI 下保持原有终端命令。
|
|
152
175
|
|
|
153
176
|
## 玻璃拟态(Glassmorphism)
|
|
154
177
|
|
|
@@ -204,13 +227,18 @@ node scripts/generate-palettes.mjs
|
|
|
204
227
|
A: 官方外观行只列出内置的浅色/深色/跟随系统偏好。四个主题在它正下方的
|
|
205
228
|
**Catppuccin** 行里。
|
|
206
229
|
- Q: **_"我的主题选择是怎么记住的?"_**
|
|
207
|
-
A:
|
|
208
|
-
|
|
230
|
+
A: 选择持久保存在 DSH home 下的 `catppuccin-state.json`(同一台机器的
|
|
231
|
+
DSH 共享这份偏好),浏览器 localStorage 作为即时缓存与多标签页同步。
|
|
232
|
+
因此普通 `dsh web`、`dsh web --port` 自定义端口,以及 **DSH Desktop**
|
|
233
|
+
(每次启动用随机回环端口)都能跨重启自动恢复;玻璃质感开关与各旋钮同样
|
|
234
|
+
持久保存。
|
|
209
235
|
- Q: **_"怎么知道这个插件有没有新版本?"_**
|
|
210
236
|
A: 设置 → 常规 → **检查 Catppuccin 插件更新** 一键检测本插件在 npm 上的最新版本,
|
|
211
237
|
发现新版会给出可复制的升级命令;也可以随时手动执行
|
|
212
238
|
`dsh plugin --profile web update @nonamelego/dsh-catppuccin`
|
|
213
|
-
(或重新 `add`
|
|
239
|
+
(或重新 `add` 最新版)。在 [DSH Desktop](https://github.com/anywhere-labs/deepseek-harness-desktop) 中,把 `web` 换成 `desktop`
|
|
240
|
+
(`dsh plugin --profile desktop update @nonamelego/dsh-catppuccin`),
|
|
241
|
+
或者直接在 DSH 终端里运行 `dsh plugin update`(默认作用于当前 profile)。
|
|
214
242
|
|
|
215
243
|
## 💝 致谢
|
|
216
244
|
|
package/lib/client.js
CHANGED
|
@@ -144,7 +144,9 @@ window.__ModuleLoader__.load({
|
|
|
144
144
|
"update.available": "发现新版本:",
|
|
145
145
|
"update.commandHint": "在终端运行以下命令升级(把 web 换成你的 profile 名):",
|
|
146
146
|
"update.commandHintDetected": "已自动探测到 profile「{profile}」,在终端运行以下命令升级:",
|
|
147
|
+
"update.commandHintDesktop": "已检测到你在使用 DSH Desktop,目标 profile「{profile}」,请在 DSH 终端中运行以下命令升级:",
|
|
147
148
|
"update.restartHint": "升级完成后重启 dsh web 生效。",
|
|
149
|
+
"update.restartHintDesktop": "升级完成后重启 DSH Desktop 生效。",
|
|
148
150
|
"update.copy": "复制命令",
|
|
149
151
|
"update.copied": "已复制 ✓",
|
|
150
152
|
"update.failed": "检查失败,请稍后重试。",
|
|
@@ -190,7 +192,9 @@ window.__ModuleLoader__.load({
|
|
|
190
192
|
"update.available": "New version available:",
|
|
191
193
|
"update.commandHint": "Run this in a terminal to upgrade (replace web with your profile name):",
|
|
192
194
|
"update.commandHintDetected": "Profile \"{profile}\" detected — run this in a terminal to upgrade:",
|
|
195
|
+
"update.commandHintDesktop": "DSH Desktop detected — target profile \"{profile}\", run this in the DSH terminal to upgrade:",
|
|
193
196
|
"update.restartHint": "Restart dsh web after the upgrade.",
|
|
197
|
+
"update.restartHintDesktop": "Restart DSH Desktop after the upgrade.",
|
|
194
198
|
"update.copy": "Copy command",
|
|
195
199
|
"update.copied": "Copied ✓",
|
|
196
200
|
"update.failed": "Check failed — try again later.",
|
|
@@ -965,7 +969,8 @@ window.__ModuleLoader__.load({
|
|
|
965
969
|
* Shipped knob defaults — aligned with the reference project
|
|
966
970
|
* (DSH-Transparent-UI-Plugin / Aqua): mica mode, blur 2px, frost 20
|
|
967
971
|
* (the 0-100 slider maps to a 0-1.4 alpha multiplier via frost/50, so 20
|
|
968
|
-
* reads as a light frost) and neutral backdrop brightness.
|
|
972
|
+
* reads as a light frost) and neutral backdrop brightness. MUST stay in sync
|
|
973
|
+
* with `DEFAULT_GLASS` in `src/state.ts` (guarded by `tests/state.spec.ts`).
|
|
969
974
|
*/
|
|
970
975
|
const SETTINGS_DEFAULTS = {
|
|
971
976
|
mode: "mica",
|
|
@@ -1109,6 +1114,34 @@ window.__ModuleLoader__.load({
|
|
|
1109
1114
|
this.listeners.delete(listener);
|
|
1110
1115
|
};
|
|
1111
1116
|
}
|
|
1117
|
+
/** The durable subset of the current layer state (no derived `dark`). */
|
|
1118
|
+
getRemoteState() {
|
|
1119
|
+
return {
|
|
1120
|
+
enabled: this.enabled,
|
|
1121
|
+
mode: this.settings.mode,
|
|
1122
|
+
blur: this.settings.blur,
|
|
1123
|
+
frost: this.settings.frost,
|
|
1124
|
+
brightness: this.settings.brightness
|
|
1125
|
+
};
|
|
1126
|
+
}
|
|
1127
|
+
/** Overlay durable state hydrated from the Host file: persist it to
|
|
1128
|
+
* localStorage (the cache), apply it to the live layer, and republish so
|
|
1129
|
+
* the settings row reflects the restored choice. */
|
|
1130
|
+
applyRemote(remote) {
|
|
1131
|
+
this.enabled = remote.enabled;
|
|
1132
|
+
this.settings = {
|
|
1133
|
+
mode: remote.mode === "compat" ? "compat" : "mica",
|
|
1134
|
+
blur: clampSetting("blur", remote.blur),
|
|
1135
|
+
frost: clampSetting("frost", remote.frost),
|
|
1136
|
+
brightness: clampSetting("brightness", remote.brightness)
|
|
1137
|
+
};
|
|
1138
|
+
writeEnabled(this.enabled);
|
|
1139
|
+
writeMode(this.settings.mode);
|
|
1140
|
+
writeSetting("blur", this.settings.blur);
|
|
1141
|
+
writeSetting("frost", this.settings.frost);
|
|
1142
|
+
writeSetting("brightness", this.settings.brightness);
|
|
1143
|
+
this.sync();
|
|
1144
|
+
}
|
|
1112
1145
|
/** Flip the layer: persist, then apply or retract every owned effect. */
|
|
1113
1146
|
setEnabled(value) {
|
|
1114
1147
|
if (value === this.enabled) return;
|
|
@@ -1508,6 +1541,7 @@ window.__ModuleLoader__.load({
|
|
|
1508
1541
|
opacity: phase === "checking" ? .6 : 1
|
|
1509
1542
|
};
|
|
1510
1543
|
const localInstall = payload?.ok === true && payload.installSource !== void 0 && payload.installSource !== "registry";
|
|
1544
|
+
const isDesktop = payload?.ok === true && payload.env === "desktop";
|
|
1511
1545
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1512
1546
|
style: {
|
|
1513
1547
|
borderBottom: "1px solid var(--dsw-alias-border-l2)",
|
|
@@ -1603,7 +1637,7 @@ window.__ModuleLoader__.load({
|
|
|
1603
1637
|
fontSize: 12,
|
|
1604
1638
|
lineHeight: "18px"
|
|
1605
1639
|
},
|
|
1606
|
-
children: payload.profileDetected === true && payload.profile !== void 0 ? t("update.commandHintDetected").replace("{profile}", payload.profile) : t("update.commandHint")
|
|
1640
|
+
children: isDesktop ? t("update.commandHintDesktop").replace("{profile}", payload.profile ?? "") : payload.profileDetected === true && payload.profile !== void 0 ? t("update.commandHintDetected").replace("{profile}", payload.profile) : t("update.commandHint")
|
|
1607
1641
|
}),
|
|
1608
1642
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1609
1643
|
style: {
|
|
@@ -1654,7 +1688,7 @@ window.__ModuleLoader__.load({
|
|
|
1654
1688
|
fontSize: 12,
|
|
1655
1689
|
lineHeight: "18px"
|
|
1656
1690
|
},
|
|
1657
|
-
children: t("update.restartHint")
|
|
1691
|
+
children: t(isDesktop ? "update.restartHintDesktop" : "update.restartHint")
|
|
1658
1692
|
})
|
|
1659
1693
|
] })] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1660
1694
|
style: {
|
|
@@ -1695,6 +1729,140 @@ window.__ModuleLoader__.load({
|
|
|
1695
1729
|
`${"@nonamelego/dsh-catppuccin".replace("/", "%2F")}`;
|
|
1696
1730
|
/** Host route the Client row fetches (exact match, same origin). */
|
|
1697
1731
|
const UPDATE_ROUTE_PATH = "/catppuccin/check-update";
|
|
1732
|
+
/** Host route answering the durable state (GET reads, PUT writes). */
|
|
1733
|
+
const STATE_ROUTE_PATH = "/catppuccin/state";
|
|
1734
|
+
/** The four registered Catppuccin theme ids. MUST stay in sync with the
|
|
1735
|
+
* `themeId` of `CATPPUCCIN_FLAVORS` in `src/client/palettes.ts` — guarded by
|
|
1736
|
+
* `tests/state.spec.ts` — because the persisted flavour value IS the theme id. */
|
|
1737
|
+
const CATPPUCCIN_THEME_IDS = [
|
|
1738
|
+
"catppuccin-latte",
|
|
1739
|
+
"catppuccin-frappe",
|
|
1740
|
+
"catppuccin-macchiato",
|
|
1741
|
+
"catppuccin-mocha"
|
|
1742
|
+
];
|
|
1743
|
+
/** Shipped glass defaults — aligned with `SETTINGS_DEFAULTS` in
|
|
1744
|
+
* `src/client/glass/glass-layer.ts` (guarded by `tests/state.spec.ts`). */
|
|
1745
|
+
const DEFAULT_GLASS = {
|
|
1746
|
+
enabled: false,
|
|
1747
|
+
mode: "mica",
|
|
1748
|
+
blur: 2,
|
|
1749
|
+
frost: 20,
|
|
1750
|
+
brightness: 50
|
|
1751
|
+
};
|
|
1752
|
+
/** A fully default state: no Catppuccin flavour and no glass. */
|
|
1753
|
+
function defaultState() {
|
|
1754
|
+
return {
|
|
1755
|
+
version: 1,
|
|
1756
|
+
flavor: "off",
|
|
1757
|
+
glass: { ...DEFAULT_GLASS }
|
|
1758
|
+
};
|
|
1759
|
+
}
|
|
1760
|
+
/** Clamp a finite number into [min, max]; non-finite values fall back. */
|
|
1761
|
+
function clampFinite(value, min, max, fallback) {
|
|
1762
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.min(max, Math.max(min, value)) : fallback;
|
|
1763
|
+
}
|
|
1764
|
+
/**
|
|
1765
|
+
* Normalize arbitrary input (JSON from disk or the wire) into a valid state:
|
|
1766
|
+
* unknown/missing fields fall back to defaults, out-of-range numbers clamp,
|
|
1767
|
+
* and unknown flavours/invalid enums fall back too. The Host applies this on
|
|
1768
|
+
* both read and write so a corrupt file or a hand-crafted payload can never
|
|
1769
|
+
* poison the plugin's settings.
|
|
1770
|
+
*/
|
|
1771
|
+
function sanitizeState(input) {
|
|
1772
|
+
const state = defaultState();
|
|
1773
|
+
if (typeof input !== "object" || input === null) return state;
|
|
1774
|
+
const raw = input;
|
|
1775
|
+
const flavor = raw.flavor;
|
|
1776
|
+
if (typeof flavor === "string" && CATPPUCCIN_THEME_IDS.includes(flavor)) state.flavor = flavor;
|
|
1777
|
+
else if (flavor === "off") state.flavor = "off";
|
|
1778
|
+
const glass = typeof raw.glass === "object" && raw.glass !== null ? raw.glass : {};
|
|
1779
|
+
state.glass.enabled = glass.enabled === true;
|
|
1780
|
+
state.glass.mode = glass.mode === "compat" ? "compat" : "mica";
|
|
1781
|
+
state.glass.blur = clampFinite(glass.blur, 0, 40, DEFAULT_GLASS.blur);
|
|
1782
|
+
state.glass.frost = clampFinite(glass.frost, 0, 100, DEFAULT_GLASS.frost);
|
|
1783
|
+
state.glass.brightness = clampFinite(glass.brightness, 0, 100, DEFAULT_GLASS.brightness);
|
|
1784
|
+
return state;
|
|
1785
|
+
}
|
|
1786
|
+
/** Whether a normalized state carries nothing beyond the shipped defaults —
|
|
1787
|
+
* i.e. the user never actually chose anything worth persisting. Used to tell
|
|
1788
|
+
* "no durable state yet" apart from "an explicit default choice". */
|
|
1789
|
+
function isDefaultState(state) {
|
|
1790
|
+
const expected = defaultState();
|
|
1791
|
+
return state.flavor === expected.flavor && state.glass.enabled === expected.glass.enabled && state.glass.mode === expected.glass.mode && state.glass.blur === expected.glass.blur && state.glass.frost === expected.glass.frost && state.glass.brightness === expected.glass.brightness;
|
|
1792
|
+
}
|
|
1793
|
+
//#endregion
|
|
1794
|
+
//#region src/client/state-sync.ts
|
|
1795
|
+
/**
|
|
1796
|
+
* Browser half of the durable Catppuccin state — a thin wrapper over the
|
|
1797
|
+
* Host's `/catppuccin/state` route (same-origin relative fetch, so it works on
|
|
1798
|
+
* DSH Desktop's per-launch random loopback port). The Host file is the source
|
|
1799
|
+
* of truth; this module adds the fetch wrapper plus a debounced trailing
|
|
1800
|
+
* writer so rapid knob drags coalesce into a single PUT. Every failure is
|
|
1801
|
+
* non-fatal: the plugin keeps working from browser localStorage alone.
|
|
1802
|
+
*/
|
|
1803
|
+
/** Read the durable state from the Host file (same-origin GET). */
|
|
1804
|
+
async function readDurableStateRemote() {
|
|
1805
|
+
try {
|
|
1806
|
+
const response = await fetch(STATE_ROUTE_PATH, { headers: { accept: "application/json" } });
|
|
1807
|
+
if (!response.ok) return {
|
|
1808
|
+
available: false,
|
|
1809
|
+
state: null
|
|
1810
|
+
};
|
|
1811
|
+
const payload = await response.json();
|
|
1812
|
+
if (payload.ok !== true) return {
|
|
1813
|
+
available: false,
|
|
1814
|
+
state: null
|
|
1815
|
+
};
|
|
1816
|
+
return {
|
|
1817
|
+
available: true,
|
|
1818
|
+
state: payload.state === null || payload.state === void 0 ? null : sanitizeState(payload.state)
|
|
1819
|
+
};
|
|
1820
|
+
} catch {
|
|
1821
|
+
return {
|
|
1822
|
+
available: false,
|
|
1823
|
+
state: null
|
|
1824
|
+
};
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
/** Write the durable state to the Host file (same-origin PUT). */
|
|
1828
|
+
async function persistDurableState(state) {
|
|
1829
|
+
try {
|
|
1830
|
+
return (await fetch(STATE_ROUTE_PATH, {
|
|
1831
|
+
method: "PUT",
|
|
1832
|
+
headers: {
|
|
1833
|
+
accept: "application/json",
|
|
1834
|
+
"content-type": "application/json"
|
|
1835
|
+
},
|
|
1836
|
+
body: JSON.stringify(sanitizeState(state))
|
|
1837
|
+
})).ok;
|
|
1838
|
+
} catch {
|
|
1839
|
+
return false;
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
let pendingTimer;
|
|
1843
|
+
let pendingGetState;
|
|
1844
|
+
/**
|
|
1845
|
+
* Debounced trailing persist: after a burst of changes (a slider drag emits a
|
|
1846
|
+
* stream of snapshot updates) the latest state is written to the Host once,
|
|
1847
|
+
* a short beat after the last change. Pass an accessor so the snapshot is
|
|
1848
|
+
* taken at flush time, never stale.
|
|
1849
|
+
*/
|
|
1850
|
+
function scheduleDurablePersist(getState, delayMs = 300) {
|
|
1851
|
+
if (pendingTimer !== void 0) window.clearTimeout(pendingTimer);
|
|
1852
|
+
pendingGetState = getState;
|
|
1853
|
+
pendingTimer = window.setTimeout(() => {
|
|
1854
|
+
pendingTimer = void 0;
|
|
1855
|
+
const state = pendingGetState;
|
|
1856
|
+
pendingGetState = void 0;
|
|
1857
|
+
if (state !== void 0) persistDurableState(state()).catch(() => {});
|
|
1858
|
+
}, delayMs);
|
|
1859
|
+
}
|
|
1860
|
+
/** Drop any queued persist (plugin unload / page teardown). */
|
|
1861
|
+
function cancelDurablePersist() {
|
|
1862
|
+
if (pendingTimer !== void 0) window.clearTimeout(pendingTimer);
|
|
1863
|
+
pendingTimer = void 0;
|
|
1864
|
+
pendingGetState = void 0;
|
|
1865
|
+
}
|
|
1698
1866
|
//#endregion
|
|
1699
1867
|
//#region \0dsh-css:/home/runner/work/dsh-catppuccin-theme/dsh-catppuccin-theme/src/client/glass/glass.module.css.mjs
|
|
1700
1868
|
const css = "[data-dsh-glass] body{--dsh-glass-card:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(52% * var(--dsh-glass-frost,1)), transparent);--dsh-glass-card-raised:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(64% * var(--dsh-glass-frost,1)), transparent);--dsh-glass-card-hover:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(76% * var(--dsh-glass-frost,1)), transparent);--dsh-glass-rim:color-mix(in srgb, var(--dsw-alias-label-primary) 18%, transparent);--dsh-glass-rim-soft:color-mix(in srgb, var(--dsw-alias-label-primary) 12%, transparent);--dsh-glass-edge:inset 0 1px 0 #ffffff6b;--dsh-glass-drop:0 10px 32px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 38%, transparent)}[data-dsh-glass] body[data-ds-dark-theme]{--dsh-glass-rim:color-mix(in srgb, var(--dsw-alias-label-primary) 24%, transparent);--dsh-glass-rim-soft:color-mix(in srgb, var(--dsw-alias-label-primary) 16%, transparent);--dsh-glass-edge:inset 0 1px 0 #ffffff14;--dsh-glass-drop:0 10px 32px #02060e73}[data-dsh-glass] body{background:color-mix(in srgb, color-mix(in srgb, var(--dsw-alias-bg-base), #fff calc(var(--dsh-glass-brightness-white,0) * 100%)), #000 calc(var(--dsh-glass-brightness-black,0) * 100%))}[data-dsh-glass] [data-dsh-glass-frame],[data-dsh-glass] [data-phase],[data-dsh-glass] [data-dsh-glass-details]{background:0 0}[data-dsh-glass-float] [data-phase=active] header{z-index:8;position:relative}[data-dsh-glass-float] [class*=banner]{position:static}[data-dsh-glass-float] [data-phase=active] [data-conversation-scroll]{margin-top:-95px;padding-top:107px}[data-dsh-glass] [data-phase] [class*=composerSeat][class*=composerSeat]{background:0 0}[data-dsh-glass] [data-dsh-glass-fade]{z-index:7;pointer-events:none;backdrop-filter:blur(5px);background:#ffffff2e;height:13px;position:fixed;left:0;right:0}[data-dsh-glass] body[data-ds-dark-theme] [data-dsh-glass-fade]{background:#00000024}[data-dsh-glass] [data-dsh-glass-fade=top]{top:0;-webkit-mask-image:linear-gradient(#000 0%,#0000 100%);mask-image:linear-gradient(#000 0%,#0000 100%)}[data-dsh-glass] [data-dsh-glass-fade=bottom]{bottom:0;-webkit-mask-image:linear-gradient(#0000 0%,#000 100%);mask-image:linear-gradient(#0000 0%,#000 100%)}[data-dsh-glass-float] [role=menu],[data-dsh-glass-float] [role=dialog],[data-dsh-glass-float] [role=alert],[data-dsh-glass-float] [data-dsh-glass-surface]{border-radius:14px}[data-dsh-glass-float] [role=menuitem],[data-dsh-glass-float] [role=tooltip],[data-dsh-glass-float] [class*=pill]{border-radius:8px}[data-dsh-glass-float] button[class*=button]{border-radius:10px}[data-dsh-glass-float] [class*=iconButton],[data-dsh-glass-float] [class*=searchButton]{border-radius:8px}[data-dsh-glass-float] [class*=block]{--dsl-code-block-border-radius:14px;--dsl-diff-radius:14px;--dsl-read-radius:14px;--dsl-terminal-radius:14px;--dsl-web-radius:14px;--dsl-search-radius:14px;border-radius:14px}[data-dsh-glass-float] [data-dsh-glass-add]{background:var(--dsh-glass-card-raised);border:1px solid var(--dsh-glass-rim);box-shadow:var(--dsh-glass-edge);backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass-float] [data-dsh-glass-add]:hover:not(:disabled){background:var(--dsh-glass-card-hover)}[data-dsh-glass-float] [data-dsh-glass-surface]{background:var(--dsh-glass-card-raised);border:1px solid var(--dsh-glass-rim);box-shadow:var(--dsh-glass-edge);backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass-float] [data-dsh-glass-surface]:hover:not(:disabled){background:var(--dsh-glass-card-hover)}[data-dsh-glass-float] [class*=bubble]{border:1px solid var(--dsh-glass-rim-soft);background:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(46% * var(--dsh-glass-frost,1)), transparent);backdrop-filter:blur(var(--dsh-glass-blur,14px));border-radius:14px}[data-dsh-glass-float] [class*=card]{border-radius:14px}[data-dsh-glass-float] header{border:1px solid var(--dsh-glass-rim);background:var(--dsh-glass-card);box-shadow:var(--dsh-glass-edge), var(--dsh-glass-drop);backdrop-filter:blur(var(--dsh-glass-blur,14px));border-bottom-color:#0000;border-radius:20px;margin:12px 16px 0;padding:10px 16px 8px}[data-dsh-glass-float] header:after{display:none}[data-dsh-glass-float] [data-dsh-glass-frame][data-sidebar-collapsed] header{margin-left:28px}[data-dsh-glass-float] [class*=sidebarCol]{--dsw-specific-sidebar-fill:transparent;z-index:9;border:1px solid var(--dsh-glass-rim);border-right-color:color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 40%, transparent);background:var(--dsh-glass-card);box-shadow:var(--dsh-glass-edge), var(--dsh-glass-drop);border-radius:20px;margin:12px;padding:10px 12px 14px;position:relative;overflow:hidden}[data-dsh-glass-float] body[data-ds-dark-theme] [class*=sidebarCol]{border-right-color:color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 22%, transparent)}[data-dsh-glass-float] [class*=sidebarCol]:has([role=dialog]){backdrop-filter:none}[data-dsh-glass-float] [class*=sidebarCol]{backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass-float] [data-dsh-glass-frame][data-sidebar-collapsed] [class*=sidebarCol]{transition:margin .15s var(--ds-ease-in-out), border-radius .15s var(--ds-ease-in-out);border-radius:16px;margin:12px -12px 12px 12px;padding:0}[data-dsh-glass-float] [data-dsh-glass-frame]:not([data-sidebar-collapsed]) [data-dsh-glass-sidebar-root]{width:100%!important}[data-dsh-glass-float] [data-dsh-glass-trajectory]{border:1px solid var(--dsh-glass-rim);background:var(--dsh-glass-card);width:calc(100% - 32px);height:calc(100% - 20px);box-shadow:var(--dsh-glass-edge), var(--dsh-glass-drop);backdrop-filter:blur(var(--dsh-glass-blur,14px));border-radius:20px;margin:8px 16px 12px;overflow:hidden}[data-dsh-glass-float] [data-dsh-glass-trajectory] [role=toolbar],[data-dsh-glass-float] [data-dsh-glass-trajectory] section[aria-label=Trajectory\\ timeline]{background:0 0}[data-dsh-glass-float] [data-composer-card],[data-dsh-glass-float] [data-composer-card]:after{border-radius:24px}[data-dsh-glass-float] [data-composer-card]{z-index:8;background:var(--dsh-glass-card);border:1px solid var(--dsh-glass-rim);box-shadow:var(--dsh-glass-edge), var(--dsh-glass-drop);backdrop-filter:blur(var(--dsh-glass-blur,14px));position:relative}[data-dsh-glass-float] [data-dsh-glass-inputbar]:not([class*=hero]):not(:has([data-dsh-glass-stats])){padding-bottom:12px}[data-dsh-glass][data-dsh-glass-float] [data-dsh-glass-inputbar]:has([data-dsh-glass-stats]){border:1px solid var(--dsh-glass-rim);background:var(--dsh-glass-card);box-shadow:var(--dsh-glass-edge), var(--dsh-glass-drop);backdrop-filter:blur(var(--dsh-glass-blur,14px));border-radius:24px;margin:0 auto 12px;padding:0;width:var(--dsh-composer-card-max-width)!important;max-width:var(--dsh-composer-card-max-width)!important}[data-dsh-glass-float] [data-dsh-glass-inputbar]:has([data-dsh-glass-stats]) [data-composer-card]{box-shadow:none;backdrop-filter:none;background:0 0;border:none;border-radius:0}[data-dsh-glass-float] [data-dsh-glass-inputbar]:has([data-dsh-glass-stats]) [data-composer-card]:after{display:none}[data-dsh-glass][data-dsh-glass-float] [data-dsh-glass-inputbar]:has([data-dsh-glass-stats]) [data-slot]{border:none;border-top:1px solid var(--dsh-glass-rim-soft);box-shadow:none;backdrop-filter:none;background:0 0;border-radius:0;margin:0;padding:2px 16px 6px;width:100%!important;max-width:none!important}[data-dsh-glass][data-dsh-glass-float] [data-dsh-glass-inputbar] [data-slot] [data-dsh-glass-stats]{min-width:0;box-shadow:none;backdrop-filter:none;background:0 0;border:none;border-radius:0;margin:0;width:100%!important;padding:4px 0 0!important}[data-dsh-glass][data-dsh-glass-float] [data-dsh-glass-inputbar] [data-slot] [data-dsh-live-tps]{padding-right:0}[data-dsh-glass-float] [role=treeitem][aria-selected=true]{box-shadow:inset 2px 0 0 var(--dsw-specific-sidebar-nav-item-active-accent), 0 0 16px color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 20%, transparent)}[data-dsh-glass-float] button[class*=button]:hover:not(:disabled),[data-dsh-glass-float] [role=menuitem]:hover:not(:disabled){box-shadow:0 0 12px color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 20%, transparent), inset 0 0 0 1px color-mix(in srgb, var(--dsw-alias-border-l3) 60%, transparent)}[data-dsh-glass-float] [role=menu]{background:var(--dsh-glass-card-raised);border:1px solid var(--dsh-glass-rim-soft);backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass-float] [role=menu]:has([role=group]>[role=menuitemradio]){background:color-mix(in srgb, var(--dsw-alias-bg-layer-2) 70%, transparent)}[data-dsh-glass-float] [role=menu] [role=group]:has(>[role=menuitemradio])>:first-child{border:1px solid var(--dsh-glass-rim);background:var(--dsh-glass-card-raised);backdrop-filter:blur(var(--dsh-glass-blur,14px));border-radius:999px;align-items:center;width:fit-content;margin:3px 0 5px 6px;padding:3px 10px;display:inline-flex}[data-dsh-glass-float] [role=dialog][aria-modal=true]{background:var(--dsh-glass-card-raised);border:1px solid var(--dsh-glass-rim);box-shadow:var(--dsh-glass-edge);backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass] [data-conversation-scroll]{text-shadow:0 0 1px #ffffff80}[data-dsh-glass] body[data-ds-dark-theme] [data-conversation-scroll]{text-shadow:0 0 1px #0006}[data-dsh-glass-float] [data-composer-card] textarea::placeholder{color:color-mix(in srgb, var(--dsw-alias-label-primary) 45%, transparent)}[data-dsh-glass-float] [data-dsh-glass-inputbar] [data-slot]{color:var(--dsw-alias-label-secondary)}[data-dsh-glass-float] [data-phase=hero]{animation:SsOp2G_dsh-glass-in .32s var(--ds-ease-in-out)}[data-dsh-glass-float] [data-phase=active]{animation:SsOp2G_dsh-glass-in .3s var(--ds-ease-in-out)}[data-dsh-glass-float] [data-testid^=view-]{animation:SsOp2G_dsh-glass-in .26s var(--ds-ease-in-out)}[data-dsh-glass-float] [data-tool]{animation:SsOp2G_dsh-glass-rise .3s var(--ds-ease-in-out) both}[data-dsh-glass-float] [role=dialog]{animation:SsOp2G_dsh-glass-dialog-in .24s var(--ds-ease-in-out)}@keyframes SsOp2G_dsh-glass-in{0%{opacity:0}}@keyframes SsOp2G_dsh-glass-rise{0%{opacity:0;transform:translateY(6px)}}@keyframes SsOp2G_dsh-glass-dialog-in{0%{opacity:0;transform:translateY(8px)scale(.985)}}[data-dsh-glass] :focus-visible{outline:2px solid color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 85%, transparent);outline-offset:1px}[data-dsh-glass] ::selection{background:color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 35%, transparent)}[data-dsh-glass-compat] [role=menu],[data-dsh-glass-compat] [role=tooltip],[data-dsh-glass-compat] [class*=card],[data-dsh-glass-compat] [class*=bubble],[data-dsh-glass-compat] [class*=panel],[data-dsh-glass-compat] [class*=popover],[data-dsh-glass-compat] [class*=dropdown]{backdrop-filter:blur(12px)}[data-dsh-glass-compat] [role=dialog][aria-modal=true]{background:var(--dsh-glass-card-raised);border:1px solid var(--dsh-glass-rim);backdrop-filter:blur(var(--dsh-glass-blur,12px))}@media (prefers-reduced-motion:reduce){[data-dsh-glass-float] [data-phase=hero],[data-dsh-glass-float] [data-phase=active],[data-dsh-glass-float] [data-testid^=view-],[data-dsh-glass-float] [data-tool],[data-dsh-glass-float] [role=dialog]{animation:none}}";
|
|
@@ -1766,23 +1934,29 @@ window.__ModuleLoader__.load({
|
|
|
1766
1934
|
for (const dispose of disposers) dispose();
|
|
1767
1935
|
};
|
|
1768
1936
|
}, "catppuccin: flavour themes");
|
|
1937
|
+
const glass = new GlassLayer(ctx);
|
|
1938
|
+
const buildLocalState = () => ({
|
|
1939
|
+
version: 1,
|
|
1940
|
+
flavor: readFlavor(),
|
|
1941
|
+
glass: glass.getRemoteState()
|
|
1942
|
+
});
|
|
1769
1943
|
ctx.effect(() => {
|
|
1770
|
-
|
|
1771
|
-
if (saved === "off") return () => {};
|
|
1944
|
+
let desired = readFlavor();
|
|
1772
1945
|
let settled = false;
|
|
1773
1946
|
const started = Date.now();
|
|
1774
|
-
const
|
|
1947
|
+
const applyDesired = () => {
|
|
1775
1948
|
if (settled) return;
|
|
1776
1949
|
if (Date.now() - started > 5e3) {
|
|
1777
1950
|
settled = true;
|
|
1778
1951
|
return;
|
|
1779
1952
|
}
|
|
1953
|
+
if (desired === "off") return;
|
|
1780
1954
|
try {
|
|
1781
|
-
if (theme.getTheme().preference !==
|
|
1955
|
+
if (theme.getTheme().preference !== desired) theme.setTheme(desired);
|
|
1782
1956
|
} catch {}
|
|
1783
1957
|
};
|
|
1784
|
-
|
|
1785
|
-
const disposer = ctx.on("theme/change",
|
|
1958
|
+
applyDesired();
|
|
1959
|
+
const disposer = ctx.on("theme/change", applyDesired);
|
|
1786
1960
|
const timer = window.setTimeout(() => {
|
|
1787
1961
|
settled = true;
|
|
1788
1962
|
}, 5e3);
|
|
@@ -1794,10 +1968,29 @@ window.__ModuleLoader__.load({
|
|
|
1794
1968
|
} catch {}
|
|
1795
1969
|
};
|
|
1796
1970
|
window.addEventListener("storage", onStorage);
|
|
1971
|
+
const offGlass = glass.subscribe(() => {
|
|
1972
|
+
scheduleDurablePersist(buildLocalState);
|
|
1973
|
+
});
|
|
1974
|
+
let cancelled = false;
|
|
1975
|
+
readDurableStateRemote().then((result) => {
|
|
1976
|
+
if (cancelled) return;
|
|
1977
|
+
if (!result.available) return;
|
|
1978
|
+
if (result.state === null) {
|
|
1979
|
+
if (!isDefaultState(buildLocalState())) scheduleDurablePersist(buildLocalState);
|
|
1980
|
+
return;
|
|
1981
|
+
}
|
|
1982
|
+
writeFlavor(result.state.flavor);
|
|
1983
|
+
glass.applyRemote(result.state.glass);
|
|
1984
|
+
desired = result.state.flavor;
|
|
1985
|
+
applyDesired();
|
|
1986
|
+
});
|
|
1797
1987
|
return () => {
|
|
1988
|
+
cancelled = true;
|
|
1989
|
+
offGlass();
|
|
1798
1990
|
disposer();
|
|
1799
1991
|
window.clearTimeout(timer);
|
|
1800
1992
|
window.removeEventListener("storage", onStorage);
|
|
1993
|
+
cancelDurablePersist();
|
|
1801
1994
|
};
|
|
1802
1995
|
}, "catppuccin: boot restore");
|
|
1803
1996
|
const injected = () => ({
|
|
@@ -1815,12 +2008,14 @@ window.__ModuleLoader__.load({
|
|
|
1815
2008
|
if (choice === "off") {
|
|
1816
2009
|
theme.setTheme("system");
|
|
1817
2010
|
writeFlavor("off");
|
|
2011
|
+
scheduleDurablePersist(buildLocalState);
|
|
1818
2012
|
return;
|
|
1819
2013
|
}
|
|
1820
2014
|
const flavor = flavorInfo(choice);
|
|
1821
2015
|
if (!flavor) return;
|
|
1822
2016
|
theme.setTheme(flavor.themeId);
|
|
1823
2017
|
writeFlavor(flavor.themeId);
|
|
2018
|
+
scheduleDurablePersist(buildLocalState);
|
|
1824
2019
|
}
|
|
1825
2020
|
});
|
|
1826
2021
|
ctx.slots.inject("settings.general.item", () => ctx.slots.register({
|
|
@@ -1830,7 +2025,6 @@ window.__ModuleLoader__.load({
|
|
|
1830
2025
|
locale: NS,
|
|
1831
2026
|
inject: injected
|
|
1832
2027
|
}, CatppuccinRow));
|
|
1833
|
-
const glass = new GlassLayer(ctx);
|
|
1834
2028
|
const glassInjected = () => ({
|
|
1835
2029
|
getState: () => glass.getSnapshot(),
|
|
1836
2030
|
subscribe: (listener) => glass.subscribe(listener),
|