Files
eveAI/eveai_chat_client/static/assets/js/services/LanguageProvider.js
Josako 4ad621428e - verbeteringen client
- Enkel nog probleem met vertaling van de ProgressTracker constanten
2025-07-21 21:45:46 +02:00

181 lines
6.3 KiB
JavaScript

// LanguageProvider.js - Central language management system
import { ref, reactive, computed, provide, inject } from 'vue';
import { useConstantsTranslation } from '../composables/useTranslation.js';
// Injection key for type safety
export const LANGUAGE_PROVIDER_KEY = Symbol('LanguageProvider');
/**
* Language Provider Service
* Central management of language state and translations
*/
export function createLanguageProvider(initialLanguage = 'en', apiPrefix = '') {
// Reactive state
const currentLanguage = ref(initialLanguage);
const isTranslating = ref(false);
const translationError = ref(null);
// Translation composable
const { translateConstants, getCachedTranslations, clearCache } = useConstantsTranslation();
// Component-specific translations cache
const componentTranslations = reactive({});
/**
* Register a component for translations with component-specific caching
*/
const registerComponent = (componentName, originalTexts) => {
console.log(`LanguageProvider: Registering component ${componentName} with language ${currentLanguage.value}`);
if (!componentTranslations[componentName]) {
componentTranslations[componentName] = reactive({
original: originalTexts,
translated: { ...originalTexts }, // Start with original English texts
isLoading: false,
error: null
});
// Force initial translation if current language is not English
if (currentLanguage.value !== 'en') {
console.log(`LanguageProvider: Component ${componentName} needs initial translation to ${currentLanguage.value}`);
translateComponentTexts(componentName, currentLanguage.value);
}
}
return componentTranslations[componentName];
};
/**
* Translate texts for a specific component
*/
const translateComponentTexts = async (componentName, targetLanguage) => {
const component = componentTranslations[componentName];
if (!component) {
console.warn(`LanguageProvider: Component ${componentName} not found for translation`);
return;
}
component.isLoading = true;
component.error = null;
try {
if (targetLanguage === 'en') {
// For English, use original texts (no translation needed)
component.translated = { ...component.original };
console.log(`LanguageProvider: Using original English texts for ${componentName}`);
} else {
// For other languages, translate from English
console.log(`LanguageProvider: Translating ${componentName} from English to ${targetLanguage}`);
const translatedTexts = await translateConstants(
component.original,
targetLanguage,
{
context: componentName,
apiPrefix
}
);
component.translated = translatedTexts;
console.log(`LanguageProvider: Successfully translated ${componentName} to ${targetLanguage}`);
}
} catch (error) {
console.error(`LanguageProvider: Translation error for ${componentName}:`, error);
component.error = error;
// Fallback to original English texts
component.translated = { ...component.original };
} finally {
component.isLoading = false;
}
};
/**
* Update language for all registered components
*/
const setLanguage = async (newLanguage) => {
if (currentLanguage.value === newLanguage) {
return;
}
console.log('LanguageProvider: Setting language to', newLanguage);
currentLanguage.value = newLanguage;
isTranslating.value = true;
translationError.value = null;
try {
// Update all registered components
const translationPromises = Object.keys(componentTranslations).map(componentName =>
translateComponentTexts(componentName, newLanguage)
);
await Promise.all(translationPromises);
console.log(`LanguageProvider: Successfully updated all components to ${newLanguage}`);
} catch (error) {
console.error('LanguageProvider: Error setting language:', error);
translationError.value = error;
} finally {
isTranslating.value = false;
}
};
/**
* Get translations voor een specifieke component
*/
const getComponentTranslations = (componentName) => {
return componentTranslations[componentName] || null;
};
/**
* Clear alle caches
*/
const clearAllCaches = () => {
clearCache();
Object.keys(componentTranslations).forEach(key => {
delete componentTranslations[key];
});
};
return {
// State
currentLanguage: computed(() => currentLanguage.value),
isTranslating: computed(() => isTranslating.value),
translationError: computed(() => translationError.value),
// Methods
registerComponent,
setLanguage,
getComponentTranslations,
clearAllCaches,
// Computed
componentTranslations: computed(() => componentTranslations)
};
}
/**
* Composable voor het gebruiken van de Language Provider
*/
export function useLanguageProvider() {
const provider = inject(LANGUAGE_PROVIDER_KEY);
if (!provider) {
throw new Error('useLanguageProvider must be used within a LanguageProvider');
}
return provider;
}
/**
* Composable voor component-specifieke vertalingen
*/
export function useComponentTranslations(componentName, originalTexts) {
const provider = useLanguageProvider();
// Registreer component bij eerste gebruik
const translations = provider.registerComponent(componentName, originalTexts);
return {
translations: computed(() => translations.translated),
isLoading: computed(() => translations.isLoading),
error: computed(() => translations.error),
currentLanguage: provider.currentLanguage
};
}