dsh-ask-from-text 0.1.19 → 0.1.20
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/CHANGELOG.md +18 -0
- package/README.md +2 -2
- package/client.js +100 -77
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,14 @@ All notable changes to `dsh-ask-from-text` are documented here. The format is
|
|
|
4
4
|
based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this
|
|
5
5
|
project follows [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [0.1.20] - 2026-11-13
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Runtime UI localization for Chinese and English. The active DSH language is
|
|
12
|
+
read through `ctx.locale`; other languages fall back to English. Native
|
|
13
|
+
conversation and Plugin Manager metadata continue to follow DSH.
|
|
14
|
+
|
|
7
15
|
## [0.1.19] - 2026-11-13
|
|
8
16
|
|
|
9
17
|
### Fixed
|
|
@@ -55,6 +63,14 @@ project follows [Semantic Versioning](https://semver.org/).
|
|
|
55
63
|
|
|
56
64
|
- README screenshots now use absolute CDN URLs so they render on the npm package page.
|
|
57
65
|
|
|
66
|
+
## [0.1.20] - 2026-11-13
|
|
67
|
+
|
|
68
|
+
### Added
|
|
69
|
+
|
|
70
|
+
- Runtime UI localization for Chinese and English. The active DSH language is
|
|
71
|
+
read through `ctx.locale`; other languages fall back to English. Native
|
|
72
|
+
conversation and Plugin Manager metadata continue to follow DSH.
|
|
73
|
+
|
|
58
74
|
## [0.1.19] - 2026-11-13
|
|
59
75
|
|
|
60
76
|
### Fixed
|
|
@@ -194,6 +210,7 @@ project follows [Semantic Versioning](https://semver.org/).
|
|
|
194
210
|
[0.1.17]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.17
|
|
195
211
|
[0.1.18]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.18
|
|
196
212
|
[0.1.19]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.19
|
|
213
|
+
[0.1.20]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.20
|
|
197
214
|
[0.1.13]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.13
|
|
198
215
|
[0.1.14]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.14
|
|
199
216
|
[0.1.15]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.15
|
|
@@ -201,3 +218,4 @@ project follows [Semantic Versioning](https://semver.org/).
|
|
|
201
218
|
[0.1.17]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.17
|
|
202
219
|
[0.1.18]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.18
|
|
203
220
|
[0.1.19]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.19
|
|
221
|
+
[0.1.20]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.20
|
package/README.md
CHANGED
|
@@ -103,7 +103,7 @@ dsh plugin --profile web add /absolute/path/to/dsh-ask-from-text
|
|
|
103
103
|
- 追问回答是真实的 DSH Session,可以使用思考、工具调用、Stop 和原生输入框。
|
|
104
104
|
- 分支只看到父级和祖先内容,不看到兄弟分支,也不会自动获得父级后来新增的内容。
|
|
105
105
|
- 分支对话会出现在普通 Session 列表中,这是正常现象。
|
|
106
|
-
-
|
|
106
|
+
- 界面文案跟随 DSH 语言:中文/英文;其他语言自动回退英文。原生对话区域继续跟随 DSH 自身的语言。
|
|
107
107
|
- 目前主要面向 DSH Desktop;Web 共用同一套 UI,窄屏体验尚未专门优化。
|
|
108
108
|
|
|
109
109
|
## 常见问题
|
|
@@ -225,7 +225,7 @@ These sessions are grouped under a `追问分支` header. Click the header to co
|
|
|
225
225
|
- A follow-up is a real DSH Session. It can use reasoning, tool calls, Stop, and the native composer.
|
|
226
226
|
- A branch sees its parent and ancestors, not siblings, and does not automatically receive later turns added to its parent.
|
|
227
227
|
- Branch conversations also appear in the normal Session list. This is expected.
|
|
228
|
-
- Runtime UI
|
|
228
|
+
- Runtime UI follows the DSH language: Chinese and English are bundled; other languages fall back to English. The native conversation follows DSH.
|
|
229
229
|
- DSH Desktop is the primary target. The Web client shares the same UI, but narrow-screen behavior has not been specifically polished.
|
|
230
230
|
|
|
231
231
|
### FAQ
|
package/client.js
CHANGED
|
@@ -78,6 +78,13 @@ window.__ModuleLoader__.load({
|
|
|
78
78
|
stages: '个节点',
|
|
79
79
|
collapseDock: '收起列表',
|
|
80
80
|
expandDock: '展开列表',
|
|
81
|
+
sidebarGroup: '追问分支',
|
|
82
|
+
context: '上下文',
|
|
83
|
+
contextStart: '上下文起点',
|
|
84
|
+
waiting: '待提问',
|
|
85
|
+
treeNote: '当前模型上下文:{context}。兄弟分支不在其中。',
|
|
86
|
+
anchorMissing: '的原文当前不可见,可能已被折叠或尚未加载',
|
|
87
|
+
draftWait: '在下方输入浮窗中提问',
|
|
81
88
|
},
|
|
82
89
|
en: {
|
|
83
90
|
chip: 'Ask',
|
|
@@ -126,6 +133,13 @@ window.__ModuleLoader__.load({
|
|
|
126
133
|
stages: 'nodes',
|
|
127
134
|
collapseDock: 'Collapse list',
|
|
128
135
|
expandDock: 'Expand list',
|
|
136
|
+
sidebarGroup: 'Branches',
|
|
137
|
+
context: 'Context',
|
|
138
|
+
contextStart: 'Context root',
|
|
139
|
+
waiting: 'Waiting for question',
|
|
140
|
+
treeNote: 'Current model context: {context}. Sibling branches are not included.',
|
|
141
|
+
anchorMissing: 'source text is not visible; it may be folded or not loaded yet',
|
|
142
|
+
draftWait: 'Ask in the input window below',
|
|
129
143
|
},
|
|
130
144
|
}
|
|
131
145
|
|
|
@@ -342,21 +356,21 @@ window.__ModuleLoader__.load({
|
|
|
342
356
|
}
|
|
343
357
|
|
|
344
358
|
function pathLabel(state, branch) {
|
|
345
|
-
return `${
|
|
359
|
+
return `${app.t('main')}${pathOf(state, branch).map(item => ` › #${item.number}`).join('')}`
|
|
346
360
|
}
|
|
347
361
|
|
|
348
362
|
function branchBasis(state, branch) {
|
|
349
|
-
if (!branch.parentBranchId) return `${
|
|
363
|
+
if (!branch.parentBranchId) return `${app.t('basedOn')} ${app.t('main')}`
|
|
350
364
|
const parent = state.branches[branch.parentBranchId]
|
|
351
|
-
return parent ? `${
|
|
365
|
+
return parent ? `${app.t('basedOn')} #${parent.number}` : `${app.t('basedOn')} ${app.t('main')}`
|
|
352
366
|
}
|
|
353
367
|
|
|
354
368
|
function statusLabel(branch) {
|
|
355
|
-
if (branch.status === 'sending') return
|
|
356
|
-
if (branch.status === 'running') return
|
|
357
|
-
if (branch.status === 'error') return
|
|
358
|
-
if (branch.prompted) return
|
|
359
|
-
return
|
|
369
|
+
if (branch.status === 'sending') return app.t('sending')
|
|
370
|
+
if (branch.status === 'running') return app.t('running')
|
|
371
|
+
if (branch.status === 'error') return app.t('failed')
|
|
372
|
+
if (branch.prompted) return app.t('ready')
|
|
373
|
+
return app.t('draft')
|
|
360
374
|
}
|
|
361
375
|
|
|
362
376
|
function colorVars(color) {
|
|
@@ -422,7 +436,15 @@ window.__ModuleLoader__.load({
|
|
|
422
436
|
refs,
|
|
423
437
|
chats,
|
|
424
438
|
get main() { return main },
|
|
425
|
-
t(key) {
|
|
439
|
+
t(key, params) {
|
|
440
|
+
if (ctx.locale) {
|
|
441
|
+
const value = ctx.locale.bind(NS)(key, params)
|
|
442
|
+
if (value && value !== key) return value
|
|
443
|
+
}
|
|
444
|
+
const template = DICT.en[key] ?? key
|
|
445
|
+
if (!params) return template
|
|
446
|
+
return template.replace(/\{(\w+)\}/g, (match, name) => name in params ? String(params[name]) : match)
|
|
447
|
+
},
|
|
426
448
|
subscribe(listener) {
|
|
427
449
|
listeners.add(listener)
|
|
428
450
|
return () => { listeners.delete(listener) }
|
|
@@ -902,7 +924,7 @@ window.__ModuleLoader__.load({
|
|
|
902
924
|
const quote = ranges.map(part => part.quote).join('\n').trim()
|
|
903
925
|
if (!quote) { clearChip(); return }
|
|
904
926
|
if (quote.length > MAX_QUOTE) {
|
|
905
|
-
notify(
|
|
927
|
+
notify(app.t('tooLong'))
|
|
906
928
|
clearChip()
|
|
907
929
|
return
|
|
908
930
|
}
|
|
@@ -1102,7 +1124,7 @@ window.__ModuleLoader__.load({
|
|
|
1102
1124
|
|
|
1103
1125
|
function serialize(quote, question) {
|
|
1104
1126
|
const body = String(quote || '').trim().split(/\r?\n/).map(line => `> ${line}`).join('\n')
|
|
1105
|
-
const text = String(question || '').trim() ||
|
|
1127
|
+
const text = String(question || '').trim() || app.t('defaultQuestion')
|
|
1106
1128
|
return `${body}\n\n${text}`
|
|
1107
1129
|
}
|
|
1108
1130
|
|
|
@@ -1160,7 +1182,7 @@ window.__ModuleLoader__.load({
|
|
|
1160
1182
|
await ensureReference(branch)
|
|
1161
1183
|
}
|
|
1162
1184
|
const reference = refs.get(branch.id)
|
|
1163
|
-
if (!reference) throw new Error(
|
|
1185
|
+
if (!reference) throw new Error(app.t('noSession'))
|
|
1164
1186
|
const text = serialize(branch.anchor.quote, branch.question)
|
|
1165
1187
|
const echo = reference.binding.session.beginSubmission({
|
|
1166
1188
|
mode: 'queue',
|
|
@@ -1175,7 +1197,7 @@ window.__ModuleLoader__.load({
|
|
|
1175
1197
|
)
|
|
1176
1198
|
if (!result.ok) {
|
|
1177
1199
|
branch.status = 'error'
|
|
1178
|
-
branch.error = result.error?.message ||
|
|
1200
|
+
branch.error = result.error?.message || app.t('error')
|
|
1179
1201
|
emit()
|
|
1180
1202
|
return false
|
|
1181
1203
|
}
|
|
@@ -1204,7 +1226,7 @@ window.__ModuleLoader__.load({
|
|
|
1204
1226
|
try {
|
|
1205
1227
|
await ensureReference(branch)
|
|
1206
1228
|
const reference = refs.get(branch.id)
|
|
1207
|
-
if (!reference) throw new Error(
|
|
1229
|
+
if (!reference) throw new Error(app.t('noSession'))
|
|
1208
1230
|
const echo = reference.binding.session.beginSubmission({
|
|
1209
1231
|
mode: 'queue',
|
|
1210
1232
|
text,
|
|
@@ -1218,7 +1240,7 @@ window.__ModuleLoader__.load({
|
|
|
1218
1240
|
)
|
|
1219
1241
|
if (!result.ok) {
|
|
1220
1242
|
branch.status = 'error'
|
|
1221
|
-
branch.error = result.error?.message ||
|
|
1243
|
+
branch.error = result.error?.message || app.t('error')
|
|
1222
1244
|
emit()
|
|
1223
1245
|
return false
|
|
1224
1246
|
}
|
|
@@ -1310,7 +1332,7 @@ window.__ModuleLoader__.load({
|
|
|
1310
1332
|
if (other !== header) other.remove()
|
|
1311
1333
|
}
|
|
1312
1334
|
if (header.nextSibling !== first) firstParent.insertBefore(header, first)
|
|
1313
|
-
const label = `${state.sidebarCollapsed ? '▸' : '▾'}
|
|
1335
|
+
const label = `${state.sidebarCollapsed ? '▸' : '▾'} ${app.t('sidebarGroup')} · ${rows.length}`
|
|
1314
1336
|
if (header.textContent !== label) header.textContent = label
|
|
1315
1337
|
for (const row of rows) row.classList.toggle('ifu-sidebar-hidden', state.sidebarCollapsed)
|
|
1316
1338
|
|
|
@@ -1424,7 +1446,7 @@ window.__ModuleLoader__.load({
|
|
|
1424
1446
|
// giving up on this attempt.
|
|
1425
1447
|
if (navigator && attempt === 0) navigator.click()
|
|
1426
1448
|
if (attempt < 14) setTimeout(() => scrollBranchIntoView(branch, attempt + 1), 100)
|
|
1427
|
-
else notify(`#${branch.number}
|
|
1449
|
+
else notify(`#${branch.number} ${app.t('anchorMissing')}`)
|
|
1428
1450
|
return
|
|
1429
1451
|
}
|
|
1430
1452
|
if (navigator && attempt === 0) navigator.click()
|
|
@@ -1852,14 +1874,14 @@ window.__ModuleLoader__.load({
|
|
|
1852
1874
|
}
|
|
1853
1875
|
return h('div', { className: 'ifu-compose' },
|
|
1854
1876
|
h('div', { className: 'ifu-quote', title: branch.anchor.quote },
|
|
1855
|
-
h('div', { className: 'ifu-quote-label' }, `${
|
|
1877
|
+
h('div', { className: 'ifu-quote-label' }, `${app.t('quote')} · ${app.t('basedOn')} ${branch.parentBranchId ? `#${app.state.branches[branch.parentBranchId]?.number ?? ''}` : app.t('main')}`),
|
|
1856
1878
|
h('div', { className: 'ifu-quote-text' }, branch.anchor.quote.length > 220 ? `${branch.anchor.quote.slice(0, 219)}…` : branch.anchor.quote),
|
|
1857
1879
|
),
|
|
1858
1880
|
h('textarea', {
|
|
1859
1881
|
ref: areaRef,
|
|
1860
1882
|
className: 'ifu-textarea',
|
|
1861
1883
|
value: text,
|
|
1862
|
-
placeholder:
|
|
1884
|
+
placeholder: app.t('empty'),
|
|
1863
1885
|
rows: 3,
|
|
1864
1886
|
onChange: event => { setText(event.target.value); app.setDraftText(branch.id, event.target.value) },
|
|
1865
1887
|
onKeyDown: event => {
|
|
@@ -1871,14 +1893,14 @@ window.__ModuleLoader__.load({
|
|
|
1871
1893
|
}),
|
|
1872
1894
|
branch.error ? h('div', { className: 'ifu-error', role: 'alert' }, branch.error) : null,
|
|
1873
1895
|
h('div', { className: 'ifu-compose-foot' },
|
|
1874
|
-
h('span', { className: 'ifu-hint' },
|
|
1896
|
+
h('span', { className: 'ifu-hint' }, app.t('sendHint')),
|
|
1875
1897
|
h('div', { className: 'ifu-grow' }),
|
|
1876
1898
|
h('button', {
|
|
1877
1899
|
type: 'button',
|
|
1878
1900
|
className: 'ifu-send',
|
|
1879
1901
|
disabled: sending,
|
|
1880
1902
|
onClick: submit,
|
|
1881
|
-
}, sending ?
|
|
1903
|
+
}, sending ? app.t('sendingAction') : (branch.error ? app.t('retry') : app.t('send'))),
|
|
1882
1904
|
),
|
|
1883
1905
|
)
|
|
1884
1906
|
}
|
|
@@ -1887,7 +1909,7 @@ window.__ModuleLoader__.load({
|
|
|
1887
1909
|
const { branch, SessionProvider, renderSlot } = props
|
|
1888
1910
|
const reference = app.refs.get(branch.id)
|
|
1889
1911
|
if (!reference) {
|
|
1890
|
-
return h('div', { className: 'ifu-loading' }, branch.error ||
|
|
1912
|
+
return h('div', { className: 'ifu-loading' }, branch.error || app.t('sending'))
|
|
1891
1913
|
}
|
|
1892
1914
|
return h(SessionProvider, { session: reference },
|
|
1893
1915
|
h('div', {
|
|
@@ -1935,18 +1957,18 @@ window.__ModuleLoader__.load({
|
|
|
1935
1957
|
...colorVars(branch.color),
|
|
1936
1958
|
},
|
|
1937
1959
|
role: 'dialog',
|
|
1938
|
-
'aria-label': `${
|
|
1960
|
+
'aria-label': `${app.t('branchN')} #${branch.number} ${app.t('input')}`,
|
|
1939
1961
|
},
|
|
1940
1962
|
h('header', { className: 'ifu-head', onPointerDown: event => app.startPanelDrag(branch.id, event, 'input') },
|
|
1941
1963
|
h('span', { className: 'ifu-dot' }),
|
|
1942
1964
|
h('div', { className: 'ifu-title-wrap' },
|
|
1943
|
-
h('div', { className: 'ifu-title' }, `${
|
|
1965
|
+
h('div', { className: 'ifu-title' }, `${app.t('input')} · #${branch.number}`),
|
|
1944
1966
|
h('div', { className: 'ifu-sub' }, statusLabel(branch)),
|
|
1945
1967
|
),
|
|
1946
1968
|
h('div', { className: 'ifu-grow' }),
|
|
1947
|
-
h(IconButton, { title:
|
|
1969
|
+
h(IconButton, { title: app.t('collapse'), onClick: () => app.collapse(branch.id) }, '—'),
|
|
1948
1970
|
branch.sessionId ? null : h(IconButton, {
|
|
1949
|
-
title:
|
|
1971
|
+
title: app.t('deleteDraft'),
|
|
1950
1972
|
className: 'ifu-danger',
|
|
1951
1973
|
onClick: () => app.deleteDraft(branch.id),
|
|
1952
1974
|
}, '⌫'),
|
|
@@ -1956,7 +1978,7 @@ window.__ModuleLoader__.load({
|
|
|
1956
1978
|
ref: areaRef,
|
|
1957
1979
|
className: 'ifu-textarea',
|
|
1958
1980
|
value: text,
|
|
1959
|
-
placeholder:
|
|
1981
|
+
placeholder: app.t('empty'),
|
|
1960
1982
|
rows: 3,
|
|
1961
1983
|
onChange: event => { setText(event.target.value); app.setInputText(branch.id, event.target.value) },
|
|
1962
1984
|
onKeyDown: event => {
|
|
@@ -1968,14 +1990,14 @@ window.__ModuleLoader__.load({
|
|
|
1968
1990
|
}),
|
|
1969
1991
|
branch.error ? h('div', { className: 'ifu-error', role: 'alert' }, branch.error) : null,
|
|
1970
1992
|
h('div', { className: 'ifu-compose-foot' },
|
|
1971
|
-
h('span', { className: 'ifu-hint' },
|
|
1993
|
+
h('span', { className: 'ifu-hint' }, app.t('sendHint')),
|
|
1972
1994
|
h('div', { className: 'ifu-grow' }),
|
|
1973
1995
|
h('button', {
|
|
1974
1996
|
type: 'button',
|
|
1975
1997
|
className: 'ifu-send',
|
|
1976
1998
|
disabled: sending,
|
|
1977
1999
|
onClick: submit,
|
|
1978
|
-
}, sending ?
|
|
2000
|
+
}, sending ? app.t('sendingAction') : app.t('send')),
|
|
1979
2001
|
),
|
|
1980
2002
|
),
|
|
1981
2003
|
...['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'].map(direction => h('div', {
|
|
@@ -1991,7 +2013,7 @@ window.__ModuleLoader__.load({
|
|
|
1991
2013
|
useVersion()
|
|
1992
2014
|
if (!branch.prompted) return h(InputWindow, { key: `${branch.id}-input`, branch })
|
|
1993
2015
|
const parent = branch.parentBranchId ? app.state.branches[branch.parentBranchId] : null
|
|
1994
|
-
const basis = parent ? `${
|
|
2016
|
+
const basis = parent ? `${app.t('basedOn')} #${parent.number}` : `${app.t('basedOn')} ${app.t('main')}`
|
|
1995
2017
|
const reference = app.refs.get(branch.id)
|
|
1996
2018
|
const showThread = branch.prompted && reference && !branch.loading
|
|
1997
2019
|
const showDraft = !branch.prompted
|
|
@@ -2012,20 +2034,20 @@ window.__ModuleLoader__.load({
|
|
|
2012
2034
|
...colorVars(branch.color),
|
|
2013
2035
|
},
|
|
2014
2036
|
role: 'dialog',
|
|
2015
|
-
'aria-label': `${
|
|
2037
|
+
'aria-label': `${app.t('branchN')} #${branch.number}`,
|
|
2016
2038
|
},
|
|
2017
2039
|
h('header', { className: 'ifu-head', onPointerDown: event => app.startPanelDrag(branch.id, event) },
|
|
2018
2040
|
h('span', { className: 'ifu-dot' }),
|
|
2019
2041
|
h('div', { className: 'ifu-title-wrap' },
|
|
2020
|
-
h('div', { className: 'ifu-title' }, `${
|
|
2042
|
+
h('div', { className: 'ifu-title' }, `${app.t('branchN')} #${branch.number}`),
|
|
2021
2043
|
h('div', { className: 'ifu-sub' }, `${basis} · ${statusLabel(branch)}`),
|
|
2022
2044
|
),
|
|
2023
2045
|
h('div', { className: 'ifu-grow' }),
|
|
2024
|
-
h(IconButton, { title:
|
|
2025
|
-
h(IconButton, { title:
|
|
2046
|
+
h(IconButton, { title: app.t('expand'), onClick: () => app.promote(branch.id), disabled: !branch.prompted || !branch.sessionId }, '↗'),
|
|
2047
|
+
h(IconButton, { title: app.t('collapse'), onClick: () => app.collapse(branch.id) }, '—'),
|
|
2026
2048
|
branch.sessionId || branch.prompted
|
|
2027
|
-
? h(IconButton, { title:
|
|
2028
|
-
: h(IconButton, { title:
|
|
2049
|
+
? h(IconButton, { title: app.t('close'), onClick: () => app.collapse(branch.id) }, '✕')
|
|
2050
|
+
: h(IconButton, { title: app.t('deleteDraft'), className: 'ifu-danger', onClick: () => app.deleteDraft(branch.id) }, '⌫'),
|
|
2029
2051
|
),
|
|
2030
2052
|
h('div', { className: 'ifu-panel-body' },
|
|
2031
2053
|
showThread
|
|
@@ -2033,12 +2055,12 @@ window.__ModuleLoader__.load({
|
|
|
2033
2055
|
: showDraft
|
|
2034
2056
|
? h('div', { className: 'ifu-compose-center' },
|
|
2035
2057
|
h('div', { className: 'ifu-draft-quote' },
|
|
2036
|
-
h('div', { className: 'ifu-quote-label' }, `${
|
|
2058
|
+
h('div', { className: 'ifu-quote-label' }, `${app.t('quote')} · ${basis}`),
|
|
2037
2059
|
h('div', { className: 'ifu-quote-text' }, branch.anchor.quote),
|
|
2038
|
-
h('div', { className: 'ifu-draft-wait' }, '
|
|
2060
|
+
h('div', { className: 'ifu-draft-wait' }, app.t('draftWait')),
|
|
2039
2061
|
),
|
|
2040
2062
|
)
|
|
2041
|
-
: h('div', { className: 'ifu-loading' }, branch.error ||
|
|
2063
|
+
: h('div', { className: 'ifu-loading' }, branch.error || app.t('sending')),
|
|
2042
2064
|
),
|
|
2043
2065
|
...['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'].map(direction => h('div', {
|
|
2044
2066
|
key: direction,
|
|
@@ -2053,11 +2075,11 @@ window.__ModuleLoader__.load({
|
|
|
2053
2075
|
function StageQuote(props) {
|
|
2054
2076
|
const { branch } = props
|
|
2055
2077
|
const parent = branch.parentBranchId ? app.state.branches[branch.parentBranchId] : null
|
|
2056
|
-
const basis = parent ? `#${parent.number}` :
|
|
2078
|
+
const basis = parent ? `#${parent.number}` : app.t('main')
|
|
2057
2079
|
return h('div', { className: 'ifu-stage-quote', title: branch.anchor.quote },
|
|
2058
2080
|
h('div', { className: 'ifu-stage-quote-label' },
|
|
2059
2081
|
h('span', { className: 'ifu-dot' }),
|
|
2060
|
-
`${
|
|
2082
|
+
`${app.t('quote')} · ${app.t('basedOn')} ${basis}`,
|
|
2061
2083
|
),
|
|
2062
2084
|
h('div', { className: 'ifu-stage-quote-text' }, branch.anchor.quote),
|
|
2063
2085
|
)
|
|
@@ -2079,7 +2101,7 @@ window.__ModuleLoader__.load({
|
|
|
2079
2101
|
observer.observe(host, { childList: true, subtree: true, characterData: true })
|
|
2080
2102
|
return () => observer.disconnect()
|
|
2081
2103
|
}, [branch.id])
|
|
2082
|
-
if (!reference) return h('div', { className: 'ifu-loading' }, branch.error ||
|
|
2104
|
+
if (!reference) return h('div', { className: 'ifu-loading' }, branch.error || app.t('sending'))
|
|
2083
2105
|
return h(SessionProvider, { session: reference },
|
|
2084
2106
|
h('div', {
|
|
2085
2107
|
ref: hostRef,
|
|
@@ -2106,24 +2128,24 @@ window.__ModuleLoader__.load({
|
|
|
2106
2128
|
? rows.filter(row => pathIds.has(row.branch.id))
|
|
2107
2129
|
: rows
|
|
2108
2130
|
const contextText = path.length > 0
|
|
2109
|
-
? `${
|
|
2110
|
-
:
|
|
2131
|
+
? `${app.t('main')}${path.map(branch => ` → #${branch.number}`).join('')}`
|
|
2132
|
+
: app.t('main')
|
|
2111
2133
|
return h('aside', { className: 'ifu-tree', 'data-ifu-no-select': '' },
|
|
2112
2134
|
h('div', { className: 'ifu-tree-head' },
|
|
2113
|
-
h('span', null,
|
|
2135
|
+
h('span', null, app.t('tree')),
|
|
2114
2136
|
h('div', { className: 'ifu-tree-tabs' },
|
|
2115
2137
|
h('button', {
|
|
2116
2138
|
type: 'button',
|
|
2117
2139
|
className: `ifu-tree-tab ${scope === 'path' ? 'is-active' : ''}`,
|
|
2118
2140
|
onClick: () => setScope('path'),
|
|
2119
|
-
}, '
|
|
2141
|
+
}, app.t('path')),
|
|
2120
2142
|
h('button', {
|
|
2121
2143
|
type: 'button',
|
|
2122
2144
|
className: `ifu-tree-tab ${scope === 'all' ? 'is-active' : ''}`,
|
|
2123
2145
|
onClick: () => setScope('all'),
|
|
2124
|
-
}, '
|
|
2146
|
+
}, app.t('all')),
|
|
2125
2147
|
),
|
|
2126
|
-
h('button', { type: 'button', className: 'ifu-icon', title:
|
|
2148
|
+
h('button', { type: 'button', className: 'ifu-icon', title: app.t('close'), onClick: () => app.toggleTree() }, '✕'),
|
|
2127
2149
|
),
|
|
2128
2150
|
h('div', { className: 'ifu-tree-list' },
|
|
2129
2151
|
h('div', {
|
|
@@ -2138,15 +2160,15 @@ window.__ModuleLoader__.load({
|
|
|
2138
2160
|
},
|
|
2139
2161
|
},
|
|
2140
2162
|
h('span', { className: 'ifu-dot' }),
|
|
2141
|
-
h('span', { className: 'ifu-tree-root-name' },
|
|
2163
|
+
h('span', { className: 'ifu-tree-root-name' }, app.t('main')),
|
|
2142
2164
|
h('span', { className: 'ifu-tree-root-tag' }, 'ROOT'),
|
|
2143
|
-
h('span', { className: 'ifu-tree-root-meta' }, '
|
|
2165
|
+
h('span', { className: 'ifu-tree-root-meta' }, app.t('contextStart')),
|
|
2144
2166
|
),
|
|
2145
2167
|
visibleRows.map(({ branch, depth }) => {
|
|
2146
2168
|
const isDraft = !branch.sessionId && !branch.prompted
|
|
2147
2169
|
const parent = branch.parentBranchId ? state.branches[branch.parentBranchId] : null
|
|
2148
|
-
const parentLabel = parent ? `${
|
|
2149
|
-
const title = branch.question || branch.anchor.quote || '
|
|
2170
|
+
const parentLabel = parent ? `${app.t('main')} · #${parent.number}` : app.t('main')
|
|
2171
|
+
const title = branch.question || branch.anchor.quote || app.t('waiting')
|
|
2150
2172
|
const inPath = pathIds.has(branch.id)
|
|
2151
2173
|
return h('div', {
|
|
2152
2174
|
key: branch.id,
|
|
@@ -2172,34 +2194,34 @@ window.__ModuleLoader__.load({
|
|
|
2172
2194
|
} else if (branch.prompted && branch.sessionId) app.promote(branch.id)
|
|
2173
2195
|
else app.openPanel(branch.id)
|
|
2174
2196
|
},
|
|
2175
|
-
title: `${
|
|
2197
|
+
title: `${app.t('switchBranch')} #${branch.number}`,
|
|
2176
2198
|
},
|
|
2177
2199
|
h('div', { className: 'ifu-tree-top' },
|
|
2178
2200
|
h('span', { className: 'ifu-dot' }),
|
|
2179
2201
|
h('span', { className: 'ifu-tree-num' }, `#${branch.number}`),
|
|
2180
2202
|
h('span', { className: 'ifu-tree-title' }, snippet(title, 36)),
|
|
2181
2203
|
branch.id === activeId
|
|
2182
|
-
? h('span', { className: 'ifu-tree-tag' },
|
|
2204
|
+
? h('span', { className: 'ifu-tree-tag' }, app.t('current'))
|
|
2183
2205
|
: inPath
|
|
2184
|
-
? h('span', { className: 'ifu-tree-tag is-context' }, '
|
|
2206
|
+
? h('span', { className: 'ifu-tree-tag is-context' }, app.t('context'))
|
|
2185
2207
|
: null,
|
|
2186
2208
|
isDraft ? h('button', {
|
|
2187
2209
|
type: 'button',
|
|
2188
2210
|
className: 'ifu-tree-delete',
|
|
2189
|
-
title:
|
|
2211
|
+
title: app.t('deleteDraft'),
|
|
2190
2212
|
onClick: (event) => { event.stopPropagation(); app.deleteDraft(branch.id) },
|
|
2191
2213
|
}, '⌫') : null,
|
|
2192
2214
|
),
|
|
2193
2215
|
h('div', { className: 'ifu-tree-quote' }, snippet(branch.anchor.quote, 72)),
|
|
2194
2216
|
h('div', { className: 'ifu-tree-meta' },
|
|
2195
|
-
h('span', null, `${
|
|
2217
|
+
h('span', null, `${app.t('basedOn')} ${parentLabel}`),
|
|
2196
2218
|
h('span', null, statusLabel(branch)),
|
|
2197
2219
|
),
|
|
2198
2220
|
)
|
|
2199
2221
|
}),
|
|
2200
2222
|
),
|
|
2201
2223
|
h('div', { className: 'ifu-tree-note' },
|
|
2202
|
-
|
|
2224
|
+
app.t('treeNote', { context: contextText }),
|
|
2203
2225
|
),
|
|
2204
2226
|
)
|
|
2205
2227
|
}
|
|
@@ -2223,23 +2245,23 @@ window.__ModuleLoader__.load({
|
|
|
2223
2245
|
type: 'button',
|
|
2224
2246
|
className: 'ifu-stage-back',
|
|
2225
2247
|
onClick: () => index <= 0 ? app.stageClose() : app.stageGo(-1),
|
|
2226
|
-
title: index <= 0 ?
|
|
2227
|
-
}, `← ${
|
|
2248
|
+
title: index <= 0 ? app.t('main') : app.t('back'),
|
|
2249
|
+
}, `← ${app.t('back')}`),
|
|
2228
2250
|
h('span', { className: 'ifu-stage-count' }, `${index + 1}/${total}`),
|
|
2229
2251
|
h('button', {
|
|
2230
2252
|
type: 'button',
|
|
2231
2253
|
className: 'ifu-stage-back',
|
|
2232
2254
|
disabled: index >= total - 1,
|
|
2233
2255
|
onClick: () => app.stageGo(1),
|
|
2234
|
-
},
|
|
2256
|
+
}, app.t('forward'), ' →'),
|
|
2235
2257
|
h('span', { className: 'ifu-stage-divider' }),
|
|
2236
2258
|
h('div', { className: 'ifu-crumbs' },
|
|
2237
2259
|
h('button', {
|
|
2238
2260
|
type: 'button',
|
|
2239
2261
|
className: 'ifu-crumb-btn',
|
|
2240
2262
|
onClick: () => app.stageClose(),
|
|
2241
|
-
title:
|
|
2242
|
-
},
|
|
2263
|
+
title: app.t('main'),
|
|
2264
|
+
}, app.t('main')),
|
|
2243
2265
|
...path.flatMap(item => [
|
|
2244
2266
|
h('span', { key: `sep-${item.id}`, className: 'ifu-crumb-sep' }, '›'),
|
|
2245
2267
|
h('button', {
|
|
@@ -2250,23 +2272,23 @@ window.__ModuleLoader__.load({
|
|
|
2250
2272
|
if (item.id === branch.id) return
|
|
2251
2273
|
app.promote(item.id)
|
|
2252
2274
|
},
|
|
2253
|
-
title: `${
|
|
2275
|
+
title: `${app.t('switchBranch')} #${item.number}`,
|
|
2254
2276
|
}, `#${item.number}`),
|
|
2255
2277
|
]),
|
|
2256
2278
|
),
|
|
2257
|
-
h('span', { className: 'ifu-context-chip' },
|
|
2279
|
+
h('span', { className: 'ifu-context-chip' }, `${app.t('context')} · ${path.length} ${app.t('stages')}`),
|
|
2258
2280
|
h('div', { className: 'ifu-grow' }),
|
|
2259
2281
|
h('span', { className: 'ifu-stage-status' }, statusLabel(branch)),
|
|
2260
|
-
h('button', { type: 'button', className: 'ifu-stage-action', onClick: () => app.toggleTree() }, '▤ ',
|
|
2261
|
-
h('button', { type: 'button', className: 'ifu-stage-action', onClick: () => app.stageRestore() }, '↘ ',
|
|
2262
|
-
h('button', { type: 'button', className: 'ifu-stage-action', onClick: () => app.stageClose() }, '✕ ',
|
|
2282
|
+
h('button', { type: 'button', className: 'ifu-stage-action', onClick: () => app.toggleTree() }, '▤ ', app.t('tree')),
|
|
2283
|
+
h('button', { type: 'button', className: 'ifu-stage-action', onClick: () => app.stageRestore() }, '↘ ', app.t('restore')),
|
|
2284
|
+
h('button', { type: 'button', className: 'ifu-stage-action', onClick: () => app.stageClose() }, '✕ ', app.t('close')),
|
|
2263
2285
|
),
|
|
2264
|
-
h('div', { className: 'ifu-stage-tip' },
|
|
2286
|
+
h('div', { className: 'ifu-stage-tip' }, app.t('stageHint')),
|
|
2265
2287
|
h('div', { className: 'ifu-stage-body' },
|
|
2266
2288
|
h(StageQuote, { branch }),
|
|
2267
2289
|
reference && !branch.loading
|
|
2268
2290
|
? h(StageThread, { key: branch.id, branch, SessionProvider, renderSlot })
|
|
2269
|
-
: h('div', { className: 'ifu-loading' }, branch.error ||
|
|
2291
|
+
: h('div', { className: 'ifu-loading' }, branch.error || app.t('sending')),
|
|
2270
2292
|
),
|
|
2271
2293
|
h(BranchTree),
|
|
2272
2294
|
)
|
|
@@ -2403,7 +2425,7 @@ window.__ModuleLoader__.load({
|
|
|
2403
2425
|
className: 'ifu-dock-collapsed',
|
|
2404
2426
|
'data-ifu-dock': '',
|
|
2405
2427
|
onClick: () => app.toggleDock(),
|
|
2406
|
-
}, `◉ ${
|
|
2428
|
+
}, `◉ ${app.t('dock')} · ${branches.length}`)
|
|
2407
2429
|
}
|
|
2408
2430
|
const dockStyle = state.dock
|
|
2409
2431
|
? {
|
|
@@ -2417,11 +2439,11 @@ window.__ModuleLoader__.load({
|
|
|
2417
2439
|
: {}
|
|
2418
2440
|
return h('aside', { className: 'ifu-dock', 'data-ifu-dock': '', style: dockStyle },
|
|
2419
2441
|
h('div', { className: 'ifu-dock-head', onPointerDown: event => app.startDockDrag(event) },
|
|
2420
|
-
h('span', null, `${
|
|
2442
|
+
h('span', null, `${app.t('dock')} · ${branches.length}`),
|
|
2421
2443
|
h('button', {
|
|
2422
2444
|
type: 'button',
|
|
2423
2445
|
className: 'ifu-dock-toggle',
|
|
2424
|
-
title:
|
|
2446
|
+
title: app.t('collapseDock'),
|
|
2425
2447
|
onClick: () => app.closeDock(),
|
|
2426
2448
|
}, '—'),
|
|
2427
2449
|
),
|
|
@@ -2440,7 +2462,7 @@ window.__ModuleLoader__.load({
|
|
|
2440
2462
|
event.preventDefault()
|
|
2441
2463
|
app.revealBranch(branch.id)
|
|
2442
2464
|
},
|
|
2443
|
-
title: `${
|
|
2465
|
+
title: `${app.t('switchBranch')}: #${branch.number}`,
|
|
2444
2466
|
},
|
|
2445
2467
|
h('span', { className: 'ifu-dot', style: colorVars(branch.color) }),
|
|
2446
2468
|
h('span', { className: 'ifu-dock-num' }, `#${branch.number}`),
|
|
@@ -2449,7 +2471,7 @@ window.__ModuleLoader__.load({
|
|
|
2449
2471
|
isDraft ? h('button', {
|
|
2450
2472
|
type: 'button',
|
|
2451
2473
|
className: 'ifu-dock-delete',
|
|
2452
|
-
title:
|
|
2474
|
+
title: app.t('deleteDraft'),
|
|
2453
2475
|
onClick: (event) => { event.stopPropagation(); app.deleteDraft(branch.id) },
|
|
2454
2476
|
}, '⌫') : null,
|
|
2455
2477
|
)
|
|
@@ -2471,14 +2493,14 @@ window.__ModuleLoader__.load({
|
|
|
2471
2493
|
className: 'ifu-chip',
|
|
2472
2494
|
'data-ifu-chip': '',
|
|
2473
2495
|
style: { left: `${chip.x}px`, top: `${chip.y}px` },
|
|
2474
|
-
title:
|
|
2496
|
+
title: app.t('chipHint'),
|
|
2475
2497
|
onMouseDown: event => event.preventDefault(),
|
|
2476
2498
|
onClick: () => {
|
|
2477
2499
|
const x = clamp(chip.x - 120, 12, window.innerWidth - PANEL_WIDTH - 12)
|
|
2478
2500
|
const y = clamp(chip.y + 38, 12, window.innerHeight - 320)
|
|
2479
2501
|
app.openDraft(chip.anchor, x, y)
|
|
2480
2502
|
},
|
|
2481
|
-
}, '✦ ',
|
|
2503
|
+
}, '✦ ', app.t('chip'))
|
|
2482
2504
|
}
|
|
2483
2505
|
|
|
2484
2506
|
function Notice() {
|
|
@@ -2707,6 +2729,7 @@ window.__ModuleLoader__.load({
|
|
|
2707
2729
|
app = createApp(ctx)
|
|
2708
2730
|
app.load()
|
|
2709
2731
|
ctx.effect(() => ctx.locale.register(NS, { zh: DICT.zh, en: DICT.en }), 'inline-followup: locale')
|
|
2732
|
+
ctx.effect(() => ctx.on('locale/change', () => app.emit()), 'inline-followup: locale-change')
|
|
2710
2733
|
ctx.effect(() => app.install(), 'inline-followup: lifetime')
|
|
2711
2734
|
ctx.slots.inject('shell.overlay', () => ctx.slots.register({
|
|
2712
2735
|
name: 'shell.overlay',
|
package/package.json
CHANGED