From 22be534a8d6fe103b7175c5246a8232a3343e583 Mon Sep 17 00:00:00 2001 From: Guillermo Villafuerte Date: Mon, 8 Apr 2024 14:07:38 -0600 Subject: [PATCH 1/8] Initial setup for Settings search. Signed-off-by: Guillermo Villafuerte --- .idea/codeStyles/Project.xml | 1 + .idea/codeStyles/codeStyleConfig.xml | 1 - app/app/build.gradle.kts | 1 + .../de/mm20/launcher2/LauncherApplication.kt | 2 + app/ui/build.gradle.kts | 1 + .../ui/launcher/search/SearchColumn.kt | 30 +++---- .../launcher2/ui/launcher/search/SearchVM.kt | 13 ++- .../launcher/search/common/list/ListItem.kt | 21 +++-- .../launcher/search/settings/SettingsItem.kt | 27 +++++++ .../settings/search/SearchSettingsScreen.kt | 11 +++ .../settings/search/SearchSettingsScreenVM.kt | 9 +++ core/i18n/src/main/res/values/strings.xml | 6 ++ .../preferences/LauncherSettingsData.kt | 1 + .../de/mm20/launcher2/preferences/Module.kt | 2 + .../search/SettingsSearchSettings.kt | 30 +++++++ data/settings/.gitignore | 1 + data/settings/build.gradle.kts | 49 +++++++++++ data/settings/consumer-rules.pro | 0 data/settings/proguard-rules.pro | 21 +++++ data/settings/src/main/AndroidManifest.xml | 4 + .../launcher2/search/data/PojoSettings.kt | 73 +++++++++++++++++ .../java/de/mm20/launcher2/settings/Module.kt | 8 ++ .../launcher2/settings/SettingsRepository.kt | 81 +++++++++++++++++++ services/search/build.gradle.kts | 1 + .../java/de/mm20/launcher2/search/Module.kt | 1 + .../de/mm20/launcher2/search/SearchService.kt | 12 +++ settings.gradle.kts | 1 + 27 files changed, 377 insertions(+), 31 deletions(-) create mode 100644 app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/settings/SettingsItem.kt create mode 100644 core/preferences/src/main/java/de/mm20/launcher2/preferences/search/SettingsSearchSettings.kt create mode 100644 data/settings/.gitignore create mode 100644 data/settings/build.gradle.kts create mode 100644 data/settings/consumer-rules.pro create mode 100644 data/settings/proguard-rules.pro create mode 100644 data/settings/src/main/AndroidManifest.xml create mode 100644 data/settings/src/main/java/de/mm20/launcher2/search/data/PojoSettings.kt create mode 100644 data/settings/src/main/java/de/mm20/launcher2/settings/Module.kt create mode 100644 data/settings/src/main/java/de/mm20/launcher2/settings/SettingsRepository.kt diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 529374ff4..117d3aa46 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -56,6 +56,7 @@ + diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml index 6e6eec114..79ee123c2 100644 --- a/.idea/codeStyles/codeStyleConfig.xml +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -1,6 +1,5 @@ \ No newline at end of file diff --git a/app/app/build.gradle.kts b/app/app/build.gradle.kts index 796f5e915..4b57b7df4 100644 --- a/app/app/build.gradle.kts +++ b/app/app/build.gradle.kts @@ -146,6 +146,7 @@ dependencies { implementation(project(":data:currencies")) implementation(project(":data:customattrs")) implementation(project(":data:searchable")) + implementation(project(":data:settings")) implementation(project(":data:plugins")) implementation(project(":data:themes")) implementation(project(":data:files")) diff --git a/app/app/src/main/java/de/mm20/launcher2/LauncherApplication.kt b/app/app/src/main/java/de/mm20/launcher2/LauncherApplication.kt index 5874ba4ea..1988b81fe 100644 --- a/app/app/src/main/java/de/mm20/launcher2/LauncherApplication.kt +++ b/app/app/src/main/java/de/mm20/launcher2/LauncherApplication.kt @@ -36,6 +36,7 @@ import de.mm20.launcher2.searchactions.searchActionsModule import de.mm20.launcher2.services.favorites.favoritesModule import de.mm20.launcher2.services.tags.servicesTagsModule import de.mm20.launcher2.services.widgets.widgetsServiceModule +import de.mm20.launcher2.settings.settingsModule import de.mm20.launcher2.themes.themesModule import de.mm20.launcher2.weather.weatherModule import kotlinx.coroutines.* @@ -82,6 +83,7 @@ class LauncherApplication : Application(), CoroutineScope, ImageLoaderFactory { preferencesModule, searchModule, searchActionsModule, + settingsModule, themesModule, unitConverterModule, weatherModule, diff --git a/app/ui/build.gradle.kts b/app/ui/build.gradle.kts index 4b3274907..22acc8b31 100644 --- a/app/ui/build.gradle.kts +++ b/app/ui/build.gradle.kts @@ -134,6 +134,7 @@ dependencies { implementation(project(":data:files")) implementation(project(":data:widgets")) implementation(project(":data:searchable")) + implementation(project(":data:settings")) implementation(project(":data:themes")) implementation(project(":data:wikipedia")) implementation(project(":services:badges")) diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt index aea6cb75a..b59808c67 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt @@ -1,34 +1,18 @@ package de.mm20.launcher2.ui.launcher.search import androidx.appcompat.app.AppCompatActivity -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.LazyItemScope -import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.foundation.lazy.LazyListState -import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.* import androidx.compose.foundation.rememberScrollState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.Person import androidx.compose.material.icons.rounded.Star import androidx.compose.material.icons.rounded.Tag import androidx.compose.material.icons.rounded.Work -import androidx.compose.material3.FilterChip -import androidx.compose.material3.FilterChipDefaults -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedButton -import androidx.compose.material3.Text +import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -39,7 +23,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel -import de.mm20.launcher2.search.Location import de.mm20.launcher2.search.SavableSearchable import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.common.FavoritesTagSelector @@ -96,6 +79,7 @@ fun SearchColumn( val calculator by viewModel.calculatorResults val wikipedia by viewModel.articleResults val locations by viewModel.locationResults + val settings by viewModel.settingsResults val website by viewModel.websiteResults val hiddenResults by viewModel.hiddenResults val separateWorkProfile by viewModel.separateWorkProfile.collectAsState(true) @@ -245,6 +229,12 @@ fun SearchColumn( key = "shortcuts", highlightedItem = bestMatch as? SavableSearchable ) + ListResults( + items = settings.toImmutableList(), + reverse = reverse, + key = "settings", + highlightedItem = bestMatch as? SavableSearchable + ) for (conv in unitConverter) { SingleResult { UnitConverterItem(unitConverter = conv) diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchVM.kt index ba24a14a1..e7e6df826 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchVM.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchVM.kt @@ -11,7 +11,6 @@ import de.mm20.launcher2.permissions.PermissionsManager import de.mm20.launcher2.preferences.SearchResultOrder import de.mm20.launcher2.preferences.search.CalendarSearchSettings import de.mm20.launcher2.preferences.search.ContactSearchSettings -import de.mm20.launcher2.preferences.search.FavoritesSettings import de.mm20.launcher2.preferences.search.FileSearchSettings import de.mm20.launcher2.preferences.search.LocationSearchSettings import de.mm20.launcher2.preferences.search.ShortcutSearchSettings @@ -23,12 +22,13 @@ import de.mm20.launcher2.search.Article import de.mm20.launcher2.search.CalendarEvent import de.mm20.launcher2.search.Contact import de.mm20.launcher2.search.File +import de.mm20.launcher2.search.Location import de.mm20.launcher2.search.SavableSearchable import de.mm20.launcher2.search.SearchService import de.mm20.launcher2.search.Searchable -import de.mm20.launcher2.search.Location import de.mm20.launcher2.search.Website import de.mm20.launcher2.search.data.Calculator +import de.mm20.launcher2.search.data.PojoSettings import de.mm20.launcher2.search.data.UnitConverter import de.mm20.launcher2.searchable.SavableSearchableRepository import de.mm20.launcher2.searchactions.actions.SearchAction @@ -41,7 +41,6 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.first -import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch @@ -72,6 +71,7 @@ class SearchVM : ViewModel(), KoinComponent { val isSearchEmpty = mutableStateOf(true) val locationResults = mutableStateOf>(emptyList()) + val settingsResults = mutableStateOf>(emptyList()) val appResults = mutableStateOf>(emptyList()) val workAppResults = mutableStateOf>(emptyList()) val appShortcutResults = mutableStateOf>(emptyList()) @@ -147,6 +147,7 @@ class SearchVM : ViewModel(), KoinComponent { results.contacts, results.calendars, results.locations, + results.settings, results.wikipedia, results.websites, results.calculators, @@ -217,6 +218,7 @@ class SearchVM : ViewModel(), KoinComponent { val locations = mutableListOf() val website = mutableListOf() val actions = mutableListOf() + val settings = mutableListOf() for (r in resultsList) { when { r is SavableSearchable && hiddenKeys.contains(r.key) -> { @@ -235,6 +237,7 @@ class SearchVM : ViewModel(), KoinComponent { r is Article -> articles.add(r) r is Location -> locations.add(r) r is SearchAction -> actions.add(r) + r is PojoSettings -> settings.add(r) } } @@ -251,7 +254,8 @@ class SearchVM : ViewModel(), KoinComponent { articles, website, files, - actions + actions, + settings, ).firstNotNullOfOrNull { it.firstOrNull() } } @@ -266,6 +270,7 @@ class SearchVM : ViewModel(), KoinComponent { websiteResults.value = website calculatorResults.value = calc unitConverterResults.value = unitConv + settingsResults.value = settings hiddenResults.value = hidden if (results.searchActions != null) searchActionResults.value = actions } diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/list/ListItem.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/list/ListItem.kt index dd7e3b436..8eeffa3af 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/list/ListItem.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/list/ListItem.kt @@ -1,5 +1,6 @@ package de.mm20.launcher2.ui.launcher.search.common.list +import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.* @@ -9,12 +10,8 @@ import androidx.compose.ui.layout.boundsInWindow import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp -import de.mm20.launcher2.search.AppShortcut -import de.mm20.launcher2.search.CalendarEvent -import de.mm20.launcher2.search.Contact -import de.mm20.launcher2.search.File -import de.mm20.launcher2.search.Location -import de.mm20.launcher2.search.SavableSearchable +import de.mm20.launcher2.search.* +import de.mm20.launcher2.search.data.PojoSettings import de.mm20.launcher2.ui.component.InnerCard import de.mm20.launcher2.ui.ktx.toPixels import de.mm20.launcher2.ui.launcher.search.calendar.CalendarItem @@ -23,6 +20,7 @@ import de.mm20.launcher2.ui.launcher.search.contacts.ContactItem import de.mm20.launcher2.ui.launcher.search.files.FileItem import de.mm20.launcher2.ui.launcher.search.listItemViewModel import de.mm20.launcher2.ui.launcher.search.location.LocationItem +import de.mm20.launcher2.ui.launcher.search.settings.SettingsItem import de.mm20.launcher2.ui.launcher.search.shortcut.AppShortcutItem import de.mm20.launcher2.ui.locals.LocalGridSettings @@ -121,6 +119,17 @@ fun ListItem( ) } + is PojoSettings -> { + SettingsItem( + data = item, + modifier = Modifier + .fillMaxWidth() + .clickable { + viewModel.launch(context, bounds) + } + ) + } + is AppShortcut -> { AppShortcutItem( shortcut = item, diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/settings/SettingsItem.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/settings/SettingsItem.kt new file mode 100644 index 000000000..74cea25a0 --- /dev/null +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/settings/SettingsItem.kt @@ -0,0 +1,27 @@ +package de.mm20.launcher2.ui.launcher.search.settings + +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import de.mm20.launcher2.search.data.PojoSettings +import de.mm20.launcher2.ui.R + +@Composable +fun SettingsItem( + data: PojoSettings, + modifier: Modifier = Modifier) +{ + Row( + modifier = modifier.padding(8.dp) + ) { + Text( + text = stringResource(R.string.settings_placeholder, data.label), + style = MaterialTheme.typography.titleMedium + ) + } +} \ No newline at end of file diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreen.kt index 1b39357b4..3c253fc5c 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreen.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreen.kt @@ -152,6 +152,17 @@ fun SearchSettingsScreen() { enabled = hasAppShortcutsPermission == true ) + val settings by viewModel.settings.collectAsStateWithLifecycle(null) + SwitchPreference( + title = stringResource(R.string.preference_search_settings), + summary = stringResource(R.string.preference_search_settings_summary), + icon = Icons.Rounded.Settings, + value = settings == true, + onValueChanged = { + viewModel.setSettings(it) + } + ) + val calculator by viewModel.calculator.collectAsStateWithLifecycle(null) SwitchPreference( title = stringResource(R.string.preference_search_calculator), diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreenVM.kt index 7f2fcd9e1..c357616db 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreenVM.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreenVM.kt @@ -14,6 +14,7 @@ import de.mm20.launcher2.preferences.search.CalculatorSearchSettings import de.mm20.launcher2.preferences.search.CalendarSearchSettings import de.mm20.launcher2.preferences.search.ContactSearchSettings import de.mm20.launcher2.preferences.search.LocationSearchSettings +import de.mm20.launcher2.preferences.search.SettingsSearchSettings import de.mm20.launcher2.preferences.search.ShortcutSearchSettings import de.mm20.launcher2.preferences.search.UnitConverterSettings import de.mm20.launcher2.preferences.search.WebsiteSearchSettings @@ -37,6 +38,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent { private val permissionsManager: PermissionsManager by inject() private val locationSearchSettings: LocationSearchSettings by inject() + private val settingsSearchSettings: SettingsSearchSettings by inject() val hasWorkProfile = mutableStateOf(false) @@ -113,6 +115,13 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent { locationSearchSettings.setEnabled(locations) } + val settings = settingsSearchSettings.enabled + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null) + + fun setSettings(settings: Boolean) { + settingsSearchSettings.setEnabled(settings) + } + val autoFocus = searchUiSettings.openKeyboard fun setAutoFocus(autoFocus: Boolean) { diff --git a/core/i18n/src/main/res/values/strings.xml b/core/i18n/src/main/res/values/strings.xml index 61036e9de..ade815e5b 100644 --- a/core/i18n/src/main/res/values/strings.xml +++ b/core/i18n/src/main/res/values/strings.xml @@ -658,6 +658,12 @@ Search radius Show a preview of a website if the search query is a URL Search the local area for shops and other places + Settings + Search for common settings pages for your device + Settings: %1$s + Airplane mode + Device info + All apps Show your own location in the map Web search Show shortcuts to different search engines diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/LauncherSettingsData.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/LauncherSettingsData.kt index ddd4d04fb..e46122f85 100644 --- a/core/preferences/src/main/java/de/mm20/launcher2/preferences/LauncherSettingsData.kt +++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/LauncherSettingsData.kt @@ -143,6 +143,7 @@ data class LauncherSettingsData internal constructor( val locationSearchShowPositionOnMap: Boolean = false, val locationSearchThemeMap: Boolean = true, + val settingsSearchEnabled: Boolean = true, ) { constructor( diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/Module.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/Module.kt index 9536daa9f..99745b4f5 100644 --- a/core/preferences/src/main/java/de/mm20/launcher2/preferences/Module.kt +++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/Module.kt @@ -9,6 +9,7 @@ import de.mm20.launcher2.preferences.search.FavoritesSettings import de.mm20.launcher2.preferences.search.FileSearchSettings import de.mm20.launcher2.preferences.search.LocationSearchSettings import de.mm20.launcher2.preferences.search.RankingSettings +import de.mm20.launcher2.preferences.search.SettingsSearchSettings import de.mm20.launcher2.preferences.search.ShortcutSearchSettings import de.mm20.launcher2.preferences.search.UnitConverterSettings import de.mm20.launcher2.preferences.search.WebsiteSearchSettings @@ -49,4 +50,5 @@ val preferencesModule = module { factory { CalculatorSearchSettings(get()) } factory { ClockWidgetSettings(get()) } factory { LocationSearchSettings(get()) } + factory { SettingsSearchSettings(get()) } } \ No newline at end of file diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/search/SettingsSearchSettings.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/search/SettingsSearchSettings.kt new file mode 100644 index 000000000..df09f2ebf --- /dev/null +++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/search/SettingsSearchSettings.kt @@ -0,0 +1,30 @@ +package de.mm20.launcher2.preferences.search + +import de.mm20.launcher2.preferences.LauncherDataStore +import kotlinx.coroutines.flow.map + +class SettingsSearchSettings internal constructor( + private val launcherDataStore: LauncherDataStore, +) { + + val data + get() = launcherDataStore.data.map { + SettingsSearchSettingsData( + enabled = it.settingsSearchEnabled, + ) + } + + val enabled + get() = launcherDataStore.data.map { it.settingsSearchEnabled } + + fun setEnabled(enabled: Boolean) { + launcherDataStore.update { + it.copy(settingsSearchEnabled = enabled) + } + } + +} + +data class SettingsSearchSettingsData( + val enabled: Boolean = false, +) \ No newline at end of file diff --git a/data/settings/.gitignore b/data/settings/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/data/settings/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/data/settings/build.gradle.kts b/data/settings/build.gradle.kts new file mode 100644 index 000000000..fe55d0258 --- /dev/null +++ b/data/settings/build.gradle.kts @@ -0,0 +1,49 @@ +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) +} + +android { + compileSdk = libs.versions.compileSdk.get().toInt() + + defaultConfig { + minSdk = libs.versions.minSdk.get().toInt() + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = "1.8" + } + namespace = "de.mm20.launcher2.settings" +} + +dependencies { + implementation(libs.bundles.kotlin) + implementation(libs.androidx.core) + implementation(libs.androidx.appcompat) + + implementation(libs.bundles.androidx.lifecycle) + + implementation(libs.koin.android) + + implementation(project(":core:base")) + implementation(project(":core:preferences")) + implementation(project(":core:ktx")) + +} diff --git a/data/settings/consumer-rules.pro b/data/settings/consumer-rules.pro new file mode 100644 index 000000000..e69de29bb diff --git a/data/settings/proguard-rules.pro b/data/settings/proguard-rules.pro new file mode 100644 index 000000000..01639a198 --- /dev/null +++ b/data/settings/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle.kts.kts.kts. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/data/settings/src/main/AndroidManifest.xml b/data/settings/src/main/AndroidManifest.xml new file mode 100644 index 000000000..a5c402166 --- /dev/null +++ b/data/settings/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + / + \ No newline at end of file diff --git a/data/settings/src/main/java/de/mm20/launcher2/search/data/PojoSettings.kt b/data/settings/src/main/java/de/mm20/launcher2/search/data/PojoSettings.kt new file mode 100644 index 000000000..7b7b4b824 --- /dev/null +++ b/data/settings/src/main/java/de/mm20/launcher2/search/data/PojoSettings.kt @@ -0,0 +1,73 @@ +package de.mm20.launcher2.search.data + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes +import androidx.core.content.ContextCompat +import de.mm20.launcher2.base.R +import de.mm20.launcher2.icons.ColorLayer +import de.mm20.launcher2.icons.StaticLauncherIcon +import de.mm20.launcher2.icons.TintedIconLayer +import de.mm20.launcher2.ktx.tryStartActivity +import de.mm20.launcher2.search.NullSerializer +import de.mm20.launcher2.search.SavableSearchable +import de.mm20.launcher2.search.SearchableSerializer + +data class PojoSettings( + @get:StringRes val titleForPage: Int, + @get:DrawableRes val icon: Int, + + val actionId: String? = null, + val specialId: String? = null, + + override val key: String, + override val label: String +) : SavableSearchable { + override fun overrideLabel(label: String): SavableSearchable { + return copy(label = label) + } + + override fun launch(context: Context, options: Bundle?): Boolean { + return when (specialId) { + specialIdLauncher -> { + true + } + + else -> context.tryStartActivity( + Intent(actionId).apply { + flags = Intent.FLAG_ACTIVITY_NEW_TASK + }, options + ) + } + } + + override val preferDetailsOverLaunch: Boolean + get() = false + + override val domain: String + get() = Domain + + override fun getPlaceholderIcon(context: Context): StaticLauncherIcon { + val bgColor = R.color.teal + return StaticLauncherIcon( + foregroundLayer = TintedIconLayer( + icon = ContextCompat.getDrawable(context, R.drawable.ic_file_code)!!, + scale = 0.5f, + color = ContextCompat.getColor(context, bgColor) + ), + backgroundLayer = ColorLayer(ContextCompat.getColor(context, bgColor)) + ) + } + + override fun getSerializer(): SearchableSerializer { + return NullSerializer() + } + + companion object { + const val Domain: String = "settings" + + const val specialIdLauncher = "launcher-settings" + } +} \ No newline at end of file diff --git a/data/settings/src/main/java/de/mm20/launcher2/settings/Module.kt b/data/settings/src/main/java/de/mm20/launcher2/settings/Module.kt new file mode 100644 index 000000000..dab17b748 --- /dev/null +++ b/data/settings/src/main/java/de/mm20/launcher2/settings/Module.kt @@ -0,0 +1,8 @@ +package de.mm20.launcher2.settings + +import org.koin.android.ext.koin.androidContext +import org.koin.dsl.module + +val settingsModule = module { + single { SettingsRepositoryImpl(androidContext(), get()) } +} \ No newline at end of file diff --git a/data/settings/src/main/java/de/mm20/launcher2/settings/SettingsRepository.kt b/data/settings/src/main/java/de/mm20/launcher2/settings/SettingsRepository.kt new file mode 100644 index 000000000..f4933a4dd --- /dev/null +++ b/data/settings/src/main/java/de/mm20/launcher2/settings/SettingsRepository.kt @@ -0,0 +1,81 @@ +package de.mm20.launcher2.settings + +import android.content.Context +import android.provider.Settings +import de.mm20.launcher2.preferences.search.SettingsSearchSettings +import de.mm20.launcher2.search.data.PojoSettings +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.withContext +import org.koin.core.component.KoinComponent + +interface SettingsRepository { + fun search(query: String) : Flow> +} + +class SettingsRepositoryImpl( + private val context: Context, + private val settings: SettingsSearchSettings +) : SettingsRepository, KoinComponent { + + override fun search(query: String): Flow> { + return settings.enabled.map { + if (it && query.isNotBlank()) { + filteredSettingsList(query) + } else { + persistentListOf() + } + } + } + + private suspend fun filteredSettingsList(query: String): ImmutableList { + return withContext(Dispatchers.IO) { + getKnownSettingsList().filter { + it.label.contains(query, ignoreCase = true) + }.toImmutableList() + } + } + private fun getKnownSettingsList(): List = + listOf( + PojoSettings( + titleForPage = R.string.settings_airplane, + icon = 0, + + actionId = Settings.ACTION_AIRPLANE_MODE_SETTINGS, + + key = "settings-airplane", + label = context.getString(R.string.settings_airplane) + ), + PojoSettings( + titleForPage = R.string.settings_deviceinfo, + icon = 1, + + actionId = Settings.ACTION_DEVICE_INFO_SETTINGS, + + key = "settings-device", + label = context.getString(R.string.settings_deviceinfo) + ), + PojoSettings( + titleForPage = R.string.settings_manage_applications, + icon = 2, + + actionId = Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS, + + key = "settings-apps", + label = context.getString(R.string.settings_manage_applications) + ), + PojoSettings( + titleForPage = R.string.app_name, + icon = 3, + + specialId = PojoSettings.specialIdLauncher, + + key = "settings-launcher", + label = context.getString(R.string.app_name) + ) + ) +} \ No newline at end of file diff --git a/services/search/build.gradle.kts b/services/search/build.gradle.kts index fbb97dc58..0229b588c 100644 --- a/services/search/build.gradle.kts +++ b/services/search/build.gradle.kts @@ -47,6 +47,7 @@ dependencies { implementation(libs.coil.core) implementation(project(":data:calculator")) + implementation(project(":data:settings")) implementation(project(":data:unitconverter")) implementation(project(":data:customattrs")) implementation(project(":data:search-actions")) diff --git a/services/search/src/main/java/de/mm20/launcher2/search/Module.kt b/services/search/src/main/java/de/mm20/launcher2/search/Module.kt index a560c8898..d5dace2aa 100644 --- a/services/search/src/main/java/de/mm20/launcher2/search/Module.kt +++ b/services/search/src/main/java/de/mm20/launcher2/search/Module.kt @@ -15,6 +15,7 @@ val searchModule = module { get(named()), get(), get(), + get(), get(named()), get(), get(), diff --git a/services/search/src/main/java/de/mm20/launcher2/search/SearchService.kt b/services/search/src/main/java/de/mm20/launcher2/search/SearchService.kt index 6c92b2d8e..3ae7cc7e1 100644 --- a/services/search/src/main/java/de/mm20/launcher2/search/SearchService.kt +++ b/services/search/src/main/java/de/mm20/launcher2/search/SearchService.kt @@ -4,10 +4,12 @@ import de.mm20.launcher2.calculator.CalculatorRepository import de.mm20.launcher2.data.customattrs.CustomAttributesRepository import de.mm20.launcher2.data.customattrs.utils.withCustomLabels import de.mm20.launcher2.search.data.Calculator +import de.mm20.launcher2.search.data.PojoSettings import de.mm20.launcher2.search.data.UnitConverter import de.mm20.launcher2.searchactions.SearchActionService import de.mm20.launcher2.searchactions.actions.SearchAction import de.mm20.launcher2.unitconverter.UnitConverterRepository +import de.mm20.launcher2.settings.SettingsRepository import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @@ -37,6 +39,7 @@ internal class SearchServiceImpl( private val locationRepository: SearchableRepository, private val unitConverterRepository: UnitConverterRepository, private val calculatorRepository: CalculatorRepository, + private val settingsRepository: SettingsRepository, private val websiteRepository: SearchableRepository, private val searchActionService: SearchActionService, private val customAttributesRepository: CustomAttributesRepository, @@ -100,6 +103,13 @@ internal class SearchServiceImpl( } } } + launch { + settingsRepository.search(query).collectLatest { r -> + results.update { + it.copy(settings = r) + } + } + } launch { unitConverterRepository.search(query) .collectLatest { r -> @@ -177,6 +187,7 @@ data class SearchResults( val websites: ImmutableList? = null, val wikipedia: ImmutableList
? = null, val locations: ImmutableList? = null, + val settings: ImmutableList? = null, val searchActions: ImmutableList? = null, val other: ImmutableList? = null, ) @@ -192,6 +203,7 @@ fun SearchResults.toList(): List { unitConverters, websites, wikipedia, + settings, searchActions, other, ).flatten() diff --git a/settings.gradle.kts b/settings.gradle.kts index f9a180c09..a2a6f6545 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -44,6 +44,7 @@ include(":data:weather") include(":data:notifications") include(":data:search-actions") include(":data:searchable") +include(":data:settings") include(":data:plugins") include(":services:accounts") From 6b0eda0efefbfff0d492dcafa076db018dd5cc13 Mon Sep 17 00:00:00 2001 From: Guillermo Villafuerte Date: Mon, 8 Apr 2024 14:38:09 -0600 Subject: [PATCH 2/8] Open launcher settings as "special" case. Signed-off-by: Guillermo Villafuerte --- .../ui/launcher/search/common/list/ListItem.kt | 16 +++++++++++++++- .../mm20/launcher2/search/data/PojoSettings.kt | 4 +--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/list/ListItem.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/list/ListItem.kt index 8eeffa3af..7c37c942b 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/list/ListItem.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/list/ListItem.kt @@ -1,5 +1,7 @@ package de.mm20.launcher2.ui.launcher.search.common.list +import android.content.Context +import android.content.Intent import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.fillMaxWidth @@ -10,6 +12,7 @@ import androidx.compose.ui.layout.boundsInWindow import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp +import de.mm20.launcher2.ktx.tryStartActivity import de.mm20.launcher2.search.* import de.mm20.launcher2.search.data.PojoSettings import de.mm20.launcher2.ui.component.InnerCard @@ -23,6 +26,7 @@ import de.mm20.launcher2.ui.launcher.search.location.LocationItem import de.mm20.launcher2.ui.launcher.search.settings.SettingsItem import de.mm20.launcher2.ui.launcher.search.shortcut.AppShortcutItem import de.mm20.launcher2.ui.locals.LocalGridSettings +import de.mm20.launcher2.ui.settings.SettingsActivity @Composable fun ListItem( @@ -125,7 +129,11 @@ fun ListItem( modifier = Modifier .fillMaxWidth() .clickable { - viewModel.launch(context, bounds) + if (!viewModel.launch(context, bounds)) { + when (item.specialId) { + PojoSettings.specialIdLauncher -> launchSettingsPage(context) + } + } } ) } @@ -150,4 +158,10 @@ fun ListItem( } } } +} + +private fun launchSettingsPage(context: Context) { + context.tryStartActivity(Intent(context, SettingsActivity::class.java)).apply { + Intent.FLAG_ACTIVITY_NEW_TASK + } } \ No newline at end of file diff --git a/data/settings/src/main/java/de/mm20/launcher2/search/data/PojoSettings.kt b/data/settings/src/main/java/de/mm20/launcher2/search/data/PojoSettings.kt index 7b7b4b824..5b7dc95d3 100644 --- a/data/settings/src/main/java/de/mm20/launcher2/search/data/PojoSettings.kt +++ b/data/settings/src/main/java/de/mm20/launcher2/search/data/PojoSettings.kt @@ -31,9 +31,7 @@ data class PojoSettings( override fun launch(context: Context, options: Bundle?): Boolean { return when (specialId) { - specialIdLauncher -> { - true - } + specialIdLauncher -> false else -> context.tryStartActivity( Intent(actionId).apply { From baf62a4250e0d00cc9efb0eaf30c115d16bbe783 Mon Sep 17 00:00:00 2001 From: Guillermo Villafuerte Date: Mon, 8 Apr 2024 18:17:55 -0600 Subject: [PATCH 3/8] Settings moved before app shortcuts. Signed-off-by: Guillermo Villafuerte --- .../launcher2/ui/launcher/search/SearchColumn.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt index b59808c67..d0d3e88af 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt @@ -202,6 +202,12 @@ fun SearchColumn( } else null, highlightedItem = bestMatch as? SavableSearchable ) + ListResults( + items = settings.toImmutableList(), + reverse = reverse, + key = "settings", + highlightedItem = bestMatch as? SavableSearchable + ) ListResults( before = if (missingShortcutsPermission && !isSearchEmpty) { { @@ -229,12 +235,6 @@ fun SearchColumn( key = "shortcuts", highlightedItem = bestMatch as? SavableSearchable ) - ListResults( - items = settings.toImmutableList(), - reverse = reverse, - key = "settings", - highlightedItem = bestMatch as? SavableSearchable - ) for (conv in unitConverter) { SingleResult { UnitConverterItem(unitConverter = conv) From 7f312bf1b789bc0b1818fcc294c167339243921f Mon Sep 17 00:00:00 2001 From: Guillermo Villafuerte Date: Mon, 8 Apr 2024 18:19:27 -0600 Subject: [PATCH 4/8] First batch of settings, heavily based on KISS Launcher list. Signed-off-by: Guillermo Villafuerte --- .../drawable/ic_settings_accessibility.xml | 9 + .../res/drawable/ic_settings_airplane.xml | 12 ++ .../main/res/drawable/ic_settings_apps.xml | 33 ++++ .../main/res/drawable/ic_settings_battery.xml | 9 + .../res/drawable/ic_settings_bluetooth.xml | 13 ++ .../res/drawable/ic_settings_developer.xml | 9 + .../res/drawable/ic_settings_deviceinfo.xml | 9 + .../main/res/drawable/ic_settings_display.xml | 9 + .../res/drawable/ic_settings_launcher.xml | 48 ++++++ .../res/drawable/ic_settings_location.xml | 10 ++ .../src/main/res/drawable/ic_settings_nfc.xml | 9 + .../main/res/drawable/ic_settings_privacy.xml | 9 + .../main/res/drawable/ic_settings_sound.xml | 27 +++ .../main/res/drawable/ic_settings_storage.xml | 13 ++ .../res/drawable/ic_settings_tethering.xml | 16 ++ .../main/res/drawable/ic_settings_updates.xml | 9 + .../main/res/drawable/ic_settings_wifi.xml | 10 ++ .../res/drawable/ic_settings_wireless.xml | 9 + core/i18n/src/main/res/values/strings.xml | 14 ++ .../launcher2/search/data/PojoSettings.kt | 16 +- .../launcher2/settings/SettingsRepository.kt | 163 ++++++++++++++---- 21 files changed, 419 insertions(+), 37 deletions(-) create mode 100644 core/base/src/main/res/drawable/ic_settings_accessibility.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_airplane.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_apps.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_battery.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_bluetooth.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_developer.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_deviceinfo.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_display.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_launcher.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_location.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_nfc.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_privacy.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_sound.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_storage.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_tethering.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_updates.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_wifi.xml create mode 100644 core/base/src/main/res/drawable/ic_settings_wireless.xml diff --git a/core/base/src/main/res/drawable/ic_settings_accessibility.xml b/core/base/src/main/res/drawable/ic_settings_accessibility.xml new file mode 100644 index 000000000..f13540ba3 --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_accessibility.xml @@ -0,0 +1,9 @@ + + + diff --git a/core/base/src/main/res/drawable/ic_settings_airplane.xml b/core/base/src/main/res/drawable/ic_settings_airplane.xml new file mode 100644 index 000000000..c8b82d0e7 --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_airplane.xml @@ -0,0 +1,12 @@ + + + diff --git a/core/base/src/main/res/drawable/ic_settings_apps.xml b/core/base/src/main/res/drawable/ic_settings_apps.xml new file mode 100644 index 000000000..a64191464 --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_apps.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/core/base/src/main/res/drawable/ic_settings_battery.xml b/core/base/src/main/res/drawable/ic_settings_battery.xml new file mode 100644 index 000000000..61729c2c1 --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_battery.xml @@ -0,0 +1,9 @@ + + + diff --git a/core/base/src/main/res/drawable/ic_settings_bluetooth.xml b/core/base/src/main/res/drawable/ic_settings_bluetooth.xml new file mode 100644 index 000000000..e6d7d12aa --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_bluetooth.xml @@ -0,0 +1,13 @@ + + + diff --git a/core/base/src/main/res/drawable/ic_settings_developer.xml b/core/base/src/main/res/drawable/ic_settings_developer.xml new file mode 100644 index 000000000..f2870e5d2 --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_developer.xml @@ -0,0 +1,9 @@ + + + diff --git a/core/base/src/main/res/drawable/ic_settings_deviceinfo.xml b/core/base/src/main/res/drawable/ic_settings_deviceinfo.xml new file mode 100644 index 000000000..8da08411c --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_deviceinfo.xml @@ -0,0 +1,9 @@ + + + diff --git a/core/base/src/main/res/drawable/ic_settings_display.xml b/core/base/src/main/res/drawable/ic_settings_display.xml new file mode 100644 index 000000000..7991d13a6 --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_display.xml @@ -0,0 +1,9 @@ + + + diff --git a/core/base/src/main/res/drawable/ic_settings_launcher.xml b/core/base/src/main/res/drawable/ic_settings_launcher.xml new file mode 100644 index 000000000..7fb38fdad --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_launcher.xml @@ -0,0 +1,48 @@ + + + + + + + + diff --git a/core/base/src/main/res/drawable/ic_settings_location.xml b/core/base/src/main/res/drawable/ic_settings_location.xml new file mode 100644 index 000000000..6d2edde62 --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_location.xml @@ -0,0 +1,10 @@ + + + diff --git a/core/base/src/main/res/drawable/ic_settings_nfc.xml b/core/base/src/main/res/drawable/ic_settings_nfc.xml new file mode 100644 index 000000000..688654910 --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_nfc.xml @@ -0,0 +1,9 @@ + + + diff --git a/core/base/src/main/res/drawable/ic_settings_privacy.xml b/core/base/src/main/res/drawable/ic_settings_privacy.xml new file mode 100644 index 000000000..cdf5f44a6 --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_privacy.xml @@ -0,0 +1,9 @@ + + + diff --git a/core/base/src/main/res/drawable/ic_settings_sound.xml b/core/base/src/main/res/drawable/ic_settings_sound.xml new file mode 100644 index 000000000..1c25c8df9 --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_sound.xml @@ -0,0 +1,27 @@ + + + + + + + + + diff --git a/core/base/src/main/res/drawable/ic_settings_storage.xml b/core/base/src/main/res/drawable/ic_settings_storage.xml new file mode 100644 index 000000000..1d7de7b67 --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_storage.xml @@ -0,0 +1,13 @@ + + + + diff --git a/core/base/src/main/res/drawable/ic_settings_tethering.xml b/core/base/src/main/res/drawable/ic_settings_tethering.xml new file mode 100644 index 000000000..343b7e12f --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_tethering.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/core/base/src/main/res/drawable/ic_settings_updates.xml b/core/base/src/main/res/drawable/ic_settings_updates.xml new file mode 100644 index 000000000..6a96fd58c --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_updates.xml @@ -0,0 +1,9 @@ + + + diff --git a/core/base/src/main/res/drawable/ic_settings_wifi.xml b/core/base/src/main/res/drawable/ic_settings_wifi.xml new file mode 100644 index 000000000..7d5f81639 --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_wifi.xml @@ -0,0 +1,10 @@ + + + diff --git a/core/base/src/main/res/drawable/ic_settings_wireless.xml b/core/base/src/main/res/drawable/ic_settings_wireless.xml new file mode 100644 index 000000000..90974497a --- /dev/null +++ b/core/base/src/main/res/drawable/ic_settings_wireless.xml @@ -0,0 +1,9 @@ + + + diff --git a/core/i18n/src/main/res/values/strings.xml b/core/i18n/src/main/res/values/strings.xml index ade815e5b..f665b43e6 100644 --- a/core/i18n/src/main/res/values/strings.xml +++ b/core/i18n/src/main/res/values/strings.xml @@ -664,6 +664,20 @@ Airplane mode Device info All apps + Storage + Wireless connection + Tethering + Accessibility + Battery + Sound + Display + Development + Security + System updates + Wi-Fi + Bluetooth + NFC + Location Show your own location in the map Web search Show shortcuts to different search engines diff --git a/data/settings/src/main/java/de/mm20/launcher2/search/data/PojoSettings.kt b/data/settings/src/main/java/de/mm20/launcher2/search/data/PojoSettings.kt index 5b7dc95d3..494156ef3 100644 --- a/data/settings/src/main/java/de/mm20/launcher2/search/data/PojoSettings.kt +++ b/data/settings/src/main/java/de/mm20/launcher2/search/data/PojoSettings.kt @@ -4,7 +4,6 @@ import android.content.Context import android.content.Intent import android.os.Bundle import androidx.annotation.DrawableRes -import androidx.annotation.StringRes import androidx.core.content.ContextCompat import de.mm20.launcher2.base.R import de.mm20.launcher2.icons.ColorLayer @@ -16,11 +15,11 @@ import de.mm20.launcher2.search.SavableSearchable import de.mm20.launcher2.search.SearchableSerializer data class PojoSettings( - @get:StringRes val titleForPage: Int, @get:DrawableRes val icon: Int, val actionId: String? = null, val specialId: String? = null, + val packageName: String? = null, override val key: String, override val label: String @@ -30,8 +29,15 @@ data class PojoSettings( } override fun launch(context: Context, options: Bundle?): Boolean { - return when (specialId) { - specialIdLauncher -> false + return when { + specialId != null -> false + + packageName != null -> context.tryStartActivity( + Intent(actionId).apply { + setClassName(packageName, actionId!!) + flags = Intent.FLAG_ACTIVITY_NEW_TASK + }, options + ) else -> context.tryStartActivity( Intent(actionId).apply { @@ -51,7 +57,7 @@ data class PojoSettings( val bgColor = R.color.teal return StaticLauncherIcon( foregroundLayer = TintedIconLayer( - icon = ContextCompat.getDrawable(context, R.drawable.ic_file_code)!!, + icon = ContextCompat.getDrawable(context, icon)!!, scale = 0.5f, color = ContextCompat.getColor(context, bgColor) ), diff --git a/data/settings/src/main/java/de/mm20/launcher2/settings/SettingsRepository.kt b/data/settings/src/main/java/de/mm20/launcher2/settings/SettingsRepository.kt index f4933a4dd..e8b0bf9a4 100644 --- a/data/settings/src/main/java/de/mm20/launcher2/settings/SettingsRepository.kt +++ b/data/settings/src/main/java/de/mm20/launcher2/settings/SettingsRepository.kt @@ -1,6 +1,8 @@ package de.mm20.launcher2.settings import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager import android.provider.Settings import de.mm20.launcher2.preferences.search.SettingsSearchSettings import de.mm20.launcher2.search.data.PojoSettings @@ -34,48 +36,145 @@ class SettingsRepositoryImpl( private suspend fun filteredSettingsList(query: String): ImmutableList { return withContext(Dispatchers.IO) { - getKnownSettingsList().filter { + getKnownSettingsList(context).filter { + context.getString(R.string.settings_placeholder, "").contains(query, ignoreCase = true) || it.label.contains(query, ignoreCase = true) }.toImmutableList() } } - private fun getKnownSettingsList(): List = - listOf( - PojoSettings( - titleForPage = R.string.settings_airplane, - icon = 0, + private fun getKnownSettingsList(context: Context): List { + val pm = context.packageManager + val list = mutableListOf() - actionId = Settings.ACTION_AIRPLANE_MODE_SETTINGS, + list.addAll( + listOf( + PojoSettings( + icon = R.drawable.ic_settings_airplane, + actionId = Settings.ACTION_AIRPLANE_MODE_SETTINGS, + key = "settings-airplane", + label = context.getString(R.string.settings_airplane) + ), + PojoSettings( + icon = R.drawable.ic_settings_deviceinfo, + actionId = Settings.ACTION_DEVICE_INFO_SETTINGS, + key = "settings-device", + label = context.getString(R.string.settings_deviceinfo) + ), + PojoSettings( + icon = R.drawable.ic_settings_apps, + actionId = Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS, + key = "settings-apps", + label = context.getString(R.string.settings_manage_applications) + ), + PojoSettings( + icon = R.drawable.ic_settings_storage, + actionId = Settings.ACTION_INTERNAL_STORAGE_SETTINGS, + key = "settings-storage", + label = context.getString(R.string.settings_storage) + ), + PojoSettings( + icon = R.drawable.ic_settings_wireless, + actionId = Settings.ACTION_WIRELESS_SETTINGS, + key = "settings-wireless", + label = context.getString(R.string.settings_wireless) + ), + PojoSettings( + icon = R.drawable.ic_settings_tethering, + actionId = "com.android.settings.TetherSettings", + packageName = "com.android.settings", + key = "settings-tethering", + label = context.getString(R.string.settings_tethering) + ), + PojoSettings( + icon = R.drawable.ic_settings_accessibility, + actionId = Settings.ACTION_ACCESSIBILITY_SETTINGS, + key = "settings-accessibility", + label = context.getString(R.string.settings_accessibility) + ), + PojoSettings( + icon = R.drawable.ic_settings_battery, + actionId = Intent.ACTION_POWER_USAGE_SUMMARY, + key = "settings-battery", + label = context.getString(R.string.settings_battery) + ), + PojoSettings( + icon = R.drawable.ic_settings_sound, + actionId = Settings.ACTION_SOUND_SETTINGS, + key = "settings-sound", + label = context.getString(R.string.settings_sound) + ), + PojoSettings( + icon = R.drawable.ic_settings_display, + actionId = Settings.ACTION_DISPLAY_SETTINGS, + key = "settings-display", + label = context.getString(R.string.settings_display) + ), + PojoSettings( + icon = R.drawable.ic_settings_developer, + actionId = Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS, + key = "settings-developer", + label = context.getString(R.string.settings_developer) + ), + PojoSettings( + icon = R.drawable.ic_settings_privacy, + actionId = Settings.ACTION_SECURITY_SETTINGS, + key = "settings-security", + label = context.getString(R.string.settings_security) + ), + PojoSettings( + icon = R.drawable.ic_settings_updates, + actionId = "android.settings.SYSTEM_UPDATE_SETTINGS", + key = "settings-updates", + label = context.getString(R.string.settings_updates) + ), - key = "settings-airplane", - label = context.getString(R.string.settings_airplane) - ), - PojoSettings( - titleForPage = R.string.settings_deviceinfo, - icon = 1, - actionId = Settings.ACTION_DEVICE_INFO_SETTINGS, + PojoSettings( + icon = R.drawable.ic_settings_launcher, + specialId = PojoSettings.specialIdLauncher, + key = "settings-launcher", + label = context.getString(R.string.app_name) + ), + ) + ) - key = "settings-device", - label = context.getString(R.string.settings_deviceinfo) - ), - PojoSettings( - titleForPage = R.string.settings_manage_applications, - icon = 2, + if (pm.hasSystemFeature(PackageManager.FEATURE_WIFI)) { + list.add(PojoSettings( + icon = R.drawable.ic_settings_wifi, + actionId = Settings.ACTION_WIFI_SETTINGS, + key = "settings-wifi", + label = context.getString(R.string.settings_wifi) + )) + } + + if (pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) { + list.add(PojoSettings( + icon = R.drawable.ic_settings_bluetooth, + actionId = Settings.ACTION_BLUETOOTH_SETTINGS, + key = "settings-bluetooth", + label = context.getString(R.string.settings_bluetooth) + )) + } - actionId = Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS, + if (pm.hasSystemFeature(PackageManager.FEATURE_NFC)) { + list.add(PojoSettings( + icon = R.drawable.ic_settings_nfc, + actionId = Settings.ACTION_NFC_SETTINGS, + key = "settings-nfc", + label = context.getString(R.string.settings_nfc) + )) + } - key = "settings-apps", - label = context.getString(R.string.settings_manage_applications) - ), - PojoSettings( - titleForPage = R.string.app_name, - icon = 3, + if (pm.hasSystemFeature(PackageManager.FEATURE_LOCATION)) { + list.add(PojoSettings( + icon = R.drawable.ic_settings_location, + actionId = Settings.ACTION_LOCATION_SOURCE_SETTINGS, + key = "settings-location", + label = context.getString(R.string.settings_location) + )) + } - specialId = PojoSettings.specialIdLauncher, + return list + } - key = "settings-launcher", - label = context.getString(R.string.app_name) - ) - ) } \ No newline at end of file From c4fd4fbc1914e438d30c8690babf3988b56daa4f Mon Sep 17 00:00:00 2001 From: Guillermo Villafuerte Date: Mon, 8 Apr 2024 18:19:56 -0600 Subject: [PATCH 5/8] Small refactor, including current icon. Signed-off-by: Guillermo Villafuerte --- .../launcher/search/settings/SettingsItem.kt | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/settings/SettingsItem.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/settings/SettingsItem.kt index 74cea25a0..8ccd25a20 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/settings/SettingsItem.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/settings/SettingsItem.kt @@ -1,27 +1,49 @@ package de.mm20.launcher2.ui.launcher.search.settings -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.* import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import de.mm20.launcher2.search.data.PojoSettings import de.mm20.launcher2.ui.R +import de.mm20.launcher2.ui.component.ShapedLauncherIcon +import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM +import de.mm20.launcher2.ui.launcher.search.listItemViewModel @Composable fun SettingsItem( data: PojoSettings, modifier: Modifier = Modifier) { + val viewModel: SearchableItemVM = listItemViewModel(key = "search-${data.key}") + val icon by viewModel.icon.collectAsStateWithLifecycle() + Row( modifier = modifier.padding(8.dp) ) { - Text( - text = stringResource(R.string.settings_placeholder, data.label), - style = MaterialTheme.typography.titleMedium - ) + Column { + ShapedLauncherIcon( + size = 48.dp, + icon = { icon }, + ) + } + Box(modifier = Modifier.width(8.dp)) + Column( + modifier = Modifier.align(Alignment.CenterVertically) + ) { + Text( + text = stringResource(R.string.settings_placeholder, data.label), + style = MaterialTheme.typography.titleMedium, + overflow = TextOverflow.Ellipsis + ) + } + } } \ No newline at end of file From 20da0531b6d816d6d2da772da70059ef0a46fac2 Mon Sep 17 00:00:00 2001 From: Guillermo Villafuerte Date: Sun, 21 Apr 2024 13:02:25 -0600 Subject: [PATCH 6/8] "Settings" word and title are now split. Signed-off-by: Guillermo Villafuerte --- .../launcher/search/settings/SettingsItem.kt | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/settings/SettingsItem.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/settings/SettingsItem.kt index 8ccd25a20..2fec6c390 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/settings/SettingsItem.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/settings/SettingsItem.kt @@ -34,16 +34,24 @@ fun SettingsItem( icon = { icon }, ) } - Box(modifier = Modifier.width(8.dp)) + Box(modifier = Modifier.width(16.dp)) Column( modifier = Modifier.align(Alignment.CenterVertically) ) { - Text( - text = stringResource(R.string.settings_placeholder, data.label), - style = MaterialTheme.typography.titleMedium, - overflow = TextOverflow.Ellipsis - ) + Row { + Text( + text = data.label, + style = MaterialTheme.typography.titleMedium, + overflow = TextOverflow.Ellipsis + ) + } + Row { + Text( + text = stringResource(R.string.preference_search_settings), + style = MaterialTheme.typography.bodySmall, + overflow = TextOverflow.Ellipsis + ) + } } - } } \ No newline at end of file From 0ae4e69a8344f8ac56a1fb3b4c937caef8c5aeea Mon Sep 17 00:00:00 2001 From: Guillermo Villafuerte Date: Sun, 21 Apr 2024 13:08:12 -0600 Subject: [PATCH 7/8] Removed settings title placeholder. Signed-off-by: Guillermo Villafuerte --- core/i18n/src/main/res/values/strings.xml | 1 - .../main/java/de/mm20/launcher2/settings/SettingsRepository.kt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/core/i18n/src/main/res/values/strings.xml b/core/i18n/src/main/res/values/strings.xml index c1ca425ae..c2d90cb14 100644 --- a/core/i18n/src/main/res/values/strings.xml +++ b/core/i18n/src/main/res/values/strings.xml @@ -660,7 +660,6 @@ Search the local area for shops and other places Settings Search for common settings pages for your device - Settings: %1$s Airplane mode Device info All apps diff --git a/data/settings/src/main/java/de/mm20/launcher2/settings/SettingsRepository.kt b/data/settings/src/main/java/de/mm20/launcher2/settings/SettingsRepository.kt index e8b0bf9a4..7f03743e0 100644 --- a/data/settings/src/main/java/de/mm20/launcher2/settings/SettingsRepository.kt +++ b/data/settings/src/main/java/de/mm20/launcher2/settings/SettingsRepository.kt @@ -37,7 +37,7 @@ class SettingsRepositoryImpl( private suspend fun filteredSettingsList(query: String): ImmutableList { return withContext(Dispatchers.IO) { getKnownSettingsList(context).filter { - context.getString(R.string.settings_placeholder, "").contains(query, ignoreCase = true) || + context.getString(R.string.preference_search_settings).contains(query, ignoreCase = true) || it.label.contains(query, ignoreCase = true) }.toImmutableList() } From eab291937d670d9da19db4f4a52307a3d0814ba1 Mon Sep 17 00:00:00 2001 From: Guillermo Villafuerte Date: Sun, 21 Apr 2024 20:37:32 -0600 Subject: [PATCH 8/8] Minor icon tweaks. Signed-off-by: Guillermo Villafuerte --- .../drawable/ic_settings_accessibility.xml | 3 +- .../res/drawable/ic_settings_bluetooth.xml | 6 +- .../res/drawable/ic_settings_developer.xml | 6 +- .../res/drawable/ic_settings_launcher.xml | 57 +++++++------------ .../main/res/drawable/ic_settings_storage.xml | 19 +++++-- 5 files changed, 44 insertions(+), 47 deletions(-) diff --git a/core/base/src/main/res/drawable/ic_settings_accessibility.xml b/core/base/src/main/res/drawable/ic_settings_accessibility.xml index f13540ba3..e69f333f9 100644 --- a/core/base/src/main/res/drawable/ic_settings_accessibility.xml +++ b/core/base/src/main/res/drawable/ic_settings_accessibility.xml @@ -4,6 +4,7 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/core/base/src/main/res/drawable/ic_settings_bluetooth.xml b/core/base/src/main/res/drawable/ic_settings_bluetooth.xml index e6d7d12aa..341d82ab3 100644 --- a/core/base/src/main/res/drawable/ic_settings_bluetooth.xml +++ b/core/base/src/main/res/drawable/ic_settings_bluetooth.xml @@ -4,10 +4,8 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/core/base/src/main/res/drawable/ic_settings_developer.xml b/core/base/src/main/res/drawable/ic_settings_developer.xml index f2870e5d2..3a2e41199 100644 --- a/core/base/src/main/res/drawable/ic_settings_developer.xml +++ b/core/base/src/main/res/drawable/ic_settings_developer.xml @@ -4,6 +4,8 @@ android:viewportWidth="24" android:viewportHeight="24"> + android:pathData="m9.048,1.107c-4.091,0 -5.647,1.089 -5.314,4.112L4.069,8.398C4.247,10.065 2.89,10.577 1,10.577l0,2.847c1.912,0 3.247,0.512 3.069,2.179l-0.335,3.201c-0.311,2.979 1.223,4.089 5.314,4.089l0,-2.446c-1.356,0 -2.179,-0.289 -2.068,-1.4L7.313,15.756C7.58,13.244 6.247,12.356 3.868,12 6.113,11.667 7.58,10.734 7.313,8.244L6.98,4.953C6.869,3.842 7.669,3.553 9.048,3.553ZM14.952,1.107l0,2.446c1.356,0 2.179,0.289 2.068,1.4l-0.333,3.291C16.42,10.756 17.776,11.644 20.155,12c-2.268,0.333 -3.735,1.266 -3.468,3.756l0.333,3.291c0.111,1.112 -0.69,1.4 -2.068,1.4l0,2.446c4.091,0 5.647,-1.089 5.314,-4.112L19.931,15.602C19.753,13.935 21.133,13.423 23,13.423l0,-2.847c-1.89,0 -3.247,-0.512 -3.069,-2.179L20.266,5.197C20.577,2.218 19.043,1.107 14.952,1.107Z" + android:strokeWidth="1.512" + android:fillColor="#000000" + android:strokeColor="#00000000"/> diff --git a/core/base/src/main/res/drawable/ic_settings_launcher.xml b/core/base/src/main/res/drawable/ic_settings_launcher.xml index 7fb38fdad..5aa11ecf0 100644 --- a/core/base/src/main/res/drawable/ic_settings_launcher.xml +++ b/core/base/src/main/res/drawable/ic_settings_launcher.xml @@ -3,46 +3,33 @@ android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> + + + + + android:pathData="m6.42,6.422c-1.685,0 -3.07,1.383 -3.07,3.068l0,2.791c0,1.685 1.385,3.068 3.07,3.068L17.58,15.349c1.685,0 3.07,-1.383 3.07,-3.068L20.651,9.49c0,-1.685 -1.385,-3.068 -3.07,-3.068zM6.42,8.097L17.58,8.097c0.781,0 1.396,0.612 1.396,1.393l0,2.791c0,0.781 -0.614,1.396 -1.396,1.396L6.42,13.677c-0.781,0 -1.396,-0.614 -1.396,-1.396L5.024,9.49c0,-0.781 0.614,-1.393 1.396,-1.393z" + android:fillColor="#000000"/> + android:pathData="M8.373,9.491L7.257,9.491c-0.462,0 -0.837,0.375 -0.837,0.837l0,1.116c0,0.462 0.375,0.837 0.837,0.837l1.116,0c0.462,0 0.837,-0.375 0.837,-0.837l0,-1.116c0,-0.462 -0.375,-0.837 -0.837,-0.837z" + android:strokeWidth="0.14" + android:fillColor="#000000"/> + android:pathData="m12.558,9.491l-1.116,0c-0.462,0 -0.837,0.375 -0.837,0.837l0,1.116c0,0.462 0.375,0.837 0.837,0.837l1.116,0c0.462,0 0.837,-0.375 0.837,-0.837l0,-1.116c0,-0.462 -0.375,-0.837 -0.837,-0.837z" + android:strokeWidth="0.14" + android:fillColor="#000000"/> - + android:pathData="m16.743,9.491l-1.116,0c-0.462,0 -0.837,0.375 -0.837,0.837l0,1.116c0,0.462 0.375,0.837 0.837,0.837l1.116,0c0.462,0 0.837,-0.375 0.837,-0.837l0,-1.116c0,-0.462 -0.375,-0.837 -0.837,-0.837z" + android:strokeWidth="0.14" + android:fillColor="#000000"/> diff --git a/core/base/src/main/res/drawable/ic_settings_storage.xml b/core/base/src/main/res/drawable/ic_settings_storage.xml index 1d7de7b67..27afd798d 100644 --- a/core/base/src/main/res/drawable/ic_settings_storage.xml +++ b/core/base/src/main/res/drawable/ic_settings_storage.xml @@ -4,10 +4,19 @@ android:viewportWidth="24" android:viewportHeight="24"> + android:pathData="M5.002,0C3.357,0 2,1.357 2,3.002L2,20.998C2,22.643 3.357,24 5.002,24L18.998,24C20.643,24 22,22.643 22,20.998L22,3.002C22,1.357 20.643,0 18.998,0ZM5.002,2L18.998,2c0.572,0 1,0.43 1,1.002L19.998,20.998c0,0.572 -0.428,1.002 -1,1.002L5.002,22c-0.572,0 -1,-0.43 -1,-1.002L4.002,3.002C4.002,2.43 4.43,2 5.002,2Z" + android:fillColor="#020202"/> + android:pathData="m12,4.002c-3.3,0 -5.998,2.698 -5.998,5.998 0,3.3 2.698,5.996 5.998,5.996 3.3,0 5.998,-2.696 5.998,-5.996 0,-3.3 -2.698,-5.998 -5.998,-5.998zM12,6.002c2.219,0 3.996,1.779 3.996,3.998 0,2.219 -1.777,3.996 -3.996,3.996C9.781,13.996 8.004,12.219 8.004,10 8.004,7.781 9.781,6.002 12,6.002Z" + android:fillColor="#020202"/> + + +