dsh-milestone 0.6.3 → 0.6.5
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 +17 -1
- package/lib/client.js +581 -73
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -68,6 +68,7 @@ npx @deepseek-ai/dsh web # → http://127.0.0.1:3080
|
|
|
68
68
|
| 个性化与效率 | 个性化外观:强调色 / 图标圆点大小 / 距侧边距离 / 位置左右(设置内即调即存) | |
|
|
69
69
|
| 个性化与效率 | 语言切换:跟随系统 / 中文 / English,设置内一键切换 | |
|
|
70
70
|
| 个性化与效率 | 点击外部关闭:搜索 / 列表等浮层自动收起 | |
|
|
71
|
+
| 个性化与效率 | 新手教程:首次使用教练气泡引导,锚定真实组件(点击真实推进),设置内可重看 | |
|
|
71
72
|
| 发布运维 | 更新检测:6h 缓存自动检查,新版徽章,一键去 npm | |
|
|
72
73
|
| 发布运维 | 设置推广区:GitHub / Star / Issue / npm 四入口 | |
|
|
73
74
|
|
|
@@ -164,7 +165,22 @@ shell.overlay (root scope)
|
|
|
164
165
|
## 更新日志
|
|
165
166
|
|
|
166
167
|
<details>
|
|
167
|
-
<summary>v0.6.3 / v0.6.2 / v0.6.1 / v0.6.0(点击展开)</summary>
|
|
168
|
+
<summary>v0.6.5 / v0.6.4 / v0.6.3 / v0.6.2 / v0.6.1 / v0.6.0(点击展开)</summary>
|
|
169
|
+
|
|
170
|
+
**v0.6.5** · 真实组件教练教程 + 设置对比度修复 · 386 项测试
|
|
171
|
+
|
|
172
|
+
- **新手教程改为教练气泡(coach-mark)**:气泡锚定真实组件——欢迎 → 点展开箭头(真实点击自动推进)→ 点设置齿轮(真实打开自动推进,设置开着气泡挂起)→ 圆点 → 完成;目标高亮环 + 就近气泡 + 进度点 + 随时跳过,全部双语。
|
|
173
|
+
- **设置模态白色背景修复**:UA 默认按钮底色漏出导致浅底浅字不可读,基础态补透明规则(Playwright 计算色实测验证)。
|
|
174
|
+
|
|
175
|
+
> [GitHub Release v0.6.5](https://github.com/SnowCrescenter-tech/dsh-milestone/releases/tag/v0.6.5)
|
|
176
|
+
|
|
177
|
+
**v0.6.4** · 新手教程 · 385 项测试
|
|
178
|
+
|
|
179
|
+
- **首次使用引导**:第一次安装后进入首个可用会话时弹出教程(全局持久化,**印象即写**——欢迎页一显示即记录,关页/刷新不重弹;想再看走设置里的「重新查看教程」)。
|
|
180
|
+
- 4 步教学 + 内置演示:迷你圆点条 hover/点击、玩具搜索与收藏、个性化与设置图例、更新检测与支持;进度点 + 上一步/下一步 + 随时跳过,全部双语。
|
|
181
|
+
- 设置与教程模态视觉共用 `modal-tokens.ts` 单一来源。
|
|
182
|
+
|
|
183
|
+
> [GitHub Release v0.6.4](https://github.com/SnowCrescenter-tech/dsh-milestone/releases/tag/v0.6.4)
|
|
168
184
|
|
|
169
185
|
**v0.6.3** · 聚焦高级设置 + 设置模态重设计 · 363 项测试
|
|
170
186
|
|
package/lib/client.js
CHANGED
|
@@ -795,7 +795,41 @@ window.__ModuleLoader__.load({
|
|
|
795
795
|
/** Language option: force Chinese copy. */
|
|
796
796
|
"settings.lang.zh": "中文",
|
|
797
797
|
/** Language option: force English copy. */
|
|
798
|
-
"settings.lang.en": "English"
|
|
798
|
+
"settings.lang.en": "English",
|
|
799
|
+
/** 0.6.5 tour: bubble 0 title (also the bubble's aria-label). */
|
|
800
|
+
"tour.welcome.title": "欢迎使用 dsh-milestone",
|
|
801
|
+
/** 0.6.5 tour: bubble 0 description — the REAL rail list anchor. */
|
|
802
|
+
"tour.welcome.desc": "这是你的会话导航条:每条提问一个圆点,点击跳转,悬停查看元信息。",
|
|
803
|
+
/** 0.6.5 tour: bubble 1 title — the expand arrow. */
|
|
804
|
+
"tour.step1.title": "展开工具栏",
|
|
805
|
+
/** 0.6.5 tour: bubble 1 description — what clicking REALLY does (auto-advance on the real click). */
|
|
806
|
+
"tour.step1.desc": "点这里展开全部功能键:搜索、列表、收藏、聚焦、更新检测与设置都在里面。",
|
|
807
|
+
/** 0.6.5 tour: bubble 2 title — the settings gear. */
|
|
808
|
+
"tour.step2.title": "打开设置",
|
|
809
|
+
/** 0.6.5 tour: bubble 2 description — what opening settings contains (auto-advance on the real open). */
|
|
810
|
+
"tour.step2.desc": "打开设置:钉住常用键、个性化外观、切换语言、搭配「聚焦」。",
|
|
811
|
+
/** 0.6.5 tour: bubble 3 title — the dots (real hover/click behavior). */
|
|
812
|
+
"tour.step3.title": "圆点导航",
|
|
813
|
+
/** 0.6.5 tour: bubble 3 description. */
|
|
814
|
+
"tour.step3.desc": "每个圆点 = 一条提问——点击跳转,悬停查看时间、模型与用量。",
|
|
815
|
+
/** 0.6.5 tour: bubble 4 title — done. */
|
|
816
|
+
"tour.step4.title": "开始使用",
|
|
817
|
+
/** 0.6.5 tour: bubble 4 description — finish line. */
|
|
818
|
+
"tour.step4.desc": "去试试吧;有问题欢迎到 GitHub 提 Issue。",
|
|
819
|
+
/** 0.6.5 tour: primary action on bubble 0 (begin) and bubble 4 (finish). */
|
|
820
|
+
"tour.start": "开始使用",
|
|
821
|
+
/** 0.6.5 tour: forward navigation (bubbles 1–3; the real-click auto-advance comes first). */
|
|
822
|
+
"tour.next": "下一步",
|
|
823
|
+
/** 0.6.5 tour: back navigation (bubbles 1–4). */
|
|
824
|
+
"tour.prev": "上一步",
|
|
825
|
+
/** 0.6.5 tour: corner skip — every bubble, persists the flag. */
|
|
826
|
+
"tour.skip": "跳过",
|
|
827
|
+
/** 0.6.5 tour: progress text `第 n / 5 步`. */
|
|
828
|
+
"tour.step.label": "第 {n} / 5 步",
|
|
829
|
+
/** 0.6.5 tour: aria-label on one progress dot. */
|
|
830
|
+
"tour.step.short": "第 {n} 步",
|
|
831
|
+
/** 0.6.5 settings footer action: replay the tour (data-onboarding-reopen kept). */
|
|
832
|
+
"tour.reopen": "重新查看教程"
|
|
799
833
|
};
|
|
800
834
|
const en = {
|
|
801
835
|
"jump.to": "Jump to message {n}",
|
|
@@ -900,7 +934,24 @@ window.__ModuleLoader__.load({
|
|
|
900
934
|
"settings.language": "Language",
|
|
901
935
|
"settings.lang.system": "Follow system",
|
|
902
936
|
"settings.lang.zh": "Chinese",
|
|
903
|
-
"settings.lang.en": "English"
|
|
937
|
+
"settings.lang.en": "English",
|
|
938
|
+
"tour.welcome.title": "Welcome to dsh-milestone",
|
|
939
|
+
"tour.welcome.desc": "This is your session milestone rail: every prompt is a dot — click to jump, hover for metadata.",
|
|
940
|
+
"tour.step1.title": "Expand the toolbar",
|
|
941
|
+
"tour.step1.desc": "Click to reveal every function key: search, list, bookmarks, focus, update check, and settings.",
|
|
942
|
+
"tour.step2.title": "Open settings",
|
|
943
|
+
"tour.step2.desc": "Open settings: pin your favorite keys, personalize the look, switch language, and tune focus.",
|
|
944
|
+
"tour.step3.title": "Dot navigation",
|
|
945
|
+
"tour.step3.desc": "Each dot is one prompt — click to jump, hover for time, model, and usage.",
|
|
946
|
+
"tour.step4.title": "Get started",
|
|
947
|
+
"tour.step4.desc": "Go try it — questions and issues are welcome on GitHub.",
|
|
948
|
+
"tour.start": "Get started",
|
|
949
|
+
"tour.next": "Next",
|
|
950
|
+
"tour.prev": "Back",
|
|
951
|
+
"tour.skip": "Skip",
|
|
952
|
+
"tour.step.label": "Step {n} of 5",
|
|
953
|
+
"tour.step.short": "Step {n}",
|
|
954
|
+
"tour.reopen": "Replay the tour"
|
|
904
955
|
};
|
|
905
956
|
/**
|
|
906
957
|
* Interpolate `{name}` placeholders with params, matching the harness t seat's
|
|
@@ -1328,6 +1379,414 @@ window.__ModuleLoader__.load({
|
|
|
1328
1379
|
]
|
|
1329
1380
|
});
|
|
1330
1381
|
}
|
|
1382
|
+
const MODAL_FG = "#e6e8ee";
|
|
1383
|
+
const MODAL_TITLE = "#c7cede";
|
|
1384
|
+
const MODAL_TEXT = "#b9c2d4";
|
|
1385
|
+
const MODAL_HINT = "#8b96ab";
|
|
1386
|
+
const MODAL_BORDER = "rgba(255, 255, 255, 0.14)";
|
|
1387
|
+
const MODAL_TIP_BG = "#222834";
|
|
1388
|
+
//#endregion
|
|
1389
|
+
//#region src/client/onboarding-store.ts
|
|
1390
|
+
/**
|
|
1391
|
+
* onboarding-store: the persistence layer for the 0.6.4 first-run tutorial —
|
|
1392
|
+
* a single "has the user seen it" flag with NO payload.
|
|
1393
|
+
*
|
|
1394
|
+
* Storage contract: one localStorage key (`dsh-milestone.onboarded`) whose
|
|
1395
|
+
* VALUE is exactly the string `'1'` when the tutorial was completed or
|
|
1396
|
+
* skipped. Anything else (absent key, `'0'`, `'true'`, garbage) means "never
|
|
1397
|
+
* shown" and re-triggers the tutorial.
|
|
1398
|
+
*
|
|
1399
|
+
* Both accessors swallow storage failures silently (SSR, sandboxed iframe,
|
|
1400
|
+
* quota): the tutorial is a best-effort enhancement — a broken storage must
|
|
1401
|
+
* never crash the rail, and a user in that environment simply sees the
|
|
1402
|
+
* tutorial once per page load instead of once ever.
|
|
1403
|
+
*/
|
|
1404
|
+
/** The single localStorage key holding the onboarding "seen" flag. */
|
|
1405
|
+
const ONBOARDED_KEY = "dsh-milestone.onboarded";
|
|
1406
|
+
/**
|
|
1407
|
+
* True when the user already completed or skipped the tutorial (the stored
|
|
1408
|
+
* value is exactly `'1'`). Storage unavailability degrades to `false`.
|
|
1409
|
+
*/
|
|
1410
|
+
function readOnboardedFlag() {
|
|
1411
|
+
try {
|
|
1412
|
+
return localStorage.getItem(ONBOARDED_KEY) === "1";
|
|
1413
|
+
} catch {
|
|
1414
|
+
return false;
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
/**
|
|
1418
|
+
* Persist the tutorial as seen/completed by writing the literal string `'1'`.
|
|
1419
|
+
* Storage failures are swallowed — the flag simply will not survive a reload.
|
|
1420
|
+
*/
|
|
1421
|
+
function writeOnboardedFlag() {
|
|
1422
|
+
try {
|
|
1423
|
+
localStorage.setItem(ONBOARDED_KEY, "1");
|
|
1424
|
+
} catch {}
|
|
1425
|
+
}
|
|
1426
|
+
//#endregion
|
|
1427
|
+
//#region src/client/MilestoneTour.tsx
|
|
1428
|
+
/**
|
|
1429
|
+
* MilestoneTour: the 0.6.5 first-run coach-bubble tutorial.
|
|
1430
|
+
*
|
|
1431
|
+
* Unlike the deleted 0.6.4 MilestoneOnboarding modal (built-in toy demos on a
|
|
1432
|
+
* fake overlay), this tour never fakes anything. Each of the 5 bubbles anchors
|
|
1433
|
+
* a REAL rail element (`data-rail-list`, `data-toolbar-expand`,
|
|
1434
|
+
* `data-toolbar-settings`, the first `data-rail-dot`, the rail root), explains
|
|
1435
|
+
* what clicking that control ACTUALLY does, and auto-advances by OBSERVING the
|
|
1436
|
+
* live state the rail already owns:
|
|
1437
|
+
* - bubble 1 (expand arrow) waits for `toolbarExpanded` → true — the user
|
|
1438
|
+
* really clicked the arrow (「下一步」 remains a fallback);
|
|
1439
|
+
* - bubble 2 (settings gear) waits for `settingsOpen` → true — the settings
|
|
1440
|
+
* panel appearing IS the proof — and SUSPENDS while the modal is open
|
|
1441
|
+
* (state is kept; closing settings resumes the bubble at the current step);
|
|
1442
|
+
* - bubble 3 (dots) needs no interaction — hover/click are explained.
|
|
1443
|
+
*
|
|
1444
|
+
* Trigger/ownership lives in MilestoneRail (mount timer + settings reopen);
|
|
1445
|
+
* this component is presentation + state machine only. It persists the
|
|
1446
|
+
* `dsh-milestone.onboarded` flag itself via onboarding-store on IMPRESSION
|
|
1447
|
+
* (showing bubble 0 is enough) and on every close path (skip / Esc / finish).
|
|
1448
|
+
*
|
|
1449
|
+
* Positioning: `position: fixed`, opened on the target's FREE side (rail on
|
|
1450
|
+
* the right → bubble left of the target; rail on the left → bubble right of
|
|
1451
|
+
* it), measured with getBoundingClientRect and clamped to the viewport.
|
|
1452
|
+
* Re-measured on step changes, whenever the anchor may have (un)mounted (the
|
|
1453
|
+
* forced toolbar expansion), and on window resize. There is NO overlay and the
|
|
1454
|
+
* bubble never covers its own target — the user is supposed to CLICK the real
|
|
1455
|
+
* controls, so pointer-events live only on the bubble box itself.
|
|
1456
|
+
*
|
|
1457
|
+
* Anchor guarantee: entering any step ≥ 2 calls `onSetToolbarExpanded(true)`
|
|
1458
|
+
* because `data-toolbar-settings` renders only while the toolbar is expanded
|
|
1459
|
+
* (or the gear pinned) — the 「下一步」 fallback path lands there un-expanded.
|
|
1460
|
+
*
|
|
1461
|
+
* Visual language reuses modal-tokens (MODAL_TIP_BG panel, one border tone,
|
|
1462
|
+
* the 12/8px radius scale, three text tiers) and the rail root's inherited
|
|
1463
|
+
* `--ms-accent*` CSS variables. The highlight ring is zero-asset: a
|
|
1464
|
+
* `data-tour-highlight` attribute + one injected CSS rule.
|
|
1465
|
+
*/
|
|
1466
|
+
/** The tour bubble floats above every other rail layer (settings overlay 105). */
|
|
1467
|
+
const TOUR_Z = 106;
|
|
1468
|
+
/** Gap between the target element and the bubble (px). */
|
|
1469
|
+
const TOUR_GAP = 12;
|
|
1470
|
+
/** Bubble width (px) — the left-edge positioning math clamps against it. */
|
|
1471
|
+
const TOUR_WIDTH = 280;
|
|
1472
|
+
/** Minimum padding between the bubble and the viewport edges (px). */
|
|
1473
|
+
const VIEWPORT_PAD = 8;
|
|
1474
|
+
/** Fallback bubble height used when the layout has not settled (px). */
|
|
1475
|
+
const TOUR_HEIGHT_FALLBACK = 120;
|
|
1476
|
+
/** Progress-dot count — the 5 bubble steps (0 = welcome … 4 = done). */
|
|
1477
|
+
const STEP_COUNT = [
|
|
1478
|
+
0,
|
|
1479
|
+
1,
|
|
1480
|
+
2,
|
|
1481
|
+
3,
|
|
1482
|
+
4
|
|
1483
|
+
];
|
|
1484
|
+
/**
|
|
1485
|
+
* Static tour styling that `:hover`/`:focus-visible`/reduced-motion need (the
|
|
1486
|
+
* `:focus-visible` ring and the base-state backgrounds inline styles cannot
|
|
1487
|
+
* duplicate). BASE-states first — the UA default button face must never flood
|
|
1488
|
+
* through on the dark bubble (that exact bug already shipped once).
|
|
1489
|
+
*/
|
|
1490
|
+
const TOUR_CSS = `
|
|
1491
|
+
@keyframes ms-tour-fade { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
|
|
1492
|
+
[data-tour-bubble] { animation: ms-tour-fade 160ms ease; }
|
|
1493
|
+
/* BASE-state backgrounds for every bubble control (transparent or themed). */
|
|
1494
|
+
[data-tour-skip] { background: transparent; }
|
|
1495
|
+
[data-tour-prev] { background: rgba(255, 255, 255, 0.06); }
|
|
1496
|
+
[data-tour-primary] { background: var(--ms-accent-bg); color: var(--ms-accent-soft); }
|
|
1497
|
+
/* Hover washes on top of the explicit base states. */
|
|
1498
|
+
[data-tour-skip]:hover { background: rgba(255, 255, 255, 0.08); }
|
|
1499
|
+
[data-tour-prev]:hover:not(:disabled) { background: rgba(255, 255, 255, 0.12); }
|
|
1500
|
+
[data-tour-primary]:hover { background: rgba(255, 255, 255, 0.14); }
|
|
1501
|
+
/* ONE accent focus ring for keyboard use. */
|
|
1502
|
+
[data-tour-skip]:focus-visible, [data-tour-prev]:focus-visible, [data-tour-primary]:focus-visible {
|
|
1503
|
+
box-shadow: 0 0 0 2px var(--ms-accent-soft);
|
|
1504
|
+
}
|
|
1505
|
+
/* The real-target highlight ring: accent halo + a subtle scale hint. */
|
|
1506
|
+
[data-tour-highlight] {
|
|
1507
|
+
box-shadow: 0 0 0 2px var(--ms-accent-soft), 0 0 0 4px var(--ms-accent);
|
|
1508
|
+
transform: scale(1.04);
|
|
1509
|
+
transition: box-shadow 140ms ease, transform 140ms ease;
|
|
1510
|
+
}
|
|
1511
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1512
|
+
[data-tour-bubble] { animation: none; }
|
|
1513
|
+
[data-tour-highlight] { transform: none; transition: none; }
|
|
1514
|
+
[data-tour-skip], [data-tour-prev], [data-tour-primary] { transition: none; }
|
|
1515
|
+
}
|
|
1516
|
+
`;
|
|
1517
|
+
/** Rail root — every step's fallback anchor and bubble 4's target. */
|
|
1518
|
+
function railRoot() {
|
|
1519
|
+
return document.querySelector("[data-side]");
|
|
1520
|
+
}
|
|
1521
|
+
const STEP_DEFS = [
|
|
1522
|
+
{
|
|
1523
|
+
titleKey: "tour.welcome.title",
|
|
1524
|
+
descKey: "tour.welcome.desc",
|
|
1525
|
+
anchor: () => document.querySelector("[data-rail-list]")
|
|
1526
|
+
},
|
|
1527
|
+
{
|
|
1528
|
+
titleKey: "tour.step1.title",
|
|
1529
|
+
descKey: "tour.step1.desc",
|
|
1530
|
+
anchor: () => document.querySelector("[data-toolbar-expand]")
|
|
1531
|
+
},
|
|
1532
|
+
{
|
|
1533
|
+
titleKey: "tour.step2.title",
|
|
1534
|
+
descKey: "tour.step2.desc",
|
|
1535
|
+
anchor: () => document.querySelector("[data-toolbar-settings]")
|
|
1536
|
+
},
|
|
1537
|
+
{
|
|
1538
|
+
titleKey: "tour.step3.title",
|
|
1539
|
+
descKey: "tour.step3.desc",
|
|
1540
|
+
anchor: () => document.querySelector("[data-rail-dot]") ?? railRoot()
|
|
1541
|
+
},
|
|
1542
|
+
{
|
|
1543
|
+
titleKey: "tour.step4.title",
|
|
1544
|
+
descKey: "tour.step4.desc",
|
|
1545
|
+
anchor: () => railRoot()
|
|
1546
|
+
}
|
|
1547
|
+
];
|
|
1548
|
+
/** Clamp `value` into [min, max], never letting min exceed max. */
|
|
1549
|
+
function clamp(value, min, max) {
|
|
1550
|
+
return Math.min(Math.max(value, min), Math.max(min, max));
|
|
1551
|
+
}
|
|
1552
|
+
function MilestoneTour({ t, side, toolbarExpanded, settingsOpen, onSetToolbarExpanded, onClose }) {
|
|
1553
|
+
const [step, setStep] = (0, react.useState)(0);
|
|
1554
|
+
const [pos, setPos] = (0, react.useState)(null);
|
|
1555
|
+
const bubbleRef = (0, react.useRef)(null);
|
|
1556
|
+
const primaryRef = (0, react.useRef)(null);
|
|
1557
|
+
const stepDef = STEP_DEFS[step];
|
|
1558
|
+
(0, react.useEffect)(() => {
|
|
1559
|
+
writeOnboardedFlag();
|
|
1560
|
+
}, []);
|
|
1561
|
+
/** Skip / finish / Escape converge here: persist, then close. */
|
|
1562
|
+
const finish = (0, react.useCallback)(() => {
|
|
1563
|
+
writeOnboardedFlag();
|
|
1564
|
+
onClose();
|
|
1565
|
+
}, [onClose]);
|
|
1566
|
+
(0, react.useEffect)(() => {
|
|
1567
|
+
if (settingsOpen) return;
|
|
1568
|
+
const onKey = (e) => {
|
|
1569
|
+
if (e.key !== "Escape") return;
|
|
1570
|
+
finish();
|
|
1571
|
+
};
|
|
1572
|
+
window.addEventListener("keydown", onKey);
|
|
1573
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
1574
|
+
}, [finish, settingsOpen]);
|
|
1575
|
+
(0, react.useEffect)(() => {
|
|
1576
|
+
if (step === 1 && toolbarExpanded) setStep(2);
|
|
1577
|
+
}, [step, toolbarExpanded]);
|
|
1578
|
+
(0, react.useEffect)(() => {
|
|
1579
|
+
if (step === 2 && settingsOpen) setStep(3);
|
|
1580
|
+
}, [step, settingsOpen]);
|
|
1581
|
+
(0, react.useEffect)(() => {
|
|
1582
|
+
if (step >= 2 && !toolbarExpanded) onSetToolbarExpanded(true);
|
|
1583
|
+
}, [
|
|
1584
|
+
step,
|
|
1585
|
+
toolbarExpanded,
|
|
1586
|
+
onSetToolbarExpanded
|
|
1587
|
+
]);
|
|
1588
|
+
/** Measure the current anchor and place the bubble on its free side. */
|
|
1589
|
+
const measure = (0, react.useCallback)(() => {
|
|
1590
|
+
const anchor = STEP_DEFS[step].anchor();
|
|
1591
|
+
const bubble = bubbleRef.current;
|
|
1592
|
+
if (anchor === null || bubble === null) {
|
|
1593
|
+
setPos(null);
|
|
1594
|
+
return;
|
|
1595
|
+
}
|
|
1596
|
+
const rect = anchor.getBoundingClientRect();
|
|
1597
|
+
const bw = bubble.offsetWidth || TOUR_WIDTH;
|
|
1598
|
+
const bh = bubble.offsetHeight || TOUR_HEIGHT_FALLBACK;
|
|
1599
|
+
const left = clamp(side === "left" ? rect.right + TOUR_GAP : rect.left - TOUR_GAP - bw, VIEWPORT_PAD, window.innerWidth - bw - VIEWPORT_PAD);
|
|
1600
|
+
const top = clamp(rect.top + rect.height / 2 - bh / 2, VIEWPORT_PAD, window.innerHeight - bh - VIEWPORT_PAD);
|
|
1601
|
+
setPos({
|
|
1602
|
+
left,
|
|
1603
|
+
top
|
|
1604
|
+
});
|
|
1605
|
+
}, [step, side]);
|
|
1606
|
+
(0, react.useLayoutEffect)(() => {
|
|
1607
|
+
measure();
|
|
1608
|
+
window.addEventListener("resize", measure);
|
|
1609
|
+
return () => window.removeEventListener("resize", measure);
|
|
1610
|
+
}, [
|
|
1611
|
+
measure,
|
|
1612
|
+
toolbarExpanded,
|
|
1613
|
+
settingsOpen
|
|
1614
|
+
]);
|
|
1615
|
+
(0, react.useEffect)(() => {
|
|
1616
|
+
document.querySelectorAll("[data-tour-highlight]").forEach((el) => el.removeAttribute("data-tour-highlight"));
|
|
1617
|
+
const anchor = STEP_DEFS[step].anchor();
|
|
1618
|
+
if (anchor !== null) anchor.setAttribute("data-tour-highlight", "");
|
|
1619
|
+
return () => {
|
|
1620
|
+
document.querySelectorAll("[data-tour-highlight]").forEach((el) => el.removeAttribute("data-tour-highlight"));
|
|
1621
|
+
};
|
|
1622
|
+
}, [
|
|
1623
|
+
step,
|
|
1624
|
+
toolbarExpanded,
|
|
1625
|
+
settingsOpen
|
|
1626
|
+
]);
|
|
1627
|
+
(0, react.useEffect)(() => {
|
|
1628
|
+
if (settingsOpen) return;
|
|
1629
|
+
primaryRef.current?.focus();
|
|
1630
|
+
}, [step, settingsOpen]);
|
|
1631
|
+
const goNext = () => setStep((s) => Math.min(STEP_COUNT.length - 1, s + 1));
|
|
1632
|
+
const goPrev = () => setStep((s) => Math.max(0, s - 1));
|
|
1633
|
+
if (settingsOpen) return null;
|
|
1634
|
+
const isLast = step === STEP_COUNT.length - 1;
|
|
1635
|
+
const primaryLabel = step === 0 || isLast ? t("tour.start") : t("tour.next");
|
|
1636
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1637
|
+
ref: bubbleRef,
|
|
1638
|
+
"data-tour-bubble": true,
|
|
1639
|
+
"data-tour-step": step,
|
|
1640
|
+
role: "dialog",
|
|
1641
|
+
"aria-label": t(stepDef.titleKey),
|
|
1642
|
+
style: {
|
|
1643
|
+
position: "fixed",
|
|
1644
|
+
left: pos?.left,
|
|
1645
|
+
top: pos?.top,
|
|
1646
|
+
width: TOUR_WIDTH,
|
|
1647
|
+
maxWidth: "calc(100vw - 24px)",
|
|
1648
|
+
boxSizing: "border-box",
|
|
1649
|
+
zIndex: TOUR_Z,
|
|
1650
|
+
padding: 14,
|
|
1651
|
+
background: MODAL_TIP_BG,
|
|
1652
|
+
color: MODAL_FG,
|
|
1653
|
+
borderRadius: 12,
|
|
1654
|
+
border: `1px solid ${MODAL_BORDER}`,
|
|
1655
|
+
boxShadow: "0 12px 36px rgba(0, 0, 0, 0.45)"
|
|
1656
|
+
},
|
|
1657
|
+
children: [
|
|
1658
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: TOUR_CSS }),
|
|
1659
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1660
|
+
style: {
|
|
1661
|
+
display: "flex",
|
|
1662
|
+
alignItems: "flex-start",
|
|
1663
|
+
justifyContent: "space-between",
|
|
1664
|
+
gap: 8
|
|
1665
|
+
},
|
|
1666
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1667
|
+
"data-tour-title": true,
|
|
1668
|
+
style: {
|
|
1669
|
+
fontSize: 14,
|
|
1670
|
+
fontWeight: 700,
|
|
1671
|
+
color: MODAL_FG,
|
|
1672
|
+
lineHeight: 1.35
|
|
1673
|
+
},
|
|
1674
|
+
children: t(stepDef.titleKey)
|
|
1675
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1676
|
+
type: "button",
|
|
1677
|
+
"data-tour-skip": true,
|
|
1678
|
+
onClick: finish,
|
|
1679
|
+
style: {
|
|
1680
|
+
flexShrink: 0,
|
|
1681
|
+
background: "transparent",
|
|
1682
|
+
border: "none",
|
|
1683
|
+
padding: "2px 6px",
|
|
1684
|
+
borderRadius: 8,
|
|
1685
|
+
cursor: "pointer",
|
|
1686
|
+
color: MODAL_HINT,
|
|
1687
|
+
fontSize: 12,
|
|
1688
|
+
lineHeight: 1.4
|
|
1689
|
+
},
|
|
1690
|
+
children: t("tour.skip")
|
|
1691
|
+
})]
|
|
1692
|
+
}),
|
|
1693
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1694
|
+
"data-tour-desc": true,
|
|
1695
|
+
style: {
|
|
1696
|
+
marginTop: 6,
|
|
1697
|
+
fontSize: 12.5,
|
|
1698
|
+
lineHeight: 1.5,
|
|
1699
|
+
color: MODAL_TEXT
|
|
1700
|
+
},
|
|
1701
|
+
children: t(stepDef.descKey)
|
|
1702
|
+
}),
|
|
1703
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("footer", {
|
|
1704
|
+
style: {
|
|
1705
|
+
display: "flex",
|
|
1706
|
+
alignItems: "center",
|
|
1707
|
+
justifyContent: "space-between",
|
|
1708
|
+
gap: 10,
|
|
1709
|
+
marginTop: 12
|
|
1710
|
+
},
|
|
1711
|
+
children: [
|
|
1712
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1713
|
+
type: "button",
|
|
1714
|
+
"data-tour-prev": true,
|
|
1715
|
+
disabled: step === 0,
|
|
1716
|
+
onClick: goPrev,
|
|
1717
|
+
style: {
|
|
1718
|
+
flexShrink: 0,
|
|
1719
|
+
background: "rgba(255, 255, 255, 0.06)",
|
|
1720
|
+
border: `1px solid ${MODAL_BORDER}`,
|
|
1721
|
+
borderRadius: 8,
|
|
1722
|
+
padding: "5px 12px",
|
|
1723
|
+
cursor: step === 0 ? "default" : "pointer",
|
|
1724
|
+
color: step === 0 ? MODAL_HINT : MODAL_TEXT,
|
|
1725
|
+
fontSize: 12,
|
|
1726
|
+
lineHeight: 1.4,
|
|
1727
|
+
opacity: step === 0 ? .55 : 1
|
|
1728
|
+
},
|
|
1729
|
+
children: t("tour.prev")
|
|
1730
|
+
}),
|
|
1731
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1732
|
+
style: {
|
|
1733
|
+
display: "flex",
|
|
1734
|
+
flexDirection: "column",
|
|
1735
|
+
alignItems: "center",
|
|
1736
|
+
gap: 5,
|
|
1737
|
+
minWidth: 74
|
|
1738
|
+
},
|
|
1739
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1740
|
+
"data-tour-progress": true,
|
|
1741
|
+
style: {
|
|
1742
|
+
fontSize: 11.5,
|
|
1743
|
+
color: MODAL_HINT,
|
|
1744
|
+
lineHeight: 1.2
|
|
1745
|
+
},
|
|
1746
|
+
children: t("tour.step.label", { n: step + 1 })
|
|
1747
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1748
|
+
style: {
|
|
1749
|
+
display: "flex",
|
|
1750
|
+
gap: 4
|
|
1751
|
+
},
|
|
1752
|
+
children: STEP_COUNT.map((n) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1753
|
+
"data-tour-progress-dot": true,
|
|
1754
|
+
"data-active": step === n ? "true" : void 0,
|
|
1755
|
+
"aria-label": t("tour.step.short", { n: n + 1 }),
|
|
1756
|
+
"aria-current": step === n ? "step" : void 0,
|
|
1757
|
+
style: {
|
|
1758
|
+
width: 14,
|
|
1759
|
+
height: 4,
|
|
1760
|
+
borderRadius: 2,
|
|
1761
|
+
background: step === n ? "var(--ms-accent)" : "rgba(255, 255, 255, 0.18)"
|
|
1762
|
+
}
|
|
1763
|
+
}, n))
|
|
1764
|
+
})]
|
|
1765
|
+
}),
|
|
1766
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1767
|
+
type: "button",
|
|
1768
|
+
ref: primaryRef,
|
|
1769
|
+
"data-tour-primary": true,
|
|
1770
|
+
onClick: isLast ? finish : goNext,
|
|
1771
|
+
style: {
|
|
1772
|
+
flexShrink: 0,
|
|
1773
|
+
background: "var(--ms-accent-bg)",
|
|
1774
|
+
color: "var(--ms-accent-soft)",
|
|
1775
|
+
border: "1px solid var(--ms-accent)",
|
|
1776
|
+
borderRadius: 8,
|
|
1777
|
+
padding: "5px 14px",
|
|
1778
|
+
cursor: "pointer",
|
|
1779
|
+
fontSize: 12.5,
|
|
1780
|
+
fontWeight: 600,
|
|
1781
|
+
lineHeight: 1.4
|
|
1782
|
+
},
|
|
1783
|
+
children: primaryLabel
|
|
1784
|
+
})
|
|
1785
|
+
]
|
|
1786
|
+
})
|
|
1787
|
+
]
|
|
1788
|
+
});
|
|
1789
|
+
}
|
|
1331
1790
|
//#endregion
|
|
1332
1791
|
//#region src/client/MilestoneRailTooltip.tsx
|
|
1333
1792
|
/**
|
|
@@ -2279,7 +2738,7 @@ window.__ModuleLoader__.load({
|
|
|
2279
2738
|
* Installed plugin version. Injected at build time as
|
|
2280
2739
|
* `__DSH_MILESTONE_VERSION__`; falls back to `0.0.0-dev` when unbuilt.
|
|
2281
2740
|
*/
|
|
2282
|
-
const PLUGIN_VERSION = "0.6.
|
|
2741
|
+
const PLUGIN_VERSION = "0.6.5";
|
|
2283
2742
|
//#endregion
|
|
2284
2743
|
//#region src/client/MilestoneRail.tsx
|
|
2285
2744
|
/**
|
|
@@ -2324,6 +2783,13 @@ window.__ModuleLoader__.load({
|
|
|
2324
2783
|
* hover descriptions, the personalization controls, and the support-us card
|
|
2325
2784
|
* grid); everything the modal changes persists under `dsh-milestone.toolbar`.
|
|
2326
2785
|
*/
|
|
2786
|
+
/**
|
|
2787
|
+
* Settings modal shared palette + geometry — ONE source in modal-tokens.ts,
|
|
2788
|
+
* also consumed by the 0.6.4 onboarding tutorial modal so the two dialogs
|
|
2789
|
+
* cannot drift. Dark panel on a dark host, three text tiers (primary /
|
|
2790
|
+
* section title / hint + muted), one border tone, a 12px panel / 8px control
|
|
2791
|
+
* radius scale and a 4-unit spacing scale (4 / 8 / 12 / 16 / 20).
|
|
2792
|
+
*/
|
|
2327
2793
|
/** Minimum user messages before the rail adds value. */
|
|
2328
2794
|
const MIN_MARKS = 2;
|
|
2329
2795
|
const PREVIEW_LENGTH = 80;
|
|
@@ -2422,22 +2888,6 @@ window.__ModuleLoader__.load({
|
|
|
2422
2888
|
}
|
|
2423
2889
|
return rules.join("\n");
|
|
2424
2890
|
}
|
|
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
2891
|
/** Near-row description tip: how far its right edge sits from the row's right
|
|
2442
2892
|
* edge — clears the 32px switch + its 10px padding. */
|
|
2443
2893
|
const MODAL_TIP_RIGHT = 54;
|
|
@@ -2470,12 +2920,21 @@ window.__ModuleLoader__.load({
|
|
|
2470
2920
|
[data-personal-toggle]:hover, [data-focus-toggle-settings]:hover { background: rgba(255, 255, 255, 0.05); }
|
|
2471
2921
|
[data-focus-option]:hover { background: rgba(255, 255, 255, 0.04); }
|
|
2472
2922
|
[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); }
|
|
2923
|
+
[data-toolbar-settings-reset], [data-onboarding-reopen] { background: rgba(255, 255, 255, 0.06); }
|
|
2924
|
+
[data-toolbar-settings-reset]:hover, [data-onboarding-reopen]:hover { background: rgba(255, 255, 255, 0.1); }
|
|
2925
|
+
/* BASE state reset: every modal surface must sit transparent on the dark
|
|
2926
|
+
panel — without it the UA default button face (light gray) floods through
|
|
2927
|
+
and rows become unreadable light-on-light. Hover washes above take over
|
|
2928
|
+
on interaction. */
|
|
2929
|
+
[data-toolbar-pin-toggle], [data-personal-toggle], [data-focus-toggle-settings],
|
|
2930
|
+
[data-toolbar-settings-close], [data-focus-option] {
|
|
2931
|
+
background: transparent;
|
|
2932
|
+
}
|
|
2475
2933
|
/* ONE accent ring for keyboard focus on every modal control. */
|
|
2476
2934
|
[data-toolbar-pin-toggle]:focus-visible, [data-personal-toggle]:focus-visible,
|
|
2477
2935
|
[data-focus-toggle-settings]:focus-visible,
|
|
2478
|
-
[data-toolbar-settings-close]:focus-visible, [data-toolbar-settings-reset]:focus-visible
|
|
2936
|
+
[data-toolbar-settings-close]:focus-visible, [data-toolbar-settings-reset]:focus-visible,
|
|
2937
|
+
[data-onboarding-reopen]:focus-visible {
|
|
2479
2938
|
box-shadow: 0 0 0 2px var(--ms-accent-soft);
|
|
2480
2939
|
}
|
|
2481
2940
|
/* Near-row description tip: a rotated square peeks out of the LEFT edge so
|
|
@@ -2518,7 +2977,7 @@ window.__ModuleLoader__.load({
|
|
|
2518
2977
|
width: "100%",
|
|
2519
2978
|
padding: "8px 10px",
|
|
2520
2979
|
border: "none",
|
|
2521
|
-
borderRadius:
|
|
2980
|
+
borderRadius: 8,
|
|
2522
2981
|
cursor: "pointer",
|
|
2523
2982
|
color: MODAL_TITLE,
|
|
2524
2983
|
fontSize: 13,
|
|
@@ -2551,6 +3010,9 @@ window.__ModuleLoader__.load({
|
|
|
2551
3010
|
/** B4 update-check: mount-time silent check delay (ms) — give the harness
|
|
2552
3011
|
* time to settle before hitting the registry. */
|
|
2553
3012
|
const UPDATE_CHECK_MOUNT_DELAY = 1500;
|
|
3013
|
+
/** 0.6.5 first-run coach tour: mount-time show delay (ms) — let the rail settle
|
|
3014
|
+
* before the first bubble pops. */
|
|
3015
|
+
const ONBOARDING_MOUNT_DELAY = 800;
|
|
2554
3016
|
/** Initial state: no check has completed yet, nothing to show. */
|
|
2555
3017
|
const NO_UPDATE_CHECK = {
|
|
2556
3018
|
phase: "idle",
|
|
@@ -2778,6 +3240,8 @@ window.__ModuleLoader__.load({
|
|
|
2778
3240
|
const [expandHovered, setExpandHovered] = (0, react.useState)(false);
|
|
2779
3241
|
const [settingsHovered, setSettingsHovered] = (0, react.useState)(false);
|
|
2780
3242
|
const [settingsOpen, setSettingsOpen] = (0, react.useState)(false);
|
|
3243
|
+
const [tourOpen, setTourOpen] = (0, react.useState)(false);
|
|
3244
|
+
const [tourRun, setTourRun] = (0, react.useState)(0);
|
|
2781
3245
|
/** The feature whose near-row description tip is currently visible
|
|
2782
3246
|
* (`null` = none — tips only appear on hover/focus of their own row). */
|
|
2783
3247
|
const [descFeature, setDescFeature] = (0, react.useState)(null);
|
|
@@ -2857,6 +3321,12 @@ window.__ModuleLoader__.load({
|
|
|
2857
3321
|
const timer = window.setTimeout(runUpdateCheck, UPDATE_CHECK_MOUNT_DELAY);
|
|
2858
3322
|
return () => window.clearTimeout(timer);
|
|
2859
3323
|
}, []);
|
|
3324
|
+
(0, react.useEffect)(() => {
|
|
3325
|
+
const timer = window.setTimeout(() => {
|
|
3326
|
+
if (!readOnboardedFlag()) setTourOpen(true);
|
|
3327
|
+
}, ONBOARDING_MOUNT_DELAY);
|
|
3328
|
+
return () => window.clearTimeout(timer);
|
|
3329
|
+
}, []);
|
|
2860
3330
|
useOutsideDismiss(updatePanelRef, updateOpen, () => {
|
|
2861
3331
|
setUpdateOpen(false);
|
|
2862
3332
|
updateBtnRef.current?.focus();
|
|
@@ -3020,6 +3490,15 @@ window.__ModuleLoader__.load({
|
|
|
3020
3490
|
setSettingsOpen(false);
|
|
3021
3491
|
settingsBtnRef.current?.focus();
|
|
3022
3492
|
};
|
|
3493
|
+
/** 0.6.5: settings → 重新查看教程 — close settings and replay the coach
|
|
3494
|
+
* tour immediately (the flag may or may not be set; skipping/completing it
|
|
3495
|
+
* re-persists the flag anyway). The `tourRun` bump remounts the tour so the
|
|
3496
|
+
* replay always restarts from bubble 0. */
|
|
3497
|
+
const reopenTour = () => {
|
|
3498
|
+
setSettingsOpen(false);
|
|
3499
|
+
setTourRun((n) => n + 1);
|
|
3500
|
+
setTourOpen(true);
|
|
3501
|
+
};
|
|
3023
3502
|
/** B1: a feature renders while the toolbar is EXPANDED or while it is pinned. */
|
|
3024
3503
|
const featureVisible = (id) => toolbarExpanded || pinned.includes(id);
|
|
3025
3504
|
/** Base chrome-button style: accent-defined active tint, scaled hit area. */
|
|
@@ -3503,9 +3982,9 @@ window.__ModuleLoader__.load({
|
|
|
3503
3982
|
maxHeight: "78vh",
|
|
3504
3983
|
overflowY: "auto",
|
|
3505
3984
|
padding: 20,
|
|
3506
|
-
background:
|
|
3507
|
-
color:
|
|
3508
|
-
borderRadius:
|
|
3985
|
+
background: "rgba(20, 24, 32, 0.98)",
|
|
3986
|
+
color: "#e6e8ee",
|
|
3987
|
+
borderRadius: 12,
|
|
3509
3988
|
boxShadow: "0 24px 64px rgba(0, 0, 0, 0.55)",
|
|
3510
3989
|
scrollbarWidth: "thin",
|
|
3511
3990
|
scrollbarColor: "rgba(255, 255, 255, 0.2) transparent"
|
|
@@ -3524,7 +4003,7 @@ window.__ModuleLoader__.load({
|
|
|
3524
4003
|
style: {
|
|
3525
4004
|
fontSize: 15,
|
|
3526
4005
|
fontWeight: 600,
|
|
3527
|
-
color:
|
|
4006
|
+
color: "#e6e8ee"
|
|
3528
4007
|
},
|
|
3529
4008
|
children: t("settings.title")
|
|
3530
4009
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -3543,8 +4022,8 @@ window.__ModuleLoader__.load({
|
|
|
3543
4022
|
border: "none",
|
|
3544
4023
|
padding: 0,
|
|
3545
4024
|
cursor: "pointer",
|
|
3546
|
-
color:
|
|
3547
|
-
borderRadius:
|
|
4025
|
+
color: "#8b96ab",
|
|
4026
|
+
borderRadius: 8,
|
|
3548
4027
|
lineHeight: 1
|
|
3549
4028
|
},
|
|
3550
4029
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
@@ -3569,7 +4048,7 @@ window.__ModuleLoader__.load({
|
|
|
3569
4048
|
style: {
|
|
3570
4049
|
fontSize: 13,
|
|
3571
4050
|
fontWeight: 600,
|
|
3572
|
-
color:
|
|
4051
|
+
color: "#c7cede",
|
|
3573
4052
|
marginBottom: 4
|
|
3574
4053
|
},
|
|
3575
4054
|
children: t("settings.section.features")
|
|
@@ -3578,7 +4057,7 @@ window.__ModuleLoader__.load({
|
|
|
3578
4057
|
"data-settings-pin-hint": true,
|
|
3579
4058
|
style: {
|
|
3580
4059
|
fontSize: 12,
|
|
3581
|
-
color:
|
|
4060
|
+
color: "#8b96ab",
|
|
3582
4061
|
lineHeight: 1.5,
|
|
3583
4062
|
marginBottom: 10
|
|
3584
4063
|
},
|
|
@@ -3619,9 +4098,9 @@ window.__ModuleLoader__.load({
|
|
|
3619
4098
|
width: "100%",
|
|
3620
4099
|
padding: "8px 10px",
|
|
3621
4100
|
border: "none",
|
|
3622
|
-
borderRadius:
|
|
4101
|
+
borderRadius: 8,
|
|
3623
4102
|
cursor: "pointer",
|
|
3624
|
-
color:
|
|
4103
|
+
color: "#e6e8ee",
|
|
3625
4104
|
fontSize: 13,
|
|
3626
4105
|
textAlign: "left"
|
|
3627
4106
|
},
|
|
@@ -3667,11 +4146,11 @@ window.__ModuleLoader__.load({
|
|
|
3667
4146
|
maxWidth: "55%",
|
|
3668
4147
|
transform: `translateY(-50%) translateX(${active ? 0 : 4}px)`,
|
|
3669
4148
|
padding: "5px 10px",
|
|
3670
|
-
borderRadius:
|
|
3671
|
-
background:
|
|
3672
|
-
border: `1px solid
|
|
4149
|
+
borderRadius: 8,
|
|
4150
|
+
background: "#222834",
|
|
4151
|
+
border: `1px solid rgba(255, 255, 255, 0.14)`,
|
|
3673
4152
|
boxShadow: "0 8px 24px rgba(0, 0, 0, 0.35)",
|
|
3674
|
-
color:
|
|
4153
|
+
color: "#b9c2d4",
|
|
3675
4154
|
fontSize: 12,
|
|
3676
4155
|
lineHeight: 1.45,
|
|
3677
4156
|
opacity: active ? 1 : 0,
|
|
@@ -3743,7 +4222,7 @@ window.__ModuleLoader__.load({
|
|
|
3743
4222
|
"data-settings-personal-hint": true,
|
|
3744
4223
|
style: {
|
|
3745
4224
|
fontSize: 12,
|
|
3746
|
-
color:
|
|
4225
|
+
color: "#8b96ab",
|
|
3747
4226
|
lineHeight: 1.5,
|
|
3748
4227
|
padding: "0 6px"
|
|
3749
4228
|
},
|
|
@@ -3759,7 +4238,7 @@ window.__ModuleLoader__.load({
|
|
|
3759
4238
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3760
4239
|
style: {
|
|
3761
4240
|
fontSize: 12.5,
|
|
3762
|
-
color:
|
|
4241
|
+
color: "#8b96ab",
|
|
3763
4242
|
width: 90,
|
|
3764
4243
|
flexShrink: 0
|
|
3765
4244
|
},
|
|
@@ -3797,7 +4276,7 @@ window.__ModuleLoader__.load({
|
|
|
3797
4276
|
alignItems: "center",
|
|
3798
4277
|
gap: 6,
|
|
3799
4278
|
fontSize: 12.5,
|
|
3800
|
-
color:
|
|
4279
|
+
color: "#b9c2d4",
|
|
3801
4280
|
cursor: "pointer"
|
|
3802
4281
|
},
|
|
3803
4282
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -3828,7 +4307,7 @@ window.__ModuleLoader__.load({
|
|
|
3828
4307
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3829
4308
|
style: {
|
|
3830
4309
|
fontSize: 12.5,
|
|
3831
|
-
color:
|
|
4310
|
+
color: "#8b96ab",
|
|
3832
4311
|
width: 90,
|
|
3833
4312
|
flexShrink: 0
|
|
3834
4313
|
},
|
|
@@ -3852,7 +4331,7 @@ window.__ModuleLoader__.load({
|
|
|
3852
4331
|
"data-icon-size-value": true,
|
|
3853
4332
|
style: {
|
|
3854
4333
|
fontSize: 12.5,
|
|
3855
|
-
color:
|
|
4334
|
+
color: "#b9c2d4",
|
|
3856
4335
|
width: 40
|
|
3857
4336
|
},
|
|
3858
4337
|
children: [iconSize, "px"]
|
|
@@ -3870,7 +4349,7 @@ window.__ModuleLoader__.load({
|
|
|
3870
4349
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3871
4350
|
style: {
|
|
3872
4351
|
fontSize: 12.5,
|
|
3873
|
-
color:
|
|
4352
|
+
color: "#8b96ab",
|
|
3874
4353
|
width: 90,
|
|
3875
4354
|
flexShrink: 0
|
|
3876
4355
|
},
|
|
@@ -3894,7 +4373,7 @@ window.__ModuleLoader__.load({
|
|
|
3894
4373
|
"data-inset-value": true,
|
|
3895
4374
|
style: {
|
|
3896
4375
|
fontSize: 12.5,
|
|
3897
|
-
color:
|
|
4376
|
+
color: "#b9c2d4",
|
|
3898
4377
|
width: 40
|
|
3899
4378
|
},
|
|
3900
4379
|
children: [inset, "px"]
|
|
@@ -3914,7 +4393,7 @@ window.__ModuleLoader__.load({
|
|
|
3914
4393
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3915
4394
|
style: {
|
|
3916
4395
|
fontSize: 12.5,
|
|
3917
|
-
color:
|
|
4396
|
+
color: "#8b96ab",
|
|
3918
4397
|
width: 90,
|
|
3919
4398
|
flexShrink: 0
|
|
3920
4399
|
},
|
|
@@ -3926,7 +4405,7 @@ window.__ModuleLoader__.load({
|
|
|
3926
4405
|
alignItems: "center",
|
|
3927
4406
|
gap: 5,
|
|
3928
4407
|
fontSize: 13,
|
|
3929
|
-
color:
|
|
4408
|
+
color: "#e6e8ee",
|
|
3930
4409
|
cursor: "pointer"
|
|
3931
4410
|
},
|
|
3932
4411
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -3944,7 +4423,7 @@ window.__ModuleLoader__.load({
|
|
|
3944
4423
|
alignItems: "center",
|
|
3945
4424
|
gap: 5,
|
|
3946
4425
|
fontSize: 13,
|
|
3947
|
-
color:
|
|
4426
|
+
color: "#e6e8ee",
|
|
3948
4427
|
cursor: "pointer"
|
|
3949
4428
|
},
|
|
3950
4429
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -4014,7 +4493,7 @@ window.__ModuleLoader__.load({
|
|
|
4014
4493
|
"data-settings-focus-hint": true,
|
|
4015
4494
|
style: {
|
|
4016
4495
|
fontSize: 12,
|
|
4017
|
-
color:
|
|
4496
|
+
color: "#8b96ab",
|
|
4018
4497
|
lineHeight: 1.5,
|
|
4019
4498
|
padding: "0 6px"
|
|
4020
4499
|
},
|
|
@@ -4027,9 +4506,9 @@ window.__ModuleLoader__.load({
|
|
|
4027
4506
|
alignItems: "center",
|
|
4028
4507
|
gap: 8,
|
|
4029
4508
|
padding: "6px 8px",
|
|
4030
|
-
borderRadius:
|
|
4509
|
+
borderRadius: 8,
|
|
4031
4510
|
fontSize: 13,
|
|
4032
|
-
color:
|
|
4511
|
+
color: "#e6e8ee",
|
|
4033
4512
|
cursor: "pointer"
|
|
4034
4513
|
},
|
|
4035
4514
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -4046,9 +4525,9 @@ window.__ModuleLoader__.load({
|
|
|
4046
4525
|
alignItems: "center",
|
|
4047
4526
|
gap: 8,
|
|
4048
4527
|
padding: "6px 8px",
|
|
4049
|
-
borderRadius:
|
|
4528
|
+
borderRadius: 8,
|
|
4050
4529
|
fontSize: 13,
|
|
4051
|
-
color:
|
|
4530
|
+
color: "#e6e8ee",
|
|
4052
4531
|
cursor: "pointer"
|
|
4053
4532
|
},
|
|
4054
4533
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -4065,9 +4544,9 @@ window.__ModuleLoader__.load({
|
|
|
4065
4544
|
alignItems: "center",
|
|
4066
4545
|
gap: 8,
|
|
4067
4546
|
padding: "6px 8px",
|
|
4068
|
-
borderRadius:
|
|
4547
|
+
borderRadius: 8,
|
|
4069
4548
|
fontSize: 13,
|
|
4070
|
-
color:
|
|
4549
|
+
color: "#e6e8ee",
|
|
4071
4550
|
cursor: "pointer"
|
|
4072
4551
|
},
|
|
4073
4552
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -4088,7 +4567,7 @@ window.__ModuleLoader__.load({
|
|
|
4088
4567
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4089
4568
|
style: {
|
|
4090
4569
|
fontSize: 12.5,
|
|
4091
|
-
color:
|
|
4570
|
+
color: "#8b96ab",
|
|
4092
4571
|
width: 90,
|
|
4093
4572
|
flexShrink: 0
|
|
4094
4573
|
},
|
|
@@ -4112,7 +4591,7 @@ window.__ModuleLoader__.load({
|
|
|
4112
4591
|
"data-focus-opacity-value": true,
|
|
4113
4592
|
style: {
|
|
4114
4593
|
fontSize: 12.5,
|
|
4115
|
-
color:
|
|
4594
|
+
color: "#b9c2d4",
|
|
4116
4595
|
width: 44
|
|
4117
4596
|
},
|
|
4118
4597
|
children: [Math.round(prefs.focus.opacity * 100), "%"]
|
|
@@ -4131,7 +4610,7 @@ window.__ModuleLoader__.load({
|
|
|
4131
4610
|
style: {
|
|
4132
4611
|
fontSize: 13,
|
|
4133
4612
|
fontWeight: 600,
|
|
4134
|
-
color:
|
|
4613
|
+
color: "#c7cede",
|
|
4135
4614
|
marginBottom: 8
|
|
4136
4615
|
},
|
|
4137
4616
|
children: t("settings.language")
|
|
@@ -4154,7 +4633,7 @@ window.__ModuleLoader__.load({
|
|
|
4154
4633
|
alignItems: "center",
|
|
4155
4634
|
gap: 5,
|
|
4156
4635
|
fontSize: 13,
|
|
4157
|
-
color:
|
|
4636
|
+
color: "#e6e8ee",
|
|
4158
4637
|
cursor: "pointer"
|
|
4159
4638
|
},
|
|
4160
4639
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -4174,7 +4653,7 @@ window.__ModuleLoader__.load({
|
|
|
4174
4653
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4175
4654
|
style: {
|
|
4176
4655
|
fontSize: 12,
|
|
4177
|
-
color:
|
|
4656
|
+
color: "#8b96ab",
|
|
4178
4657
|
marginBottom: 10
|
|
4179
4658
|
},
|
|
4180
4659
|
children: t("settings.support")
|
|
@@ -4275,25 +4754,54 @@ window.__ModuleLoader__.load({
|
|
|
4275
4754
|
]
|
|
4276
4755
|
})]
|
|
4277
4756
|
}),
|
|
4278
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
4279
|
-
|
|
4280
|
-
"data-toolbar-settings-reset": true,
|
|
4281
|
-
onClick: onResetAll,
|
|
4757
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4758
|
+
"data-toolbar-settings-actions": true,
|
|
4282
4759
|
style: {
|
|
4283
|
-
display: "
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
cursor: "pointer",
|
|
4289
|
-
color: MODAL_TEXT,
|
|
4290
|
-
fontSize: 12.5
|
|
4760
|
+
display: "flex",
|
|
4761
|
+
alignItems: "center",
|
|
4762
|
+
justifyContent: "center",
|
|
4763
|
+
gap: 10,
|
|
4764
|
+
margin: "16px auto 2px"
|
|
4291
4765
|
},
|
|
4292
|
-
children:
|
|
4766
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4767
|
+
type: "button",
|
|
4768
|
+
"data-toolbar-settings-reset": true,
|
|
4769
|
+
onClick: onResetAll,
|
|
4770
|
+
style: {
|
|
4771
|
+
padding: "7px 16px",
|
|
4772
|
+
border: `1px solid rgba(255, 255, 255, 0.14)`,
|
|
4773
|
+
borderRadius: 8,
|
|
4774
|
+
cursor: "pointer",
|
|
4775
|
+
color: "#b9c2d4",
|
|
4776
|
+
fontSize: 12.5
|
|
4777
|
+
},
|
|
4778
|
+
children: t("settings.reset")
|
|
4779
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4780
|
+
type: "button",
|
|
4781
|
+
"data-onboarding-reopen": true,
|
|
4782
|
+
onClick: reopenTour,
|
|
4783
|
+
style: {
|
|
4784
|
+
padding: "7px 16px",
|
|
4785
|
+
border: `1px solid rgba(255, 255, 255, 0.14)`,
|
|
4786
|
+
borderRadius: 8,
|
|
4787
|
+
cursor: "pointer",
|
|
4788
|
+
color: "#b9c2d4",
|
|
4789
|
+
fontSize: 12.5
|
|
4790
|
+
},
|
|
4791
|
+
children: t("tour.reopen")
|
|
4792
|
+
})]
|
|
4293
4793
|
})
|
|
4294
4794
|
]
|
|
4295
4795
|
})
|
|
4296
4796
|
}),
|
|
4797
|
+
tourOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MilestoneTour, {
|
|
4798
|
+
t,
|
|
4799
|
+
side,
|
|
4800
|
+
toolbarExpanded,
|
|
4801
|
+
settingsOpen,
|
|
4802
|
+
onSetToolbarExpanded: setToolbarExpanded,
|
|
4803
|
+
onClose: () => setTourOpen(false)
|
|
4804
|
+
}, tourRun),
|
|
4297
4805
|
updateOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4298
4806
|
ref: updatePanelRef,
|
|
4299
4807
|
"data-update-panel": true,
|
|
@@ -4330,7 +4838,7 @@ window.__ModuleLoader__.load({
|
|
|
4330
4838
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4331
4839
|
style: { color: "#8b96ab" },
|
|
4332
4840
|
children: [t("update.current"), ": "]
|
|
4333
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "0.6.
|
|
4841
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "0.6.5" })] }),
|
|
4334
4842
|
updateCheck.phase === "ok" && updateCheck.latest !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4335
4843
|
"data-update-latest": true,
|
|
4336
4844
|
children: [
|
package/package.json
CHANGED