|
|
@@ -0,0 +1,46 @@
|
|
|
+<template>
|
|
|
+ <div v-if="words.length" class="word-pronunciation-display">
|
|
|
+ <span
|
|
|
+ v-for="(w, i) in words"
|
|
|
+ :key="i"
|
|
|
+ class="wpd-word"
|
|
|
+ :class="`wpd-${classFor(w.errorType)}`"
|
|
|
+ :title="`${w.word} · ${w.errorType} · ${Math.round(w.accuracyScore)}`"
|
|
|
+ >{{ w.word }}<span v-if="i < words.length - 1"> </span></span>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts" setup>
|
|
|
+import type { WordAnalysisItem, WordErrorType } from '@/types/englishSpeaking'
|
|
|
+
|
|
|
+interface Props {
|
|
|
+ words: WordAnalysisItem[]
|
|
|
+}
|
|
|
+defineProps<Props>()
|
|
|
+
|
|
|
+function classFor(t: WordErrorType): 'correct' | 'wrong' | 'missed' | 'ignored' {
|
|
|
+ if (t === 'None') return 'correct'
|
|
|
+ if (t === 'Mispronunciation' || t === 'Insertion') return 'wrong'
|
|
|
+ if (t === 'Omission') return 'missed'
|
|
|
+ return 'ignored'
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.word-pronunciation-display {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #1f2937;
|
|
|
+ line-height: 2;
|
|
|
+ word-wrap: break-word;
|
|
|
+}
|
|
|
+
|
|
|
+.wpd-word {
|
|
|
+ border-bottom: 2px solid transparent;
|
|
|
+ padding-bottom: 1px;
|
|
|
+}
|
|
|
+
|
|
|
+.wpd-correct { border-bottom-color: #16a34a; }
|
|
|
+.wpd-wrong { border-bottom-color: #ef4444; }
|
|
|
+.wpd-missed { border-bottom-color: #9ca3af; }
|
|
|
+.wpd-ignored { border-bottom-color: transparent; }
|
|
|
+</style>
|