diff --git a/app/src/main/java/helium314/keyboard/settings/SettingsContainer.kt b/app/src/main/java/helium314/keyboard/settings/SettingsContainer.kt index a147280b..59c44379 100644 --- a/app/src/main/java/helium314/keyboard/settings/SettingsContainer.kt +++ b/app/src/main/java/helium314/keyboard/settings/SettingsContainer.kt @@ -33,14 +33,22 @@ class SettingsContainer(context: Context) { // show, but change will not do anything because another setting needs to be enabled first -> probably best fun filter(searchTerm: String): List { val term = searchTerm.lowercase() - val results = mutableSetOf() - list.forEach { setting -> if (setting.title.lowercase().startsWith(term)) results.add(setting) } - list.forEach { setting -> if (setting.title.lowercase().split(' ').any { it.startsWith(term) }) results.add(setting) } + val titleMatch = mutableListOf() + val titleWordMatch = mutableListOf() + val descriptionMatch = mutableListOf() + list.forEach { setting -> - if (setting.description?.lowercase()?.split(' ')?.any { it.startsWith(term) } == true) - results.add(setting) + val titleLower = setting.titleLower + if (titleLower.startsWith(term)) { + titleMatch.add(setting) + } else if (setting.titleWords.any { it.startsWith(term) }) { + titleWordMatch.add(setting) + } else if (setting.descriptionWords?.any { it.startsWith(term) } == true) { + descriptionMatch.add(setting) + } } - return results.toList() + + return titleMatch + titleWordMatch + descriptionMatch } } @@ -53,7 +61,10 @@ class Setting( private val content: @Composable (Setting) -> Unit ) { val title = context.getString(titleId) + val titleLower = title.lowercase() + val titleWords = titleLower.split(' ') val description = descriptionId?.let { context.getString(it) } + val descriptionWords = description?.lowercase()?.split(' ') @Composable fun Preference() { diff --git a/app/src/test/java/helium314/keyboard/settings/SettingsContainerTest.kt b/app/src/test/java/helium314/keyboard/settings/SettingsContainerTest.kt new file mode 100644 index 00000000..99f275c1 --- /dev/null +++ b/app/src/test/java/helium314/keyboard/settings/SettingsContainerTest.kt @@ -0,0 +1,53 @@ +package helium314.keyboard.settings + +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import kotlin.system.measureNanoTime + +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [33]) +class SettingsContainerTest { + + private lateinit var container: SettingsContainer + + @Before + fun setup() { + val context = ApplicationProvider.getApplicationContext() + container = SettingsContainer(context) + } + + @Test + fun testFilterFunctionality() { + // Just verify it doesn't crash and returns some results for empty or common strings + val res = container.filter("a") + assertTrue(res.isNotEmpty()) + } + + @Test + fun testFilterPerformance() { + val searches = listOf("a", "b", "c", "theme", "color", "sound", "vib", "dictionary", "key", "layout") + + // Warmup + for (i in 1..10) { + for (s in searches) { + container.filter(s) + } + } + + val time = measureNanoTime { + for (i in 1..100) { + for (s in searches) { + container.filter(s) + } + } + } + println("Filter performance: ${time / 1_000_000} ms") + } +}