diff --git a/Dockerfile b/Dockerfile index afd23c9..e7fb019 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ RUN apt-get update && apt-get install -y \ git \ unzip \ wget \ - openjdk-17-jdk \ + openjdk-21-jdk \ build-essential \ imagemagick \ && rm -rf /var/lib/apt/lists/* @@ -50,8 +50,8 @@ RUN sdkmanager "platform-tools" \ # Imposta JAVA_HOME in base all'architettura RUN ARCH=$(dpkg --print-architecture) && \ - echo "export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-${ARCH}" >> /etc/profile && \ - ln -sf /usr/lib/jvm/java-17-openjdk-${ARCH} /usr/lib/jvm/default-java + echo "export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-${ARCH}" >> /etc/profile && \ + ln -sf /usr/lib/jvm/java-21-openjdk-${ARCH} /usr/lib/jvm/default-java ENV JAVA_HOME=/usr/lib/jvm/default-java @@ -69,10 +69,11 @@ COPY . . # Build script CMD ["bash", "-c", "\ + npm install --legacy-peer-deps && \ npm run build && \ npx cap add android && \ npx cap sync && \ - sed -i 's/android:configChanges=\"\\([^\"]*\\)\"/android:configChanges=\"\\1\" android:screenOrientation=\"landscape\"/g' android/app/src/main/AndroidManifest.xml && \ + sed -i 's/android:configChanges=\"\\([^\"]*\\)\"/android:configChanges=\"\\1\" android:screenOrientation=\"sensorLandscape\"/g' android/app/src/main/AndroidManifest.xml && \ bash setup-android-icons.sh && \ cd android && ./gradlew assembleDebug --no-daemon && \ mkdir -p /app/output && \ diff --git a/package.json b/package.json index 2953b08..b578ded 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "docker:build": "./build-apk.sh" }, "dependencies": { + "@capacitor-community/text-to-speech": "^6.0.0", "@capacitor/android": "^6.0.0", "@capacitor/app": "^6.0.0", "@capacitor/core": "^6.0.0", diff --git a/src/components/HomePage.vue b/src/components/HomePage.vue index 9bccbcd..2853e77 100644 --- a/src/components/HomePage.vue +++ b/src/components/HomePage.vue @@ -2,6 +2,7 @@ import NoSleep from "nosleep.js"; import { Capacitor } from '@capacitor/core'; import { App } from '@capacitor/app'; +import { TextToSpeech } from '@capacitor-community/text-to-speech'; export default { name: "HomePage", @@ -29,9 +30,17 @@ export default { } }, mounted() { + // Carica le voci (necessario su alcuni browser) this.voices = window.speechSynthesis.getVoices(); + + // Ascolta l'evento voiceschanged per Android/Chrome + if (speechSynthesis.onvoiceschanged !== undefined) { + speechSynthesis.onvoiceschanged = () => { + this.voices = window.speechSynthesis.getVoices(); + }; + } + if (this.isMobile()) { - this.speak(); var noSleep = new NoSleep(); noSleep.enable(); document.documentElement.requestFullscreen(); @@ -86,32 +95,64 @@ export default { this.sp.form[team].unshift(this.sp.form[team].pop()); } }, - speak() { - const msg = new SpeechSynthesisUtterance(); + async speak() { + // Prepara il testo da pronunciare + let text = ""; if (this.sp.punt.home + this.sp.punt.guest == 0) { - msg.text = "zero a zero"; + text = "zero a zero"; } else if (this.sp.punt.home == this.sp.punt.guest) { - msg.text = this.sp.punt.home + " pari"; + text = this.sp.punt.home + " pari"; } else { if (this.sp.servHome) { - msg.text = this.sp.punt.home + " a " + this.sp.punt.guest; + text = this.sp.punt.home + " a " + this.sp.punt.guest; } else { - msg.text = this.sp.punt.guest + " a " + this.sp.punt.home; + text = this.sp.punt.guest + " a " + this.sp.punt.home; } } - // msg.volume = 1.0; // speech volume (default: 1.0) - // msg.pitch = 1.0; // speech pitch (default: 1.0) - // msg.rate = 1.0; // speech rate (default: 1.0) - msg.lang = 'it_IT'; // speech language (default: 'en-US') - const voices = window.speechSynthesis.getVoices(); - msg.voice = voices.find(voice => voice.name === 'Google italiano'); // voice URI (default: platform-dependent) - // msg.onboundary = function (event) { - // console.log('Speech reached a boundary:', event.name); - // }; - // msg.onpause = function (event) { - // console.log('Speech paused:', event.utterance.text.substring(event.charIndex)); - // }; - window.speechSynthesis.speak(msg); + + console.log('Speak called, text:', text); + console.log('Is native platform:', Capacitor.isNativePlatform()); + + // Usa plugin nativo su mobile, Web API su desktop + if (Capacitor.isNativePlatform()) { + try { + console.log('Using native TTS'); + await TextToSpeech.speak({ + text: text, + lang: 'it-IT', + rate: 0.9, + pitch: 1.0, + volume: 1.0, + category: 'ambient' + }); + console.log('TTS completed successfully'); + } catch (error) { + console.error('TTS error:', error); + this.$waveui.notify('Errore TTS: ' + error.message, 'error', 3000); + } + } else { + // Fallback Web API per desktop/browser + console.log('Using web API speechSynthesis'); + window.speechSynthesis.cancel(); + + const msg = new SpeechSynthesisUtterance(); + msg.text = text; + msg.volume = 1.0; + msg.rate = 0.9; + msg.pitch = 1.0; + msg.lang = 'it-IT'; + + const voices = window.speechSynthesis.getVoices(); + const italianVoice = voices.find(voice => + voice.lang.startsWith('it') || voice.name.includes('Italian') || voice.name.includes('italiano') + ); + + if (italianVoice) { + msg.voice = italianVoice; + } + + window.speechSynthesis.speak(msg); + } }, apriDialogConfig() { this.disabilitaTastiSpeciali();