Skip to content

Commit d6a88b7

Browse files
committed
Merge upstream/main into kiosk-pr1-core
2 parents 7a2cceb + 1bd05c0 commit d6a88b7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+465
-89
lines changed

Sources/App/Assist/Local/TTSVoicePickerView.swift

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import SwiftUI
66
struct TTSVoicePickerView: View {
77
@Binding var selectedVoiceIdentifier: String?
88
@Environment(\.dismiss) private var dismiss
9+
@State private var searchTerm = ""
10+
@State private var voiceGroups: [VoiceGroup]
911

1012
private struct VoiceGroup: Identifiable {
1113
let language: String
@@ -14,17 +16,37 @@ struct TTSVoicePickerView: View {
1416
var id: String { language }
1517
}
1618

17-
private var voiceGroups: [VoiceGroup] {
18-
let grouped = Dictionary(grouping: AVSpeechSynthesisVoice.speechVoices()) { $0.language }
19-
return grouped
20-
.map { language, voices in
21-
VoiceGroup(
22-
language: language,
23-
displayName: Locale.current.localizedString(forIdentifier: language) ?? language,
24-
voices: voices.sorted { $0.name < $1.name }
25-
)
19+
init(selectedVoiceIdentifier: Binding<String?>) {
20+
self._selectedVoiceIdentifier = selectedVoiceIdentifier
21+
self._voiceGroups = State(initialValue: Self.makeVoiceGroups())
22+
}
23+
24+
private var filteredVoiceGroups: [VoiceGroup] {
25+
let trimmedSearchTerm = searchTerm.trimmingCharacters(in: .whitespacesAndNewlines)
26+
guard !trimmedSearchTerm.isEmpty else {
27+
return voiceGroups
28+
}
29+
30+
return voiceGroups.compactMap { group in
31+
if group.displayName.localizedCaseInsensitiveContains(trimmedSearchTerm) {
32+
return group
2633
}
27-
.sorted { $0.displayName < $1.displayName }
34+
35+
let matchingVoices = group.voices.filter { voice in
36+
voice.name.localizedCaseInsensitiveContains(trimmedSearchTerm)
37+
|| qualityLabel(for: voice)?.localizedCaseInsensitiveContains(trimmedSearchTerm) == true
38+
}
39+
40+
guard !matchingVoices.isEmpty else {
41+
return nil
42+
}
43+
44+
return VoiceGroup(
45+
language: group.language,
46+
displayName: group.displayName,
47+
voices: matchingVoices
48+
)
49+
}
2850
}
2951

3052
var body: some View {
@@ -46,7 +68,7 @@ struct TTSVoicePickerView: View {
4668
}
4769
}
4870

49-
ForEach(voiceGroups) { group in
71+
ForEach(filteredVoiceGroups) { group in
5072
Section(group.displayName.capitalizedFirst) {
5173
ForEach(group.voices, id: \.identifier) { voice in
5274
Button {
@@ -74,6 +96,7 @@ struct TTSVoicePickerView: View {
7496
}
7597
}
7698
}
99+
.searchable(text: $searchTerm)
77100
.navigationTitle(L10n.Assist.Settings.OnDeviceTts.voice)
78101
.navigationBarTitleDisplayMode(.inline)
79102
}
@@ -85,4 +108,17 @@ struct TTSVoicePickerView: View {
85108
default: return nil
86109
}
87110
}
111+
112+
private static func makeVoiceGroups() -> [VoiceGroup] {
113+
let grouped = Dictionary(grouping: AVSpeechSynthesisVoice.speechVoices()) { $0.language }
114+
return grouped
115+
.map { language, voices in
116+
VoiceGroup(
117+
language: language,
118+
displayName: Locale.current.localizedString(forIdentifier: language) ?? language,
119+
voices: voices.sorted { $0.name < $1.name }
120+
)
121+
}
122+
.sorted { $0.displayName < $1.displayName }
123+
}
88124
}

Sources/App/Frontend/ExternalMessageBus/EntityAddToHandler.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ final class EntityAddToHandler {
5151
#endif
5252

5353
// Widgets are available on all platforms
54-
actions.append(CustomWidgetAction())
54+
if let domain, HAAppUsedContent.domains.contains(domain) {
55+
actions.append(CustomWidgetAction())
56+
}
5557

5658
seal.fulfill(actions)
5759
}

Sources/App/Resources/bg.lproj/Localizable.strings

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,16 @@
127127
"assist.settings.modern_ui.theme.label" = "Theme";
128128
"assist.settings.modern_ui.toggle" = "Experimental UI";
129129
"assist.settings.on_device_stt.footer" = "Use Apple's on-device speech recognition for improved privacy. Your voice will be processed locally and transcribed to text before being sent to your server. Not all languages are supported.";
130+
"assist.settings.on_device_stt.language" = "Language";
131+
"assist.settings.on_device_stt.title" = "On-device STT";
130132
"assist.settings.on_device_stt.toggle" = "Enable on-device Speech-to-Text";
133+
"assist.settings.on_device_tts.default_voice" = "Default";
134+
"assist.settings.on_device_tts.footer" = "Use Apple's on-device speech synthesis for improved privacy. Text responses will be spoken locally without sending audio data to your server.";
135+
"assist.settings.on_device_tts.quality.enhanced" = "Enhanced";
136+
"assist.settings.on_device_tts.quality.premium" = "Premium";
137+
"assist.settings.on_device_tts.title" = "On-device TTS";
138+
"assist.settings.on_device_tts.voice" = "Voice";
139+
"assist.settings.section.experimental.title" = "Experimental";
131140
"assist.settings.title" = "Assist Settings";
132141
"assist.settings.tts_mute.footer" = "When enabled, Assist will not play audio responses even if the pipeline has text-to-speech configured. You will still see text responses.";
133142
"assist.settings.tts_mute.toggle" = "Mute voice responses";

Sources/App/Resources/ca-ES.lproj/Localizable.strings

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,16 @@
127127
"assist.settings.modern_ui.theme.label" = "Tema";
128128
"assist.settings.modern_ui.toggle" = "Interfície Experimental";
129129
"assist.settings.on_device_stt.footer" = "Fes servir el reconeixement de veu integrat al dispositiu d'Apple per millorar la privadesa. La teva veu es processarà localment i es transcriurà a text abans d'enviar-se al teu servidor. No tots els idiomes són compatibles.";
130+
"assist.settings.on_device_stt.language" = "Language";
131+
"assist.settings.on_device_stt.title" = "On-device STT";
130132
"assist.settings.on_device_stt.toggle" = "Activa la conversió de veu a text al dispositiu";
133+
"assist.settings.on_device_tts.default_voice" = "Default";
134+
"assist.settings.on_device_tts.footer" = "Use Apple's on-device speech synthesis for improved privacy. Text responses will be spoken locally without sending audio data to your server.";
135+
"assist.settings.on_device_tts.quality.enhanced" = "Enhanced";
136+
"assist.settings.on_device_tts.quality.premium" = "Premium";
137+
"assist.settings.on_device_tts.title" = "On-device TTS";
138+
"assist.settings.on_device_tts.voice" = "Voice";
139+
"assist.settings.section.experimental.title" = "Experimental";
131140
"assist.settings.title" = "Configuració d'assistència";
132141
"assist.settings.tts_mute.footer" = "When enabled, Assist will not play audio responses even if the pipeline has text-to-speech configured. You will still see text responses.";
133142
"assist.settings.tts_mute.toggle" = "Mute voice responses";
@@ -271,14 +280,14 @@
271280
"connection_security_level_block.title" = "You're disconnected";
272281
"connectivity.check.dns" = "DNS Resolution";
273282
"connectivity.check.dns.description" = "Resolving hostname to IP address";
274-
"connectivity.check.port" = "Port Reachability";
275-
"connectivity.check.port.description" = "Checking if port is reachable";
276-
"connectivity.check.running" = "Checking...";
283+
"connectivity.check.port" = "Accessibilitat del port";
284+
"connectivity.check.port.description" = "Comprovant si el port és accessible";
285+
"connectivity.check.running" = "Comprovant...";
277286
"connectivity.check.server" = "Server Connection";
278-
"connectivity.check.server.description" = "Testing server connection";
287+
"connectivity.check.server.description" = "Comprovant la connexió amb el servidor";
279288
"connectivity.check.skipped" = "Skipped due to previous failure";
280-
"connectivity.check.tls" = "TLS Certificate";
281-
"connectivity.check.tls.description" = "Validating TLS certificate";
289+
"connectivity.check.tls" = "Certificat TLS";
290+
"connectivity.check.tls.description" = "Validant el certificat TLS";
282291
"connectivity.diagnostics.run_checks" = "Run checks";
283292
"connectivity.diagnostics.start" = "Start diagnostics";
284293
"connectivity.diagnostics.title" = "Connectivity diagnostics";
@@ -305,7 +314,7 @@
305314
"entity_picker.filter.domain.all.title" = "All domains";
306315
"entity_picker.filter.domain.title" = "Domain";
307316
"entity_picker.filter.group_by.title" = "Group by";
308-
"entity_picker.filter.server.title" = "Servers";
317+
"entity_picker.filter.server.title" = "Servidors";
309318
"entity_picker.list.area.no_area.title" = "No area";
310319
"entity_picker.placeholder" = "Pick entity";
311320
"entity_picker.search.placeholder" = "Entity name, ID, area name, device name...";
@@ -562,7 +571,7 @@ Les etiquetes funcionaran en qualsevol dispositiu amb Home Assistant instal·lat
562571
"notifications_configurator.settings.header" = "Configuració";
563572
"ok_label" = "D'acord";
564573
"onboarding.client_certificate.description" = "This server requires a client certificate (mTLS) for authentication. Please import your certificate file (.p12 or .pfx).";
565-
"onboarding.client_certificate.error.file_access" = "Unable to access the selected file";
574+
"onboarding.client_certificate.error.file_access" = "No s'ha pogut accedir al fitxer seleccionat";
566575
"onboarding.client_certificate.password_prompt.import_button" = "Import";
567576
"onboarding.client_certificate.password_prompt.message" = "Enter the password for this certificate";
568577
"onboarding.client_certificate.password_prompt.placeholder" = "Password";
@@ -719,16 +728,16 @@ Home Assistant is open source, advocates for privacy and runs locally in your ho
719728
"settings.connection_section.client_certificate.footer" = "Import a PKCS#12 (.p12) certificate for mutual TLS authentication. Required when your Home Assistant server requires client certificates.";
720729
"settings.connection_section.client_certificate.header" = "Client Certificate";
721730
"settings.connection_section.client_certificate.import" = "Import Certificate";
722-
"settings.connection_section.client_certificate.import_error.title" = "Import Failed";
731+
"settings.connection_section.client_certificate.import_error.title" = "Importació Fallida";
723732
"settings.connection_section.client_certificate.importing" = "Importing...";
724-
"settings.connection_section.client_certificate.password_prompt.import_button" = "Import";
733+
"settings.connection_section.client_certificate.password_prompt.import_button" = "Importa";
725734
"settings.connection_section.client_certificate.password_prompt.message" = "Enter the password for the certificate file";
726-
"settings.connection_section.client_certificate.password_prompt.placeholder" = "Password";
735+
"settings.connection_section.client_certificate.password_prompt.placeholder" = "Contrasenya";
727736
"settings.connection_section.client_certificate.password_prompt.title" = "Certificate Password";
728737
"settings.connection_section.client_certificate.remove" = "Remove Certificate";
729738
"settings.connection_section.client_certificate.remove_confirmation.message" = "The certificate will be removed from the device. You will need to import it again to use mTLS authentication.";
730739
"settings.connection_section.client_certificate.remove_confirmation.remove" = "Remove";
731-
"settings.connection_section.client_certificate.remove_confirmation.title" = "Remove Certificate?";
740+
"settings.connection_section.client_certificate.remove_confirmation.title" = "Eliminar Certificat?";
732741
"settings.connection_section.cloud_overrides_external" = "Quan es connecti mitjançant el núvol, no s’utilitzarà la URL externa. No cal configurar-ne una tret que vulgueu desactivar el núvol.";
733742
"settings.connection_section.connecting_via" = "Connectat a través de";
734743
"settings.connection_section.connection_access_security_level.less_secure.title" = "Less secure";
@@ -768,7 +777,7 @@ Home Assistant is open source, advocates for privacy and runs locally in your ho
768777
"settings.connection_section.location_send_type.title" = "Ubicació enviada";
769778
"settings.connection_section.logged_in_as" = "Sessió iniciada com";
770779
"settings.connection_section.no_base_url.title" = "No URL";
771-
"settings.connection_section.refresh_server" = "Update server information";
780+
"settings.connection_section.refresh_server" = "Actualitza la informació del servidor";
772781
"settings.connection_section.remote_ui_url.title" = "URL UI Remota";
773782
"settings.connection_section.sensor_send_type.setting.all" = "Tot";
774783
"settings.connection_section.sensor_send_type.setting.none" = "Cap";
@@ -1499,7 +1508,7 @@ Home Assistant is open source, advocates for privacy and runs locally in your ho
14991508
"widgets.open_page.description" = "Obrir una pàgina del Home Assistant";
15001509
"widgets.open_page.not_configured" = "No hi ha pàgines disponibles";
15011510
"widgets.open_page.title" = "Obre la pàgina";
1502-
"widgets.param.server.title" = "Server";
1511+
"widgets.param.server.title" = "Servidor";
15031512
"widgets.preview.custom.description" = "Create your own widget inside the App and then display it here.";
15041513
"widgets.preview.custom.title" = "Custom widget";
15051514
"widgets.preview.empty.create.button" = "Create widget";
@@ -1513,18 +1522,18 @@ Home Assistant is open source, advocates for privacy and runs locally in your ho
15131522
"widgets.sensors.description" = "Display state of sensors";
15141523
"widgets.sensors.not_configured" = "No Sensors Configured";
15151524
"widgets.sensors.title" = "Sensors";
1516-
"widgets.todo_list.all_done" = "All done! 🎉";
1525+
"widgets.todo_list.all_done" = "Tot fet! 🎉";
15171526
"widgets.todo_list.complete_item_title" = "Complete To-do Item";
15181527
"widgets.todo_list.description" = "Check your lists and add items";
15191528
"widgets.todo_list.due_date.ago_format" = "%@ ago";
15201529
"widgets.todo_list.due_date.in_format" = "In %@";
1521-
"widgets.todo_list.due_date.now" = "Now";
1522-
"widgets.todo_list.due_date.today" = "Today";
1530+
"widgets.todo_list.due_date.now" = "Ara";
1531+
"widgets.todo_list.due_date.today" = "Avui";
15231532
"widgets.todo_list.parameter.item_id" = "Item ID";
1524-
"widgets.todo_list.parameter.list" = "List";
1525-
"widgets.todo_list.parameter.list_id" = "List ID";
1526-
"widgets.todo_list.parameter.server" = "Server";
1527-
"widgets.todo_list.parameter.server_id" = "Server ID";
1533+
"widgets.todo_list.parameter.list" = "Llista";
1534+
"widgets.todo_list.parameter.list_id" = "ID de la llista";
1535+
"widgets.todo_list.parameter.server" = "Servidor";
1536+
"widgets.todo_list.parameter.server_id" = "ID del Servidor";
15281537
"widgets.todo_list.refresh_title" = "Refresh To-do List";
15291538
"widgets.todo_list.select_list" = "Edit widget to select list.";
15301539
"widgets.todo_list.title" = "To-do List";

Sources/App/Resources/cs.lproj/Localizable.strings

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,16 @@
127127
"assist.settings.modern_ui.theme.label" = "Motiv";
128128
"assist.settings.modern_ui.toggle" = "Experimentální uživatelské rozhraní";
129129
"assist.settings.on_device_stt.footer" = "Pro lepší soukromí použije rozpoznávání řeči v zařízení Apple. Váš hlas bude zpracován lokálně a před odesláním na server přepsán do textu. Nejsou podporovány všechny jazyky.";
130+
"assist.settings.on_device_stt.language" = "Language";
131+
"assist.settings.on_device_stt.title" = "On-device STT";
130132
"assist.settings.on_device_stt.toggle" = "Povolit převod řeči na text v zařízení";
133+
"assist.settings.on_device_tts.default_voice" = "Default";
134+
"assist.settings.on_device_tts.footer" = "Use Apple's on-device speech synthesis for improved privacy. Text responses will be spoken locally without sending audio data to your server.";
135+
"assist.settings.on_device_tts.quality.enhanced" = "Enhanced";
136+
"assist.settings.on_device_tts.quality.premium" = "Premium";
137+
"assist.settings.on_device_tts.title" = "On-device TTS";
138+
"assist.settings.on_device_tts.voice" = "Voice";
139+
"assist.settings.section.experimental.title" = "Experimental";
131140
"assist.settings.title" = "Nastavení Assist";
132141
"assist.settings.tts_mute.footer" = "Pokud je tato povoleno, Assist nepřehrává zvukové odpovědi, a to ani v případě, že je v kanálu nastaven převod textu na řeč. Textové odpovědi se však budou zobrazovat i nadále.";
133142
"assist.settings.tts_mute.toggle" = "Ztlumit hlasové odpovědi";

Sources/App/Resources/cy-GB.lproj/Localizable.strings

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,16 @@
127127
"assist.settings.modern_ui.theme.label" = "Theme";
128128
"assist.settings.modern_ui.toggle" = "Experimental UI";
129129
"assist.settings.on_device_stt.footer" = "Use Apple's on-device speech recognition for improved privacy. Your voice will be processed locally and transcribed to text before being sent to your server. Not all languages are supported.";
130+
"assist.settings.on_device_stt.language" = "Language";
131+
"assist.settings.on_device_stt.title" = "On-device STT";
130132
"assist.settings.on_device_stt.toggle" = "Enable on-device Speech-to-Text";
133+
"assist.settings.on_device_tts.default_voice" = "Default";
134+
"assist.settings.on_device_tts.footer" = "Use Apple's on-device speech synthesis for improved privacy. Text responses will be spoken locally without sending audio data to your server.";
135+
"assist.settings.on_device_tts.quality.enhanced" = "Enhanced";
136+
"assist.settings.on_device_tts.quality.premium" = "Premium";
137+
"assist.settings.on_device_tts.title" = "On-device TTS";
138+
"assist.settings.on_device_tts.voice" = "Voice";
139+
"assist.settings.section.experimental.title" = "Experimental";
131140
"assist.settings.title" = "Assist Settings";
132141
"assist.settings.tts_mute.footer" = "When enabled, Assist will not play audio responses even if the pipeline has text-to-speech configured. You will still see text responses.";
133142
"assist.settings.tts_mute.toggle" = "Mute voice responses";

Sources/App/Resources/da.lproj/Localizable.strings

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,16 @@
127127
"assist.settings.modern_ui.theme.label" = "Tema";
128128
"assist.settings.modern_ui.toggle" = "Eksperimentel brugerflade";
129129
"assist.settings.on_device_stt.footer" = "Brug Apples talegenkendelse lokalt på enheden for forbedret privatlivsbeskyttelse. Din stemme behandles lokalt og transskriberes til tekst, før den sendes til din server. Ikke alle sprog understøttes.";
130+
"assist.settings.on_device_stt.language" = "Language";
131+
"assist.settings.on_device_stt.title" = "On-device STT";
130132
"assist.settings.on_device_stt.toggle" = "Aktivér tale-til-tekst lokalt på enheden";
133+
"assist.settings.on_device_tts.default_voice" = "Default";
134+
"assist.settings.on_device_tts.footer" = "Use Apple's on-device speech synthesis for improved privacy. Text responses will be spoken locally without sending audio data to your server.";
135+
"assist.settings.on_device_tts.quality.enhanced" = "Enhanced";
136+
"assist.settings.on_device_tts.quality.premium" = "Premium";
137+
"assist.settings.on_device_tts.title" = "On-device TTS";
138+
"assist.settings.on_device_tts.voice" = "Voice";
139+
"assist.settings.section.experimental.title" = "Experimental";
131140
"assist.settings.title" = "Assist-indstillinger";
132141
"assist.settings.tts_mute.footer" = "Når den er aktiveret, afspiller Assist ikke lydsvar, selv om pipelinen har tekst-til-tale konfigureret. Du vil stadig se tekstsvar.";
133142
"assist.settings.tts_mute.toggle" = "Slå stemmesvar fra";

Sources/App/Resources/de.lproj/Localizable.strings

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,16 @@
127127
"assist.settings.modern_ui.theme.label" = "Design";
128128
"assist.settings.modern_ui.toggle" = "Experimentelle Benutzeroberfläche";
129129
"assist.settings.on_device_stt.footer" = "Apples geräteinterne Spracherkennung für mehr Datenschutz verwenden. Deine Stimme wird lokal verarbeitet und in Text umgewandelt, bevor sie an deinen Server gesendet wird. Nicht alle Sprachen werden unterstützt.";
130+
"assist.settings.on_device_stt.language" = "Language";
131+
"assist.settings.on_device_stt.title" = "On-device STT";
130132
"assist.settings.on_device_stt.toggle" = "Geräteinterne Sprache-zu-Text-Funktion aktivieren";
133+
"assist.settings.on_device_tts.default_voice" = "Default";
134+
"assist.settings.on_device_tts.footer" = "Use Apple's on-device speech synthesis for improved privacy. Text responses will be spoken locally without sending audio data to your server.";
135+
"assist.settings.on_device_tts.quality.enhanced" = "Enhanced";
136+
"assist.settings.on_device_tts.quality.premium" = "Premium";
137+
"assist.settings.on_device_tts.title" = "On-device TTS";
138+
"assist.settings.on_device_tts.voice" = "Voice";
139+
"assist.settings.section.experimental.title" = "Experimental";
131140
"assist.settings.title" = "Assist-Einstellungen";
132141
"assist.settings.tts_mute.footer" = "Wenn diese Option aktiviert ist, werden keine Audioantworten wiedergegeben, selbst wenn die Pipeline über eine Text-zu-Sprache-Funktion verfügt. Textantworten werden weiterhin angezeigt.";
133142
"assist.settings.tts_mute.toggle" = "Sprachantworten stummschalten";

0 commit comments

Comments
 (0)