dsh-milestone 0.6.2 → 0.6.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/README.md +12 -4
- package/lib/client.js +679 -170
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
<img src="
|
|
3
|
+
<img src="https://raw.githubusercontent.com/SnowCrescenter-tech/dsh-milestone/main/assets/logo.svg" alt="dsh-milestone" width="112">
|
|
4
4
|
|
|
5
5
|
# dsh-milestone
|
|
6
6
|
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
- 右侧挂一条**圆点时间线**:一个提问一个圆点,悬停看内容,点击瞬间跳转——长对话的「导航地图」。
|
|
26
26
|
- 官方 slot 机制挂载,不修改 harness 源码,装完即用。
|
|
27
27
|
|
|
28
|
-
<img src="
|
|
28
|
+
<img src="https://raw.githubusercontent.com/SnowCrescenter-tech/dsh-milestone/main/assets/demo.svg" alt="dsh-milestone 效果示意图" width="100%">
|
|
29
29
|
|
|
30
30
|
## 快速开始
|
|
31
31
|
|
|
@@ -63,7 +63,7 @@ npx @deepseek-ai/dsh web # → http://127.0.0.1:3080
|
|
|
63
63
|
| 个性化与效率 | 键盘导航:全程不用鼠标 | ↑↓ 移动 · Enter 跳转 · Home/End 首尾 |
|
|
64
64
|
| 个性化与效率 | turn 分组折叠:按轮次成组,长轮次折成一条 | |
|
|
65
65
|
| 个性化与效率 | 复制与 fork:一键复制提问全文 / 从此处分支 | |
|
|
66
|
-
| 个性化与效率 | 聚焦模式:淡化
|
|
66
|
+
| 个性化与效率 | 聚焦模式:淡化 / 折叠思考与工具调用,强度可调、自由搭配 | |
|
|
67
67
|
| 个性化与效率 | 折叠工具栏:功能键默认收起,箭头展开;设置菜单可把常用键钉到折叠外(持久化 + 恢复默认) | |
|
|
68
68
|
| 个性化与效率 | 个性化外观:强调色 / 图标圆点大小 / 距侧边距离 / 位置左右(设置内即调即存) | |
|
|
69
69
|
| 个性化与效率 | 语言切换:跟随系统 / 中文 / English,设置内一键切换 | |
|
|
@@ -164,7 +164,15 @@ shell.overlay (root scope)
|
|
|
164
164
|
## 更新日志
|
|
165
165
|
|
|
166
166
|
<details>
|
|
167
|
-
<summary>v0.6.2 / v0.6.1 / v0.6.0(点击展开)</summary>
|
|
167
|
+
<summary>v0.6.3 / v0.6.2 / v0.6.1 / v0.6.0(点击展开)</summary>
|
|
168
|
+
|
|
169
|
+
**v0.6.3** · 聚焦高级设置 + 设置模态重设计 · 363 项测试
|
|
170
|
+
|
|
171
|
+
- **聚焦高级设置**:设置内「聚焦」可展开——自定义淡化/折叠 think 推理区与工具调用卡片,淡化强度 20%–80% 可调(稳定选择器 `[data-variant="think"]` / `[data-chat-call-id]`),搭配持久化。
|
|
172
|
+
- **设置模态重设计**:功能悬停描述改为**就近 tip**(行旁悬浮,不再有大块常驻描述区);恢复表头说明(「开启后,折叠时仍显示在箭头旁」);个性化收进**可展开块**(默认折叠,头部实时摘要);间距/圆角/强调色统一,修复行 hover 洗色失效。
|
|
173
|
+
- README 图片改绝对 URL(npm 渲染器不重写相对路径),npm 页 logo/演示图恢复正常。
|
|
174
|
+
|
|
175
|
+
> [GitHub Release v0.6.3](https://github.com/SnowCrescenter-tech/dsh-milestone/releases/tag/v0.6.3)
|
|
168
176
|
|
|
169
177
|
**v0.6.2** · 设置模态化 + 个性化 + 语言切换 · 346 项测试
|
|
170
178
|
|
package/lib/client.js
CHANGED
|
@@ -682,6 +682,8 @@ window.__ModuleLoader__.load({
|
|
|
682
682
|
"settings.title": "设置",
|
|
683
683
|
/** Per-feature toggle label inside the settings menu: keep visible while collapsed. */
|
|
684
684
|
"settings.pin": "在折叠外显示",
|
|
685
|
+
/** Settings: feature-section hint explaining what the pin switch does. */
|
|
686
|
+
"settings.pin.hint": "开启后,工具栏折叠时该功能仍显示在箭头旁",
|
|
685
687
|
/** Settings action that clears every pinned feature. */
|
|
686
688
|
"settings.reset": "恢复默认",
|
|
687
689
|
/** Settings footer heading above the project links. */
|
|
@@ -702,6 +704,16 @@ window.__ModuleLoader__.load({
|
|
|
702
704
|
"settings.section.features": "功能与快捷区",
|
|
703
705
|
/** Settings modal: section heading for the personalization controls. */
|
|
704
706
|
"settings.section.personal": "个性化",
|
|
707
|
+
/** Settings modal: section heading for the focus-mode controls (0.6.3). */
|
|
708
|
+
"settings.section.focus": "聚焦",
|
|
709
|
+
/** Settings: personalization-section hint shown inside the expanded block. */
|
|
710
|
+
"settings.personal.hint": "圆点、强调色与位置,即调即存",
|
|
711
|
+
/** Settings: aria-label on the personalization block toggle while COLLAPSED. */
|
|
712
|
+
"settings.personal.expand": "展开个性化设置",
|
|
713
|
+
/** Settings: aria-label on the personalization block toggle while EXPANDED. */
|
|
714
|
+
"settings.personal.collapse": "收起个性化设置",
|
|
715
|
+
/** Settings: live value summary on the collapsed personalization header. */
|
|
716
|
+
"settings.personal.summary": "{accent} · 图标 {icon}px · {side}",
|
|
705
717
|
/** Settings: hover description — in-rail search. */
|
|
706
718
|
"settings.desc.search": "按完整消息内容过滤并跳转到对应消息",
|
|
707
719
|
/** Settings: hover description — all-prompts list. */
|
|
@@ -730,6 +742,30 @@ window.__ModuleLoader__.load({
|
|
|
730
742
|
"settings.side.left": "左侧",
|
|
731
743
|
/** Settings personalization: side radio — hug the right edge. */
|
|
732
744
|
"settings.side.right": "右侧",
|
|
745
|
+
/** Settings: focus block — hint shown inside the expanded block. */
|
|
746
|
+
"settings.focus.hint": "这些选项自由组合成你的「聚焦搭配」;总开关仍是工具栏的眼睛按钮",
|
|
747
|
+
/** Settings: aria-label on the focus block toggle while COLLAPSED. */
|
|
748
|
+
"settings.focus.expand": "展开聚焦设置",
|
|
749
|
+
/** Settings: aria-label on the focus block toggle while EXPANDED. */
|
|
750
|
+
"settings.focus.collapse": "收起聚焦设置",
|
|
751
|
+
/** Settings: focus option — dim the think reasoning disclosures. */
|
|
752
|
+
"settings.focus.dimThink": "淡化 think 推理区",
|
|
753
|
+
/** Settings: focus option — dim the tool-call cards. */
|
|
754
|
+
"settings.focus.dimTools": "淡化工具调用卡片",
|
|
755
|
+
/** Settings: focus option — compress think disclosures to a hover strip. */
|
|
756
|
+
"settings.focus.collapseThink": "折叠 think",
|
|
757
|
+
/** Settings: focus option — dim strength slider label. */
|
|
758
|
+
"settings.focus.opacity": "淡化强度",
|
|
759
|
+
/** Settings: live value summary on the collapsed focus header. */
|
|
760
|
+
"settings.focus.summary": "{opts} · 强度 {opacity}%",
|
|
761
|
+
/** Settings: focus summary — short label for the think-dim option. */
|
|
762
|
+
"settings.focus.summary.think": "think 淡化",
|
|
763
|
+
/** Settings: focus summary — short label for the tool-dim option. */
|
|
764
|
+
"settings.focus.summary.tools": "工具淡化",
|
|
765
|
+
/** Settings: focus summary — short label for the think-collapse option. */
|
|
766
|
+
"settings.focus.summary.collapse": "折叠 think",
|
|
767
|
+
/** Settings: focus summary — placeholder when every option is off. */
|
|
768
|
+
"settings.focus.summary.none": "未启用",
|
|
733
769
|
/** B4 update-check: toolbar button label + title/aria-label. */
|
|
734
770
|
"update.check": "检查更新",
|
|
735
771
|
/** B4 update-check: popover title. */
|
|
@@ -808,6 +844,7 @@ window.__ModuleLoader__.load({
|
|
|
808
844
|
"toolbar.settings.close": "Close settings",
|
|
809
845
|
"settings.title": "Settings",
|
|
810
846
|
"settings.pin": "Show outside collapse",
|
|
847
|
+
"settings.pin.hint": "When on, the feature stays beside the arrow while the toolbar is folded",
|
|
811
848
|
"settings.reset": "Restore defaults",
|
|
812
849
|
"settings.support": "Support us",
|
|
813
850
|
"settings.repo": "GitHub repo",
|
|
@@ -818,6 +855,11 @@ window.__ModuleLoader__.load({
|
|
|
818
855
|
"settings.close": "Close",
|
|
819
856
|
"settings.section.features": "Features & Shortcuts",
|
|
820
857
|
"settings.section.personal": "Personalization",
|
|
858
|
+
"settings.section.focus": "Focus",
|
|
859
|
+
"settings.personal.hint": "Dot size, accent color, and position — saved as you adjust",
|
|
860
|
+
"settings.personal.expand": "Expand personalization",
|
|
861
|
+
"settings.personal.collapse": "Collapse personalization",
|
|
862
|
+
"settings.personal.summary": "{accent} · Icon {icon}px · {side}",
|
|
821
863
|
"settings.desc.search": "Filter by full message text and jump to the match",
|
|
822
864
|
"settings.desc.list": "Overview of every prompt in this session",
|
|
823
865
|
"settings.desc.sessionSearch": "Search across all sessions",
|
|
@@ -832,6 +874,18 @@ window.__ModuleLoader__.load({
|
|
|
832
874
|
"settings.side": "Position",
|
|
833
875
|
"settings.side.left": "Left",
|
|
834
876
|
"settings.side.right": "Right",
|
|
877
|
+
"settings.focus.hint": "Combine these options into your own focus recipe; the eye button on the toolbar stays the master switch",
|
|
878
|
+
"settings.focus.expand": "Expand focus settings",
|
|
879
|
+
"settings.focus.collapse": "Collapse focus settings",
|
|
880
|
+
"settings.focus.dimThink": "Dim think reasoning",
|
|
881
|
+
"settings.focus.dimTools": "Dim tool call cards",
|
|
882
|
+
"settings.focus.collapseThink": "Collapse think",
|
|
883
|
+
"settings.focus.opacity": "Dim strength",
|
|
884
|
+
"settings.focus.summary": "{opts} · Strength {opacity}%",
|
|
885
|
+
"settings.focus.summary.think": "Think dim",
|
|
886
|
+
"settings.focus.summary.tools": "Tools dim",
|
|
887
|
+
"settings.focus.summary.collapse": "Think collapse",
|
|
888
|
+
"settings.focus.summary.none": "Off",
|
|
835
889
|
"update.check": "Check updates",
|
|
836
890
|
"update.title": "Update check",
|
|
837
891
|
"update.current": "Current version",
|
|
@@ -1739,11 +1793,15 @@ window.__ModuleLoader__.load({
|
|
|
1739
1793
|
* JSON object:
|
|
1740
1794
|
*
|
|
1741
1795
|
* { "pinned": string[], "accent": "#rrggbb", "iconSize": number,
|
|
1742
|
-
* "inset": number, "side": "left" | "right", "locale": "system"|"zh"|"en"
|
|
1796
|
+
* "inset": number, "side": "left" | "right", "locale": "system"|"zh"|"en",
|
|
1797
|
+
* "focus": { "dimThink": boolean, "dimTools": boolean,
|
|
1798
|
+
* "collapseThink": boolean, "opacity": number } }
|
|
1743
1799
|
*
|
|
1744
1800
|
* Backward compatibility: the pre-personalization blob `{ "pinned": string[] }`
|
|
1745
1801
|
* (and an entirely absent value) parses to the DEFAULT prefs with the new
|
|
1746
|
-
* fields at their defaults — old users keep their pins untouched.
|
|
1802
|
+
* fields at their defaults — old users keep their pins untouched. The same
|
|
1803
|
+
* rule covers the `focus` object: a blob stored before 0.6.3 (no `focus`
|
|
1804
|
+
* field) gains the default focus mix.
|
|
1747
1805
|
*
|
|
1748
1806
|
* All reads are sanitized per field:
|
|
1749
1807
|
* - `pinned`: whitelisted ids only (`TOOLBAR_PIN_IDS`), duplicates dropped,
|
|
@@ -1752,7 +1810,10 @@ window.__ModuleLoader__.load({
|
|
|
1752
1810
|
* back to the default blue;
|
|
1753
1811
|
* - `iconSize` / `inset`: finite numbers snapped to the slider step
|
|
1754
1812
|
* (even values) and clamped to the slider range;
|
|
1755
|
-
* - `side`: exactly `'left'` or `'right'
|
|
1813
|
+
* - `side`: exactly `'left'` or `'right'`;
|
|
1814
|
+
* - `focus`: three booleans (`dimThink` / `dimTools` / `collapseThink`)
|
|
1815
|
+
* defaulting to `true` / `false` / `false`, plus the dim `opacity`
|
|
1816
|
+
* snapped to the 0.1 step and clamped to [0.2, 0.8].
|
|
1756
1817
|
*
|
|
1757
1818
|
* The whitelist lives HERE (not in MilestoneRail) so the pure functions stay
|
|
1758
1819
|
* dependency-free and unit-testable; MilestoneRail's feature registry keys
|
|
@@ -1776,14 +1837,27 @@ window.__ModuleLoader__.load({
|
|
|
1776
1837
|
"updateCheck",
|
|
1777
1838
|
"settings"
|
|
1778
1839
|
];
|
|
1840
|
+
/** The default accent (the classic milestone blue). */
|
|
1841
|
+
const DEFAULT_ACCENT = "#4d7cfd";
|
|
1842
|
+
/** Slider domain for the focus dim strength (0.2 = 20% .. 0.8 = 80%). */
|
|
1843
|
+
const FOCUS_OPACITY_MIN = .2;
|
|
1844
|
+
const FOCUS_OPACITY_MAX = .8;
|
|
1845
|
+
/** The canonical default focus mix (dim think at 40%; tools/collapse off). */
|
|
1846
|
+
const DEFAULT_FOCUS_PREFS = {
|
|
1847
|
+
dimThink: true,
|
|
1848
|
+
dimTools: false,
|
|
1849
|
+
collapseThink: false,
|
|
1850
|
+
opacity: .4
|
|
1851
|
+
};
|
|
1779
1852
|
/** The canonical default prefs ("恢复默认" target; also the read fallback). */
|
|
1780
1853
|
const DEFAULT_PREFS = {
|
|
1781
1854
|
pinned: [],
|
|
1782
|
-
accent:
|
|
1855
|
+
accent: DEFAULT_ACCENT,
|
|
1783
1856
|
iconSize: 28,
|
|
1784
1857
|
inset: 14,
|
|
1785
1858
|
side: "right",
|
|
1786
|
-
locale: "system"
|
|
1859
|
+
locale: "system",
|
|
1860
|
+
focus: { ...DEFAULT_FOCUS_PREFS }
|
|
1787
1861
|
};
|
|
1788
1862
|
/** Type guard for registry ids — unknown strings never survive a parse. */
|
|
1789
1863
|
function isToolbarPinId(id) {
|
|
@@ -1811,11 +1885,36 @@ window.__ModuleLoader__.load({
|
|
|
1811
1885
|
const snapped = Math.round(Math.min(max, Math.max(min, value)) / step) * step;
|
|
1812
1886
|
return Math.min(max, Math.max(min, snapped));
|
|
1813
1887
|
}
|
|
1888
|
+
/** Boolean sanitizer for the focus mix flags: only `true`/`false` survive. */
|
|
1889
|
+
function sanitizeBoolean(value, fallback) {
|
|
1890
|
+
return typeof value === "boolean" ? value : fallback;
|
|
1891
|
+
}
|
|
1892
|
+
/**
|
|
1893
|
+
* Focus-mix sanitizer: `dimTools`/`collapseThink` default off, `dimThink`
|
|
1894
|
+
* defaults ON (the classic pre-0.6.3 behavior), and `opacity` snaps to the
|
|
1895
|
+
* 0.1 step inside [0.2, 0.8]. Snapping works in tenths (step × 10 = integer)
|
|
1896
|
+
* instead of a raw division so hand-edited floats like `0.30000000000000004`
|
|
1897
|
+
* always converge on exactly `0.3`.
|
|
1898
|
+
*/
|
|
1899
|
+
function sanitizeFocus(raw) {
|
|
1900
|
+
if (typeof raw !== "object" || raw === null) return { ...DEFAULT_FOCUS_PREFS };
|
|
1901
|
+
const { dimThink, dimTools, collapseThink, opacity } = raw;
|
|
1902
|
+
const clamped = typeof opacity === "number" && Number.isFinite(opacity) ? Math.min(FOCUS_OPACITY_MAX, Math.max(FOCUS_OPACITY_MIN, opacity)) : DEFAULT_FOCUS_PREFS.opacity;
|
|
1903
|
+
const tenths = Math.round(clamped * 10);
|
|
1904
|
+
const snapped = Math.min(FOCUS_OPACITY_MAX, Math.max(FOCUS_OPACITY_MIN, tenths / 10));
|
|
1905
|
+
return {
|
|
1906
|
+
dimThink: sanitizeBoolean(dimThink, DEFAULT_FOCUS_PREFS.dimThink),
|
|
1907
|
+
dimTools: sanitizeBoolean(dimTools, DEFAULT_FOCUS_PREFS.dimTools),
|
|
1908
|
+
collapseThink: sanitizeBoolean(collapseThink, DEFAULT_FOCUS_PREFS.collapseThink),
|
|
1909
|
+
opacity: snapped
|
|
1910
|
+
};
|
|
1911
|
+
}
|
|
1814
1912
|
/**
|
|
1815
1913
|
* Parse + sanitize the raw persisted blob: `null` (nothing stored), invalid
|
|
1816
1914
|
* JSON, or a non-object shape all degrade to the DEFAULT prefs. Each field is
|
|
1817
1915
|
* sanitized independently, so a half-corrupt blob keeps its valid parts
|
|
1818
|
-
* (e.g. an old `{pinned}`-only blob gains the default accent/size/inset/side
|
|
1916
|
+
* (e.g. an old `{pinned}`-only blob gains the default accent/size/inset/side
|
|
1917
|
+
* AND the default focus mix).
|
|
1819
1918
|
*/
|
|
1820
1919
|
function parsePrefs(raw) {
|
|
1821
1920
|
if (raw === null) return { ...DEFAULT_PREFS };
|
|
@@ -1826,14 +1925,15 @@ window.__ModuleLoader__.load({
|
|
|
1826
1925
|
return { ...DEFAULT_PREFS };
|
|
1827
1926
|
}
|
|
1828
1927
|
if (typeof parsed !== "object" || parsed === null) return { ...DEFAULT_PREFS };
|
|
1829
|
-
const { pinned, accent, iconSize, inset, side, locale } = parsed;
|
|
1928
|
+
const { pinned, accent, iconSize, inset, side, locale, focus } = parsed;
|
|
1830
1929
|
return {
|
|
1831
1930
|
pinned: sanitizePinned(pinned),
|
|
1832
1931
|
accent: typeof accent === "string" && isHexColor(accent) ? accent.toLowerCase() : DEFAULT_PREFS.accent,
|
|
1833
1932
|
iconSize: clampStep(iconSize, 20, 36, 2, DEFAULT_PREFS.iconSize),
|
|
1834
1933
|
inset: clampStep(inset, 0, 40, 2, DEFAULT_PREFS.inset),
|
|
1835
1934
|
side: side === "left" || side === "right" ? side : DEFAULT_PREFS.side,
|
|
1836
|
-
locale: locale === "zh" || locale === "en" || locale === "system" ? locale : DEFAULT_PREFS.locale
|
|
1935
|
+
locale: locale === "zh" || locale === "en" || locale === "system" ? locale : DEFAULT_PREFS.locale,
|
|
1936
|
+
focus: sanitizeFocus(focus)
|
|
1837
1937
|
};
|
|
1838
1938
|
}
|
|
1839
1939
|
/**
|
|
@@ -2179,7 +2279,7 @@ window.__ModuleLoader__.load({
|
|
|
2179
2279
|
* Installed plugin version. Injected at build time as
|
|
2180
2280
|
* `__DSH_MILESTONE_VERSION__`; falls back to `0.0.0-dev` when unbuilt.
|
|
2181
2281
|
*/
|
|
2182
|
-
const PLUGIN_VERSION = "0.6.
|
|
2282
|
+
const PLUGIN_VERSION = "0.6.3";
|
|
2183
2283
|
//#endregion
|
|
2184
2284
|
//#region src/client/MilestoneRail.tsx
|
|
2185
2285
|
/**
|
|
@@ -2266,39 +2366,176 @@ window.__ModuleLoader__.load({
|
|
|
2266
2366
|
/** Tooltip anchor width: its maxWidth cap, so a tooltip never overlaps the rail. */
|
|
2267
2367
|
const TOOLTIP_ANCHOR_WIDTH = 300;
|
|
2268
2368
|
/**
|
|
2269
|
-
* P3 focus mode:
|
|
2270
|
-
*
|
|
2271
|
-
*
|
|
2272
|
-
*
|
|
2273
|
-
*
|
|
2274
|
-
*
|
|
2275
|
-
*
|
|
2369
|
+
* P3 focus mode (0.6.3: user-tuned "聚焦搭配"): when the eye toggle is armed,
|
|
2370
|
+
* an inline <style> (zero-asset, same pattern as the original FOCUS_CSS)
|
|
2371
|
+
* dims/collapses the harness content classes the USER opted into, at the
|
|
2372
|
+
* strength the user picked. Which content to dim and whether to additionally
|
|
2373
|
+
* collapse think is a persisted `prefs.focus` mix; the master on/off switch
|
|
2374
|
+
* stays the toolbar eye button.
|
|
2375
|
+
*
|
|
2376
|
+
* STABLE SELECTORS — researched against the rc.2 official build products:
|
|
2377
|
+
*
|
|
2378
|
+
* - think: `dsh-client-ui-conversation` renders every assistant reasoning
|
|
2379
|
+
* disclosure as a root `div[data-variant="think"][data-state="running|ok"]`
|
|
2380
|
+
* (ReasoningRow). The reasoning body lives INSIDE that root — the
|
|
2381
|
+
* DisclosureRow's children — so the root is a single clampable container:
|
|
2382
|
+
* CSS `max-height` + `overflow: hidden` collapses exactly the body while
|
|
2383
|
+
* the header row ("Think · summary") stays visible. → collapseThink is
|
|
2384
|
+
* feasible with pure CSS (no JS, no harness-internal interaction).
|
|
2385
|
+
*
|
|
2386
|
+
* - tool calls: `dsh-client-ui-tool` wraps EVERY atomic call (all ToolRow
|
|
2387
|
+
* presentation variants AND the bash-sample row) in
|
|
2388
|
+
* `div[data-chat-call-id]` (with `data-chat-anchor-key="call:<callId>"`);
|
|
2389
|
+
* no other card type in the harness uses that attribute (verified across
|
|
2390
|
+
* the whole @deepseek-ai install). → `[data-chat-call-id]` is the stable,
|
|
2391
|
+
* variant-independent tool-call-card selector.
|
|
2392
|
+
*
|
|
2393
|
+
* Hover/open restore mirrors the classic rule: `:hover` restores, and the
|
|
2394
|
+
* DisclosureRow inside the collapsed target sets `[data-open]` when the user
|
|
2395
|
+
* opens it (the DESCENDANT form `target [data-open]` is required — same as
|
|
2396
|
+
* pre-0.6.3). The collapse strip releases on hover AND on `[data-open]` so
|
|
2397
|
+
* an opened think disclosure never stays crushed.
|
|
2276
2398
|
*/
|
|
2277
|
-
const
|
|
2278
|
-
|
|
2399
|
+
const FOCUS_SELECTOR_THINK = "[data-variant=\"think\"]";
|
|
2400
|
+
const FOCUS_SELECTOR_TOOL = "[data-chat-call-id]";
|
|
2401
|
+
/** Restored height when hovering/opening a collapsed think disclosure. */
|
|
2402
|
+
const FOCUS_THINK_MAX_HEIGHT = "78vh";
|
|
2279
2403
|
/**
|
|
2280
|
-
*
|
|
2281
|
-
*
|
|
2282
|
-
*
|
|
2283
|
-
|
|
2404
|
+
* Compose the focus-mode stylesheet from the persisted focus mix. Pure —
|
|
2405
|
+
* exported so unit tests can pin the exact rule text. `''` when no option is
|
|
2406
|
+
* armed (the master switch simply injects nothing).
|
|
2407
|
+
*/
|
|
2408
|
+
function buildFocusCss(focus) {
|
|
2409
|
+
const { dimThink, dimTools, collapseThink } = focus;
|
|
2410
|
+
const strength = focus.opacity.toFixed(1);
|
|
2411
|
+
const rules = [];
|
|
2412
|
+
if (dimThink || collapseThink) {
|
|
2413
|
+
const decls = [];
|
|
2414
|
+
if (dimThink) decls.push(`opacity: ${strength}`);
|
|
2415
|
+
if (collapseThink) decls.push(`max-height: 36px`, "overflow: hidden");
|
|
2416
|
+
rules.push(`${FOCUS_SELECTOR_THINK} { ${decls.join("; ")}; transition: opacity 0.2s${collapseThink ? ", max-height 0.2s" : ""}; }`);
|
|
2417
|
+
rules.push(`${FOCUS_SELECTOR_THINK}:hover, ${FOCUS_SELECTOR_THINK} [data-open] { opacity: 1;${collapseThink ? ` max-height: ${FOCUS_THINK_MAX_HEIGHT};` : ""} }`);
|
|
2418
|
+
}
|
|
2419
|
+
if (dimTools) {
|
|
2420
|
+
rules.push(`${FOCUS_SELECTOR_TOOL} { opacity: ${strength}; transition: opacity 0.2s; }`);
|
|
2421
|
+
rules.push(`${FOCUS_SELECTOR_TOOL}:hover, ${FOCUS_SELECTOR_TOOL} [data-open] { opacity: 1; }`);
|
|
2422
|
+
}
|
|
2423
|
+
return rules.join("\n");
|
|
2424
|
+
}
|
|
2425
|
+
/**
|
|
2426
|
+
* Settings modal shared palette + geometry — one source for the inline
|
|
2427
|
+
* styles AND the static MODAL_CSS block below so they cannot drift. Dark
|
|
2428
|
+
* panel on a dark host, three text tiers (primary / section title / hint +
|
|
2429
|
+
* muted), one border tone, a 12px panel / 8px control radius scale and a
|
|
2430
|
+
* 4-unit spacing scale (4 / 8 / 12 / 16 / 20).
|
|
2431
|
+
*/
|
|
2432
|
+
const MODAL_BG = "rgba(20, 24, 32, 0.98)";
|
|
2433
|
+
const MODAL_FG = "#e6e8ee";
|
|
2434
|
+
const MODAL_TITLE = "#c7cede";
|
|
2435
|
+
const MODAL_TEXT = "#b9c2d4";
|
|
2436
|
+
const MODAL_HINT = "#8b96ab";
|
|
2437
|
+
const MODAL_BORDER = "rgba(255, 255, 255, 0.14)";
|
|
2438
|
+
const MODAL_TIP_BG = "#222834";
|
|
2439
|
+
const MODAL_RADIUS_PANEL = 12;
|
|
2440
|
+
const MODAL_RADIUS_CONTROL = 8;
|
|
2441
|
+
/** Near-row description tip: how far its right edge sits from the row's right
|
|
2442
|
+
* edge — clears the 32px switch + its 10px padding. */
|
|
2443
|
+
const MODAL_TIP_RIGHT = 54;
|
|
2444
|
+
/**
|
|
2445
|
+
* Static settings-modal styling that needs `:hover`/`:focus-visible` (which
|
|
2446
|
+
* inline styles cannot express): the support-us card grid (micro-lift +
|
|
2447
|
+
* accent highlight), the pin-row / personal-header hover washes, one accent
|
|
2448
|
+
* focus ring for every modal control, the near-row tip's little arrow, the
|
|
2449
|
+
* personalization body's reveal, and a themed thin scrollbar. Accent values
|
|
2450
|
+
* come from the rail root's CSS variables (`--ms-accent*`), so one block
|
|
2451
|
+
* serves every accent. Inline styles keep these elements background-free
|
|
2452
|
+
* (except where noted) so the `:hover` washes below actually win. The
|
|
2284
2453
|
* search-toggle recolor rule makes the EXTERNAL RailSearchUi chrome follow
|
|
2285
2454
|
* the accent too (that file is owned by an earlier phase and cannot change);
|
|
2286
|
-
* `!important` is required because
|
|
2455
|
+
* `!important` is required because that toggle's own inline styles win
|
|
2287
2456
|
* otherwise.
|
|
2288
2457
|
*/
|
|
2289
2458
|
const MODAL_CSS = `
|
|
2290
2459
|
[data-support-card] {
|
|
2291
2460
|
display: flex; align-items: center; justify-content: center; gap: 8px;
|
|
2292
2461
|
padding: 10px 12px; border-radius: 8px;
|
|
2293
|
-
background: rgba(255, 255, 255, 0.05); border: 1px solid
|
|
2462
|
+
background: rgba(255, 255, 255, 0.05); border: 1px solid ${MODAL_BORDER};
|
|
2294
2463
|
color: #c7cede; text-decoration: none; font-size: 12.5px; line-height: 1.4;
|
|
2295
2464
|
transition: transform 120ms ease, border-color 120ms ease, background 120ms ease;
|
|
2296
2465
|
}
|
|
2297
2466
|
[data-support-card]:hover { transform: translateY(-2px); border-color: var(--ms-accent); background: rgba(255, 255, 255, 0.09); }
|
|
2467
|
+
/* Row and header washes (the inline styles deliberately leave backgrounds
|
|
2468
|
+
unset so these rules win over the default padding-box background). */
|
|
2298
2469
|
[data-toolbar-pin-toggle]:hover, [data-toolbar-pin-toggle]:focus-visible { background: rgba(255, 255, 255, 0.06); }
|
|
2470
|
+
[data-personal-toggle]:hover, [data-focus-toggle-settings]:hover { background: rgba(255, 255, 255, 0.05); }
|
|
2471
|
+
[data-focus-option]:hover { background: rgba(255, 255, 255, 0.04); }
|
|
2472
|
+
[data-toolbar-settings-close]:hover { background: rgba(255, 255, 255, 0.08); }
|
|
2473
|
+
[data-toolbar-settings-reset] { background: rgba(255, 255, 255, 0.06); }
|
|
2474
|
+
[data-toolbar-settings-reset]:hover { background: rgba(255, 255, 255, 0.1); }
|
|
2475
|
+
/* ONE accent ring for keyboard focus on every modal control. */
|
|
2476
|
+
[data-toolbar-pin-toggle]:focus-visible, [data-personal-toggle]:focus-visible,
|
|
2477
|
+
[data-focus-toggle-settings]:focus-visible,
|
|
2478
|
+
[data-toolbar-settings-close]:focus-visible, [data-toolbar-settings-reset]:focus-visible {
|
|
2479
|
+
box-shadow: 0 0 0 2px var(--ms-accent-soft);
|
|
2480
|
+
}
|
|
2481
|
+
/* Near-row description tip: a rotated square peeks out of the LEFT edge so
|
|
2482
|
+
the apex points back at the row's label. */
|
|
2483
|
+
[data-settings-tip]::before {
|
|
2484
|
+
content: ''; position: absolute; left: -3px; top: 50%;
|
|
2485
|
+
width: 7px; height: 7px; transform: translateY(-50%) rotate(45deg);
|
|
2486
|
+
background: ${MODAL_TIP_BG};
|
|
2487
|
+
border-left: 1px solid ${MODAL_BORDER};
|
|
2488
|
+
border-bottom: 1px solid ${MODAL_BORDER};
|
|
2489
|
+
}
|
|
2490
|
+
/* Tip + chevron motion lives here (not inline) so reduced-motion can kill it. */
|
|
2491
|
+
[data-settings-tip] { transition: opacity 140ms ease, transform 140ms ease, visibility 140ms; }
|
|
2492
|
+
[data-personal-toggle] svg, [data-focus-toggle-settings] svg { transition: transform 150ms ease; }
|
|
2493
|
+
/* One authored reveal: the personalization/focus bodies fade in on expand. */
|
|
2494
|
+
@keyframes ms-settings-fade { from { opacity: 0; transform: translateY(-2px); } to { opacity: 1; transform: none; } }
|
|
2495
|
+
[data-settings-personal-body], [data-settings-focus-body] { animation: ms-settings-fade 140ms ease; }
|
|
2496
|
+
/* Thin themed scrollbar for the scrollable modal panel. */
|
|
2497
|
+
[data-toolbar-settings-panel]::-webkit-scrollbar { width: 10px; }
|
|
2498
|
+
[data-toolbar-settings-panel]::-webkit-scrollbar-thumb {
|
|
2499
|
+
background: rgba(255, 255, 255, 0.16); border-radius: 6px; border: 3px solid transparent; background-clip: padding-box;
|
|
2500
|
+
}
|
|
2501
|
+
[data-toolbar-settings-panel]::-webkit-scrollbar-track { background: transparent; }
|
|
2502
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2503
|
+
[data-settings-tip], [data-personal-toggle] svg, [data-focus-toggle-settings] svg, [data-support-card] { transition: none; }
|
|
2504
|
+
[data-settings-personal-body], [data-settings-focus-body] { animation: none; }
|
|
2505
|
+
}
|
|
2299
2506
|
[data-search-toggle] { color: #8b96ab !important; }
|
|
2300
2507
|
[data-search-toggle][aria-pressed="true"] { background: var(--ms-accent-bg) !important; color: var(--ms-accent-soft) !important; }
|
|
2301
2508
|
`;
|
|
2509
|
+
/**
|
|
2510
|
+
* Shared collapsible-section chrome (personalization + focus blocks): the
|
|
2511
|
+
* header button (chevron + title + live summary) and the summary text span.
|
|
2512
|
+
* One source so the two settings blocks cannot drift.
|
|
2513
|
+
*/
|
|
2514
|
+
const SECTION_TOGGLE_STYLE = {
|
|
2515
|
+
display: "flex",
|
|
2516
|
+
alignItems: "center",
|
|
2517
|
+
gap: 8,
|
|
2518
|
+
width: "100%",
|
|
2519
|
+
padding: "8px 10px",
|
|
2520
|
+
border: "none",
|
|
2521
|
+
borderRadius: MODAL_RADIUS_CONTROL,
|
|
2522
|
+
cursor: "pointer",
|
|
2523
|
+
color: MODAL_TITLE,
|
|
2524
|
+
fontSize: 13,
|
|
2525
|
+
fontWeight: 600,
|
|
2526
|
+
textAlign: "left"
|
|
2527
|
+
};
|
|
2528
|
+
const SECTION_SUMMARY_STYLE = {
|
|
2529
|
+
flex: 1,
|
|
2530
|
+
minWidth: 0,
|
|
2531
|
+
textAlign: "right",
|
|
2532
|
+
fontWeight: 400,
|
|
2533
|
+
fontSize: 12,
|
|
2534
|
+
color: MODAL_HINT,
|
|
2535
|
+
overflow: "hidden",
|
|
2536
|
+
textOverflow: "ellipsis",
|
|
2537
|
+
whiteSpace: "nowrap"
|
|
2538
|
+
};
|
|
2302
2539
|
/**
|
|
2303
2540
|
* P3 deep links (`#msg=<anchor-key>`): initial delay before the first
|
|
2304
2541
|
* deep-link attempt — the harness scrolls the conversation to the bottom on
|
|
@@ -2501,6 +2738,28 @@ window.__ModuleLoader__.load({
|
|
|
2501
2738
|
return next;
|
|
2502
2739
|
});
|
|
2503
2740
|
};
|
|
2741
|
+
/** 0.6.3: patch ONE focus-mix flag/strength (nested field, same write-through). */
|
|
2742
|
+
const updateFocus = (patch) => {
|
|
2743
|
+
updatePrefs({ focus: {
|
|
2744
|
+
...prefs.focus,
|
|
2745
|
+
...patch
|
|
2746
|
+
} });
|
|
2747
|
+
};
|
|
2748
|
+
/**
|
|
2749
|
+
* 0.6.3: the focus block's live summary — the armed options joined into a
|
|
2750
|
+
* "聚焦搭配" line, plus the strength percentage. e.g. `think 淡化 · 强度 40%`.
|
|
2751
|
+
*/
|
|
2752
|
+
const focusSummary = (() => {
|
|
2753
|
+
const parts = [
|
|
2754
|
+
prefs.focus.dimThink ? t("settings.focus.summary.think") : null,
|
|
2755
|
+
prefs.focus.dimTools ? t("settings.focus.summary.tools") : null,
|
|
2756
|
+
prefs.focus.collapseThink ? t("settings.focus.summary.collapse") : null
|
|
2757
|
+
].filter((part) => part !== null);
|
|
2758
|
+
return t("settings.focus.summary", {
|
|
2759
|
+
opts: parts.length > 0 ? parts.join(" · ") : t("settings.focus.summary.none"),
|
|
2760
|
+
opacity: Math.round(prefs.focus.opacity * 100)
|
|
2761
|
+
});
|
|
2762
|
+
})();
|
|
2504
2763
|
/** B1: flip one feature's pin — state and the persisted blob update together. */
|
|
2505
2764
|
const onTogglePin = (id) => {
|
|
2506
2765
|
setPrefs((prev) => {
|
|
@@ -2519,9 +2778,15 @@ window.__ModuleLoader__.load({
|
|
|
2519
2778
|
const [expandHovered, setExpandHovered] = (0, react.useState)(false);
|
|
2520
2779
|
const [settingsHovered, setSettingsHovered] = (0, react.useState)(false);
|
|
2521
2780
|
const [settingsOpen, setSettingsOpen] = (0, react.useState)(false);
|
|
2522
|
-
/** The feature whose description
|
|
2523
|
-
* (
|
|
2524
|
-
const [descFeature, setDescFeature] = (0, react.useState)(
|
|
2781
|
+
/** The feature whose near-row description tip is currently visible
|
|
2782
|
+
* (`null` = none — tips only appear on hover/focus of their own row). */
|
|
2783
|
+
const [descFeature, setDescFeature] = (0, react.useState)(null);
|
|
2784
|
+
/** B-design: the personalization block collapsess by default so only a
|
|
2785
|
+
* value summary leads the section; expanding reveals the controls. */
|
|
2786
|
+
const [personalOpen, setPersonalOpen] = (0, react.useState)(false);
|
|
2787
|
+
/** B-design (0.6.3): the focus block mirrors the personalization block —
|
|
2788
|
+
* collapsed by default, the header leads with a live option summary. */
|
|
2789
|
+
const [focusOpen, setFocusOpen] = (0, react.useState)(false);
|
|
2525
2790
|
const settingsRef = (0, react.useRef)(null);
|
|
2526
2791
|
const settingsBtnRef = (0, react.useRef)(null);
|
|
2527
2792
|
const [updateOpen, setUpdateOpen] = (0, react.useState)(false);
|
|
@@ -3130,27 +3395,25 @@ window.__ModuleLoader__.load({
|
|
|
3130
3395
|
forkAt(mark.seq).then(() => setForkedKey(mark.key));
|
|
3131
3396
|
};
|
|
3132
3397
|
const showLoadOlder = hasMore && marks.length >= MIN_MARKS;
|
|
3133
|
-
const railStyle = {
|
|
3134
|
-
position: "fixed",
|
|
3135
|
-
top: railBox.top,
|
|
3136
|
-
...side === "left" ? { left: railBox.left } : { right: railBox.right },
|
|
3137
|
-
height: railBox.height,
|
|
3138
|
-
width: hit,
|
|
3139
|
-
pointerEvents: "auto",
|
|
3140
|
-
zIndex: 100,
|
|
3141
|
-
display: "flex",
|
|
3142
|
-
flexDirection: "column",
|
|
3143
|
-
gap: 6,
|
|
3144
|
-
paddingTop: 6,
|
|
3145
|
-
"--ms-accent": accent,
|
|
3146
|
-
"--ms-accent-soft": accentSoft,
|
|
3147
|
-
"--ms-accent-bg": accentBg,
|
|
3148
|
-
"--ms-icon": `${iconSize}px`,
|
|
3149
|
-
"--ms-inset": `${inset}px`
|
|
3150
|
-
};
|
|
3151
|
-
const descKey = `settings.desc.${descFeature}`;
|
|
3152
3398
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3153
|
-
style:
|
|
3399
|
+
style: {
|
|
3400
|
+
position: "fixed",
|
|
3401
|
+
top: railBox.top,
|
|
3402
|
+
...side === "left" ? { left: railBox.left } : { right: railBox.right },
|
|
3403
|
+
height: railBox.height,
|
|
3404
|
+
width: hit,
|
|
3405
|
+
pointerEvents: "auto",
|
|
3406
|
+
zIndex: 100,
|
|
3407
|
+
display: "flex",
|
|
3408
|
+
flexDirection: "column",
|
|
3409
|
+
gap: 6,
|
|
3410
|
+
paddingTop: 6,
|
|
3411
|
+
"--ms-accent": accent,
|
|
3412
|
+
"--ms-accent-soft": accentSoft,
|
|
3413
|
+
"--ms-accent-bg": accentBg,
|
|
3414
|
+
"--ms-icon": `${iconSize}px`,
|
|
3415
|
+
"--ms-inset": `${inset}px`
|
|
3416
|
+
},
|
|
3154
3417
|
"aria-label": t("rail.label"),
|
|
3155
3418
|
"data-focus-active": focusActive ? "true" : void 0,
|
|
3156
3419
|
"data-accent": accent,
|
|
@@ -3159,7 +3422,7 @@ window.__ModuleLoader__.load({
|
|
|
3159
3422
|
"data-inset": String(inset),
|
|
3160
3423
|
children: [
|
|
3161
3424
|
pulseCss !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: pulseCss }),
|
|
3162
|
-
focusActive && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children:
|
|
3425
|
+
focusActive && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: buildFocusCss(prefs.focus) }),
|
|
3163
3426
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: MODAL_CSS }),
|
|
3164
3427
|
showLoadOlder && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3165
3428
|
type: "button",
|
|
@@ -3239,11 +3502,13 @@ window.__ModuleLoader__.load({
|
|
|
3239
3502
|
width: "min(600px, 92vw)",
|
|
3240
3503
|
maxHeight: "78vh",
|
|
3241
3504
|
overflowY: "auto",
|
|
3242
|
-
padding:
|
|
3243
|
-
background:
|
|
3244
|
-
color:
|
|
3245
|
-
borderRadius:
|
|
3246
|
-
boxShadow: "0
|
|
3505
|
+
padding: 20,
|
|
3506
|
+
background: MODAL_BG,
|
|
3507
|
+
color: MODAL_FG,
|
|
3508
|
+
borderRadius: MODAL_RADIUS_PANEL,
|
|
3509
|
+
boxShadow: "0 24px 64px rgba(0, 0, 0, 0.55)",
|
|
3510
|
+
scrollbarWidth: "thin",
|
|
3511
|
+
scrollbarColor: "rgba(255, 255, 255, 0.2) transparent"
|
|
3247
3512
|
},
|
|
3248
3513
|
children: [
|
|
3249
3514
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -3252,14 +3517,14 @@ window.__ModuleLoader__.load({
|
|
|
3252
3517
|
alignItems: "center",
|
|
3253
3518
|
justifyContent: "space-between",
|
|
3254
3519
|
gap: 8,
|
|
3255
|
-
marginBottom:
|
|
3520
|
+
marginBottom: 18
|
|
3256
3521
|
},
|
|
3257
3522
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3258
3523
|
"data-toolbar-settings-title": true,
|
|
3259
3524
|
style: {
|
|
3260
3525
|
fontSize: 15,
|
|
3261
3526
|
fontWeight: 600,
|
|
3262
|
-
color:
|
|
3527
|
+
color: MODAL_FG
|
|
3263
3528
|
},
|
|
3264
3529
|
children: t("settings.title")
|
|
3265
3530
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -3269,44 +3534,57 @@ window.__ModuleLoader__.load({
|
|
|
3269
3534
|
title: t("settings.close"),
|
|
3270
3535
|
onClick: closeSettings,
|
|
3271
3536
|
style: {
|
|
3272
|
-
width:
|
|
3273
|
-
height:
|
|
3537
|
+
width: 28,
|
|
3538
|
+
height: 28,
|
|
3274
3539
|
flexShrink: 0,
|
|
3275
3540
|
display: "flex",
|
|
3276
3541
|
alignItems: "center",
|
|
3277
3542
|
justifyContent: "center",
|
|
3278
|
-
background: "transparent",
|
|
3279
3543
|
border: "none",
|
|
3280
3544
|
padding: 0,
|
|
3281
3545
|
cursor: "pointer",
|
|
3282
|
-
color:
|
|
3283
|
-
borderRadius:
|
|
3284
|
-
fontSize: 14,
|
|
3546
|
+
color: MODAL_HINT,
|
|
3547
|
+
borderRadius: MODAL_RADIUS_CONTROL,
|
|
3285
3548
|
lineHeight: 1
|
|
3286
3549
|
},
|
|
3287
|
-
children: "
|
|
3550
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
3551
|
+
width: "14",
|
|
3552
|
+
height: "14",
|
|
3553
|
+
viewBox: "0 0 24 24",
|
|
3554
|
+
fill: "none",
|
|
3555
|
+
stroke: "currentColor",
|
|
3556
|
+
strokeWidth: "2",
|
|
3557
|
+
strokeLinecap: "round",
|
|
3558
|
+
"aria-hidden": "true",
|
|
3559
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M18 6 6 18" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "m6 6 12 12" })]
|
|
3560
|
+
})
|
|
3288
3561
|
})]
|
|
3289
3562
|
}),
|
|
3290
3563
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3291
3564
|
"data-settings-section": true,
|
|
3292
|
-
style: { marginBottom:
|
|
3293
|
-
children: [
|
|
3294
|
-
"
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3565
|
+
style: { marginBottom: 20 },
|
|
3566
|
+
children: [
|
|
3567
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3568
|
+
"data-settings-section-title": true,
|
|
3569
|
+
style: {
|
|
3570
|
+
fontSize: 13,
|
|
3571
|
+
fontWeight: 600,
|
|
3572
|
+
color: MODAL_TITLE,
|
|
3573
|
+
marginBottom: 4
|
|
3574
|
+
},
|
|
3575
|
+
children: t("settings.section.features")
|
|
3576
|
+
}),
|
|
3577
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3578
|
+
"data-settings-pin-hint": true,
|
|
3579
|
+
style: {
|
|
3580
|
+
fontSize: 12,
|
|
3581
|
+
color: MODAL_HINT,
|
|
3582
|
+
lineHeight: 1.5,
|
|
3583
|
+
marginBottom: 10
|
|
3584
|
+
},
|
|
3585
|
+
children: t("settings.pin.hint")
|
|
3586
|
+
}),
|
|
3587
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3310
3588
|
style: {
|
|
3311
3589
|
display: "flex",
|
|
3312
3590
|
flexDirection: "column",
|
|
@@ -3314,92 +3592,163 @@ window.__ModuleLoader__.load({
|
|
|
3314
3592
|
},
|
|
3315
3593
|
children: toolbarFeatures.map((feature) => {
|
|
3316
3594
|
const checked = pinned.includes(feature.id);
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
"data-toolbar-pin-
|
|
3321
|
-
"data-
|
|
3322
|
-
"
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
borderRadius: 8,
|
|
3337
|
-
cursor: "pointer",
|
|
3338
|
-
color: "#e6e8ee",
|
|
3339
|
-
fontSize: 13,
|
|
3340
|
-
textAlign: "left"
|
|
3341
|
-
},
|
|
3342
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(feature.labelKey) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3343
|
-
"aria-hidden": "true",
|
|
3595
|
+
const active = descFeature === feature.id;
|
|
3596
|
+
const tipId = `ms-settings-tip-${feature.id}`;
|
|
3597
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3598
|
+
"data-toolbar-pin-row": true,
|
|
3599
|
+
"data-row-id": feature.id,
|
|
3600
|
+
style: { position: "relative" },
|
|
3601
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
3602
|
+
type: "button",
|
|
3603
|
+
role: "switch",
|
|
3604
|
+
"data-toolbar-pin-toggle": true,
|
|
3605
|
+
"data-pin-id": feature.id,
|
|
3606
|
+
"aria-checked": checked,
|
|
3607
|
+
"aria-label": t(feature.labelKey),
|
|
3608
|
+
"aria-describedby": tipId,
|
|
3609
|
+
onMouseEnter: () => setDescFeature(feature.id),
|
|
3610
|
+
onMouseLeave: () => setDescFeature((prev) => prev === feature.id ? null : prev),
|
|
3611
|
+
onFocus: () => setDescFeature(feature.id),
|
|
3612
|
+
onBlur: () => setDescFeature((prev) => prev === feature.id ? null : prev),
|
|
3613
|
+
onClick: () => onTogglePin(feature.id),
|
|
3344
3614
|
style: {
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3615
|
+
display: "flex",
|
|
3616
|
+
alignItems: "center",
|
|
3617
|
+
justifyContent: "space-between",
|
|
3618
|
+
gap: 10,
|
|
3619
|
+
width: "100%",
|
|
3620
|
+
padding: "8px 10px",
|
|
3621
|
+
border: "none",
|
|
3622
|
+
borderRadius: MODAL_RADIUS_CONTROL,
|
|
3623
|
+
cursor: "pointer",
|
|
3624
|
+
color: MODAL_FG,
|
|
3625
|
+
fontSize: 13,
|
|
3626
|
+
textAlign: "left"
|
|
3352
3627
|
},
|
|
3353
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3628
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3629
|
+
style: {
|
|
3630
|
+
overflow: "hidden",
|
|
3631
|
+
textOverflow: "ellipsis",
|
|
3632
|
+
whiteSpace: "nowrap"
|
|
3633
|
+
},
|
|
3634
|
+
children: t(feature.labelKey)
|
|
3635
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3636
|
+
"aria-hidden": "true",
|
|
3637
|
+
style: {
|
|
3638
|
+
position: "relative",
|
|
3639
|
+
width: 32,
|
|
3640
|
+
height: 18,
|
|
3641
|
+
flexShrink: 0,
|
|
3642
|
+
borderRadius: 9,
|
|
3643
|
+
background: checked ? accentStrong : "rgba(255, 255, 255, 0.16)",
|
|
3644
|
+
transition: "background 120ms ease"
|
|
3645
|
+
},
|
|
3646
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: {
|
|
3647
|
+
position: "absolute",
|
|
3648
|
+
top: 2,
|
|
3649
|
+
left: checked ? 16 : 2,
|
|
3650
|
+
width: 14,
|
|
3651
|
+
height: 14,
|
|
3652
|
+
borderRadius: "50%",
|
|
3653
|
+
background: "#ffffff",
|
|
3654
|
+
transition: "left 120ms ease"
|
|
3655
|
+
} })
|
|
3656
|
+
})]
|
|
3657
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3658
|
+
id: tipId,
|
|
3659
|
+
role: "tooltip",
|
|
3660
|
+
"data-settings-tip": true,
|
|
3661
|
+
"data-tip-for": feature.id,
|
|
3662
|
+
"data-tip-visible": active ? "true" : void 0,
|
|
3663
|
+
style: {
|
|
3354
3664
|
position: "absolute",
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3665
|
+
right: MODAL_TIP_RIGHT,
|
|
3666
|
+
top: "50%",
|
|
3667
|
+
maxWidth: "55%",
|
|
3668
|
+
transform: `translateY(-50%) translateX(${active ? 0 : 4}px)`,
|
|
3669
|
+
padding: "5px 10px",
|
|
3670
|
+
borderRadius: MODAL_RADIUS_CONTROL,
|
|
3671
|
+
background: MODAL_TIP_BG,
|
|
3672
|
+
border: `1px solid ${MODAL_BORDER}`,
|
|
3673
|
+
boxShadow: "0 8px 24px rgba(0, 0, 0, 0.35)",
|
|
3674
|
+
color: MODAL_TEXT,
|
|
3675
|
+
fontSize: 12,
|
|
3676
|
+
lineHeight: 1.45,
|
|
3677
|
+
opacity: active ? 1 : 0,
|
|
3678
|
+
visibility: active ? "visible" : "hidden",
|
|
3679
|
+
pointerEvents: "none",
|
|
3680
|
+
zIndex: 4
|
|
3681
|
+
},
|
|
3682
|
+
children: t(`settings.desc.${feature.id}`)
|
|
3363
3683
|
})]
|
|
3364
3684
|
}, feature.id);
|
|
3365
3685
|
})
|
|
3366
|
-
})
|
|
3367
|
-
|
|
3368
|
-
"aria-live": "polite",
|
|
3369
|
-
style: {
|
|
3370
|
-
display: "flex",
|
|
3371
|
-
alignItems: "center",
|
|
3372
|
-
padding: "10px 12px",
|
|
3373
|
-
borderRadius: 8,
|
|
3374
|
-
background: "rgba(255, 255, 255, 0.05)",
|
|
3375
|
-
color: "#b9c2d4",
|
|
3376
|
-
fontSize: 12.5,
|
|
3377
|
-
lineHeight: 1.5
|
|
3378
|
-
},
|
|
3379
|
-
children: t(descKey)
|
|
3380
|
-
})]
|
|
3381
|
-
})]
|
|
3686
|
+
})
|
|
3687
|
+
]
|
|
3382
3688
|
}),
|
|
3383
3689
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3384
3690
|
"data-settings-section": true,
|
|
3385
3691
|
"data-settings-personal": true,
|
|
3386
|
-
style: { marginBottom:
|
|
3387
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
3388
|
-
"
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
children:
|
|
3396
|
-
|
|
3692
|
+
style: { marginBottom: 20 },
|
|
3693
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
3694
|
+
type: "button",
|
|
3695
|
+
"data-personal-toggle": true,
|
|
3696
|
+
"aria-expanded": personalOpen,
|
|
3697
|
+
"aria-label": personalOpen ? t("settings.personal.collapse") : t("settings.personal.expand"),
|
|
3698
|
+
title: personalOpen ? t("settings.personal.collapse") : t("settings.personal.expand"),
|
|
3699
|
+
onClick: () => setPersonalOpen((v) => !v),
|
|
3700
|
+
style: SECTION_TOGGLE_STYLE,
|
|
3701
|
+
children: [
|
|
3702
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
3703
|
+
width: "14",
|
|
3704
|
+
height: "14",
|
|
3705
|
+
viewBox: "0 0 24 24",
|
|
3706
|
+
fill: "none",
|
|
3707
|
+
stroke: "currentColor",
|
|
3708
|
+
strokeWidth: "2.5",
|
|
3709
|
+
strokeLinecap: "round",
|
|
3710
|
+
strokeLinejoin: "round",
|
|
3711
|
+
"aria-hidden": "true",
|
|
3712
|
+
style: {
|
|
3713
|
+
flexShrink: 0,
|
|
3714
|
+
transform: personalOpen ? "rotate(90deg)" : "none"
|
|
3715
|
+
},
|
|
3716
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "m9 18 6-6-6-6" })
|
|
3717
|
+
}),
|
|
3718
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3719
|
+
"data-settings-section-title": true,
|
|
3720
|
+
style: { flexShrink: 0 },
|
|
3721
|
+
children: t("settings.section.personal")
|
|
3722
|
+
}),
|
|
3723
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3724
|
+
"data-settings-personal-summary": true,
|
|
3725
|
+
style: SECTION_SUMMARY_STYLE,
|
|
3726
|
+
children: t("settings.personal.summary", {
|
|
3727
|
+
accent,
|
|
3728
|
+
icon: iconSize,
|
|
3729
|
+
side: side === "left" ? t("settings.side.left") : t("settings.side.right")
|
|
3730
|
+
})
|
|
3731
|
+
})
|
|
3732
|
+
]
|
|
3733
|
+
}), personalOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3734
|
+
"data-settings-personal-body": true,
|
|
3397
3735
|
style: {
|
|
3736
|
+
padding: "10px 4px 8px",
|
|
3398
3737
|
display: "flex",
|
|
3399
3738
|
flexDirection: "column",
|
|
3400
|
-
gap:
|
|
3739
|
+
gap: 12
|
|
3401
3740
|
},
|
|
3402
3741
|
children: [
|
|
3742
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3743
|
+
"data-settings-personal-hint": true,
|
|
3744
|
+
style: {
|
|
3745
|
+
fontSize: 12,
|
|
3746
|
+
color: MODAL_HINT,
|
|
3747
|
+
lineHeight: 1.5,
|
|
3748
|
+
padding: "0 6px"
|
|
3749
|
+
},
|
|
3750
|
+
children: t("settings.personal.hint")
|
|
3751
|
+
}),
|
|
3403
3752
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3404
3753
|
style: {
|
|
3405
3754
|
display: "flex",
|
|
@@ -3410,7 +3759,7 @@ window.__ModuleLoader__.load({
|
|
|
3410
3759
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3411
3760
|
style: {
|
|
3412
3761
|
fontSize: 12.5,
|
|
3413
|
-
color:
|
|
3762
|
+
color: MODAL_HINT,
|
|
3414
3763
|
width: 90,
|
|
3415
3764
|
flexShrink: 0
|
|
3416
3765
|
},
|
|
@@ -3448,7 +3797,7 @@ window.__ModuleLoader__.load({
|
|
|
3448
3797
|
alignItems: "center",
|
|
3449
3798
|
gap: 6,
|
|
3450
3799
|
fontSize: 12.5,
|
|
3451
|
-
color:
|
|
3800
|
+
color: MODAL_TEXT,
|
|
3452
3801
|
cursor: "pointer"
|
|
3453
3802
|
},
|
|
3454
3803
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -3479,7 +3828,7 @@ window.__ModuleLoader__.load({
|
|
|
3479
3828
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3480
3829
|
style: {
|
|
3481
3830
|
fontSize: 12.5,
|
|
3482
|
-
color:
|
|
3831
|
+
color: MODAL_HINT,
|
|
3483
3832
|
width: 90,
|
|
3484
3833
|
flexShrink: 0
|
|
3485
3834
|
},
|
|
@@ -3503,7 +3852,7 @@ window.__ModuleLoader__.load({
|
|
|
3503
3852
|
"data-icon-size-value": true,
|
|
3504
3853
|
style: {
|
|
3505
3854
|
fontSize: 12.5,
|
|
3506
|
-
color:
|
|
3855
|
+
color: MODAL_TEXT,
|
|
3507
3856
|
width: 40
|
|
3508
3857
|
},
|
|
3509
3858
|
children: [iconSize, "px"]
|
|
@@ -3521,7 +3870,7 @@ window.__ModuleLoader__.load({
|
|
|
3521
3870
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3522
3871
|
style: {
|
|
3523
3872
|
fontSize: 12.5,
|
|
3524
|
-
color:
|
|
3873
|
+
color: MODAL_HINT,
|
|
3525
3874
|
width: 90,
|
|
3526
3875
|
flexShrink: 0
|
|
3527
3876
|
},
|
|
@@ -3545,7 +3894,7 @@ window.__ModuleLoader__.load({
|
|
|
3545
3894
|
"data-inset-value": true,
|
|
3546
3895
|
style: {
|
|
3547
3896
|
fontSize: 12.5,
|
|
3548
|
-
color:
|
|
3897
|
+
color: MODAL_TEXT,
|
|
3549
3898
|
width: 40
|
|
3550
3899
|
},
|
|
3551
3900
|
children: [inset, "px"]
|
|
@@ -3565,7 +3914,7 @@ window.__ModuleLoader__.load({
|
|
|
3565
3914
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3566
3915
|
style: {
|
|
3567
3916
|
fontSize: 12.5,
|
|
3568
|
-
color:
|
|
3917
|
+
color: MODAL_HINT,
|
|
3569
3918
|
width: 90,
|
|
3570
3919
|
flexShrink: 0
|
|
3571
3920
|
},
|
|
@@ -3577,7 +3926,7 @@ window.__ModuleLoader__.load({
|
|
|
3577
3926
|
alignItems: "center",
|
|
3578
3927
|
gap: 5,
|
|
3579
3928
|
fontSize: 13,
|
|
3580
|
-
color:
|
|
3929
|
+
color: MODAL_FG,
|
|
3581
3930
|
cursor: "pointer"
|
|
3582
3931
|
},
|
|
3583
3932
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -3595,7 +3944,7 @@ window.__ModuleLoader__.load({
|
|
|
3595
3944
|
alignItems: "center",
|
|
3596
3945
|
gap: 5,
|
|
3597
3946
|
fontSize: 13,
|
|
3598
|
-
color:
|
|
3947
|
+
color: MODAL_FG,
|
|
3599
3948
|
cursor: "pointer"
|
|
3600
3949
|
},
|
|
3601
3950
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -3612,16 +3961,177 @@ window.__ModuleLoader__.load({
|
|
|
3612
3961
|
]
|
|
3613
3962
|
})]
|
|
3614
3963
|
}),
|
|
3964
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3965
|
+
"data-settings-section": true,
|
|
3966
|
+
"data-focus-settings": true,
|
|
3967
|
+
style: { marginBottom: 20 },
|
|
3968
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
3969
|
+
type: "button",
|
|
3970
|
+
"data-focus-toggle-settings": true,
|
|
3971
|
+
"aria-expanded": focusOpen,
|
|
3972
|
+
"aria-label": focusOpen ? t("settings.focus.collapse") : t("settings.focus.expand"),
|
|
3973
|
+
title: focusOpen ? t("settings.focus.collapse") : t("settings.focus.expand"),
|
|
3974
|
+
onClick: () => setFocusOpen((v) => !v),
|
|
3975
|
+
style: SECTION_TOGGLE_STYLE,
|
|
3976
|
+
children: [
|
|
3977
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
3978
|
+
width: "14",
|
|
3979
|
+
height: "14",
|
|
3980
|
+
viewBox: "0 0 24 24",
|
|
3981
|
+
fill: "none",
|
|
3982
|
+
stroke: "currentColor",
|
|
3983
|
+
strokeWidth: "2.5",
|
|
3984
|
+
strokeLinecap: "round",
|
|
3985
|
+
strokeLinejoin: "round",
|
|
3986
|
+
"aria-hidden": "true",
|
|
3987
|
+
style: {
|
|
3988
|
+
flexShrink: 0,
|
|
3989
|
+
transform: focusOpen ? "rotate(90deg)" : "none"
|
|
3990
|
+
},
|
|
3991
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "m9 18 6-6-6-6" })
|
|
3992
|
+
}),
|
|
3993
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3994
|
+
"data-settings-section-title": true,
|
|
3995
|
+
style: { flexShrink: 0 },
|
|
3996
|
+
children: t("settings.section.focus")
|
|
3997
|
+
}),
|
|
3998
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3999
|
+
"data-focus-summary": true,
|
|
4000
|
+
style: SECTION_SUMMARY_STYLE,
|
|
4001
|
+
children: focusSummary
|
|
4002
|
+
})
|
|
4003
|
+
]
|
|
4004
|
+
}), focusOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4005
|
+
"data-settings-focus-body": true,
|
|
4006
|
+
style: {
|
|
4007
|
+
padding: "10px 4px 8px",
|
|
4008
|
+
display: "flex",
|
|
4009
|
+
flexDirection: "column",
|
|
4010
|
+
gap: 12
|
|
4011
|
+
},
|
|
4012
|
+
children: [
|
|
4013
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4014
|
+
"data-settings-focus-hint": true,
|
|
4015
|
+
style: {
|
|
4016
|
+
fontSize: 12,
|
|
4017
|
+
color: MODAL_HINT,
|
|
4018
|
+
lineHeight: 1.5,
|
|
4019
|
+
padding: "0 6px"
|
|
4020
|
+
},
|
|
4021
|
+
children: t("settings.focus.hint")
|
|
4022
|
+
}),
|
|
4023
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
4024
|
+
"data-focus-option": true,
|
|
4025
|
+
style: {
|
|
4026
|
+
display: "flex",
|
|
4027
|
+
alignItems: "center",
|
|
4028
|
+
gap: 8,
|
|
4029
|
+
padding: "6px 8px",
|
|
4030
|
+
borderRadius: MODAL_RADIUS_CONTROL,
|
|
4031
|
+
fontSize: 13,
|
|
4032
|
+
color: MODAL_FG,
|
|
4033
|
+
cursor: "pointer"
|
|
4034
|
+
},
|
|
4035
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
4036
|
+
type: "checkbox",
|
|
4037
|
+
"data-focus-dim-think": true,
|
|
4038
|
+
checked: prefs.focus.dimThink,
|
|
4039
|
+
onChange: (e) => updateFocus({ dimThink: e.target.checked })
|
|
4040
|
+
}), t("settings.focus.dimThink")]
|
|
4041
|
+
}),
|
|
4042
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
4043
|
+
"data-focus-option": true,
|
|
4044
|
+
style: {
|
|
4045
|
+
display: "flex",
|
|
4046
|
+
alignItems: "center",
|
|
4047
|
+
gap: 8,
|
|
4048
|
+
padding: "6px 8px",
|
|
4049
|
+
borderRadius: MODAL_RADIUS_CONTROL,
|
|
4050
|
+
fontSize: 13,
|
|
4051
|
+
color: MODAL_FG,
|
|
4052
|
+
cursor: "pointer"
|
|
4053
|
+
},
|
|
4054
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
4055
|
+
type: "checkbox",
|
|
4056
|
+
"data-focus-dim-tools": true,
|
|
4057
|
+
checked: prefs.focus.dimTools,
|
|
4058
|
+
onChange: (e) => updateFocus({ dimTools: e.target.checked })
|
|
4059
|
+
}), t("settings.focus.dimTools")]
|
|
4060
|
+
}),
|
|
4061
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
4062
|
+
"data-focus-option": true,
|
|
4063
|
+
style: {
|
|
4064
|
+
display: "flex",
|
|
4065
|
+
alignItems: "center",
|
|
4066
|
+
gap: 8,
|
|
4067
|
+
padding: "6px 8px",
|
|
4068
|
+
borderRadius: MODAL_RADIUS_CONTROL,
|
|
4069
|
+
fontSize: 13,
|
|
4070
|
+
color: MODAL_FG,
|
|
4071
|
+
cursor: "pointer"
|
|
4072
|
+
},
|
|
4073
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
4074
|
+
type: "checkbox",
|
|
4075
|
+
"data-focus-collapse-think": true,
|
|
4076
|
+
checked: prefs.focus.collapseThink,
|
|
4077
|
+
onChange: (e) => updateFocus({ collapseThink: e.target.checked })
|
|
4078
|
+
}), t("settings.focus.collapseThink")]
|
|
4079
|
+
}),
|
|
4080
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4081
|
+
style: {
|
|
4082
|
+
display: "flex",
|
|
4083
|
+
alignItems: "center",
|
|
4084
|
+
gap: 10,
|
|
4085
|
+
flexWrap: "wrap"
|
|
4086
|
+
},
|
|
4087
|
+
children: [
|
|
4088
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4089
|
+
style: {
|
|
4090
|
+
fontSize: 12.5,
|
|
4091
|
+
color: MODAL_HINT,
|
|
4092
|
+
width: 90,
|
|
4093
|
+
flexShrink: 0
|
|
4094
|
+
},
|
|
4095
|
+
children: t("settings.focus.opacity")
|
|
4096
|
+
}),
|
|
4097
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
4098
|
+
type: "range",
|
|
4099
|
+
"data-focus-opacity": true,
|
|
4100
|
+
min: .2,
|
|
4101
|
+
max: .8,
|
|
4102
|
+
step: .1,
|
|
4103
|
+
value: prefs.focus.opacity,
|
|
4104
|
+
onChange: (e) => updateFocus({ opacity: Number(e.target.value) }),
|
|
4105
|
+
style: {
|
|
4106
|
+
flex: 1,
|
|
4107
|
+
minWidth: 140,
|
|
4108
|
+
maxWidth: 260
|
|
4109
|
+
}
|
|
4110
|
+
}),
|
|
4111
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4112
|
+
"data-focus-opacity-value": true,
|
|
4113
|
+
style: {
|
|
4114
|
+
fontSize: 12.5,
|
|
4115
|
+
color: MODAL_TEXT,
|
|
4116
|
+
width: 44
|
|
4117
|
+
},
|
|
4118
|
+
children: [Math.round(prefs.focus.opacity * 100), "%"]
|
|
4119
|
+
})
|
|
4120
|
+
]
|
|
4121
|
+
})
|
|
4122
|
+
]
|
|
4123
|
+
})]
|
|
4124
|
+
}),
|
|
3615
4125
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3616
4126
|
"data-settings-section": true,
|
|
3617
4127
|
"data-settings-lang": true,
|
|
3618
|
-
style: { marginBottom:
|
|
4128
|
+
style: { marginBottom: 20 },
|
|
3619
4129
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3620
4130
|
"data-settings-section-title": true,
|
|
3621
4131
|
style: {
|
|
3622
4132
|
fontSize: 13,
|
|
3623
4133
|
fontWeight: 600,
|
|
3624
|
-
color:
|
|
4134
|
+
color: MODAL_TITLE,
|
|
3625
4135
|
marginBottom: 8
|
|
3626
4136
|
},
|
|
3627
4137
|
children: t("settings.language")
|
|
@@ -3644,7 +4154,7 @@ window.__ModuleLoader__.load({
|
|
|
3644
4154
|
alignItems: "center",
|
|
3645
4155
|
gap: 5,
|
|
3646
4156
|
fontSize: 13,
|
|
3647
|
-
color:
|
|
4157
|
+
color: MODAL_FG,
|
|
3648
4158
|
cursor: "pointer"
|
|
3649
4159
|
},
|
|
3650
4160
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -3664,7 +4174,7 @@ window.__ModuleLoader__.load({
|
|
|
3664
4174
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3665
4175
|
style: {
|
|
3666
4176
|
fontSize: 12,
|
|
3667
|
-
color:
|
|
4177
|
+
color: MODAL_HINT,
|
|
3668
4178
|
marginBottom: 10
|
|
3669
4179
|
},
|
|
3670
4180
|
children: t("settings.support")
|
|
@@ -3771,13 +4281,12 @@ window.__ModuleLoader__.load({
|
|
|
3771
4281
|
onClick: onResetAll,
|
|
3772
4282
|
style: {
|
|
3773
4283
|
display: "block",
|
|
3774
|
-
margin: "
|
|
4284
|
+
margin: "16px auto 2px",
|
|
3775
4285
|
padding: "7px 16px",
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
borderRadius: 8,
|
|
4286
|
+
border: `1px solid ${MODAL_BORDER}`,
|
|
4287
|
+
borderRadius: MODAL_RADIUS_CONTROL,
|
|
3779
4288
|
cursor: "pointer",
|
|
3780
|
-
color:
|
|
4289
|
+
color: MODAL_TEXT,
|
|
3781
4290
|
fontSize: 12.5
|
|
3782
4291
|
},
|
|
3783
4292
|
children: t("settings.reset")
|
|
@@ -3821,7 +4330,7 @@ window.__ModuleLoader__.load({
|
|
|
3821
4330
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3822
4331
|
style: { color: "#8b96ab" },
|
|
3823
4332
|
children: [t("update.current"), ": "]
|
|
3824
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "0.6.
|
|
4333
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "0.6.3" })] }),
|
|
3825
4334
|
updateCheck.phase === "ok" && updateCheck.latest !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3826
4335
|
"data-update-latest": true,
|
|
3827
4336
|
children: [
|
package/package.json
CHANGED