feat(VocabCourseView): add hard vocabulary practice button and refresh logic
All checks were successful
Deploy to production / deploy (push) Successful in 1m57s
All checks were successful
Deploy to production / deploy (push) Successful in 1m57s
- Introduced a button to start hard vocabulary practice when applicable, enhancing user engagement with challenging vocabulary. - Implemented methods to manage and refresh the hard vocabulary list from local storage, ensuring users have access to their difficult words. - Added event listeners to refresh the hard vocabulary list on window focus, improving the overall user experience.
This commit is contained in:
@@ -16,6 +16,14 @@
|
||||
<span v-if="course.shareCode && isOwner" class="share-code">
|
||||
{{ $t('socialnetwork.vocab.courses.shareCode') }}: <code>{{ course.shareCode }}</code>
|
||||
</span>
|
||||
<button
|
||||
v-if="hardVocabCount > 0"
|
||||
type="button"
|
||||
class="course-hard-practice-link"
|
||||
@click="openHardPractice"
|
||||
>
|
||||
{{ $t('socialnetwork.vocab.courses.startHardVocabTrainer', { count: hardVocabCount }) }}
|
||||
</button>
|
||||
<button type="button" class="course-dictionary-link" @click="goCourseDictionary">
|
||||
{{ $t('socialnetwork.vocab.dictionary.open') }}
|
||||
</button>
|
||||
@@ -345,6 +353,7 @@ export default {
|
||||
srsLoading: false,
|
||||
showAddLessonDialog: false,
|
||||
assistantSettings: null,
|
||||
hardVocabList: [],
|
||||
lessonFormTouched: false,
|
||||
newLesson: {
|
||||
lessonNumber: 1,
|
||||
@@ -390,6 +399,9 @@ export default {
|
||||
}
|
||||
return Array.isArray(this.srsDueItems) ? this.srsDueItems.length : 0;
|
||||
},
|
||||
hardVocabCount() {
|
||||
return Array.isArray(this.hardVocabList) ? this.hardVocabList.length : 0;
|
||||
},
|
||||
dueReviewLessons() {
|
||||
return this.sortedLessons
|
||||
.filter((lesson) => {
|
||||
@@ -519,12 +531,45 @@ export default {
|
||||
watch: {
|
||||
courseId() {
|
||||
this.loadCourse();
|
||||
this.refreshHardVocabList();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
displayCourseTitle(course) {
|
||||
return localizeVocabCourseTitle(course?.title, this.$i18n?.locale) || '';
|
||||
},
|
||||
hardStorageKey() {
|
||||
return this.courseId ? `yourpart:vocab:hardList:${this.courseId}` : null;
|
||||
},
|
||||
refreshHardVocabList() {
|
||||
const key = this.hardStorageKey();
|
||||
if (!key) {
|
||||
this.hardVocabList = [];
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const raw = localStorage.getItem(key);
|
||||
const parsed = raw ? JSON.parse(raw) : {};
|
||||
const values = parsed && typeof parsed === 'object' ? Object.values(parsed) : [];
|
||||
this.hardVocabList = values
|
||||
.map((entry, idx) => {
|
||||
const learning = String(entry?.learning || '').trim();
|
||||
const reference = String(entry?.reference || '').trim();
|
||||
if (!learning || !reference) return null;
|
||||
return {
|
||||
id: `hard-${idx}-${learning}-${reference}`,
|
||||
learning,
|
||||
reference
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
} catch (_) {
|
||||
this.hardVocabList = [];
|
||||
}
|
||||
},
|
||||
handleWindowFocus() {
|
||||
this.refreshHardVocabList();
|
||||
},
|
||||
async loadCourse() {
|
||||
this.loading = true;
|
||||
try {
|
||||
@@ -858,6 +903,14 @@ export default {
|
||||
lessonId: lesson.id
|
||||
});
|
||||
},
|
||||
openHardPractice() {
|
||||
if (!this.hardVocabCount) return;
|
||||
this.$refs.practiceDialog?.open?.({
|
||||
courseId: this.courseId,
|
||||
initialPool: this.hardVocabList,
|
||||
onClose: () => this.refreshHardVocabList()
|
||||
});
|
||||
},
|
||||
openSrsPractice() {
|
||||
if (!this.srsDueItems.length) {
|
||||
return;
|
||||
@@ -922,6 +975,11 @@ export default {
|
||||
this.loadCourse(),
|
||||
this.loadAssistantSettings()
|
||||
]);
|
||||
this.refreshHardVocabList();
|
||||
window.addEventListener('focus', this.handleWindowFocus);
|
||||
},
|
||||
beforeUnmount() {
|
||||
window.removeEventListener('focus', this.handleWindowFocus);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -978,6 +1036,10 @@ export default {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.course-hard-practice-link {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.course-assistant {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
|
||||
Reference in New Issue
Block a user