import QtQuick 2.0 import Sailfish.Silica 1.0 Page { id: page property var voiceNames: [ "it-IT-ElsaNeural", "it-IT-DiegoNeural", "it-IT-IsabellaNeural", "it-IT-GiuseppeMultilingualNeural", "en-US-AriaNeural" ] property var engineNames: ["edge", "openai", "elevenlabs"] SilicaFlickable { anchors.fill: parent contentHeight: col.height + Theme.paddingLarge Column { id: col width: parent.width spacing: Theme.paddingMedium PageHeader { title: qsTr("Settings") } SectionHeader { text: qsTr("Server") } TextField { id: urlField width: parent.width label: qsTr("Web UI address") placeholderText: "https://hermes.example.com" inputMethodHints: Qt.ImhUrlCharactersOnly | Qt.ImhNoAutoUppercase onTextChanged: { if (text !== appSettings.baseUrl) appSettings.baseUrl = text } } SectionHeader { text: qsTr("Voice") } ComboBox { label: qsTr("Read-aloud voice") currentIndex: Math.max(0, page.voiceNames.indexOf(appSettings.ttsVoice)) // MenuItems espliciti (no Repeater: pattern non provato sul kit 5.1) menu: ContextMenu { MenuItem { text: "it-IT-ElsaNeural" onClicked: appSettings.ttsVoice = "it-IT-ElsaNeural" } MenuItem { text: "it-IT-DiegoNeural" onClicked: appSettings.ttsVoice = "it-IT-DiegoNeural" } MenuItem { text: "it-IT-IsabellaNeural" onClicked: appSettings.ttsVoice = "it-IT-IsabellaNeural" } MenuItem { text: "it-IT-GiuseppeMultilingualNeural" onClicked: appSettings.ttsVoice = "it-IT-GiuseppeMultilingualNeural" } MenuItem { text: "en-US-AriaNeural" onClicked: appSettings.ttsVoice = "en-US-AriaNeural" } } } ComboBox { label: qsTr("TTS engine") currentIndex: Math.max(0, page.engineNames.indexOf(appSettings.ttsEngine)) menu: ContextMenu { MenuItem { text: "edge" onClicked: appSettings.ttsEngine = "edge" } MenuItem { text: "openai" onClicked: appSettings.ttsEngine = "openai" } MenuItem { text: "elevenlabs" onClicked: appSettings.ttsEngine = "elevenlabs" } } } TextSwitch { text: qsTr("Read replies aloud") description: qsTr("Speak every completed reply automatically") checked: appSettings.ttsAutoRead onCheckedChanged: appSettings.ttsAutoRead = checked } SectionHeader { text: qsTr("Voice dialog") } TextSwitch { text: qsTr("Send right after dictation") description: qsTr("Send the transcribed text automatically, without tapping Send") checked: appSettings.dictationAutoSend onCheckedChanged: appSettings.dictationAutoSend = checked } ComboBox { label: qsTr("Auto-stop pause") currentIndex: { var v = appSettings.vadSilenceMs return v <= 1000 ? 0 : (v <= 1500 ? 1 : (v <= 2000 ? 2 : 3)) } menu: ContextMenu { MenuItem { text: qsTr("1.0 second"); onClicked: appSettings.vadSilenceMs = 1000 } MenuItem { text: qsTr("1.5 seconds"); onClicked: appSettings.vadSilenceMs = 1500 } MenuItem { text: qsTr("2.0 seconds"); onClicked: appSettings.vadSilenceMs = 2000 } MenuItem { text: qsTr("3.0 seconds"); onClicked: appSettings.vadSilenceMs = 3000 } } } ComboBox { label: qsTr("Mic sensitivity") currentIndex: appSettings.vadThreshold <= 500 ? 0 : (appSettings.vadThreshold <= 1000 ? 1 : 2) menu: ContextMenu { MenuItem { text: qsTr("High (even soft voices)"); onClicked: appSettings.vadThreshold = 400 } MenuItem { text: qsTr("Medium"); onClicked: appSettings.vadThreshold = 800 } MenuItem { text: qsTr("Low (noisy rooms)"); onClicked: appSettings.vadThreshold = 1600 } } } SectionHeader { text: qsTr("Account") } Button { anchors.horizontalCenter: parent.horizontalCenter text: qsTr("Sign out") onClicked: page.signOut() } SectionHeader { text: qsTr("About") } Label { x: Theme.horizontalPageMargin width: parent.width - 2 * Theme.horizontalPageMargin wrapMode: Text.WordWrap font.pixelSize: Theme.fontSizeSmall color: Theme.secondaryColor text: "harbour-hermes " + appVersion + "\n\n" + qsTr("Native client for the Hermes Web UI (hermes-webui): " + "sessions, live streaming chat, server-side voice " + "dictation and read-aloud.") } } VerticalScrollDecorator {} } function signOut() { api.logout() pageStack.replace(Qt.resolvedUrl("LoginPage.qml")) } Component.onCompleted: urlField.text = appSettings.baseUrl }