Load text through url

This commit is contained in:
2025-07-01 16:17:57 +10:00
parent dbf8641a71
commit dd960ef58c
+189 -1
View File
@@ -331,6 +331,52 @@
border-color: #9ca3af;
}
/* Loading overlay styles */
.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(4px);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 9999;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s ease, visibility 0.3s ease;
}
.loading-overlay.show {
opacity: 1;
visibility: visible;
}
.loading-spinner {
width: 60px;
height: 60px;
border: 4px solid #e5e7eb;
border-top: 4px solid #8e44ad;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 1rem;
}
.loading-text {
color: #374151;
font-size: 1.125rem;
font-weight: 600;
text-align: center;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@media (max-width: 768px) {
.tts-container {
padding: 1rem;
@@ -354,6 +400,15 @@
{% endblock %}
{% block content %}
<!-- Loading Overlay -->
<div id="loading-overlay" class="loading-overlay">
<div class="loading-spinner"></div>
<div class="loading-text">
<div id="loading-message">{% trans "Preparing Text-to-Speech..." %}</div>
<div class="text-sm text-gray-500 mt-2">{% trans "Please wait while we process your text" %}</div>
</div>
</div>
<div class="tts-container">
<!-- Header -->
<div class="tts-header">
@@ -777,7 +832,140 @@ function downloadAudio() {
// Auto-focus on text input when page loads
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('text-input').focus();
const textInput = document.getElementById('text-input');
// Check for URL parameters
const urlParams = new URLSearchParams(window.location.search);
const textParam = urlParams.get('text');
if (textParam) {
// Show loading overlay
showLoadingOverlay();
// Decode and set the text
const decodedText = decodeURIComponent(textParam);
textInput.value = decodedText;
textInput.dispatchEvent(new Event('input')); // Update character counter
// Auto-generate TTS after a short delay to ensure UI is ready
setTimeout(() => {
updateLoadingMessage('{% trans "Generating speech audio..." %}');
generateSpeechFromURL();
}, 500);
} else {
// Normal behavior - just focus the input
textInput.focus();
}
});
function showLoadingOverlay() {
const overlay = document.getElementById('loading-overlay');
overlay.classList.add('show');
}
function hideLoadingOverlay() {
const overlay = document.getElementById('loading-overlay');
overlay.classList.remove('show');
}
function updateLoadingMessage(message) {
const loadingMessage = document.getElementById('loading-message');
loadingMessage.textContent = message;
}
function generateSpeechFromURL() {
const textInput = document.getElementById('text-input');
const text = textInput.value.trim();
if (!text) {
hideLoadingOverlay();
alert('{% trans "No text found in URL parameter." %}');
return;
}
// Use the existing generateSpeech logic but with URL-specific handling
if (isLoading) return;
isLoading = true;
const speakBtn = document.getElementById('speak-btn');
const audioPlayer = document.getElementById('audio-player');
const status = document.getElementById('audio-status');
const playBtn = document.getElementById('play-pause-btn');
// Show audio player and update status (but keep loading overlay)
audioPlayer.style.display = 'block';
status.textContent = '{% trans "Generating..." %}';
status.className = 'audio-status status-generating';
speakBtn.disabled = true;
speakBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i>{% trans "Generating..." %}';
playBtn.disabled = true;
fetch('{% url "tts-api" %}', {
method: 'POST',
headers: {
'X-CSRFToken': '{{ csrf_token }}',
'Content-Type': 'application/json',
},
body: JSON.stringify({
text: text
})
})
.then(response => {
if (!response.ok) {
throw new Error('TTS generation failed');
}
return response.blob();
})
.then(blob => {
// Store the blob for download functionality
currentAudioBlob = blob;
const audioUrl = URL.createObjectURL(blob);
const audio = document.getElementById('tts-audio');
audio.src = audioUrl;
currentAudio = audio;
audio.addEventListener('loadedmetadata', function() {
status.textContent = '{% trans "Ready" %}';
status.className = 'audio-status status-ready';
playBtn.disabled = false;
document.getElementById('download-btn').disabled = false;
updateTotalTime();
setupAudioEvents();
// Hide loading overlay - audio is ready
updateLoadingMessage('{% trans "Audio ready! Click play to start..." %}');
setTimeout(() => {
hideLoadingOverlay();
}, 500);
});
audio.addEventListener('error', function() {
status.textContent = '{% trans "Error" %}';
status.className = 'audio-status status-error';
playBtn.disabled = true;
document.getElementById('download-btn').disabled = true;
hideLoadingOverlay();
alert('{% trans "Failed to generate audio. Please try again." %}');
});
audio.load();
})
.catch(error => {
console.error('TTS Error:', error);
status.textContent = '{% trans "Failed" %}';
status.className = 'audio-status status-error';
playBtn.disabled = true;
document.getElementById('download-btn').disabled = true;
hideLoadingOverlay();
alert('{% trans "Failed to generate audio. Please try again." %}');
})
.finally(() => {
isLoading = false;
speakBtn.disabled = false;
speakBtn.innerHTML = '<i class="fas fa-volume-up mr-2"></i>{% trans "Speak" %}';
});
}
</script>
{% endblock %}