Major PWA and mobile UI improvements

- Fixed PWA installation on Android by correcting manifest.json icon configuration
- Made UI mobile-friendly with compact layout and sticky record button
- Implemented auto-translation after transcription stops
- Updated branding from 'Voice Translator' to 'Talk2Me' throughout
- Added reverse proxy support with ProxyFix middleware
- Created diagnostic tools for PWA troubleshooting
- Added proper HTTP headers for service worker and manifest
- Improved mobile CSS with responsive design
- Fixed JavaScript bundling with webpack configuration
- Updated service worker cache versioning
- Added comprehensive PWA documentation

These changes ensure the app works properly as a PWA on Android devices
and provides a better mobile user experience.
This commit is contained in:
2025-06-03 12:28:09 -06:00
parent b5f2b53262
commit d818ec7d73
16 changed files with 2813 additions and 50 deletions

View File

@@ -714,6 +714,21 @@ function initApp(): void {
language: data.detected_language || sourceLanguage.value,
timestamp: new Date().toISOString()
} as TranscriptionRecord);
// Automatically trigger translation
setTimeout(async () => {
statusIndicator.textContent = 'Automatically translating...';
statusIndicator.classList.add('processing');
try {
await performTranslation();
} catch (error) {
console.error('Auto-translation failed:', error);
statusIndicator.textContent = 'Transcription complete - Translation failed';
statusIndicator.classList.remove('processing');
statusIndicator.classList.add('warning');
setTimeout(() => statusIndicator.classList.remove('warning'), 2000);
}
}, 500); // Small delay for better UX
} else {
sourceText.innerHTML = `<p class="text-danger fade-in">Error: ${data.error}</p>`;
statusIndicator.textContent = 'Transcription failed';
@@ -756,8 +771,8 @@ function initApp(): void {
}
);
// Translate button click event
translateBtn.addEventListener('click', errorBoundary.wrapAsync(async function() {
// Function to perform translation (extracted from button handler)
const performTranslation = async function(): Promise<void> {
if (!currentSourceText) {
return;
}
@@ -794,7 +809,10 @@ function initApp(): void {
}
// No cache hit, proceed with API call
statusIndicator.textContent = 'Translating...';
// Don't update status if already showing 'Automatically translating...'
if (!statusIndicator.textContent?.includes('Automatically translating')) {
statusIndicator.textContent = 'Translating...';
}
// Use streaming if enabled
if (streamingEnabled && navigator.onLine) {
@@ -992,12 +1010,19 @@ function initApp(): void {
statusIndicator.textContent = 'Translation failed';
}
}
}, 'translation', async () => {
hideProgress();
hideLoadingOverlay();
translatedText.innerHTML = '<p class="text-danger">Translation failed. Please try again.</p>';
statusIndicator.textContent = 'Translation error - please retry';
}));
};
// Translate button click event (now just calls performTranslation)
translateBtn.addEventListener('click', errorBoundary.wrapAsync(
performTranslation,
'translation',
async () => {
hideProgress();
hideLoadingOverlay();
translatedText.innerHTML = '<p class="text-danger">Translation failed. Please try again.</p>';
statusIndicator.textContent = 'Translation error - please retry';
}
));
// Play source text
playSource.addEventListener('click', function() {
@@ -1398,7 +1423,7 @@ function initInstallPrompt(): void {
const installButton = document.createElement('button');
installButton.style.display = 'none';
installButton.classList.add('btn', 'btn-success', 'fixed-bottom', 'm-3');
installButton.innerHTML = 'Install Voice Translator <i class="fas fa-download ml-2"></i>';
installButton.innerHTML = 'Install Talk2Me <i class="fas fa-download ml-2"></i>';
document.body.appendChild(installButton);
window.addEventListener('beforeinstallprompt', (e: Event) => {