- 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.
108 lines
3.5 KiB
TypeScript
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 };
|