mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
refactor(desktop): drop System settings section; keep-awake → Advanced
Revert the dedicated System section: Window Translucency + UI Scale move back to Appearance, and Haptics returns to its titlebar-only home. Keep computer awake now lives as a device-local toggle at the top of Advanced (a ConfigSettings section-specific extra, like the Model block), keeping the statusbar quick-toggle. Relocated i18n back to settings.appearance / settings.config across all four locales.
This commit is contained in:
parent
9b513a3b8d
commit
ac9a1014a6
10 changed files with 112 additions and 178 deletions
|
|
@ -16,6 +16,8 @@ import { $backdrop, setBackdrop } from '@/store/backdrop'
|
|||
import { $embedAllowed, $embedMode, clearEmbedAllowed, type EmbedMode, setEmbedMode } from '@/store/embed-consent'
|
||||
import { $activeGatewayProfile, $profiles, normalizeProfileKey } from '@/store/profile'
|
||||
import { $toolViewMode, setToolViewMode } from '@/store/tool-view'
|
||||
import { $translucency, setTranslucency } from '@/store/translucency'
|
||||
import { $zoomPercent, setZoomPercent } from '@/store/zoom'
|
||||
import { getBaseColors, useTheme } from '@/themes/context'
|
||||
import { installVscodeThemeFromMarketplace } from '@/themes/install'
|
||||
import type { DesktopTheme } from '@/themes/types'
|
||||
|
|
@ -62,6 +64,18 @@ function ThemePreview({ name, mode }: { name: string; mode: 'light' | 'dark' })
|
|||
)
|
||||
}
|
||||
|
||||
// UI scale presets, as zoom percentages. 100 is the browser-default size;
|
||||
// the ids double as the percent values sent to the main process. A Cmd/Ctrl
|
||||
// +/- step landing between presets highlights nothing, and the row
|
||||
// description keeps showing the exact current percent.
|
||||
const UI_SCALE_PRESETS = ['90', '100', '110', '125', '150', '175'] as const
|
||||
|
||||
type UiScalePreset = (typeof UI_SCALE_PRESETS)[number]
|
||||
|
||||
function matchUiScalePreset(percent: number): UiScalePreset | null {
|
||||
return UI_SCALE_PRESETS.find(preset => Number(preset) === percent) ?? null
|
||||
}
|
||||
|
||||
function useDebounced<T>(value: T, delayMs: number): T {
|
||||
const [debounced, setDebounced] = useState(value)
|
||||
|
||||
|
|
@ -231,8 +245,10 @@ export function AppearanceSettings() {
|
|||
const { t, isSavingLocale } = useI18n()
|
||||
const { themeName, mode, resolvedMode, availableThemes, setTheme, setMode } = useTheme()
|
||||
const toolViewMode = useStore($toolViewMode)
|
||||
const zoomPercent = useStore($zoomPercent)
|
||||
const embedMode = useStore($embedMode)
|
||||
const embedAllowed = useStore($embedAllowed)
|
||||
const translucency = useStore($translucency)
|
||||
const backdrop = useStore($backdrop)
|
||||
const installs = useStore($marketplaceInstalls)
|
||||
const profiles = useStore($profiles)
|
||||
|
|
@ -277,6 +293,10 @@ export function AppearanceSettings() {
|
|||
{ id: 'off', label: a.embedsOff }
|
||||
] as const satisfies readonly { id: EmbedMode; label: string }[]
|
||||
|
||||
const uiScaleOptions = UI_SCALE_PRESETS.map(preset => ({ id: preset, label: `${preset}%` }))
|
||||
|
||||
const matchedScalePreset = matchUiScalePreset(zoomPercent)
|
||||
|
||||
return (
|
||||
<SettingsContent>
|
||||
<div>
|
||||
|
|
@ -392,6 +412,47 @@ export function AppearanceSettings() {
|
|||
wide
|
||||
/>
|
||||
|
||||
<ListRow
|
||||
action={
|
||||
<SegmentedControl
|
||||
onChange={id => {
|
||||
triggerHaptic('selection')
|
||||
setZoomPercent(Number(id))
|
||||
}}
|
||||
options={uiScaleOptions}
|
||||
value={matchedScalePreset ?? ('' as UiScalePreset)}
|
||||
/>
|
||||
}
|
||||
description={a.uiScaleDesc(zoomPercent)}
|
||||
title={a.uiScaleTitle}
|
||||
/>
|
||||
|
||||
<ListRow
|
||||
action={
|
||||
<div className="flex items-center gap-3">
|
||||
<input
|
||||
aria-label={a.translucencyTitle}
|
||||
className="h-1 w-40 cursor-pointer appearance-none rounded-full bg-(--ui-stroke-tertiary)"
|
||||
max={100}
|
||||
min={0}
|
||||
onChange={event => {
|
||||
triggerHaptic('selection')
|
||||
setTranslucency(Number(event.target.value))
|
||||
}}
|
||||
step={5}
|
||||
style={{ accentColor: 'var(--dt-primary)' }}
|
||||
type="range"
|
||||
value={translucency}
|
||||
/>
|
||||
<span className="w-9 text-right text-[length:var(--conversation-caption-font-size)] tabular-nums text-(--ui-text-tertiary)">
|
||||
{translucency}%
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
description={a.translucencyDesc}
|
||||
title={a.translucencyTitle}
|
||||
/>
|
||||
|
||||
<ListRow
|
||||
action={
|
||||
<SegmentedControl
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { useStore } from '@nanostores/react'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import type { ChangeEvent, ReactNode } from 'react'
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
|
|
@ -11,6 +12,7 @@ import { Textarea } from '@/components/ui/textarea'
|
|||
import { getElevenLabsVoices, getHermesConfigSchema, saveHermesConfig } from '@/hermes'
|
||||
import { useI18n } from '@/i18n'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { $keepAwake, setKeepAwake } from '@/store/keep-awake'
|
||||
import { notify, notifyError } from '@/store/notifications'
|
||||
import type { ConfigFieldSchema, HermesConfigRecord } from '@/types/hermes'
|
||||
|
||||
|
|
@ -32,7 +34,7 @@ import {
|
|||
import { MemoryConnect } from './memory/connect'
|
||||
import { ProviderConfigPanel } from './memory/provider-config-panel'
|
||||
import { ModelSettings, ModelSettingsSkeleton } from './model-settings'
|
||||
import { EmptyState, ListRow, LoadingState, SettingsContent } from './primitives'
|
||||
import { EmptyState, ListRow, LoadingState, SettingsContent, ToggleRow } from './primitives'
|
||||
|
||||
// On the Voice page, only surface the sub-fields of the *selected* TTS/STT
|
||||
// provider — otherwise every provider's options render at once (the "totally
|
||||
|
|
@ -242,6 +244,7 @@ export function ConfigSettings({
|
|||
}) {
|
||||
const { t } = useI18n()
|
||||
const c = t.settings.config
|
||||
const keepAwake = useStore($keepAwake)
|
||||
// The editable draft is local (debounced autosave watches it), but it's seeded
|
||||
// from — and saved back through — the shared config cache, so edits are visible
|
||||
// in the MCP/model surfaces and reopening the page doesn't reload-flash.
|
||||
|
|
@ -458,6 +461,11 @@ export function ConfigSettings({
|
|||
<ModelSettings onMainModelChanged={onMainModelChanged} />
|
||||
</div>
|
||||
)}
|
||||
{/* Device-local desktop pref (not config.yaml) — lives here since keeping
|
||||
the machine awake is a power-user knob. */}
|
||||
{activeSectionId === 'advanced' && (
|
||||
<ToggleRow checked={keepAwake} description={c.keepAwakeDesc} label={c.keepAwakeTitle} onChange={setKeepAwake} />
|
||||
)}
|
||||
{visibleFields.length === 0 ? (
|
||||
<EmptyState description={c.emptyDesc} title={c.emptyTitle} />
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import {
|
|||
Archive,
|
||||
BarChart3,
|
||||
Bell,
|
||||
Cpu,
|
||||
Download,
|
||||
Globe,
|
||||
Info,
|
||||
|
|
@ -43,7 +42,6 @@ import { NotificationsSettings } from './notifications-settings'
|
|||
import { PluginsSettings } from './plugins-settings'
|
||||
import { PROVIDER_VIEWS, ProvidersSettings, type ProviderView } from './providers-settings'
|
||||
import { SessionsSettings } from './sessions-settings'
|
||||
import { SystemSettings } from './system-settings'
|
||||
import type { SettingsPageProps, SettingsView as SettingsViewId } from './types'
|
||||
|
||||
const SETTINGS_VIEWS: readonly SettingsViewId[] = [
|
||||
|
|
@ -56,7 +54,6 @@ const SETTINGS_VIEWS: readonly SettingsViewId[] = [
|
|||
'billing',
|
||||
'plugins',
|
||||
'sessions',
|
||||
'system',
|
||||
'about'
|
||||
]
|
||||
|
||||
|
|
@ -156,13 +153,6 @@ export function SettingsView({ onClose, onConfigSaved, onMainModelChanged }: Set
|
|||
label: t.settings.nav.notifications,
|
||||
onSelect: () => setActiveView('notifications')
|
||||
},
|
||||
{
|
||||
active: activeView === 'system',
|
||||
icon: Cpu,
|
||||
id: 'system',
|
||||
label: t.settings.nav.system,
|
||||
onSelect: () => setActiveView('system')
|
||||
},
|
||||
{
|
||||
active: activeView === 'billing',
|
||||
icon: BarChart3,
|
||||
|
|
@ -326,8 +316,6 @@ export function SettingsView({ onClose, onConfigSaved, onMainModelChanged }: Set
|
|||
<KeysSettings view={keysView} />
|
||||
) : activeView === 'notifications' ? (
|
||||
<NotificationsSettings />
|
||||
) : activeView === 'system' ? (
|
||||
<SystemSettings />
|
||||
) : activeView === 'billing' ? (
|
||||
<BillingSettings />
|
||||
) : activeView === 'plugins' ? (
|
||||
|
|
|
|||
|
|
@ -1,90 +0,0 @@
|
|||
import { useStore } from '@nanostores/react'
|
||||
|
||||
import { SegmentedControl } from '@/components/ui/segmented-control'
|
||||
import { useI18n } from '@/i18n'
|
||||
import { triggerHaptic } from '@/lib/haptics'
|
||||
import { Cpu } from '@/lib/icons'
|
||||
import { $hapticsMuted, setHapticsMuted } from '@/store/haptics'
|
||||
import { $keepAwake, setKeepAwake } from '@/store/keep-awake'
|
||||
import { $translucency, setTranslucency } from '@/store/translucency'
|
||||
import { $zoomPercent, setZoomPercent } from '@/store/zoom'
|
||||
|
||||
import { ListRow, SectionHeading, SettingsContent, ToggleRow } from './primitives'
|
||||
|
||||
// UI scale presets as zoom percentages (100 = browser default); the ids double
|
||||
// as the percent sent to main. A Cmd/Ctrl +/- step between presets highlights
|
||||
// nothing, and the row description keeps showing the exact current percent.
|
||||
const UI_SCALE_PRESETS = ['90', '100', '110', '125', '150', '175'] as const
|
||||
|
||||
type UiScalePreset = (typeof UI_SCALE_PRESETS)[number]
|
||||
|
||||
export function SystemSettings() {
|
||||
const { t } = useI18n()
|
||||
const s = t.settings.system
|
||||
const keepAwake = useStore($keepAwake)
|
||||
const translucency = useStore($translucency)
|
||||
const zoomPercent = useStore($zoomPercent)
|
||||
const hapticsMuted = useStore($hapticsMuted)
|
||||
|
||||
const uiScaleOptions = UI_SCALE_PRESETS.map(preset => ({ id: preset, label: `${preset}%` }))
|
||||
const matchedScale = UI_SCALE_PRESETS.find(preset => Number(preset) === zoomPercent) ?? ('' as UiScalePreset)
|
||||
|
||||
return (
|
||||
<SettingsContent>
|
||||
<SectionHeading icon={Cpu} title={s.title} />
|
||||
<p className="mb-2 max-w-2xl text-[length:var(--conversation-caption-font-size)] leading-(--conversation-caption-line-height) text-(--ui-text-tertiary)">
|
||||
{s.intro}
|
||||
</p>
|
||||
|
||||
<ToggleRow checked={keepAwake} description={s.keepAwakeDesc} label={s.keepAwakeTitle} onChange={setKeepAwake} />
|
||||
|
||||
<ListRow
|
||||
action={
|
||||
<SegmentedControl
|
||||
onChange={id => {
|
||||
triggerHaptic('selection')
|
||||
setZoomPercent(Number(id))
|
||||
}}
|
||||
options={uiScaleOptions}
|
||||
value={matchedScale}
|
||||
/>
|
||||
}
|
||||
description={s.uiScaleDesc(zoomPercent)}
|
||||
title={s.uiScaleTitle}
|
||||
/>
|
||||
|
||||
<ListRow
|
||||
action={
|
||||
<div className="flex items-center gap-3">
|
||||
<input
|
||||
aria-label={s.translucencyTitle}
|
||||
className="h-1 w-40 cursor-pointer appearance-none rounded-full bg-(--ui-stroke-tertiary)"
|
||||
max={100}
|
||||
min={0}
|
||||
onChange={event => {
|
||||
triggerHaptic('selection')
|
||||
setTranslucency(Number(event.target.value))
|
||||
}}
|
||||
step={5}
|
||||
style={{ accentColor: 'var(--dt-primary)' }}
|
||||
type="range"
|
||||
value={translucency}
|
||||
/>
|
||||
<span className="w-9 text-right text-[length:var(--conversation-caption-font-size)] tabular-nums text-(--ui-text-tertiary)">
|
||||
{translucency}%
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
description={s.translucencyDesc}
|
||||
title={s.translucencyTitle}
|
||||
/>
|
||||
|
||||
<ToggleRow
|
||||
checked={!hapticsMuted}
|
||||
description={s.hapticsDesc}
|
||||
label={s.hapticsTitle}
|
||||
onChange={on => setHapticsMuted(!on)}
|
||||
/>
|
||||
</SettingsContent>
|
||||
)
|
||||
}
|
||||
|
|
@ -14,7 +14,6 @@ export type SettingsView =
|
|||
| 'plugins'
|
||||
| 'providers'
|
||||
| 'sessions'
|
||||
| 'system'
|
||||
| `config:${string}`
|
||||
export type EnvPatch = Partial<Pick<EnvVarInfo, 'is_set' | 'redacted_value'>>
|
||||
|
||||
|
|
|
|||
|
|
@ -325,8 +325,7 @@ export const en: Translations = {
|
|||
about: 'About',
|
||||
billing: 'Billing',
|
||||
notifications: 'Notifications',
|
||||
plugins: 'Plugins',
|
||||
system: 'System'
|
||||
plugins: 'Plugins'
|
||||
},
|
||||
plugins: {
|
||||
title: 'Desktop plugins',
|
||||
|
|
@ -380,19 +379,6 @@ export const en: Translations = {
|
|||
completionSoundDesc: 'Plays when an agent turn finishes. Pick a preset and preview it here.',
|
||||
completionSoundPreview: 'Preview'
|
||||
},
|
||||
system: {
|
||||
title: 'System',
|
||||
intro: 'How Hermes behaves on this machine. These are device-local — each computer keeps its own settings.',
|
||||
keepAwakeTitle: 'Keep computer awake',
|
||||
keepAwakeDesc: 'Stop this machine from sleeping so long or overnight runs keep going. The display can still dim.',
|
||||
translucencyTitle: 'Window Translucency',
|
||||
translucencyDesc: 'See your desktop through the whole window. macOS and Windows only.',
|
||||
uiScaleTitle: 'UI Scale',
|
||||
uiScaleDesc: (percent: number) =>
|
||||
`Scales text and controls across the whole app. Cmd/Ctrl with +, - and 0 also works. Current: ${percent}%.`,
|
||||
hapticsTitle: 'Haptic Feedback',
|
||||
hapticsDesc: 'Trackpad taps on actions and toggles. Supported hardware only (macOS).'
|
||||
},
|
||||
sections: {
|
||||
model: 'Model',
|
||||
chat: 'Chat',
|
||||
|
|
@ -424,6 +410,11 @@ export const en: Translations = {
|
|||
colorModeDesc: 'Pick a fixed mode or let Hermes follow your system setting.',
|
||||
toolViewTitle: 'Tool Call Display',
|
||||
toolViewDesc: 'Product hides raw tool payloads; Technical shows full input/output.',
|
||||
uiScaleTitle: 'UI Scale',
|
||||
uiScaleDesc: (percent: number) =>
|
||||
`Scales text and controls across the whole app. Cmd/Ctrl with +, - and 0 also works. Current: ${percent}%.`,
|
||||
translucencyTitle: 'Window Translucency',
|
||||
translucencyDesc: 'See your desktop through the whole window. macOS and Windows only.',
|
||||
backdropTitle: 'Chat Backdrop',
|
||||
backdropDesc: 'The faint statue image behind the conversation.',
|
||||
embedsTitle: 'Inline Embeds',
|
||||
|
|
@ -532,7 +523,9 @@ export const en: Translations = {
|
|||
failedLoad: 'Settings failed to load',
|
||||
autosaveFailed: 'Autosave failed',
|
||||
imported: 'Config imported',
|
||||
invalidJson: 'Invalid config JSON'
|
||||
invalidJson: 'Invalid config JSON',
|
||||
keepAwakeTitle: 'Keep computer awake',
|
||||
keepAwakeDesc: 'Stop this machine from sleeping so long or overnight runs keep going. The display can still dim.'
|
||||
},
|
||||
credentials: {
|
||||
pasteKey: 'Paste key',
|
||||
|
|
|
|||
|
|
@ -225,8 +225,7 @@ export const ja = defineLocale({
|
|||
archivedChats: 'アーカイブ済みチャット',
|
||||
about: '情報',
|
||||
billing: '請求',
|
||||
notifications: '通知',
|
||||
system: 'システム'
|
||||
notifications: '通知'
|
||||
},
|
||||
notifications: {
|
||||
title: '通知',
|
||||
|
|
@ -266,18 +265,6 @@ export const ja = defineLocale({
|
|||
completionSoundDesc: 'エージェントのターン終了時に再生されます。プリセットを選んでここで試聴できます。',
|
||||
completionSoundPreview: '試聴'
|
||||
},
|
||||
system: {
|
||||
title: 'システム',
|
||||
intro: 'この端末での Hermes の動作。設定は端末ごとに保存されます。',
|
||||
keepAwakeTitle: 'コンピューターをスリープさせない',
|
||||
keepAwakeDesc: '本体のスリープを防ぎ、長時間や夜通しの実行を継続します。画面は暗転できます。',
|
||||
translucencyTitle: 'ウィンドウの透過',
|
||||
translucencyDesc: 'ウィンドウ全体を透過させてデスクトップを表示します。macOS と Windows のみ。',
|
||||
uiScaleTitle: 'UI スケール',
|
||||
uiScaleDesc: (percent: number) => `アプリ全体の文字と UI を拡大縮小します。Cmd/Ctrl と +、-、0 でも変更できます。現在: ${percent}%`,
|
||||
hapticsTitle: '触覚フィードバック',
|
||||
hapticsDesc: '操作やトグル時にトラックパッドの触覚を返します。対応ハードウェアのみ(macOS)。'
|
||||
},
|
||||
sections: {
|
||||
model: 'モデル',
|
||||
chat: 'チャット',
|
||||
|
|
@ -309,6 +296,11 @@ export const ja = defineLocale({
|
|||
colorModeDesc: '固定モードを選ぶか、Hermes をシステム設定に合わせます。',
|
||||
toolViewTitle: 'ツール呼び出しの表示',
|
||||
toolViewDesc: 'プロダクト表示は生のツールペイロードを隠し、テクニカル表示は入出力をすべて表示します。',
|
||||
uiScaleTitle: 'UI スケール',
|
||||
uiScaleDesc: (percent: number) =>
|
||||
`アプリ全体の文字と UI を拡大縮小します。Cmd/Ctrl と +、-、0 でも変更できます。現在: ${percent}%`,
|
||||
translucencyTitle: 'ウィンドウの透過',
|
||||
translucencyDesc: 'ウィンドウ全体を透過させてデスクトップを表示します。macOS と Windows のみ。',
|
||||
backdropTitle: 'チャット背景',
|
||||
backdropDesc: '会話の背後に表示される淡い彫像の画像。',
|
||||
embedsTitle: 'インライン埋め込み',
|
||||
|
|
@ -629,7 +621,9 @@ export const ja = defineLocale({
|
|||
failedLoad: '設定の読み込みに失敗しました',
|
||||
autosaveFailed: '自動保存に失敗しました',
|
||||
imported: '設定をインポートしました',
|
||||
invalidJson: '設定 JSON が無効です'
|
||||
invalidJson: '設定 JSON が無効です',
|
||||
keepAwakeTitle: 'コンピューターをスリープさせない',
|
||||
keepAwakeDesc: '本体のスリープを防ぎ、長時間や夜通しの実行を継続します。画面は暗転できます。'
|
||||
},
|
||||
credentials: {
|
||||
pasteKey: 'キーを貼り付け',
|
||||
|
|
|
|||
|
|
@ -284,7 +284,6 @@ export interface Translations {
|
|||
billing: string
|
||||
notifications: string
|
||||
plugins: string
|
||||
system: string
|
||||
}
|
||||
plugins: {
|
||||
title: string
|
||||
|
|
@ -318,18 +317,6 @@ export interface Translations {
|
|||
completionSoundDesc: string
|
||||
completionSoundPreview: string
|
||||
}
|
||||
system: {
|
||||
title: string
|
||||
intro: string
|
||||
keepAwakeTitle: string
|
||||
keepAwakeDesc: string
|
||||
translucencyTitle: string
|
||||
translucencyDesc: string
|
||||
uiScaleTitle: string
|
||||
uiScaleDesc: (percent: number) => string
|
||||
hapticsTitle: string
|
||||
hapticsDesc: string
|
||||
}
|
||||
sections: Record<string, string>
|
||||
searchPlaceholder: Record<'about' | 'config' | 'gateway' | 'keys' | 'mcp' | 'sessions', string>
|
||||
modeOptions: Record<'light' | 'dark' | 'system', ModeOptionCopy>
|
||||
|
|
@ -340,6 +327,10 @@ export interface Translations {
|
|||
colorModeDesc: string
|
||||
toolViewTitle: string
|
||||
toolViewDesc: string
|
||||
uiScaleTitle: string
|
||||
uiScaleDesc: (percent: number) => string
|
||||
translucencyTitle: string
|
||||
translucencyDesc: string
|
||||
backdropTitle: string
|
||||
backdropDesc: string
|
||||
embedsTitle: string
|
||||
|
|
@ -444,6 +435,8 @@ export interface Translations {
|
|||
autosaveFailed: string
|
||||
imported: string
|
||||
invalidJson: string
|
||||
keepAwakeTitle: string
|
||||
keepAwakeDesc: string
|
||||
}
|
||||
credentials: {
|
||||
pasteKey: string
|
||||
|
|
|
|||
|
|
@ -219,8 +219,7 @@ export const zhHant = defineLocale({
|
|||
archivedChats: '已封存聊天',
|
||||
about: '關於',
|
||||
billing: '帳單',
|
||||
notifications: '通知',
|
||||
system: '系統'
|
||||
notifications: '通知'
|
||||
},
|
||||
notifications: {
|
||||
title: '通知',
|
||||
|
|
@ -259,18 +258,6 @@ export const zhHant = defineLocale({
|
|||
completionSoundDesc: '代理回合結束時播放。可在此選擇預設並預覽。',
|
||||
completionSoundPreview: '預覽'
|
||||
},
|
||||
system: {
|
||||
title: '系統',
|
||||
intro: 'Hermes 在這台電腦上的行為。設定會依裝置保存,每台電腦各自獨立。',
|
||||
keepAwakeTitle: '保持電腦喚醒',
|
||||
keepAwakeDesc: '阻止本機睡眠,讓長時間或整夜執行持續進行。螢幕仍可變暗。',
|
||||
translucencyTitle: '視窗透明',
|
||||
translucencyDesc: '讓整個視窗透出桌面。僅支援 macOS 與 Windows。',
|
||||
uiScaleTitle: '介面縮放',
|
||||
uiScaleDesc: (percent: number) => `縮放整個應用程式的文字與介面。也可使用 Cmd/Ctrl 加 +、- 或 0 調整。目前:${percent}%`,
|
||||
hapticsTitle: '觸覺回饋',
|
||||
hapticsDesc: '在操作與開關時觸發觸控板輕觸。僅支援對應硬體(macOS)。'
|
||||
},
|
||||
sections: {
|
||||
model: '模型',
|
||||
chat: '聊天',
|
||||
|
|
@ -301,6 +288,11 @@ export const zhHant = defineLocale({
|
|||
colorModeDesc: '選擇固定模式,或讓 Hermes 跟隨系統設定。',
|
||||
toolViewTitle: '工具呼叫顯示',
|
||||
toolViewDesc: '產品模式會隱藏原始工具 payload;技術模式會顯示完整輸入/輸出。',
|
||||
uiScaleTitle: '介面縮放',
|
||||
uiScaleDesc: (percent: number) =>
|
||||
`縮放整個應用程式的文字與介面。也可使用 Cmd/Ctrl 加 +、- 或 0 調整。目前:${percent}%`,
|
||||
translucencyTitle: '視窗透明',
|
||||
translucencyDesc: '讓整個視窗透出桌面。僅支援 macOS 與 Windows。',
|
||||
backdropTitle: '聊天背景',
|
||||
backdropDesc: '對話後方那張淡淡的雕像圖片。',
|
||||
embedsTitle: '內嵌預覽',
|
||||
|
|
@ -617,7 +609,9 @@ export const zhHant = defineLocale({
|
|||
failedLoad: '設定載入失敗',
|
||||
autosaveFailed: '自動儲存失敗',
|
||||
imported: '設定已匯入',
|
||||
invalidJson: '設定 JSON 無效'
|
||||
invalidJson: '設定 JSON 無效',
|
||||
keepAwakeTitle: '保持電腦喚醒',
|
||||
keepAwakeDesc: '阻止本機睡眠,讓長時間或整夜執行持續進行。螢幕仍可變暗。'
|
||||
},
|
||||
credentials: {
|
||||
pasteKey: '貼上金鑰',
|
||||
|
|
|
|||
|
|
@ -316,8 +316,7 @@ export const zh: Translations = {
|
|||
about: '关于',
|
||||
billing: '账单',
|
||||
notifications: '通知',
|
||||
plugins: '插件',
|
||||
system: '系统'
|
||||
plugins: '插件'
|
||||
},
|
||||
plugins: {
|
||||
title: '桌面插件',
|
||||
|
|
@ -370,18 +369,6 @@ export const zh: Translations = {
|
|||
completionSoundDesc: '智能体回合结束时播放。可在此选择预设并预览。',
|
||||
completionSoundPreview: '预览'
|
||||
},
|
||||
system: {
|
||||
title: '系统',
|
||||
intro: 'Hermes 在这台电脑上的行为。设置按设备保存,每台电脑各自独立。',
|
||||
keepAwakeTitle: '保持电脑唤醒',
|
||||
keepAwakeDesc: '阻止本机休眠,让长时间或通宵运行继续进行。屏幕仍可变暗。',
|
||||
translucencyTitle: '窗口透明',
|
||||
translucencyDesc: '让整个窗口透出桌面。仅支持 macOS 和 Windows。',
|
||||
uiScaleTitle: '界面缩放',
|
||||
uiScaleDesc: (percent: number) => `缩放整个应用的文字和界面。也可使用 Cmd/Ctrl 加 +、- 或 0 调整。当前:${percent}%`,
|
||||
hapticsTitle: '触感反馈',
|
||||
hapticsDesc: '在操作和开关时触发触控板轻触。仅支持相应硬件(macOS)。'
|
||||
},
|
||||
sections: {
|
||||
model: '模型',
|
||||
chat: '对话',
|
||||
|
|
@ -412,6 +399,11 @@ export const zh: Translations = {
|
|||
colorModeDesc: '选择固定模式,或让 Hermes 跟随系统设置。',
|
||||
toolViewTitle: '工具调用显示',
|
||||
toolViewDesc: '产品模式隐藏原始工具数据;技术模式显示完整输入/输出。',
|
||||
uiScaleTitle: '界面缩放',
|
||||
uiScaleDesc: (percent: number) =>
|
||||
`缩放整个应用的文字和界面。也可使用 Cmd/Ctrl 加 +、- 或 0 调整。当前:${percent}%`,
|
||||
translucencyTitle: '窗口透明',
|
||||
translucencyDesc: '让整个窗口透出桌面。仅支持 macOS 和 Windows。',
|
||||
backdropTitle: '聊天背景',
|
||||
backdropDesc: '对话后方那张淡淡的雕像图片。',
|
||||
embedsTitle: '内嵌预览',
|
||||
|
|
@ -728,7 +720,9 @@ export const zh: Translations = {
|
|||
failedLoad: '设置加载失败',
|
||||
autosaveFailed: '自动保存失败',
|
||||
imported: '配置已导入',
|
||||
invalidJson: '配置 JSON 无效'
|
||||
invalidJson: '配置 JSON 无效',
|
||||
keepAwakeTitle: '保持电脑唤醒',
|
||||
keepAwakeDesc: '阻止本机休眠,让长时间或通宵运行继续进行。屏幕仍可变暗。'
|
||||
},
|
||||
credentials: {
|
||||
pasteKey: '粘贴密钥',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue