diff --git a/typing.css b/typing.css index 504606d..07c1277 100644 --- a/typing.css +++ b/typing.css @@ -94,6 +94,12 @@ gap: 0.5rem; margin-left: auto; } +#btn-typing-speak { + width: 36px; + padding-left: 0; + padding-right: 0; + text-align: center; +} .type-toolbar button { background: none; border: 1px solid var(--border); diff --git a/typing.html b/typing.html index b7f1f07..654d242 100644 --- a/typing.html +++ b/typing.html @@ -53,6 +53,7 @@
diff --git a/typing.js b/typing.js index 54d3528..3dc408d 100644 --- a/typing.js +++ b/typing.js @@ -6,6 +6,7 @@ var typed = ''; var typingStartedAt = 0; var typingFinished = false; var typingSession = { mode: '', categoryId: '', categoryName: '', itemCount: 0 }; +var typingSelectionTimer = null; var KEY_ROWS = [ [ @@ -195,6 +196,7 @@ function renderPractice() { } var item = typingItems[typingIndex]; var target = item.es; + speakText(item.es, 'es'); var targetHtml = ''; for (var i = 0; i < target.length; i++) { var ch = escTyping(target[i]); @@ -312,6 +314,35 @@ function showSetupView() { loadTypingLogs(); } +function readCurrentTarget() { + var item = typingItems[typingIndex]; + if (item && item.es) speakText(item.es, 'es'); +} + +function getTypingSelectedSpanish() { + var input = document.getElementById('typing-input'); + if (document.activeElement === input && input.selectionStart !== input.selectionEnd) { + return input.value.substring(input.selectionStart, input.selectionEnd).trim(); + } + var selection = window.getSelection(); + if (!selection || selection.isCollapsed || !selection.toString().trim()) return ''; + var node = selection.anchorNode; + var container = node && node.nodeType === 3 ? node.parentNode : node; + var target = document.getElementById('target-text'); + return container && target && target.contains(container) + ? selection.toString().trim() + : ''; +} + +function handleTypingSelection() { + var text = getTypingSelectedSpanish(); + if (!text || !typingItems[typingIndex]) return; + if (typingSelectionTimer) clearTimeout(typingSelectionTimer); + typingSelectionTimer = setTimeout(function() { + speakText(text, 'es'); + }, 150); +} + function renderKeyboard(target) { var next = target[typed.length] || ''; var press = keyPressForChar(next); @@ -422,7 +453,17 @@ document.getElementById('btn-start').addEventListener('click', startTyping); document.getElementById('btn-restart').addEventListener('click', startTyping); document.getElementById('btn-choose').addEventListener('click', showSetupView); document.getElementById('btn-refresh-records').addEventListener('click', loadTypingLogs); +document.getElementById('btn-typing-speak').addEventListener('click', readCurrentTarget); document.getElementById('typing-input').addEventListener('input', handleTypingInput); +document.getElementById('typing-input').addEventListener('mouseup', handleTypingSelection); +document.getElementById('typing-input').addEventListener('keyup', handleTypingSelection); +document.addEventListener('selectionchange', handleTypingSelection); +document.addEventListener('keydown', function(e) { + if (e.key === 'F6') { + e.preventDefault(); + readCurrentTarget(); + } +}); renderCategories(); loadTypingLogs();