mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-20 13:53:32 +08:00
Session inspection was coupling quick status and usage rendering to live context control requests, so a slow get_context_usage path could leave the desktop inspector stuck on a loading state. The desktop panel now loads basic inspection data first, renders a transcript-based context estimate immediately, and only asks for live context details as a background refinement. The translation hook now returns a stable function per locale so effects that depend on translation do not reset and re-fetch after every render. Constraint: Third-party provider sessions may not expose reliable live context capabilities through the control request path. Rejected: Keep waiting on live get_context_usage for the context tab | it recreates the user-visible loading stall. Rejected: Hardcode provider-specific context windows | provider capabilities are not always known from the desktop session record. Confidence: high Scope-risk: moderate Directive: Do not make the inspector first render depend on live CLI control requests without a transcript or cached fallback. Tested: bun test src/server/__tests__/conversations.test.ts -t "structured session inspection|Sonnet 4.6 transcript usage" Tested: cd desktop && bun run test -- --run src/i18n/index.test.tsx Tested: cd desktop && bun run build Tested: git diff --check Tested: agent-browser verified /context renders transcript estimate without Loading context data Not-tested: Provider-specific true context-window discovery for every third-party vendor
59 lines
1.7 KiB
TypeScript
59 lines
1.7 KiB
TypeScript
import { useCallback } from 'react'
|
|
import { useSettingsStore } from '../stores/settingsStore'
|
|
import { en, type TranslationKey } from './locales/en'
|
|
import { zh } from './locales/zh'
|
|
|
|
export type Locale = 'en' | 'zh'
|
|
|
|
const translations: Record<Locale, Record<string, string>> = { en, zh }
|
|
|
|
/**
|
|
* Translate a key with optional interpolation params.
|
|
* Falls back to the key itself if no translation is found.
|
|
*
|
|
* @example
|
|
* translate('en', 'settings.providers.connected', { latency: '42' })
|
|
* // => "Connected (42ms)"
|
|
*/
|
|
export function translate(
|
|
locale: Locale,
|
|
key: TranslationKey,
|
|
params?: Record<string, string | number>,
|
|
): string {
|
|
let text = translations[locale]?.[key] ?? translations.en[key] ?? key
|
|
if (params) {
|
|
for (const [k, v] of Object.entries(params)) {
|
|
text = text.replace(new RegExp(`\\{${k}\\}`, 'g'), String(v))
|
|
}
|
|
}
|
|
return text
|
|
}
|
|
|
|
/**
|
|
* React hook that returns a `t()` function bound to the current locale.
|
|
* Re-renders when the locale changes.
|
|
*
|
|
* @example
|
|
* const t = useTranslation()
|
|
* t('sidebar.newSession') // => "New session" or "新建会话"
|
|
*/
|
|
export function useTranslation() {
|
|
const locale = useSettingsStore((s) => s.locale)
|
|
return useCallback(
|
|
(key: TranslationKey, params?: Record<string, string | number>) =>
|
|
translate(locale, key, params),
|
|
[locale],
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Get a translation outside of React (e.g. in stores).
|
|
* Reads the current locale from the Zustand store directly.
|
|
*/
|
|
export function t(key: TranslationKey, params?: Record<string, string | number>): string {
|
|
const locale = useSettingsStore.getState().locale
|
|
return translate(locale, key, params)
|
|
}
|
|
|
|
export type { TranslationKey }
|