- Correctie marked component in SideBarExplanation.vue - AI messages ondersteunen nu markdown. Markdown rendering is als een centrale utility gedefinieerd.
117 lines
2.8 KiB
Vue
117 lines
2.8 KiB
Vue
<!-- SideBarExplanation.vue -->
|
|
<template>
|
|
<div class="sidebar-explanation">
|
|
<div
|
|
v-if="isLoading"
|
|
class="explanation-loading"
|
|
>
|
|
🔄 Translating...
|
|
</div>
|
|
<div
|
|
v-else
|
|
class="explanation-content"
|
|
v-html="renderedExplanation"
|
|
></div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, watch, onMounted } from 'vue';
|
|
import { useComponentTranslations } from '../js/services/LanguageProvider.js';
|
|
import { renderMarkdown } from '../js/utils/markdownRenderer.js';
|
|
|
|
const props = defineProps({
|
|
originalText: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
currentLanguage: {
|
|
type: String,
|
|
default: 'en'
|
|
},
|
|
apiPrefix: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
});
|
|
|
|
// Use component translations from provider - fix: use reactive object instead of computed
|
|
const originalTexts = {
|
|
explanation: props.originalText || ''
|
|
};
|
|
|
|
const { texts: translations, isLoading, error, currentLanguage } = useComponentTranslations(
|
|
'sidebar_explanation',
|
|
originalTexts
|
|
);
|
|
|
|
const translatedText = computed(() => {
|
|
const candidate = translations.value?.explanation ?? props.originalText ?? '';
|
|
return typeof candidate === 'string' ? candidate : String(candidate ?? '');
|
|
});
|
|
|
|
// Render markdown content (defensive: always pass a string and catch errors)
|
|
const renderedExplanation = computed(() => {
|
|
const text = translatedText.value || '';
|
|
if (!text) return '';
|
|
try {
|
|
return renderMarkdown(text, {
|
|
allowInlineHTML: false,
|
|
enableTables: true,
|
|
enableBreaks: true,
|
|
enableImages: false,
|
|
enableCodeBlocks: false,
|
|
allowInlineCode: false,
|
|
linkTargetBlank: true,
|
|
sidebarAccent: true
|
|
});
|
|
} catch (err) {
|
|
console.warn('Markdown render error in SideBarExplanation, falling back to plain text:', err);
|
|
return String(text);
|
|
}
|
|
});
|
|
|
|
// Watch for text changes to update the provider
|
|
watch(() => props.originalText, (newText) => {
|
|
// Re-register component with new text if needed
|
|
// The LanguageProvider will handle the update automatically
|
|
console.log('SideBarExplanation: Original text changed to:', newText);
|
|
}, { immediate: true });
|
|
</script>
|
|
|
|
<style scoped>
|
|
.sidebar-explanation {
|
|
padding: 15px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.explanation-loading {
|
|
color: var(--markdown-text-color);
|
|
font-style: italic;
|
|
text-align: center;
|
|
padding: 20px;
|
|
}
|
|
|
|
.explanation-content {
|
|
color: var(--markdown-text-color);
|
|
font-size: 0.9rem;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.explanation-content :deep(h1),
|
|
.explanation-content :deep(h2),
|
|
.explanation-content :deep(h3) {
|
|
color: var(--markdown-text-color);
|
|
margin-top: 1rem;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.explanation-content :deep(p) {
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.explanation-content :deep(strong) {
|
|
color: var(--primary-color);
|
|
font-weight: 600;
|
|
}
|
|
</style> |