diff --git a/public/src/page-reader.js b/public/src/page-reader.js index de322b9..9b8ca00 100644 --- a/public/src/page-reader.js +++ b/public/src/page-reader.js @@ -30,8 +30,8 @@ export async function readPageWithHermes(button = null) { const processedContent = await processContentWithHermes(content); - // Get voice preference from settings (format: "model:voice", e.g., "tts-1-f5:atlas") - let voice = "atlas"; + // Get voice preference from settings (format: "model:voice", e.g., "tts-1-f5:foxhop") + let voice = "foxhop"; let model = "tts-1-f5"; try { const savedVoice = localStorage.getItem("uncloseai_selected_voice"); diff --git a/public/src/tts-modal.js b/public/src/tts-modal.js index 2ba6c03..0239eeb 100644 --- a/public/src/tts-modal.js +++ b/public/src/tts-modal.js @@ -103,7 +103,8 @@ async function populateVoiceDropdown(voiceSelection) { 'ruby', 'sage', 'sofia', 'amber', 'brooke', 'cora', 'diana', 'eden', 'faye', 'gemma', 'hope', 'ivy', 'atlas', 'caleb', 'felix', 'hugo', 'jasper', 'kai', 'leo', 'marcus', 'owen', 'theo', 'archer', 'blake', - 'cole', 'dane', 'ezra', 'finn', 'grant', 'heath', 'ivan', 'jude' + 'cole', 'dane', 'ezra', 'finn', 'grant', 'heath', 'ivan', 'jude', + 'foxhop' ]; const defaultVoices = F5_VOICES.map(voice => ({ model: 'tts-1-f5', voice })); renderVoiceOptions(voiceSelection, defaultVoices); @@ -116,10 +117,10 @@ function renderVoiceOptions(voiceSelection, voices) { voiceSelection.innerHTML = ''; // Clear existing options // Get saved voice preference (vault first, fallback to default) - let savedVoice = 'tts-1-f5:atlas'; // Default + let savedVoice = 'tts-1-f5:foxhop'; // Default try { if (typeof window !== 'undefined' && window.UncloseVault && window.UncloseVault.isUnlocked()) { - savedVoice = window.UncloseVault.get('uncloseai_selected_voice', 'tts-1-f5:atlas'); + savedVoice = window.UncloseVault.get('uncloseai_selected_voice', 'tts-1-f5:foxhop'); } } catch (error) { console.warn('Failed to read voice preference:', error); @@ -134,54 +135,47 @@ function renderVoiceOptions(voiceSelection, voices) { groupedVoices[v.model].push(v.voice); }); - // Create radio buttons grouped by model - Object.keys(groupedVoices).sort().forEach(model => { - // Add model label - const modelLabel = document.createElement('div'); - modelLabel.className = 'tts-model-label'; - modelLabel.textContent = model; - voiceSelection.appendChild(modelLabel); + // Render as a single with per model (replaces the radio grid). + Spans all tracks of the surrounding .tts-voice-container grid. */ +.tts-voice-select { + grid-column: 1 / -1; + width: 100%; + padding: 10px 12px; + font-size: 15px; + border: 1px solid #ccc; + border-radius: 6px; + background: white; + color: #333; +} + /* Speed control */ .tts-speed-control { margin: 16px 0; diff --git a/public/src/uncloseai-modal-pico.css b/public/src/uncloseai-modal-pico.css index 89f9032..adee09c 100644 --- a/public/src/uncloseai-modal-pico.css +++ b/public/src/uncloseai-modal-pico.css @@ -741,6 +741,19 @@ dialog#tts-modal { overflow-y: auto; } +/* Sticky footer holding the primary Play action */ +.tts-modal-footer { + display: grid; + place-items: center; + padding: 12px 20px; + border-top: 1px solid #e0e0e0; + background: white; +} + +dialog#tts-modal .tts-modal-footer .tts-play-btn { + margin: 0; +} + /* TTS modal article */ .tts-modal-article { display: grid; @@ -804,6 +817,19 @@ dialog#tts-modal { cursor: pointer; } +/* Single