@luziyang2026/dsh-question-nav 0.7.1 → 0.7.2
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 +5 -4
- package/README.zh.md +4 -3
- package/lib/client.js +91 -97
- package/lib/client.js.map +1 -1
- package/lib/types/client/locales.d.ts +4 -0
- package/lib/types/core/focus.d.ts +18 -16
- package/package.json +1 -1
- package/src/client/QuestionNavStrip.tsx +86 -118
- package/src/client/locales.ts +4 -0
- package/src/client/question-nav.module.css +66 -17
- package/src/core/focus.ts +31 -21
package/README.md
CHANGED
|
@@ -56,10 +56,11 @@ Package: **`@luziyang2026/dsh-question-nav`** ([npm][npm] · [GitHub][github]).
|
|
|
56
56
|
- **Click**: jumps to that question. Only then does the jump loop page the
|
|
57
57
|
window (`loadOlder()`) to bring that specific page into view — never the
|
|
58
58
|
whole history up front.
|
|
59
|
-
- **
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
- **Paged overflow**: when many dots don't fit the 60% band, the native
|
|
60
|
+
scrollbar is hidden and two small triangle buttons in the dot style appear —
|
|
61
|
+
**▲ above the dot queue and ▼ below it** — each click revealing five hidden
|
|
62
|
+
dots. The column fades at its top and bottom edges as a pure visual cue
|
|
63
|
+
(wheel and trackpad still scroll too); hovering never auto-scrolls.
|
|
63
64
|
- Empty/left areas of the rail pass pointer events through to the conversation
|
|
64
65
|
(it never blocks the chat).
|
|
65
66
|
|
package/README.zh.md
CHANGED
|
@@ -45,9 +45,10 @@
|
|
|
45
45
|
效果一致。
|
|
46
46
|
- **点击**:跳转到该提问;只有这时跳转循环才 `loadOlder()` 扩窗,把**那一页**
|
|
47
47
|
带进视图——绝不会一次性展开整个历史。
|
|
48
|
-
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
- **分页式溢出**:圆点太多超出 60% 限高时,原生滚动条被隐藏,点列上下会出现
|
|
49
|
+
两个与圆点同风格的三角按钮——**队列上方 ▲、队列下方 ▼**——每次点击翻出
|
|
50
|
+
5 个隐藏圆点。点列上下边缘的渐隐只是纯视觉提示(滚轮/触控板同样可滚);
|
|
51
|
+
悬停不再自动滚动。
|
|
51
52
|
- 圆点列空白区域**点穿**到对话内容,不会挡住聊天。
|
|
52
53
|
|
|
53
54
|
## 环境要求
|
package/lib/client.js
CHANGED
|
@@ -156,14 +156,13 @@ window.__ModuleLoader__.load({
|
|
|
156
156
|
const next = dotTop < viewTop ? dotTop - margin : dotTop + dotHeight + margin - clientHeight;
|
|
157
157
|
return Math.max(0, Math.min(next, Math.max(0, scrollHeight - clientHeight)));
|
|
158
158
|
}
|
|
159
|
-
/**
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
return 90 + 330 * Math.max(0, Math.min(1, ratio));
|
|
159
|
+
/** Scroll step (px) for one paging click: `rows` whole dot rows. */
|
|
160
|
+
function pageStep(dotSize = 8, gap = 6, rows = 5) {
|
|
161
|
+
return rows * (dotSize + gap);
|
|
162
|
+
}
|
|
163
|
+
/** Clamp a target scrollTop into the band's valid range (0..maxScroll). */
|
|
164
|
+
function clampScrollTop(target, maxScroll) {
|
|
165
|
+
return Math.max(0, Math.min(target, Math.max(0, maxScroll)));
|
|
167
166
|
}
|
|
168
167
|
//#endregion
|
|
169
168
|
//#region src/core/time.ts
|
|
@@ -203,7 +202,7 @@ window.__ModuleLoader__.load({
|
|
|
203
202
|
}
|
|
204
203
|
//#endregion
|
|
205
204
|
//#region \0dsh-css:dsh-question-nav/src/client/question-nav.module.css.mjs
|
|
206
|
-
const css = ".TWf_pa_rail{z-index:1;box-sizing:border-box;pointer-events:none;background:0 0;flex-direction:column;align-items:center;width:44px;display:flex;position:absolute;top:0;bottom:0;left:0}.TWf_pa_railRight{left:auto}.
|
|
205
|
+
const css = ".TWf_pa_rail{z-index:1;box-sizing:border-box;pointer-events:none;background:0 0;flex-direction:column;align-items:center;width:44px;display:flex;position:absolute;top:0;bottom:0;left:0}.TWf_pa_railRight{left:auto}.TWf_pa_queue{box-sizing:border-box;pointer-events:none;flex-direction:column;flex:0 auto;align-items:center;gap:6px;width:100%;min-height:0;max-height:60%;margin:auto 0;display:flex}.TWf_pa_list{scrollbar-width:none;pointer-events:auto;flex-direction:column;flex:auto;align-items:center;gap:6px;width:100%;min-height:0;padding:8px 0;display:flex;overflow:hidden auto}.TWf_pa_list::-webkit-scrollbar{width:0;height:0;display:none}.TWf_pa_listScrollable{-webkit-mask-image:linear-gradient(#0000,#000 22px calc(100% - 22px),#0000);mask-image:linear-gradient(#0000,#000 22px calc(100% - 22px),#0000)}.TWf_pa_dot{pointer-events:auto;background:var(--dsw-alias-border-l3);cursor:pointer;border:none;border-radius:50%;flex:none;width:8px;height:8px;padding:0;transition:transform .12s,background .12s}.TWf_pa_dot:hover,.TWf_pa_dot.TWf_pa_focused,.TWf_pa_dot.TWf_pa_active{background:var(--dsw-alias-brand-primary)}.TWf_pa_count{color:var(--dsw-alias-label-tertiary);user-select:none;flex:none;font-size:10px;font-weight:600;line-height:1}.TWf_pa_dots{flex-direction:column;align-items:center;gap:6px;display:flex}.TWf_pa_navBtn{pointer-events:auto;cursor:pointer;background:0 0;border:none;flex:none;justify-content:center;align-items:center;width:14px;height:12px;padding:0;display:flex}.TWf_pa_navBtn:before{content:\"\";border-left:5px solid #0000;border-right:5px solid #0000;width:0;height:0;transition:border-color .12s;display:block}.TWf_pa_navUp:before{border-bottom:7px solid var(--dsw-alias-border-l3)}.TWf_pa_navDown:before{border-top:7px solid var(--dsw-alias-border-l3)}.TWf_pa_navUp:hover:before{border-bottom-color:var(--dsw-alias-brand-primary)}.TWf_pa_navDown:hover:before{border-top-color:var(--dsw-alias-brand-primary)}.TWf_pa_empty{color:var(--dsw-alias-label-tertiary);text-align:center;word-break:break-word;padding:10px 4px;font-size:11px}.TWf_pa_hint{z-index:30;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);max-width:260px;color:var(--dsw-alias-label-secondary);pointer-events:none;border-radius:6px;padding:6px 10px;font-size:12px;line-height:16px;position:fixed;box-shadow:0 2px 10px #0000002e}.TWf_pa_cascade{z-index:20;pointer-events:none;flex-direction:column;align-items:flex-start;gap:6px;display:flex;position:fixed}.TWf_pa_card{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);width:380px;color:var(--dsw-alias-label-secondary);white-space:normal;word-break:break-word;pointer-events:auto;cursor:pointer;border-radius:10px;padding:8px 12px 10px;font-size:13px;line-height:18px;transition:border-color .12s,box-shadow .12s;box-shadow:0 1px 6px #0000001a}.TWf_pa_card:hover{border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-label-primary);box-shadow:0 3px 12px #0000002e}.TWf_pa_cardSelected{border-color:var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);box-shadow:inset 3px 0 0 0 var(--dsw-alias-brand-primary), 0 6px 20px #00000038}.TWf_pa_cardSelected:hover{border-color:var(--dsw-alias-brand-primary);box-shadow:inset 3px 0 0 0 var(--dsw-alias-brand-primary), 0 6px 22px #00000042}.TWf_pa_cardTitle{color:var(--dsw-alias-label-tertiary);margin-bottom:4px;font-size:11px;font-weight:600}.TWf_pa_cardBody{scrollbar-width:thin;max-height:96px;overflow-y:auto}.TWf_pa_cardClamp{word-break:break-word;-webkit-box-orient:vertical;font-size:13px;line-height:18px;display:-webkit-box;overflow:hidden}.TWf_pa_cardLine+.TWf_pa_cardLine{border-top:1px solid var(--dsw-alias-border-l1);margin-top:6px;padding-top:6px}.TWf_pa_cardTime{color:var(--dsw-alias-label-tertiary);margin-top:6px;font-size:11px}.TWf_pa_settings{flex-direction:column;gap:8px;padding:4px 0;display:flex}.TWf_pa_settingsTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:13px;font-weight:600}.TWf_pa_settingsDesc{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px;line-height:18px}.TWf_pa_segmented{border:1px solid var(--dsw-alias-border-l1);border-radius:8px;align-self:flex-start;display:inline-flex;overflow:hidden}.TWf_pa_segment{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:8px 16px;font-size:13px;line-height:1;transition:background .12s,color .12s}.TWf_pa_segment+.TWf_pa_segment{border-left:1px solid var(--dsw-alias-border-l1)}.TWf_pa_segment:hover{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}.TWf_pa_segmentActive,.TWf_pa_segmentActive:hover{background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-label-inverse)}";
|
|
207
206
|
const tagId = "@luziyang2026/dsh-question-nav/question-nav.module.css";
|
|
208
207
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
209
208
|
const tag = document.createElement("style");
|
|
@@ -230,6 +229,10 @@ window.__ModuleLoader__.load({
|
|
|
230
229
|
"hint": "TWf_pa_hint",
|
|
231
230
|
"list": "TWf_pa_list",
|
|
232
231
|
"listScrollable": "TWf_pa_listScrollable",
|
|
232
|
+
"navBtn": "TWf_pa_navBtn",
|
|
233
|
+
"navDown": "TWf_pa_navDown",
|
|
234
|
+
"navUp": "TWf_pa_navUp",
|
|
235
|
+
"queue": "TWf_pa_queue",
|
|
233
236
|
"rail": "TWf_pa_rail",
|
|
234
237
|
"railRight": "TWf_pa_railRight",
|
|
235
238
|
"segment": "TWf_pa_segment",
|
|
@@ -258,6 +261,11 @@ window.__ModuleLoader__.load({
|
|
|
258
261
|
* jumps to its question, exactly like clicking the dot; the rail scrolls the
|
|
259
262
|
* selected dot into view only when it is clipped by the band's edges.
|
|
260
263
|
*
|
|
264
|
+
* Overflow is paged, not auto-scrolled: two small triangle buttons in the dot
|
|
265
|
+
* style sit above and below the dot queue (▲ / ▼), each click revealing five
|
|
266
|
+
* hidden dots. The native scrollbar stays hidden and the column fades at its
|
|
267
|
+
* edges as a pure visual cue — no hover auto-scroll.
|
|
268
|
+
*
|
|
261
269
|
* Data source: the host-folded `questionIndex` session projection (whole
|
|
262
270
|
* history, persisted host-side, pushed live through session/projection
|
|
263
271
|
* frames) read through the injected `questionProjection` face, plus the live
|
|
@@ -313,69 +321,28 @@ window.__ModuleLoader__.load({
|
|
|
313
321
|
const lastDotsRef = (0, react.useRef)([]);
|
|
314
322
|
const lastFocusedKeyRef = (0, react.useRef)(null);
|
|
315
323
|
const [scrollable, setScrollable] = (0, react.useState)(false);
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
last: 0
|
|
324
|
+
const [scrollPos, setScrollPos] = (0, react.useState)({
|
|
325
|
+
top: 0,
|
|
326
|
+
max: 0
|
|
320
327
|
});
|
|
321
|
-
const
|
|
322
|
-
const cancelEdgeDwell = () => {
|
|
323
|
-
if (edgeDwellRef.current !== null) {
|
|
324
|
-
window.clearTimeout(edgeDwellRef.current);
|
|
325
|
-
edgeDwellRef.current = null;
|
|
326
|
-
}
|
|
327
|
-
};
|
|
328
|
-
const stopEdgeScroll = () => {
|
|
329
|
-
cancelEdgeDwell();
|
|
330
|
-
edgeScrollRef.current.speed = 0;
|
|
331
|
-
if (edgeScrollRef.current.raf !== 0) {
|
|
332
|
-
cancelAnimationFrame(edgeScrollRef.current.raf);
|
|
333
|
-
edgeScrollRef.current.raf = 0;
|
|
334
|
-
}
|
|
335
|
-
};
|
|
336
|
-
const edgeTick = (now) => {
|
|
328
|
+
const syncScroll = () => {
|
|
337
329
|
const list = listRef.current;
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
const atTop = list.scrollTop <= 0 && state.speed < 0;
|
|
345
|
-
const atBottom = list.scrollTop >= list.scrollHeight - list.clientHeight - 1 && state.speed > 0;
|
|
346
|
-
if (atTop || atBottom) {
|
|
347
|
-
state.speed = 0;
|
|
348
|
-
return;
|
|
349
|
-
}
|
|
350
|
-
state.raf = requestAnimationFrame(edgeTick);
|
|
330
|
+
if (list === null) return;
|
|
331
|
+
const max = Math.max(0, list.scrollHeight - list.clientHeight);
|
|
332
|
+
setScrollPos({
|
|
333
|
+
top: list.scrollTop,
|
|
334
|
+
max
|
|
335
|
+
});
|
|
351
336
|
};
|
|
352
|
-
const
|
|
337
|
+
const pageBy = (dir) => {
|
|
353
338
|
const list = listRef.current;
|
|
354
339
|
if (list === null) return;
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
const depthTop = 26 - y;
|
|
359
|
-
const depthBottom = y - (rect.height - 26);
|
|
360
|
-
let speed = 0;
|
|
361
|
-
if (!overDot) {
|
|
362
|
-
if (depthTop > 0 && list.scrollTop > 0) speed = -edgeScrollSpeed(depthTop / 26);
|
|
363
|
-
else if (depthBottom > 0 && list.scrollTop < list.scrollHeight - list.clientHeight - 1) speed = edgeScrollSpeed(depthBottom / 26);
|
|
364
|
-
}
|
|
365
|
-
const state = edgeScrollRef.current;
|
|
366
|
-
state.speed = speed;
|
|
367
|
-
if (speed === 0) {
|
|
368
|
-
stopEdgeScroll();
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
if (state.raf === 0 && edgeDwellRef.current === null) edgeDwellRef.current = window.setTimeout(() => {
|
|
372
|
-
edgeDwellRef.current = null;
|
|
373
|
-
if (edgeScrollRef.current.speed !== 0 && edgeScrollRef.current.raf === 0) {
|
|
374
|
-
edgeScrollRef.current.last = performance.now();
|
|
375
|
-
edgeScrollRef.current.raf = requestAnimationFrame(edgeTick);
|
|
376
|
-
}
|
|
377
|
-
}, 200);
|
|
340
|
+
const max = Math.max(0, list.scrollHeight - list.clientHeight);
|
|
341
|
+
list.scrollTop = clampScrollTop(list.scrollTop + dir * pageStep(), max);
|
|
342
|
+
syncScroll();
|
|
378
343
|
};
|
|
344
|
+
const canPageUp = scrollable && scrollPos.top > 0;
|
|
345
|
+
const canPageDown = scrollable && scrollPos.top < scrollPos.max;
|
|
379
346
|
const cancelClearFocus = () => {
|
|
380
347
|
if (clearFocusTimerRef.current !== null) {
|
|
381
348
|
window.clearTimeout(clearFocusTimerRef.current);
|
|
@@ -515,18 +482,21 @@ window.__ModuleLoader__.load({
|
|
|
515
482
|
if (lastFocusedKeyRef.current === key) return;
|
|
516
483
|
lastFocusedKeyRef.current = key;
|
|
517
484
|
if (key === null) return;
|
|
518
|
-
if (edgeScrollRef.current.raf !== 0) return;
|
|
519
485
|
const list = listRef.current;
|
|
520
486
|
if (list === null) return;
|
|
521
487
|
const target = list.querySelector("[data-question-nav-focused=\"true\"]");
|
|
522
488
|
if (target === null) return;
|
|
523
489
|
const next = minimalScrollIntoView(list.scrollTop, list.clientHeight, list.scrollHeight, target.offsetTop - list.offsetTop, target.offsetHeight);
|
|
524
490
|
if (next !== null) list.scrollTop = next;
|
|
491
|
+
syncScroll();
|
|
525
492
|
}, [focus]);
|
|
526
493
|
(0, react.useLayoutEffect)(() => {
|
|
527
494
|
const list = listRef.current;
|
|
528
495
|
if (list === null) return;
|
|
529
|
-
const check = () =>
|
|
496
|
+
const check = () => {
|
|
497
|
+
setScrollable(list.scrollHeight > list.clientHeight + 1);
|
|
498
|
+
syncScroll();
|
|
499
|
+
};
|
|
530
500
|
check();
|
|
531
501
|
if (typeof ResizeObserver === "undefined") return;
|
|
532
502
|
const observer = new ResizeObserver(check);
|
|
@@ -536,7 +506,6 @@ window.__ModuleLoader__.load({
|
|
|
536
506
|
(0, react.useEffect)(() => () => {
|
|
537
507
|
if (hintTimerRef.current !== null) window.clearTimeout(hintTimerRef.current);
|
|
538
508
|
if (clearFocusTimerRef.current !== null) window.clearTimeout(clearFocusTimerRef.current);
|
|
539
|
-
stopEdgeScroll();
|
|
540
509
|
}, []);
|
|
541
510
|
if (!visible) return null;
|
|
542
511
|
const onJump = (dot) => {
|
|
@@ -573,39 +542,60 @@ window.__ModuleLoader__.load({
|
|
|
573
542
|
"data-question-nav": "rail",
|
|
574
543
|
children: [
|
|
575
544
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
576
|
-
|
|
577
|
-
className: scrollable ? `${question_nav_module_css_default.list} ${question_nav_module_css_default.listScrollable}` : question_nav_module_css_default.list,
|
|
578
|
-
onMouseMove: scrollable ? onListMouseMove : void 0,
|
|
579
|
-
onMouseLeave: () => {
|
|
580
|
-
stopEdgeScroll();
|
|
581
|
-
scheduleClearFocus();
|
|
582
|
-
},
|
|
545
|
+
className: question_nav_module_css_default.queue,
|
|
583
546
|
children: dots.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
584
547
|
className: question_nav_module_css_default.empty,
|
|
585
548
|
children: t("strip.empty")
|
|
586
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
587
|
-
|
|
588
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
549
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
550
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
589
551
|
className: question_nav_module_css_default.count,
|
|
590
552
|
children: dots.length
|
|
591
|
-
}),
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
553
|
+
}),
|
|
554
|
+
scrollable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
555
|
+
type: "button",
|
|
556
|
+
className: `${question_nav_module_css_default.navBtn} ${question_nav_module_css_default.navUp}`,
|
|
557
|
+
"aria-label": t("strip.up"),
|
|
558
|
+
style: { visibility: canPageUp ? "visible" : "hidden" },
|
|
559
|
+
onMouseEnter: cancelClearFocus,
|
|
560
|
+
onMouseLeave: scheduleClearFocus,
|
|
561
|
+
onClick: () => pageBy(-1)
|
|
562
|
+
}) : null,
|
|
563
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
564
|
+
ref: listRef,
|
|
565
|
+
className: scrollable ? `${question_nav_module_css_default.list} ${question_nav_module_css_default.listScrollable}` : question_nav_module_css_default.list,
|
|
566
|
+
onScroll: syncScroll,
|
|
567
|
+
onMouseLeave: scheduleClearFocus,
|
|
568
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
569
|
+
className: question_nav_module_css_default.dots,
|
|
570
|
+
children: dots.map((dot, index) => {
|
|
571
|
+
const isFocused = focus !== null && focus.key === dot.key;
|
|
572
|
+
const tier = selectedIndex < 0 ? null : focusTier(index - selectedIndex);
|
|
573
|
+
const scale = jumpingKey === dot.key ? 1.6 : tier !== null ? focusScale(tier) : 1;
|
|
574
|
+
const cls = [question_nav_module_css_default.dot];
|
|
575
|
+
if (isFocused) cls.push(question_nav_module_css_default.focused);
|
|
576
|
+
if (jumpingKey === dot.key) cls.push(question_nav_module_css_default.active);
|
|
577
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
578
|
+
className: cls.join(" "),
|
|
579
|
+
style: { transform: `scale(${scale})` },
|
|
580
|
+
"data-question-nav-focused": isFocused ? "true" : void 0,
|
|
581
|
+
"data-question-nav-index": index,
|
|
582
|
+
"aria-label": dot.texts[0] ?? "",
|
|
583
|
+
onMouseEnter: (e) => openFocus(dot, e.currentTarget),
|
|
584
|
+
onClick: () => onJump(dot)
|
|
585
|
+
}, dot.key);
|
|
586
|
+
})
|
|
587
|
+
})
|
|
588
|
+
}),
|
|
589
|
+
scrollable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
590
|
+
type: "button",
|
|
591
|
+
className: `${question_nav_module_css_default.navBtn} ${question_nav_module_css_default.navDown}`,
|
|
592
|
+
"aria-label": t("strip.down"),
|
|
593
|
+
style: { visibility: canPageDown ? "visible" : "hidden" },
|
|
594
|
+
onMouseEnter: cancelClearFocus,
|
|
595
|
+
onMouseLeave: scheduleClearFocus,
|
|
596
|
+
onClick: () => pageBy(1)
|
|
597
|
+
}) : null
|
|
598
|
+
] })
|
|
609
599
|
}),
|
|
610
600
|
hint !== null ? (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
611
601
|
className: question_nav_module_css_default.hint,
|
|
@@ -803,6 +793,8 @@ window.__ModuleLoader__.load({
|
|
|
803
793
|
*/
|
|
804
794
|
const zh = {
|
|
805
795
|
"strip.empty": "本会话还没有提问",
|
|
796
|
+
"strip.up": "向上翻出 5 个提问圆点",
|
|
797
|
+
"strip.down": "向下翻出 5 个提问圆点",
|
|
806
798
|
"jump.inactive": "聊天视图未激活",
|
|
807
799
|
"jump.hidden": "目标无独立气泡,已定位到邻近内容",
|
|
808
800
|
"jump.notfound": "目标未加载或不存在(可能已压缩)",
|
|
@@ -815,6 +807,8 @@ window.__ModuleLoader__.load({
|
|
|
815
807
|
};
|
|
816
808
|
const en = {
|
|
817
809
|
"strip.empty": "No questions in this session yet",
|
|
810
|
+
"strip.up": "Reveal 5 question dots above",
|
|
811
|
+
"strip.down": "Reveal 5 question dots below",
|
|
818
812
|
"jump.inactive": "Chat view is not active",
|
|
819
813
|
"jump.hidden": "No dedicated bubble; landed on nearby content",
|
|
820
814
|
"jump.notfound": "Target not loaded or missing (maybe compacted)",
|