feat(reader): multi-word and phrasal verb detector in reader (Task 14)
This commit is contained in:
1 parent
37a1f1ab35
commit
1c3f03a64c
9 files changed
+738
-16
No files matched your search
@@ -1160,6 +1160,17 @@ export async function openWordPopup(term, contextSentence, targetElement) {
|
||||
const popupContextMeaningVal = document.getElementById('popup-context-meaning-val');
|
||||
const popupSentenceAiBar = document.querySelector('.popup-sentence-ai-bar');
|
||||
|
||||
const popupPhrasalCard = document.getElementById('popup-phrasal-card');
|
||||
const popupPhrasalTerm = document.getElementById('popup-phrasal-term');
|
||||
const popupPhrasalRaw = document.getElementById('popup-phrasal-raw');
|
||||
const popupPhrasalTranslation = document.getElementById('popup-phrasal-translation');
|
||||
const popupPhrasalLibraryBadge = document.getElementById('popup-phrasal-library-badge');
|
||||
const popupSwitchPhrasalBtn = document.getElementById('popup-switch-phrasal-btn');
|
||||
|
||||
if (popupPhrasalCard) popupPhrasalCard.classList.add('hidden');
|
||||
popupCurrentData.phrasalVerb = null;
|
||||
popupCurrentData.isPhrasalMode = false;
|
||||
|
||||
if (popupSentenceLoading) popupSentenceLoading.classList.add('hidden');
|
||||
if (popupSentenceTranslationWrap) popupSentenceTranslationWrap.classList.add('hidden');
|
||||
if (popupSentenceRu) popupSentenceRu.textContent = '';
|
||||
@@ -1202,9 +1213,27 @@ export async function openWordPopup(term, contextSentence, targetElement) {
|
||||
positionWordPopup(targetElement);
|
||||
|
||||
try {
|
||||
const data = await api.lookup.search(cleanTerm);
|
||||
const data = await api.lookup.search(cleanTerm, contextSentence);
|
||||
popupCurrentData.lookup = data;
|
||||
|
||||
// Phrasal verb detection
|
||||
if (data.phrasal_verb) {
|
||||
const pv = data.phrasal_verb;
|
||||
popupCurrentData.phrasalVerb = pv;
|
||||
if (popupPhrasalCard) {
|
||||
popupPhrasalCard.classList.remove('hidden');
|
||||
if (popupPhrasalTerm) popupPhrasalTerm.textContent = pv.term;
|
||||
if (popupPhrasalRaw) popupPhrasalRaw.textContent = `(в тексте: «${pv.raw}»)`;
|
||||
if (popupPhrasalTranslation) popupPhrasalTranslation.textContent = pv.translation;
|
||||
if (popupPhrasalLibraryBadge) popupPhrasalLibraryBadge.classList.toggle('hidden', !pv.in_library);
|
||||
if (popupSwitchPhrasalBtn) {
|
||||
popupSwitchPhrasalBtn.textContent = `🔗 Переключить на «${pv.term}»`;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (popupPhrasalCard) popupPhrasalCard.classList.add('hidden');
|
||||
}
|
||||
|
||||
const trans = data.translation || data.translation_ru || (data.translations_list && data.translations_list.length > 0 ? data.translations_list.join(', ') : '');
|
||||
if (popupPhonetic) popupPhonetic.textContent = data.phonetic || '';
|
||||
if (popupTranslation) popupTranslation.textContent = trans || 'Перевод не найден';
|
||||
@@ -1924,23 +1953,81 @@ export function initReader() {
|
||||
});
|
||||
}
|
||||
|
||||
const popupSwitchPhrasalBtn = document.getElementById('popup-switch-phrasal-btn');
|
||||
if (popupSwitchPhrasalBtn) {
|
||||
popupSwitchPhrasalBtn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
if (!popupCurrentData || !popupCurrentData.phrasalVerb) return;
|
||||
const pv = popupCurrentData.phrasalVerb;
|
||||
|
||||
if (!popupCurrentData.isPhrasalMode) {
|
||||
// Switch to phrasal verb mode
|
||||
popupCurrentData.isPhrasalMode = true;
|
||||
if (popupTerm) popupTerm.textContent = pv.term;
|
||||
if (popupTranslation) popupTranslation.textContent = pv.translation;
|
||||
if (popupPhonetic) popupPhonetic.textContent = '';
|
||||
|
||||
const inLib = Boolean(pv.in_library);
|
||||
if (popupInLibrary) popupInLibrary.classList.toggle('hidden', !inLib);
|
||||
if (popupSaveBtn) {
|
||||
popupSaveBtn.classList.toggle('hidden', inLib);
|
||||
popupSaveBtn.textContent = `💾 Сохранить «${pv.term}» в словарь`;
|
||||
}
|
||||
if (popupSavedBadge) {
|
||||
popupSavedBadge.classList.toggle('hidden', !inLib);
|
||||
popupSavedBadge.textContent = '⭐ Фразовый глагол уже в библиотеке';
|
||||
}
|
||||
if (popupAddContextBtn) popupAddContextBtn.classList.add('hidden');
|
||||
popupSwitchPhrasalBtn.textContent = `↩️ Вернуться к «${popupCurrentData.term}»`;
|
||||
} else {
|
||||
// Revert back to single word
|
||||
popupCurrentData.isPhrasalMode = false;
|
||||
const origTrans = popupCurrentData.lookup ? (popupCurrentData.lookup.translation || popupCurrentData.lookup.translation_ru || '') : '';
|
||||
|
||||
if (popupTerm) popupTerm.textContent = popupCurrentData.term;
|
||||
if (popupTranslation) popupTranslation.textContent = origTrans;
|
||||
if (popupPhonetic) popupPhonetic.textContent = popupCurrentData.lookup?.phonetic || '';
|
||||
|
||||
const inLib = Boolean(popupCurrentData.lookup?.in_library || popupCurrentData.existingCard);
|
||||
if (popupInLibrary) popupInLibrary.classList.toggle('hidden', !inLib);
|
||||
if (popupSaveBtn) {
|
||||
popupSaveBtn.classList.toggle('hidden', inLib);
|
||||
popupSaveBtn.textContent = '💾 Добавить в словарь';
|
||||
}
|
||||
if (popupSavedBadge) {
|
||||
popupSavedBadge.classList.toggle('hidden', !inLib);
|
||||
popupSavedBadge.textContent = '⭐ Слово уже в библиотеке';
|
||||
}
|
||||
popupSwitchPhrasalBtn.textContent = `🔗 Переключить на «${pv.term}»`;
|
||||
}
|
||||
positionWordPopup(popupCurrentData.targetElement);
|
||||
});
|
||||
}
|
||||
|
||||
if (popupSaveBtn) {
|
||||
popupSaveBtn.addEventListener('click', async () => {
|
||||
if (!popupCurrentData) return;
|
||||
const d = popupCurrentData;
|
||||
const lookup = d.lookup || {};
|
||||
const bookTag = currentBook ? slugify(currentBook.title) : 'reader';
|
||||
const isPv = Boolean(d.isPhrasalMode && d.phrasalVerb);
|
||||
const termToSave = isPv ? d.phrasalVerb.term : d.term;
|
||||
const transToSave = isPv
|
||||
? d.phrasalVerb.translation
|
||||
: (lookup.translation || lookup.translation_ru || (popupTranslation ? popupTranslation.textContent : ''));
|
||||
const collectionToSave = isPv ? 'Фразовые глаголы & Идиомы' : 'Книги & Сериалы';
|
||||
const tagsToSave = isPv ? `${bookTag}, phrasal-verbs, reader` : `${bookTag}, reader`;
|
||||
|
||||
const payload = {
|
||||
term: d.term,
|
||||
translation: lookup.translation || lookup.translation_ru || (popupTranslation ? popupTranslation.textContent : ''),
|
||||
term: termToSave,
|
||||
translation: transToSave,
|
||||
context_sentence: d.contextSentence || '',
|
||||
phonetic: lookup.phonetic || '',
|
||||
audio_url: lookup.audio_url || '',
|
||||
part_of_speech: lookup.part_of_speech || '',
|
||||
phonetic: isPv ? '' : (lookup.phonetic || ''),
|
||||
audio_url: isPv ? '' : (lookup.audio_url || ''),
|
||||
part_of_speech: isPv ? 'verb phrase' : (lookup.part_of_speech || ''),
|
||||
definition_en: lookup.definition_en || '',
|
||||
collection: 'Книги & Сериалы',
|
||||
tags: `${bookTag}, reader`,
|
||||
collection: collectionToSave,
|
||||
tags: tagsToSave,
|
||||
notes: currentBook ? `Из книги: ${currentBook.title}` : '',
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user