Files
zn-ai/src-react/i18n/index.ts
duanshuwen b1dea9a5c2 feat: implement task management store with IPC integration
- Added a new task store in `src-react/stores/task.ts` to manage tasks and their statuses.
- Implemented functions for creating, executing, and retrying tasks, along with handling task progress and completion.
- Introduced persistence for tasks using IPC.
- Created utility functions for normalizing room types and building subtasks.
- Added a new CSS file for global styles in `src-react/styles.css`.
- Created runtime types in `src-react/types/runtime.ts` and exported them.
- Updated the main entry points for Vue and React applications to support dynamic framework loading.
- Refactored chat model interfaces and utility functions into `src/shared/chat-model.ts`.
- Updated TypeScript configuration to include paths for React components and types.
- Enhanced Vite configuration to support both Vue and React frameworks.
2026-04-17 07:09:56 +08:00

108 lines
3.5 KiB
TypeScript

import { DEFAULT_LANGUAGE } from '../lib/constants';
import type { LanguageCode } from '../types/runtime';
import type { Namespace } from './constants';
import { detectSystemLanguage, resolveSupportedLanguage } from './resolver';
import { messages, type MessageTree } from './messages';
type InterpolationParams = Record<string, string | number>;
function lookupMessage(source: MessageTree, path: string): unknown {
return path.split('.').reduce<unknown>((current, segment) => {
if (!current || typeof current !== 'object') return undefined;
return (current as Record<string, unknown>)[segment];
}, source);
}
function interpolate(template: string, params?: InterpolationParams): string {
if (!params) return template;
return template.replace(/\{(\w+)\}/g, (_match, token) => {
const value = params[token];
return typeof value === 'undefined' ? `{${token}}` : String(value);
});
}
export interface I18nBridge {
getLocale(): LanguageCode;
setLocale(locale: string | null | undefined): LanguageCode;
t(path: string, params?: InterpolationParams): string;
has(path: string): boolean;
getMessages(locale?: LanguageCode): MessageTree;
subscribe(listener: (locale: LanguageCode) => void): () => void;
}
export function createI18nBridge(initialLocale?: string | null): I18nBridge {
let locale = resolveSupportedLanguage(initialLocale ?? detectSystemLanguage() ?? DEFAULT_LANGUAGE);
const listeners = new Set<(locale: LanguageCode) => void>();
const notify = () => {
for (const listener of listeners) {
listener(locale);
}
};
const api: I18nBridge = {
getLocale() {
return locale;
},
setLocale(nextLocale: string | null | undefined) {
const resolved = resolveSupportedLanguage(nextLocale, locale);
if (resolved !== locale) {
locale = resolved;
notify();
}
return locale;
},
t(path: string, params?: InterpolationParams) {
const localeMessages = messages[locale] ?? messages[DEFAULT_LANGUAGE];
const fallbackMessages = messages[DEFAULT_LANGUAGE];
const translated = lookupMessage(localeMessages, path) ?? lookupMessage(fallbackMessages, path);
if (typeof translated === 'string' || typeof translated === 'number') {
return interpolate(String(translated), params);
}
return path;
},
has(path: string) {
const localeMessages = messages[locale] ?? messages[DEFAULT_LANGUAGE];
const fallbackMessages = messages[DEFAULT_LANGUAGE];
return typeof lookupMessage(localeMessages, path) !== 'undefined' || typeof lookupMessage(fallbackMessages, path) !== 'undefined';
},
getMessages(targetLocale?: LanguageCode) {
return messages[targetLocale ?? locale] ?? messages[DEFAULT_LANGUAGE];
},
subscribe(listener: (locale: LanguageCode) => void) {
listeners.add(listener);
return () => listeners.delete(listener);
},
};
return api;
}
export const i18n = createI18nBridge();
export function setLocale(locale: string | null | undefined): LanguageCode {
return i18n.setLocale(locale);
}
export function getLocale(): LanguageCode {
return i18n.getLocale();
}
export function t(path: string, params?: InterpolationParams): string {
return i18n.t(path, params);
}
export function hasMessage(path: string): boolean {
return i18n.has(path);
}
export function getMessages(locale?: LanguageCode): MessageTree {
return i18n.getMessages(locale);
}
export { SUPPORTED_LANGUAGE_CODES, SUPPORTED_LANGUAGES, NAMESPACES } from './constants';
export type { LanguageCode, Namespace };