feat: 增加中译西辅助、在线翻译、B1词库与三语语音对照
This commit is contained in:
@@ -229,6 +229,106 @@ function saveTextareaSelection() {
|
||||
savedSelEnd = ta.selectionEnd;
|
||||
}
|
||||
|
||||
// ----- Chinese to Spanish helper -----
|
||||
|
||||
var helperDebounceTimer = null;
|
||||
var helperRequestSeq = 0;
|
||||
var helperOnlineResult = '';
|
||||
|
||||
function openHelperModal() {
|
||||
var ta = document.getElementById('entry-text');
|
||||
savedSelStart = ta.selectionStart;
|
||||
savedSelEnd = ta.selectionEnd;
|
||||
helperOnlineResult = '';
|
||||
if (helperDebounceTimer) clearTimeout(helperDebounceTimer);
|
||||
document.getElementById('helper-input').value = '';
|
||||
document.getElementById('helper-result').textContent = '';
|
||||
document.getElementById('helper-confirm').disabled = true;
|
||||
document.getElementById('helper-modal-overlay').classList.add('show');
|
||||
setTimeout(function() { document.getElementById('helper-input').focus(); }, 0);
|
||||
}
|
||||
|
||||
function closeHelperModal() {
|
||||
if (helperDebounceTimer) clearTimeout(helperDebounceTimer);
|
||||
helperRequestSeq++;
|
||||
document.getElementById('helper-modal-overlay').classList.remove('show');
|
||||
}
|
||||
|
||||
function updateHelperPreview() {
|
||||
var zh = document.getElementById('helper-input').value;
|
||||
helperOnlineResult = '';
|
||||
if (helperDebounceTimer) clearTimeout(helperDebounceTimer);
|
||||
if (!zh.trim()) {
|
||||
document.getElementById('helper-result').textContent = '';
|
||||
document.getElementById('helper-confirm').disabled = true;
|
||||
return;
|
||||
}
|
||||
var local = translateZhToEs(zh);
|
||||
document.getElementById('helper-result').textContent = local || '本地词典未收录,正在尝试在线翻译...';
|
||||
document.getElementById('helper-confirm').disabled = !local;
|
||||
helperDebounceTimer = setTimeout(function() {
|
||||
translateZhOnline(zh);
|
||||
}, 600);
|
||||
}
|
||||
|
||||
function translateZhOnline(zh) {
|
||||
var seq = ++helperRequestSeq;
|
||||
var url = 'https://api.mymemory.translated.net/get?q=' +
|
||||
encodeURIComponent(zh) + '&langpair=zh-CN|es';
|
||||
fetch(url)
|
||||
.then(function(res) { return res.json(); })
|
||||
.then(function(data) {
|
||||
if (seq !== helperRequestSeq) return;
|
||||
var text = data && data.responseData && data.responseData.translatedText;
|
||||
if (text && !data.quotaFinished) {
|
||||
helperOnlineResult = text.trim();
|
||||
document.getElementById('helper-result').textContent = helperOnlineResult;
|
||||
document.getElementById('helper-confirm').disabled = false;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
if (seq !== helperRequestSeq) return;
|
||||
var local = translateZhToEs(zh);
|
||||
if (local) {
|
||||
document.getElementById('helper-result').textContent = local;
|
||||
document.getElementById('helper-confirm').disabled = false;
|
||||
} else {
|
||||
document.getElementById('helper-result').textContent = '在线翻译暂不可用,且本地词典未收录';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getHelperResult() {
|
||||
if (helperOnlineResult) return helperOnlineResult;
|
||||
return translateZhToEs(document.getElementById('helper-input').value);
|
||||
}
|
||||
|
||||
function insertSpanishAtCursor(es) {
|
||||
var ta = document.getElementById('entry-text');
|
||||
var start = savedSelStart || ta.selectionStart;
|
||||
var end = savedSelEnd || ta.selectionEnd;
|
||||
var before = ta.value.slice(0, start);
|
||||
var after = ta.value.slice(end);
|
||||
var prefix = '';
|
||||
var suffix = '';
|
||||
if (before.length > 0 && !/\s$/.test(before)) prefix = ' ';
|
||||
if (after.length > 0 && !/^\s/.test(after)) suffix = ' ';
|
||||
var insert = prefix + es + suffix;
|
||||
var newPos = start + insert.length;
|
||||
ta.value = before + insert + after;
|
||||
ta.focus();
|
||||
ta.setSelectionRange(newPos, newPos);
|
||||
savedSelStart = savedSelEnd = newPos;
|
||||
updateLiveTranslation();
|
||||
}
|
||||
|
||||
function confirmHelperInsert() {
|
||||
var es = getHelperResult();
|
||||
if (!es) return;
|
||||
insertSpanishAtCursor(es);
|
||||
closeHelperModal();
|
||||
}
|
||||
|
||||
// ----- Speech handler -----
|
||||
|
||||
function handleSpeech(lang) {
|
||||
@@ -260,6 +360,10 @@ function init() {
|
||||
|
||||
document.getElementById('btn-new').addEventListener('click', newEntry);
|
||||
document.getElementById('btn-save').addEventListener('click', saveCurrentEntry);
|
||||
document.getElementById('btn-helper').addEventListener('click', openHelperModal);
|
||||
document.getElementById('helper-cancel').addEventListener('click', closeHelperModal);
|
||||
document.getElementById('helper-confirm').addEventListener('click', confirmHelperInsert);
|
||||
document.getElementById('helper-input').addEventListener('input', updateHelperPreview);
|
||||
|
||||
document.querySelectorAll('.btn-speech').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() { handleSpeech(btn.dataset.lang); });
|
||||
|
||||
Reference in New Issue
Block a user