@objectivex666/dsh-settings-search 1.9.0 → 1.10.0
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.en.md +3 -1
- package/README.md +3 -1
- package/lib/client.js +94 -54
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
[](./LICENSE)
|
|
7
7
|
[](https://nodejs.org)
|
|
8
8
|
[](https://awesome-dsh-plugin.com)
|
|
9
|
+
[](https://dsh-plugin.org/plugins/objectivex666/dsh-settings-search)
|
|
9
10
|
|
|
10
11
|
**English** · [中文](./README.md)
|
|
11
12
|
|
|
@@ -14,7 +15,8 @@
|
|
|
14
15
|
## Features
|
|
15
16
|
|
|
16
17
|
- 🔍 **Live search** — a search box in the settings panel filters every registered settings page (`settings.section`) and general item (`settings.general.item`) as you type.
|
|
17
|
-
- 🧩 **
|
|
18
|
+
- 🧩 **Three search styles** — choose the classic sidebar, window top bar, or popup search page. The choice is saved in the current browser.
|
|
19
|
+
- ⌨️ **Search shortcut (v1.10.0)** — focus the search box with `Ctrl+F` or `⌘F` inside the settings panel. You can enable or disable it from the "Settings Search" page; disabling keeps the browser's default find behavior.
|
|
18
20
|
- 🤝 **Import DSH model config (v1.9.0)** — import the Base URL and model name from DSH's current default model in the AI config section. For credential safety, the API key is never imported.
|
|
19
21
|
- 🎯 **First-run onboarding (v1.9.0)** — a welcome modal appears only the first time the settings panel opens after installation. It introduces the four search styles, pinyin/intent/AI hints, click-to-jump, and auto-indexing; there are no "Don't show again" or manual reopen buttons.
|
|
20
22
|
- 📂 **In-page option search (v1.2.0)** — search beyond pages and reach the specific options inside them: Plugins-page tabs (`settings.plugins.tab`), Web UI plugin cards (`web-ui.plugin.item`), general rows, and more, each shown with a "page › option" breadcrumb.
|
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
[](./LICENSE)
|
|
7
7
|
[](https://nodejs.org)
|
|
8
8
|
[](https://awesome-dsh-plugin.com)
|
|
9
|
+
[](https://dsh-plugin.org/plugins/objectivex666/dsh-settings-search)
|
|
9
10
|
|
|
10
11
|
**中文** · [English](./README.en.md)
|
|
11
12
|
|
|
@@ -14,7 +15,8 @@
|
|
|
14
15
|
## 功能特性
|
|
15
16
|
|
|
16
17
|
- 🔍 **实时搜索**:在设置面板中嵌入搜索框,输入关键词立即过滤所有已注册的设置页(`settings.section`)与通用设置项(`settings.general.item`)。
|
|
17
|
-
- 🧩
|
|
18
|
+
- 🧩 **三种搜索样式**:可选择经典侧栏、窗口顶栏或弹出搜索页;选择会保存在当前浏览器。
|
|
19
|
+
- ⌨️ **搜索快捷键(v1.10.0)**:在设置面板内按 `Ctrl+F` 或 `⌘F` 聚焦搜索框;可在「设置搜索」页启用或关闭,关闭后保留浏览器默认查找。
|
|
18
20
|
- 🤝 **导入 DSH 模型配置(v1.9.0)**:在 AI 配置区一键读取 DSH 当前默认模型的 Base URL 与模型名;为避免凭据扩散,导入始终不包含 API Key。
|
|
19
21
|
- 🎯 **新用户引导(v1.9.0)**:仅在安装后首次打开设置面板时弹出引导弹窗,介绍四种搜索样式、拼音/意图/AI 联想、点击即达与自动导入索引等核心功能;不再提供“不再显示”和手动重开按钮。
|
|
20
22
|
- 📂 **页内选项搜索(v1.2.0)**:不只搜页面,还能直达每个设置页内部的具体选项——插件页的标签页(`settings.plugins.tab`)、Web UI 插件的卡片(`web-ui.plugin.item`)、通用设置行等,结果以「页面 › 选项」面包屑展示。
|
package/lib/client.js
CHANGED
|
@@ -30,7 +30,7 @@ window.__ModuleLoader__.load({
|
|
|
30
30
|
|
|
31
31
|
const NS = 'settings-search-v5'
|
|
32
32
|
/** Single source of truth is package.json — scripts/check.mjs asserts this matches. */
|
|
33
|
-
const PKG_VERSION = '1.
|
|
33
|
+
const PKG_VERSION = '1.10.0'
|
|
34
34
|
const NPM_NAME = '@objectivex666/dsh-settings-search'
|
|
35
35
|
const zh = {
|
|
36
36
|
title: '设置',
|
|
@@ -41,8 +41,9 @@ window.__ModuleLoader__.load({
|
|
|
41
41
|
styleClassic: '经典侧栏',
|
|
42
42
|
styleTop: '窗口顶栏',
|
|
43
43
|
stylePage: '弹出搜索页',
|
|
44
|
-
styleMixed: '顶栏 + 搜索页',
|
|
45
44
|
openSearch: '打开搜索',
|
|
45
|
+
shortcutTitle: 'Ctrl+F / ⌘F 快捷键',
|
|
46
|
+
shortcutHint: '在设置面板内按 Ctrl+F 或 ⌘F 聚焦搜索框;关闭后保留浏览器默认查找。',
|
|
46
47
|
warming: '正在导入各分区选项…',
|
|
47
48
|
empty: '没有匹配的设置',
|
|
48
49
|
pages: '设置页',
|
|
@@ -128,7 +129,7 @@ window.__ModuleLoader__.load({
|
|
|
128
129
|
wlTitle: '欢迎使用设置搜索',
|
|
129
130
|
wlSubtitle: '为 DSH 设置面板提供即时搜索与导航,几秒钟就能找到任何设置。',
|
|
130
131
|
wlFeature1Title: '实时搜索',
|
|
131
|
-
wlFeature1Desc: '
|
|
132
|
+
wlFeature1Desc: '支持经典侧栏、窗口顶栏与弹出搜索页;输入关键词即可过滤设置。',
|
|
132
133
|
wlFeature2Title: '拼音与意图联想',
|
|
133
134
|
wlFeature2Desc: '输入拼音首字母(如 sz)或直接描述需求(如「太亮」),也能联想设置项。',
|
|
134
135
|
wlFeature3Title: 'AI 联想(可选)',
|
|
@@ -151,8 +152,9 @@ window.__ModuleLoader__.load({
|
|
|
151
152
|
styleClassic: 'Classic sidebar',
|
|
152
153
|
styleTop: 'Top bar',
|
|
153
154
|
stylePage: 'Popup page',
|
|
154
|
-
styleMixed: 'Top bar + popup',
|
|
155
155
|
openSearch: 'Open search',
|
|
156
|
+
shortcutTitle: 'Ctrl+F / ⌘F shortcut',
|
|
157
|
+
shortcutHint: 'Focus the search box with Ctrl+F or ⌘F inside the settings panel; turn it off to keep the browser default.',
|
|
156
158
|
warming: 'Importing section options…',
|
|
157
159
|
empty: 'No matching settings',
|
|
158
160
|
pages: 'Settings pages',
|
|
@@ -238,7 +240,7 @@ window.__ModuleLoader__.load({
|
|
|
238
240
|
wlTitle: 'Welcome to Settings Search',
|
|
239
241
|
wlSubtitle: 'Instant search and navigation for the DSH settings panel — find any setting in seconds.',
|
|
240
242
|
wlFeature1Title: 'Instant search',
|
|
241
|
-
wlFeature1Desc: 'Choose classic sidebar, top bar,
|
|
243
|
+
wlFeature1Desc: 'Choose classic sidebar, top bar, or popup search page; typing filters settings.',
|
|
242
244
|
wlFeature2Title: 'Pinyin & intent hints',
|
|
243
245
|
wlFeature2Desc: 'Type pinyin initials (e.g. sz) or describe what you want to do to find settings.',
|
|
244
246
|
wlFeature3Title: 'AI hints (optional)',
|
|
@@ -514,7 +516,9 @@ window.__ModuleLoader__.load({
|
|
|
514
516
|
const WELCOME_EVENT = 'dsh-settings-search:welcome'
|
|
515
517
|
const SEARCH_STYLE_KEY = 'dsh-settings-search:style'
|
|
516
518
|
const SEARCH_STYLE_EVENT = 'dsh-settings-search:style-change'
|
|
517
|
-
const
|
|
519
|
+
const SEARCH_SHORTCUT_KEY = 'dsh-settings-search:shortcut-enabled'
|
|
520
|
+
const SEARCH_SHORTCUT_EVENT = 'dsh-settings-search:shortcut-change'
|
|
521
|
+
const SEARCH_STYLES = ['sidebar', 'top', 'page']
|
|
518
522
|
const readSearchStyle = () => {
|
|
519
523
|
if (typeof localStorage === 'undefined') return 'sidebar'
|
|
520
524
|
const style = localStorage.getItem(SEARCH_STYLE_KEY)
|
|
@@ -525,6 +529,15 @@ window.__ModuleLoader__.load({
|
|
|
525
529
|
localStorage.setItem(SEARCH_STYLE_KEY, style)
|
|
526
530
|
window.dispatchEvent(new CustomEvent(SEARCH_STYLE_EVENT, { detail: style }))
|
|
527
531
|
}
|
|
532
|
+
const searchShortcutEnabled = () => {
|
|
533
|
+
if (typeof localStorage === 'undefined') return true
|
|
534
|
+
return localStorage.getItem(SEARCH_SHORTCUT_KEY) !== '0'
|
|
535
|
+
}
|
|
536
|
+
const setSearchShortcutEnabled = (enabled) => {
|
|
537
|
+
if (typeof localStorage === 'undefined') return
|
|
538
|
+
localStorage.setItem(SEARCH_SHORTCUT_KEY, enabled ? '1' : '0')
|
|
539
|
+
window.dispatchEvent(new CustomEvent(SEARCH_SHORTCUT_EVENT, { detail: enabled }))
|
|
540
|
+
}
|
|
528
541
|
const welcomed = () => {
|
|
529
542
|
if (typeof localStorage === 'undefined') return true
|
|
530
543
|
return localStorage.getItem(ONBOARD_KEY) === '1'
|
|
@@ -630,6 +643,7 @@ window.__ModuleLoader__.load({
|
|
|
630
643
|
method: 'POST',
|
|
631
644
|
headers,
|
|
632
645
|
signal,
|
|
646
|
+
redirect: 'error',
|
|
633
647
|
body: JSON.stringify(body),
|
|
634
648
|
})
|
|
635
649
|
if (!response.ok) throw new Error(`HTTP ${response.status}`)
|
|
@@ -716,6 +730,7 @@ window.__ModuleLoader__.load({
|
|
|
716
730
|
const response = await fetch(requestUrl, {
|
|
717
731
|
method: 'POST',
|
|
718
732
|
headers,
|
|
733
|
+
redirect: 'error',
|
|
719
734
|
body: JSON.stringify(body),
|
|
720
735
|
})
|
|
721
736
|
if (!response.ok) return { ok: false, code: testHttpCode(response.status), detail: `HTTP ${response.status}` }
|
|
@@ -795,7 +810,6 @@ window.__ModuleLoader__.load({
|
|
|
795
810
|
.sss-page-results { flex: 1; min-height: 0; overflow: auto; padding: 8px; }
|
|
796
811
|
.sss-page-results .sss-group { padding: 2px; }
|
|
797
812
|
.sss-page-results .sss-item { padding: 10px 8px; border-radius: 8px; }
|
|
798
|
-
.sss-mixed-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsw-alias-label-primary); font-size: 16px; line-height: 24px; }
|
|
799
813
|
@keyframes sssFlashBg { 0% { background-color: var(--dsw-alias-interactive-bg-hover); } 100% { background-color: transparent; } }
|
|
800
814
|
.sss-flash { animation: sssFlashBg 1.8s ease-out; border-radius: 8px; }
|
|
801
815
|
.sss-vr { list-style: none; border: 1px solid var(--dsw-alias-border-l2); background: var(--dsw-alias-bg-layer-3); border-radius: 12px; max-width: 780px; width: 100%; box-sizing: border-box; transition: border-color .16s, background .16s; }
|
|
@@ -1225,9 +1239,16 @@ window.__ModuleLoader__.load({
|
|
|
1225
1239
|
|
|
1226
1240
|
/* ---------- DOM-level navigation into the settings shell ---------- */
|
|
1227
1241
|
|
|
1228
|
-
/**
|
|
1242
|
+
/**
|
|
1243
|
+
* Root element that hosts the settings panel's nav buttons. Derived from
|
|
1244
|
+
* the plugin's own mounted UI so an unrelated or plugin-owned dialog can
|
|
1245
|
+
* never become the click root; the first-dialog fallback only applies
|
|
1246
|
+
* when the plugin's anchors are not mounted.
|
|
1247
|
+
*/
|
|
1229
1248
|
const panelRoot = () => {
|
|
1230
1249
|
if (typeof document === 'undefined') return null
|
|
1250
|
+
const anchor = document.querySelector('.sss-wrap, .sss-vr')
|
|
1251
|
+
if (anchor) return anchor.closest('[role="dialog"]') ?? document.body
|
|
1231
1252
|
return document.querySelector('[role="dialog"]') ?? document.body
|
|
1232
1253
|
}
|
|
1233
1254
|
const panelButtons = () => {
|
|
@@ -1237,7 +1258,7 @@ window.__ModuleLoader__.load({
|
|
|
1237
1258
|
const clickNavButton = (wantText) => {
|
|
1238
1259
|
const want = String(wantText ?? '').trim()
|
|
1239
1260
|
if (want === '') return false
|
|
1240
|
-
const buttons = panelButtons()
|
|
1261
|
+
const buttons = panelButtons().filter((b) => /_navCell/.test(String(b.className || '')))
|
|
1241
1262
|
const textOf = (b) => (b.textContent ?? '').trim()
|
|
1242
1263
|
const hit = buttons.find((b) => textOf(b) === want)
|
|
1243
1264
|
if (!hit) return false
|
|
@@ -1477,6 +1498,7 @@ window.__ModuleLoader__.load({
|
|
|
1477
1498
|
const [open, setOpen] = React.useState(false)
|
|
1478
1499
|
const [searchStyle, setSearchStyleState] = React.useState(readSearchStyle)
|
|
1479
1500
|
const [pageOpen, setPageOpen] = React.useState(false)
|
|
1501
|
+
const [shortcutEnabled, setShortcutEnabled] = React.useState(searchShortcutEnabled)
|
|
1480
1502
|
const [showWelcome, setShowWelcome] = React.useState(() => !welcomed())
|
|
1481
1503
|
const [tick, setTick] = React.useState(0)
|
|
1482
1504
|
const [warming, setWarming] = React.useState(false)
|
|
@@ -1555,6 +1577,21 @@ window.__ModuleLoader__.load({
|
|
|
1555
1577
|
return () => window.removeEventListener(SEARCH_STYLE_EVENT, sync)
|
|
1556
1578
|
}, [])
|
|
1557
1579
|
|
|
1580
|
+
// A style switch must not carry an open popup from the previous layout
|
|
1581
|
+
// into the new one. The host can keep this component mounted while the
|
|
1582
|
+
// settings choice changes, so reset transient view state explicitly.
|
|
1583
|
+
React.useEffect(() => {
|
|
1584
|
+
setOpen(false)
|
|
1585
|
+
setPageOpen(false)
|
|
1586
|
+
setHint(null)
|
|
1587
|
+
}, [searchStyle])
|
|
1588
|
+
|
|
1589
|
+
React.useEffect(() => {
|
|
1590
|
+
const sync = () => setShortcutEnabled(searchShortcutEnabled())
|
|
1591
|
+
window.addEventListener(SEARCH_SHORTCUT_EVENT, sync)
|
|
1592
|
+
return () => window.removeEventListener(SEARCH_SHORTCUT_EVENT, sync)
|
|
1593
|
+
}, [])
|
|
1594
|
+
|
|
1558
1595
|
React.useEffect(() => {
|
|
1559
1596
|
const sync = () => setAiEnabled(aiSearchEnabled())
|
|
1560
1597
|
const onConfig = () => forceTick()
|
|
@@ -1670,8 +1707,7 @@ window.__ModuleLoader__.load({
|
|
|
1670
1707
|
const popRef = React.useRef(null)
|
|
1671
1708
|
const inputRef = React.useRef(null)
|
|
1672
1709
|
const pageMode = searchStyle === 'page'
|
|
1673
|
-
const
|
|
1674
|
-
const topMode = searchStyle === 'top' || mixedMode
|
|
1710
|
+
const topMode = searchStyle === 'top'
|
|
1675
1711
|
const activeIndex = Math.min(active, Math.max(results.length - 1, 0))
|
|
1676
1712
|
|
|
1677
1713
|
React.useEffect(() => { setActive(0) }, [query])
|
|
@@ -1680,6 +1716,23 @@ window.__ModuleLoader__.load({
|
|
|
1680
1716
|
const timer = setTimeout(() => inputRef.current?.focus(), 0)
|
|
1681
1717
|
return () => clearTimeout(timer)
|
|
1682
1718
|
}, [pageMode, pageOpen])
|
|
1719
|
+
React.useEffect(() => {
|
|
1720
|
+
if (!shortcutEnabled) return
|
|
1721
|
+
const onKeyDown = (event) => {
|
|
1722
|
+
if (!event.ctrlKey && !event.metaKey) return
|
|
1723
|
+
if (event.altKey || event.shiftKey || event.key !== 'f' && event.key !== 'F') return
|
|
1724
|
+
event.preventDefault()
|
|
1725
|
+
if (pageMode) {
|
|
1726
|
+
setPageOpen(true)
|
|
1727
|
+
return
|
|
1728
|
+
}
|
|
1729
|
+
setHint(null)
|
|
1730
|
+
setOpen(true)
|
|
1731
|
+
inputRef.current?.focus()
|
|
1732
|
+
}
|
|
1733
|
+
window.addEventListener('keydown', onKeyDown)
|
|
1734
|
+
return () => window.removeEventListener('keydown', onKeyDown)
|
|
1735
|
+
}, [pageMode, shortcutEnabled])
|
|
1683
1736
|
React.useEffect(() => {
|
|
1684
1737
|
const el = popRef.current?.querySelector('.sss-item.is-active')
|
|
1685
1738
|
el?.scrollIntoView?.({ block: 'nearest' })
|
|
@@ -1812,12 +1865,12 @@ window.__ModuleLoader__.load({
|
|
|
1812
1865
|
const item = results[activeIndex]
|
|
1813
1866
|
if (item) { e.preventDefault(); pick(item) }
|
|
1814
1867
|
} else if (e.key === 'Escape') {
|
|
1815
|
-
if (pageMode
|
|
1868
|
+
if (pageMode) setPageOpen(false)
|
|
1816
1869
|
else setOpen(false)
|
|
1817
1870
|
}
|
|
1818
1871
|
},
|
|
1819
|
-
onChange: (e) => { setQuery(e.target.value); setHint(null); setOpen(true)
|
|
1820
|
-
onFocus: () =>
|
|
1872
|
+
onChange: (e) => { setQuery(e.target.value); setHint(null); setOpen(true) },
|
|
1873
|
+
onFocus: () => setOpen(true),
|
|
1821
1874
|
onBlur: () => setOpen(false),
|
|
1822
1875
|
})
|
|
1823
1876
|
const clearButton = query !== '' ? React.createElement('button', {
|
|
@@ -1912,44 +1965,11 @@ window.__ModuleLoader__.load({
|
|
|
1912
1965
|
clearButton,
|
|
1913
1966
|
]),
|
|
1914
1967
|
warming ? React.createElement('p', { className: 'sss-warm-note' }, t('warming')) : null,
|
|
1915
|
-
|
|
1916
|
-
|
|
1968
|
+
open && q !== '' ? React.createElement('div', { className: 'sss-pop', ref: popRef }, [resultsNode]) : null,
|
|
1969
|
+
hint !== null
|
|
1917
1970
|
? React.createElement('div', { className: 'sss-guide' }, t('jumpFail').replace('{path}', hint))
|
|
1918
1971
|
: null,
|
|
1919
1972
|
]),
|
|
1920
|
-
mixedMode && pageOpen
|
|
1921
|
-
? React.createElement('div', {
|
|
1922
|
-
className: 'sss-page-overlay',
|
|
1923
|
-
onMouseDown: (event) => { if (event.target === event.currentTarget) setPageOpen(false) },
|
|
1924
|
-
}, [
|
|
1925
|
-
React.createElement('div', { className: 'sss-page' }, [
|
|
1926
|
-
React.createElement('div', { className: 'sss-page-head' }, [
|
|
1927
|
-
React.createElement('button', {
|
|
1928
|
-
className: 'sss-icon-btn',
|
|
1929
|
-
type: 'button',
|
|
1930
|
-
'aria-label': t('searchBtn'),
|
|
1931
|
-
title: t('searchBtn'),
|
|
1932
|
-
onClick: () => inputRef.current?.focus(),
|
|
1933
|
-
}, [SearchIcon]),
|
|
1934
|
-
React.createElement('span', { className: 'sss-page-input sss-mixed-title' }, t('pageSearchTitle')),
|
|
1935
|
-
clearButton,
|
|
1936
|
-
React.createElement('button', {
|
|
1937
|
-
className: 'sss-page-close',
|
|
1938
|
-
type: 'button',
|
|
1939
|
-
'aria-label': 'Close',
|
|
1940
|
-
onClick: () => setPageOpen(false),
|
|
1941
|
-
}, '✕'),
|
|
1942
|
-
]),
|
|
1943
|
-
React.createElement('div', { className: 'sss-page-results' }, [
|
|
1944
|
-
warming ? React.createElement('p', { className: 'sss-warm-note' }, t('warming')) : null,
|
|
1945
|
-
q !== '' ? resultsNode : null,
|
|
1946
|
-
hint !== null
|
|
1947
|
-
? React.createElement('div', { className: 'sss-guide' }, t('jumpFail').replace('{path}', hint))
|
|
1948
|
-
: null,
|
|
1949
|
-
]),
|
|
1950
|
-
]),
|
|
1951
|
-
])
|
|
1952
|
-
: null,
|
|
1953
1973
|
])
|
|
1954
1974
|
}
|
|
1955
1975
|
|
|
@@ -1998,6 +2018,7 @@ window.__ModuleLoader__.load({
|
|
|
1998
2018
|
function UpdatePanel() {
|
|
1999
2019
|
const [open, setOpen] = React.useState(true)
|
|
2000
2020
|
const [searchStyle, setSearchStyleState] = React.useState(readSearchStyle)
|
|
2021
|
+
const [shortcutOn, setShortcutOn] = React.useState(searchShortcutEnabled)
|
|
2001
2022
|
const [state, setState] = React.useState('idle') // idle | loading | newest | outdated | error
|
|
2002
2023
|
const [latest, setLatest] = React.useState('')
|
|
2003
2024
|
const [copied, setCopied] = React.useState(false)
|
|
@@ -2035,6 +2056,12 @@ window.__ModuleLoader__.load({
|
|
|
2035
2056
|
return () => window.removeEventListener(SEARCH_STYLE_EVENT, sync)
|
|
2036
2057
|
}, [])
|
|
2037
2058
|
|
|
2059
|
+
React.useEffect(() => {
|
|
2060
|
+
const sync = () => setShortcutOn(searchShortcutEnabled())
|
|
2061
|
+
window.addEventListener(SEARCH_SHORTCUT_EVENT, sync)
|
|
2062
|
+
return () => window.removeEventListener(SEARCH_SHORTCUT_EVENT, sync)
|
|
2063
|
+
}, [])
|
|
2064
|
+
|
|
2038
2065
|
useAutoReset(copied, () => { setCopied(false); setCopyFailed(false) })
|
|
2039
2066
|
useAutoReset(aiSaved, () => setAiSaved(false))
|
|
2040
2067
|
|
|
@@ -2086,6 +2113,12 @@ window.__ModuleLoader__.load({
|
|
|
2086
2113
|
setSearchStyleState(style)
|
|
2087
2114
|
}
|
|
2088
2115
|
|
|
2116
|
+
const updateShortcutEnabled = (enabled) => {
|
|
2117
|
+
setSearchShortcutEnabled(enabled)
|
|
2118
|
+
setShortcutOn(enabled)
|
|
2119
|
+
log('info', enabled ? '启用搜索快捷键' : '禁用搜索快捷键', {})
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2089
2122
|
const requestClearAi = () => setConfirmClearAi(true)
|
|
2090
2123
|
const cancelClearAi = () => setConfirmClearAi(false)
|
|
2091
2124
|
const clearAiConfig = () => {
|
|
@@ -2268,11 +2301,6 @@ window.__ModuleLoader__.load({
|
|
|
2268
2301
|
type: 'button',
|
|
2269
2302
|
onClick: () => updateSearchStyle('page'),
|
|
2270
2303
|
}, t('stylePage')),
|
|
2271
|
-
React.createElement('button', {
|
|
2272
|
-
className: 'sss-vr-seg' + (searchStyle === 'mixed' ? ' is-active' : ''),
|
|
2273
|
-
type: 'button',
|
|
2274
|
-
onClick: () => updateSearchStyle('mixed'),
|
|
2275
|
-
}, t('styleMixed')),
|
|
2276
2304
|
]),
|
|
2277
2305
|
]),
|
|
2278
2306
|
React.createElement('div', { className: 'sss-vr-field' }, [
|
|
@@ -2292,6 +2320,18 @@ window.__ModuleLoader__.load({
|
|
|
2292
2320
|
React.createElement('p', { className: 'sss-vr-hint' }, t('aiDesc')),
|
|
2293
2321
|
React.createElement('p', { className: 'sss-vr-hint' }, t('aiPrivacy')),
|
|
2294
2322
|
]),
|
|
2323
|
+
React.createElement('div', { className: 'sss-vr-field' }, [
|
|
2324
|
+
React.createElement('div', { className: 'sss-vr-field-head' }, [
|
|
2325
|
+
React.createElement('span', { className: 'sss-vr-label' }, t('shortcutTitle')),
|
|
2326
|
+
React.createElement('input', {
|
|
2327
|
+
className: 'sss-vr-check',
|
|
2328
|
+
type: 'checkbox',
|
|
2329
|
+
checked: shortcutOn,
|
|
2330
|
+
onChange: (event) => updateShortcutEnabled(event.target.checked),
|
|
2331
|
+
}),
|
|
2332
|
+
]),
|
|
2333
|
+
React.createElement('p', { className: 'sss-vr-hint' }, t('shortcutHint')),
|
|
2334
|
+
]),
|
|
2295
2335
|
React.createElement('div', { className: 'sss-vr-field sss-vr-form' }, [
|
|
2296
2336
|
React.createElement('div', { className: 'sss-vr-field-head' }, [
|
|
2297
2337
|
React.createElement('label', { className: 'sss-vr-label' }, t('aiProvider')),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@objectivex666/dsh-settings-search",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "DSH settings panel search plugin – instantly filter setting sections and general items with navigation guidance. Installable via `dsh plugin add`.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|