feat(VocabPracticeDialog, VocabCourseView): enhance hard vocabulary management and UI
All checks were successful
Deploy to production / deploy (push) Successful in 2m6s
All checks were successful
Deploy to production / deploy (push) Successful in 2m6s
- Refactored methods in VocabPracticeDialog to improve the handling of hard vocabulary items, including the addition of `findMatchingHardKey` and `removeHardEntriesForItem` for better management of hard vocabulary entries. - Updated the VocabCourseView to display a new section for hard vocabulary items, allowing users to view and remove difficult words easily. - Enhanced the UI with new styles for the hard vocabulary list, improving user engagement and accessibility to challenging vocabulary practice.
This commit is contained in:
@@ -297,11 +297,11 @@ export default {
|
||||
},
|
||||
isCurrentMarkedHard() {
|
||||
if (!this.current) return false;
|
||||
return Boolean(this.hardVocabMap[this.getHardKey(this.current)]);
|
||||
return this.isItemMarkedHard(this.current);
|
||||
},
|
||||
hardPoolItems() {
|
||||
if (!Array.isArray(this.pool) || this.pool.length === 0) return [];
|
||||
return this.pool.filter((item) => Boolean(this.hardVocabMap[this.getHardKey(item)]));
|
||||
return this.pool.filter((item) => this.isItemMarkedHard(item));
|
||||
},
|
||||
hardRemainingCount() {
|
||||
return this.hardPoolItems.filter((item) => {
|
||||
@@ -344,8 +344,63 @@ export default {
|
||||
const reference = this.normalize(item?.reference || '');
|
||||
return `${learning}|${reference}`;
|
||||
},
|
||||
findMatchingHardKey(item) {
|
||||
const exactKey = this.getHardKey(item);
|
||||
if (this.hardVocabMap[exactKey]) return exactKey;
|
||||
|
||||
const itemLearning = this.normalize(item?.learning || '');
|
||||
const itemReference = this.normalize(item?.reference || '');
|
||||
if (!itemLearning || !itemReference) return null;
|
||||
|
||||
const entries = Object.entries(this.hardVocabMap || {});
|
||||
for (const [key, value] of entries) {
|
||||
const learningAlts = this.splitPhraseAlternatives(value?.learning || '')
|
||||
.map((part) => this.normalize(part))
|
||||
.filter(Boolean);
|
||||
const referenceAlts = this.splitPhraseAlternatives(value?.reference || '')
|
||||
.map((part) => this.normalize(part))
|
||||
.filter(Boolean);
|
||||
if (!learningAlts.length || !referenceAlts.length) continue;
|
||||
if (learningAlts.includes(itemLearning) && referenceAlts.includes(itemReference)) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
isItemMarkedHard(item) {
|
||||
return Boolean(this.findMatchingHardKey(item));
|
||||
},
|
||||
removeHardEntriesForItem(item) {
|
||||
const itemLearning = this.normalize(item?.learning || '');
|
||||
const itemReference = this.normalize(item?.reference || '');
|
||||
if (!itemLearning || !itemReference) return;
|
||||
|
||||
const toDelete = [];
|
||||
Object.entries(this.hardVocabMap || {}).forEach(([key, value]) => {
|
||||
const learningAlts = this.splitPhraseAlternatives(value?.learning || '')
|
||||
.map((part) => this.normalize(part))
|
||||
.filter(Boolean);
|
||||
const referenceAlts = this.splitPhraseAlternatives(value?.reference || '')
|
||||
.map((part) => this.normalize(part))
|
||||
.filter(Boolean);
|
||||
if (learningAlts.includes(itemLearning) && referenceAlts.includes(itemReference)) {
|
||||
toDelete.push(key);
|
||||
}
|
||||
});
|
||||
if (!toDelete.length) return;
|
||||
|
||||
const next = { ...this.hardVocabMap };
|
||||
const nextMastery = { ...this.hardMasteryByKey };
|
||||
toDelete.forEach((key) => {
|
||||
delete next[key];
|
||||
delete nextMastery[key];
|
||||
});
|
||||
this.hardVocabMap = next;
|
||||
this.hardMasteryByKey = nextMastery;
|
||||
},
|
||||
markCurrentAsHard() {
|
||||
if (!this.current) return;
|
||||
this.removeHardEntriesForItem(this.current);
|
||||
const key = this.getHardKey(this.current);
|
||||
this.hardVocabMap = {
|
||||
...this.hardVocabMap,
|
||||
@@ -362,16 +417,9 @@ export default {
|
||||
},
|
||||
unmarkCurrentAsHard() {
|
||||
if (!this.current) return;
|
||||
const key = this.getHardKey(this.current);
|
||||
if (!this.hardVocabMap[key]) return;
|
||||
const next = { ...this.hardVocabMap };
|
||||
delete next[key];
|
||||
this.hardVocabMap = next;
|
||||
if (this.hardMasteryByKey[key] != null) {
|
||||
const nextMastery = { ...this.hardMasteryByKey };
|
||||
delete nextMastery[key];
|
||||
this.hardMasteryByKey = nextMastery;
|
||||
}
|
||||
const matchingKey = this.findMatchingHardKey(this.current);
|
||||
if (!matchingKey) return;
|
||||
this.removeHardEntriesForItem(this.current);
|
||||
if (this.hardPhaseActive && this.hardRemainingCount <= 0) {
|
||||
this.hardPhaseActive = false;
|
||||
}
|
||||
@@ -986,9 +1034,10 @@ export default {
|
||||
if (this.hardPhaseActive && this.current) {
|
||||
const key = this.getHardKey(this.current);
|
||||
this.hardMasteryByKey[key] = Math.max(0, Number(this.hardMasteryByKey[key]) || 0) + 1;
|
||||
if ((Number(this.hardMasteryByKey[key]) || 0) >= HARD_REQUIRED_CONSECUTIVE_CORRECT && this.hardVocabMap[key]) {
|
||||
const mapKey = this.findMatchingHardKey(this.current);
|
||||
if ((Number(this.hardMasteryByKey[key]) || 0) >= HARD_REQUIRED_CONSECUTIVE_CORRECT && mapKey) {
|
||||
const next = { ...this.hardVocabMap };
|
||||
delete next[key];
|
||||
delete next[mapKey];
|
||||
this.hardVocabMap = next;
|
||||
this.saveHardVocabMap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user