From a84d36f17a9fece04f9c8b63122c76d2b05eeaa5 Mon Sep 17 00:00:00 2001 From: Seb3thehacker Date: Tue, 13 Oct 2026 17:57:30 -0700 Subject: [PATCH] voice: app names match however the recognizer spaces them, so "with map quest" picks MapQuest --- .../gearslip/car/AssistantCommands.kt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/car/AssistantCommands.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/car/AssistantCommands.kt index 43e6ca2..b635a57 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/car/AssistantCommands.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/car/AssistantCommands.kt @@ -65,17 +65,22 @@ object AssistantCommands { return builtIn + (LauncherCache.entries ?: withContext(Dispatchers.IO) { LauncherCache.load(context) }) } - /** Best label match: exact, then a label starting with [name], then one containing it. */ + /** + * Best label match: exact, then a label starting with [name], then one containing it. Spaces + * and punctuation don't count, since the recognizer may hear "MapQuest" as "map quest". + */ private fun bestMatch(items: List, name: String, label: (T) -> String): T? { - val n = name.removePrefix("the ").removePrefix("my ").removeSuffix(" app").trim() + val n = squash(name.removePrefix("the ").removePrefix("my ").removeSuffix(" app")) if (n.isEmpty()) return null - items.firstOrNull { label(it).lowercase() == n }?.let { return it } + items.firstOrNull { squash(label(it)) == n }?.let { return it } // Loose matches need a real word: "pizza in a" mustn't pick "Organic Maps" for its "a". if (n.length < 3) return null - return items.firstOrNull { label(it).lowercase().startsWith(n) } - ?: items.firstOrNull { label(it).lowercase().contains(n) } + return items.firstOrNull { squash(label(it)).startsWith(n) } + ?: items.firstOrNull { squash(label(it)).contains(n) } } + private fun squash(s: String) = s.lowercase().filter { it.isLetterOrDigit() } + /** * "navigate to X [with|using|on|via Y]" - Y picks the nav app by (partial) label; without it, * whichever nav app was used last, or the only one installed, or the first one found. Starts