From 7d139c6e4580309edc9e4f48115e9e320c1ca52c Mon Sep 17 00:00:00 2001 From: Yasan Ghaffarian Date: Wed, 1 Jun 2022 09:47:39 +0430 Subject: [PATCH 1/9] Add Sesame QsbSearchProvider Co-authored-by: Daria Hamrah Paytakht --- lawnchair/res/drawable/ic_sesame.xml | 25 +++++++++++++++++++ lawnchair/res/values/strings.xml | 1 + .../qsb/providers/QsbSearchProvider.kt | 3 ++- .../src/app/lawnchair/qsb/providers/Sesame.kt | 14 +++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 lawnchair/res/drawable/ic_sesame.xml create mode 100644 lawnchair/src/app/lawnchair/qsb/providers/Sesame.kt diff --git a/lawnchair/res/drawable/ic_sesame.xml b/lawnchair/res/drawable/ic_sesame.xml new file mode 100644 index 0000000000..4ba1b532a3 --- /dev/null +++ b/lawnchair/res/drawable/ic_sesame.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/lawnchair/res/values/strings.xml b/lawnchair/res/values/strings.xml index f2b197cca8..c2f75b93fd 100644 --- a/lawnchair/res/values/strings.xml +++ b/lawnchair/res/values/strings.xml @@ -228,6 +228,7 @@ Wikipedia Presearch Bing + Sesame Always Open Website Open search provider’s website even if their app is installed. Search Provider diff --git a/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt b/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt index 1c11e0f3b9..ee992d52f9 100644 --- a/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt +++ b/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt @@ -77,7 +77,8 @@ open class QsbSearchProvider( DuckDuckGo, Presearch, Wikipedia, - Bing + Bing, + Sesame ) /** diff --git a/lawnchair/src/app/lawnchair/qsb/providers/Sesame.kt b/lawnchair/src/app/lawnchair/qsb/providers/Sesame.kt new file mode 100644 index 0000000000..a0824cef35 --- /dev/null +++ b/lawnchair/src/app/lawnchair/qsb/providers/Sesame.kt @@ -0,0 +1,14 @@ +package app.lawnchair.qsb.providers + +import app.lawnchair.qsb.ThemingMethod +import com.android.launcher3.R + +object Sesame : QsbSearchProvider( + id = "sesame", + name = R.string.search_provider_sesame, + icon = R.drawable.ic_sesame, + themingMethod = ThemingMethod.TINT, + packageName = "ninja.sesame.app.edge", + className = "ninja.sesame.app.edge.omni.OmniActivity", + website = "https://play.google.com/store/apps/details?id=ninja.sesame.app.edge" +) \ No newline at end of file From 092de5a3df16befe45da2668e14a213194d71327 Mon Sep 17 00:00:00 2001 From: Yasan Ghaffarian Date: Mon, 6 Jun 2022 11:29:35 +0430 Subject: [PATCH 2/9] Add QsbSearchProvider types for behavior customization Co-authored-by: Daria Hamrah Paytakht --- lawnchair/res/drawable/ic_download.xml | 5 + lawnchair/res/values/strings.xml | 2 + .../app/lawnchair/qsb/providers/AppSearch.kt | 3 +- .../app/lawnchair/qsb/providers/GoogleGo.kt | 3 +- .../qsb/providers/QsbSearchProvider.kt | 63 +++++++++- .../src/app/lawnchair/qsb/providers/Sesame.kt | 3 +- .../ui/preferences/DockPreferences.kt | 15 ++- .../components/QsbProviderPreference.kt | 119 ++++++++++++++++-- 8 files changed, 193 insertions(+), 20 deletions(-) create mode 100644 lawnchair/res/drawable/ic_download.xml diff --git a/lawnchair/res/drawable/ic_download.xml b/lawnchair/res/drawable/ic_download.xml new file mode 100644 index 0000000000..19eca78dfc --- /dev/null +++ b/lawnchair/res/drawable/ic_download.xml @@ -0,0 +1,5 @@ + + + diff --git a/lawnchair/res/values/strings.xml b/lawnchair/res/values/strings.xml index c2f75b93fd..ca04259890 100644 --- a/lawnchair/res/values/strings.xml +++ b/lawnchair/res/values/strings.xml @@ -86,6 +86,7 @@ Show Search Bar + App required. Admin Permissions Required To use Double-Tap to Sleep, set Lawnchair as a device admin app. Tap Open Settings, then tap “Activate this device admin app.” Double-Tap to Sleep will be turned off. @@ -239,6 +240,7 @@ All custom icons will be reset. Do you want to continue? Taskbar Enable Taskbar (Experimental) + No app market or browser installed. %1$s, %2$s diff --git a/lawnchair/src/app/lawnchair/qsb/providers/AppSearch.kt b/lawnchair/src/app/lawnchair/qsb/providers/AppSearch.kt index 5143560db8..ade4319ad2 100644 --- a/lawnchair/src/app/lawnchair/qsb/providers/AppSearch.kt +++ b/lawnchair/src/app/lawnchair/qsb/providers/AppSearch.kt @@ -11,7 +11,8 @@ object AppSearch : QsbSearchProvider( icon = R.drawable.ic_qsb_search, themingMethod = ThemingMethod.TINT, packageName = "", - website = "" + website = "", + type = QsbSearchProviderType.LOCAL ) { override suspend fun launch(launcher: Launcher, forceWebsite: Boolean) { launcher.animateToAllApps() diff --git a/lawnchair/src/app/lawnchair/qsb/providers/GoogleGo.kt b/lawnchair/src/app/lawnchair/qsb/providers/GoogleGo.kt index e94e129f7d..a156c319ca 100644 --- a/lawnchair/src/app/lawnchair/qsb/providers/GoogleGo.kt +++ b/lawnchair/src/app/lawnchair/qsb/providers/GoogleGo.kt @@ -12,7 +12,8 @@ object GoogleGo : QsbSearchProvider( packageName = "com.google.android.apps.searchlite", action = "android.search.action.GLOBAL_SEARCH", supportVoiceIntent = true, - website = "https://www.google.com/" + website = "https://www.google.com/", + type = QsbSearchProviderType.APP ) { override fun handleCreateVoiceIntent(): Intent = diff --git a/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt b/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt index ee992d52f9..654bc9e688 100644 --- a/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt +++ b/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt @@ -1,14 +1,18 @@ package app.lawnchair.qsb.providers +import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent +import android.content.pm.PackageManager import android.net.Uri +import android.widget.Toast import androidx.annotation.DrawableRes import androidx.annotation.StringRes import app.lawnchair.preferences2.PreferenceManager2 import app.lawnchair.qsb.QsbLayout import app.lawnchair.qsb.ThemingMethod import app.lawnchair.resolveIntent +import app.lawnchair.util.isPackageInstalled import com.android.launcher3.Launcher import com.android.launcher3.R import com.patrykmichalik.preferencemanager.first @@ -23,7 +27,8 @@ open class QsbSearchProvider( val className: String = "", val action: String? = null, val supportVoiceIntent: Boolean = false, - val website: String + val website: String, + val type: QsbSearchProviderType = QsbSearchProviderType.APP_AND_WEBSITE, ) { suspend fun launch(launcher: Launcher) { @@ -65,6 +70,44 @@ open class QsbSearchProvider( .addFlags(INTENT_FLAGS) .setPackage(packageName) + /** + * Checks if the search provider is downloaded. + * Should only be used for [QsbSearchProviderType]s that are downloadable. + */ + fun isDownloaded(context: Context) = context.packageManager.isPackageInstalled(packageName) + + /** + * Launches the search provider's page on an app market. + * If no app market is installed, it tries to launch the provider's page on Google Play Store. + * + * Should only be used for [QsbSearchProviderType]s that are downloadable. + */ + fun launchOnAppMarket(context: Context) { + try { + context.startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse("market://details?id=$packageName") + ) + ) + } catch (e: ActivityNotFoundException) { + try { + context.startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse("https://play.google.com/store/apps/details?id=$packageName") + ) + ) + } catch (e: Exception) { + Toast.makeText( + context, + context.getString(R.string.error_no_market_or_browser_installed), + Toast.LENGTH_SHORT + ).show() + } + } + } + companion object { internal const val INTENT_FLAGS = @@ -91,14 +134,17 @@ open class QsbSearchProvider( * Resolve the default search provider. */ fun resolveDefault(context: Context): QsbSearchProvider { - val defaultProviderId = context.getString(R.string.config_default_qsb_search_provider_id) + val defaultProviderId = + context.getString(R.string.config_default_qsb_search_provider_id) val defaultProvider = fromId(defaultProviderId) - val isDefaultProviderIntentResolved = QsbLayout.resolveIntent(context, defaultProvider.createSearchIntent()) + val isDefaultProviderIntentResolved = + QsbLayout.resolveIntent(context, defaultProvider.createSearchIntent()) // Return the default value from config.xml if the value is valid if (isDefaultProviderIntentResolved) { if (defaultProvider != AppSearch || - (defaultProvider == AppSearch && defaultProviderId == AppSearch.id)) { + (defaultProvider == AppSearch && defaultProviderId == AppSearch.id) + ) { return defaultProvider } } @@ -112,4 +158,11 @@ open class QsbSearchProvider( } } -} \ No newline at end of file +} + +enum class QsbSearchProviderType(val downloadable: Boolean) { + APP_AND_WEBSITE(downloadable = true), + WEBSITE(downloadable = false), + APP(downloadable = true), + LOCAL(downloadable = false) +} diff --git a/lawnchair/src/app/lawnchair/qsb/providers/Sesame.kt b/lawnchair/src/app/lawnchair/qsb/providers/Sesame.kt index a0824cef35..336260fa2c 100644 --- a/lawnchair/src/app/lawnchair/qsb/providers/Sesame.kt +++ b/lawnchair/src/app/lawnchair/qsb/providers/Sesame.kt @@ -10,5 +10,6 @@ object Sesame : QsbSearchProvider( themingMethod = ThemingMethod.TINT, packageName = "ninja.sesame.app.edge", className = "ninja.sesame.app.edge.omni.OmniActivity", - website = "https://play.google.com/store/apps/details?id=ninja.sesame.app.edge" + website = "https://play.google.com/store/apps/details?id=ninja.sesame.app.edge", + type = QsbSearchProviderType.APP ) \ No newline at end of file diff --git a/lawnchair/src/app/lawnchair/ui/preferences/DockPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/DockPreferences.kt index 67ecef2cc5..fdb049a010 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/DockPreferences.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/DockPreferences.kt @@ -23,6 +23,7 @@ import androidx.navigation.NavGraphBuilder import app.lawnchair.preferences.getAdapter import app.lawnchair.preferences.preferenceManager import app.lawnchair.preferences2.preferenceManager2 +import app.lawnchair.qsb.providers.QsbSearchProviderType import app.lawnchair.ui.preferences.components.* import com.android.launcher3.R @@ -55,11 +56,15 @@ fun DockPreferences() { showAsPercentage = true, ) QsbProviderPreference() - SwitchPreference( - adapter = prefs2.hotseatQsbForceWebsite.getAdapter(), - label = stringResource(R.string.always_open_website_label), - description = stringResource(R.string.always_open_website_description), - ) + val hotseatQsbProviderAdapter = + preferenceManager2().hotseatQsbProvider.getAdapter() + ExpandAndShrink(visible = hotseatQsbProviderAdapter.state.value.type == QsbSearchProviderType.APP_AND_WEBSITE) { + SwitchPreference( + adapter = prefs2.hotseatQsbForceWebsite.getAdapter(), + label = stringResource(R.string.always_open_website_label), + description = stringResource(R.string.always_open_website_description), + ) + } } } } diff --git a/lawnchair/src/app/lawnchair/ui/preferences/components/QsbProviderPreference.kt b/lawnchair/src/app/lawnchair/ui/preferences/components/QsbProviderPreference.kt index 39758d7007..ae202fb314 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/components/QsbProviderPreference.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/components/QsbProviderPreference.kt @@ -1,14 +1,27 @@ package app.lawnchair.ui.preferences.components +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.material.RadioButton +import androidx.compose.material3.Icon +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp import app.lawnchair.preferences.getAdapter import app.lawnchair.preferences2.preferenceManager2 -import app.lawnchair.qsb.QsbLayout -import app.lawnchair.qsb.providers.GoogleGo import app.lawnchair.qsb.providers.QsbSearchProvider +import app.lawnchair.qsb.providers.QsbSearchProviderType +import app.lawnchair.ui.AlertBottomSheetContent +import app.lawnchair.ui.util.addIf +import app.lawnchair.ui.util.bottomSheetHandler import com.android.launcher3.R @Composable @@ -17,16 +30,108 @@ fun QsbProviderPreference() { val context = LocalContext.current val entries = remember { QsbSearchProvider.values().map { - // Enabled is true if provider is anything but Google Go, - // or if it is Google Go and the intent can be resolved. - val enabled = it != GoogleGo || QsbLayout.resolveIntent(context, it.createSearchIntent()) + // Enabled is true if provider type is not app or it is app & the app is installed + val enabled = it.type != QsbSearchProviderType.APP || it.isDownloaded(context) ListPreferenceEntry(it, enabled) { stringResource(id = it.name) } } } - ListPreference( - adapter = adapter, + QsbProviderListPreference( entries = entries, + value = adapter.state.value, + onValueChange = adapter::onChange, label = stringResource(R.string.search_provider), ) } + +@Composable +fun QsbProviderListPreference( + entries: List>, + value: QsbSearchProvider, + onValueChange: (QsbSearchProvider) -> Unit, + label: String, + enabled: Boolean = true, + description: String? = null, +) { + val context = LocalContext.current + + val bottomSheetHandler = bottomSheetHandler + val currentDescription = description ?: entries + .firstOrNull { it.value == value } + ?.label?.invoke() + + val paddingVertical = 16.dp + val paddingHorizontal = 16.dp + + PreferenceTemplate( + title = { Text(text = label) }, + description = { currentDescription?.let { Text(text = it) } }, + enabled = enabled, + modifier = Modifier.clickable(enabled) { + bottomSheetHandler.show { + AlertBottomSheetContent( + title = { Text(label) }, + buttons = { + OutlinedButton(onClick = { bottomSheetHandler.hide() }) { + Text(text = stringResource(id = android.R.string.cancel)) + } + } + ) { + LazyColumn { + itemsIndexed(entries) { index, item -> + if (index > 0) { + PreferenceDivider(startIndent = 40.dp) + } + PreferenceTemplate( + enabled = item.enabled, + title = { Text(item.label()) }, + description = { + if (item.value.type == QsbSearchProviderType.APP) { + Text(stringResource(id = R.string.qsb_search_provider_app_required)) + } + }, + applyPaddings = false, + modifier = Modifier + .clickable(item.enabled) { + onValueChange(item.value) + bottomSheetHandler.hide() + }, + startWidget = { + RadioButton( + modifier = Modifier.padding( + horizontal = paddingHorizontal, + vertical = paddingVertical + ), + selected = item.value == value, + onClick = null, + enabled = item.enabled, + ) + }, + endWidget = { + if (item.value.type.downloadable) { + val downloaded = item.value.isDownloaded(context) + Icon( + modifier = Modifier + .addIf(!downloaded) { + clickable { + item.value.launchOnAppMarket(context = context) + bottomSheetHandler.hide() + } + } + .padding( + horizontal = paddingHorizontal, + vertical = paddingVertical + ), + painter = painterResource(id = if (downloaded) R.drawable.ic_tick else R.drawable.ic_download), + contentDescription = null, + ) + } + } + ) + } + } + } + } + } + ) +} \ No newline at end of file From dc5cdbfe60e8f7ccd86d4620b1691b63604ab1e1 Mon Sep 17 00:00:00 2001 From: Yasan Ghaffarian Date: Sat, 11 Jun 2022 16:04:18 +0430 Subject: [PATCH 3/9] Change Glance title's text alignment based on layout direction Co-authored-by: Daria Hamrah Paytakht --- lawnchair/src/app/lawnchair/smartspace/BcSmartspaceCard.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lawnchair/src/app/lawnchair/smartspace/BcSmartspaceCard.kt b/lawnchair/src/app/lawnchair/smartspace/BcSmartspaceCard.kt index f2f238fac1..05a3ef7618 100644 --- a/lawnchair/src/app/lawnchair/smartspace/BcSmartspaceCard.kt +++ b/lawnchair/src/app/lawnchair/smartspace/BcSmartspaceCard.kt @@ -3,6 +3,7 @@ package app.lawnchair.smartspace import android.content.Context import android.text.TextUtils import android.util.AttributeSet +import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.LinearLayout @@ -128,6 +129,8 @@ class BcSmartspaceCard @JvmOverloads constructor( fun setTitle(title: CharSequence?, contentDescription: CharSequence?, hasIcon: Boolean) { val titleView = titleTextView ?: return + val isRTL = TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) == View.LAYOUT_DIRECTION_RTL + titleView.textAlignment = if (isRTL) TEXT_ALIGNMENT_TEXT_END else TEXT_ALIGNMENT_TEXT_START titleView.text = title titleView.setCompoundDrawablesRelative( if (hasIcon) iconDrawable else null, null, From 5ecc2f667830dda6ec2b869ac995bf0bd71fafd6 Mon Sep 17 00:00:00 2001 From: Patryk Michalik Date: Mon, 13 Jun 2022 18:58:42 +0200 Subject: [PATCH 4/9] =?UTF-8?q?Fix=20Dock=20search=20bar=20opening=20searc?= =?UTF-8?q?h=20provider=CA=BCs=20website=20when=20search=20provider=CA=BCs?= =?UTF-8?q?=20app=20should=20be=20opened?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/app/lawnchair/qsb/providers/QsbSearchProvider.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt b/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt index 654bc9e688..f6bd9e6b5f 100644 --- a/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt +++ b/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt @@ -3,7 +3,6 @@ package app.lawnchair.qsb.providers import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent -import android.content.pm.PackageManager import android.net.Uri import android.widget.Toast import androidx.annotation.DrawableRes @@ -24,7 +23,7 @@ open class QsbSearchProvider( @DrawableRes val themedIcon: Int = icon, val themingMethod: ThemingMethod = ThemingMethod.TINT, val packageName: String, - val className: String = "", + val className: String? = null, val action: String? = null, val supportVoiceIntent: Boolean = false, val website: String, @@ -54,7 +53,10 @@ open class QsbSearchProvider( fun createSearchIntent() = Intent(action) .addFlags(INTENT_FLAGS) - .setClassName(packageName, className) + .apply { + if (className != null) setClassName(packageName, className) + else setPackage(packageName) + } fun createVoiceIntent(): Intent = if (supportVoiceIntent) { handleCreateVoiceIntent() From d00a183033b9973686203a2e06af5eb00a148dc3 Mon Sep 17 00:00:00 2001 From: Patryk Michalik Date: Mon, 13 Jun 2022 19:02:58 +0200 Subject: [PATCH 5/9] Rework search provider selection UI --- lawnchair/res/values/strings.xml | 2 + .../ui/preferences/DockPreferences.kt | 39 ++-- .../preferences/SearchProviderPreferences.kt | 168 ++++++++++++++++++ .../components/QsbProviderPreference.kt | 137 -------------- 4 files changed, 195 insertions(+), 151 deletions(-) create mode 100644 lawnchair/src/app/lawnchair/ui/preferences/SearchProviderPreferences.kt delete mode 100644 lawnchair/src/app/lawnchair/ui/preferences/components/QsbProviderPreference.kt diff --git a/lawnchair/res/values/strings.xml b/lawnchair/res/values/strings.xml index 3badca00a7..7f6c885f3e 100644 --- a/lawnchair/res/values/strings.xml +++ b/lawnchair/res/values/strings.xml @@ -319,4 +319,6 @@ Home Button Tap Back Button Tap %s & %s + App + Website diff --git a/lawnchair/src/app/lawnchair/ui/preferences/DockPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/DockPreferences.kt index fdb049a010..23aebd28ac 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/DockPreferences.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/DockPreferences.kt @@ -16,19 +16,30 @@ package app.lawnchair.ui.preferences -import androidx.compose.animation.* import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource import androidx.navigation.NavGraphBuilder import app.lawnchair.preferences.getAdapter import app.lawnchair.preferences.preferenceManager import app.lawnchair.preferences2.preferenceManager2 -import app.lawnchair.qsb.providers.QsbSearchProviderType -import app.lawnchair.ui.preferences.components.* +import app.lawnchair.qsb.providers.QsbSearchProvider +import app.lawnchair.ui.preferences.components.DividerColumn +import app.lawnchair.ui.preferences.components.ExpandAndShrink +import app.lawnchair.ui.preferences.components.NavigationActionPreference +import app.lawnchair.ui.preferences.components.PreferenceGroup +import app.lawnchair.ui.preferences.components.PreferenceLayout +import app.lawnchair.ui.preferences.components.SliderPreference +import app.lawnchair.ui.preferences.components.SwitchPreference import com.android.launcher3.R +object DockRoutes { + const val SEARCH_PROVIDER = "searchProvider" +} + fun NavGraphBuilder.dockGraph(route: String) { - preferenceGraph(route, { DockPreferences() }) + preferenceGraph(route, { DockPreferences() }) { subRoute -> + searchProviderGraph(subRoute(DockRoutes.SEARCH_PROVIDER)) + } } @Composable @@ -55,16 +66,16 @@ fun DockPreferences() { valueRange = 0F..1F, showAsPercentage = true, ) - QsbProviderPreference() - val hotseatQsbProviderAdapter = - preferenceManager2().hotseatQsbProvider.getAdapter() - ExpandAndShrink(visible = hotseatQsbProviderAdapter.state.value.type == QsbSearchProviderType.APP_AND_WEBSITE) { - SwitchPreference( - adapter = prefs2.hotseatQsbForceWebsite.getAdapter(), - label = stringResource(R.string.always_open_website_label), - description = stringResource(R.string.always_open_website_description), - ) - } + val hotseatQsbProviderAdapter by preferenceManager2().hotseatQsbProvider.getAdapter() + NavigationActionPreference( + label = stringResource(R.string.search_provider), + destination = subRoute(DockRoutes.SEARCH_PROVIDER), + subtitle = stringResource( + id = QsbSearchProvider.values() + .first { it == hotseatQsbProviderAdapter } + .name, + ), + ) } } } diff --git a/lawnchair/src/app/lawnchair/ui/preferences/SearchProviderPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/SearchProviderPreferences.kt new file mode 100644 index 0000000000..b5d2ca7834 --- /dev/null +++ b/lawnchair/src/app/lawnchair/ui/preferences/SearchProviderPreferences.kt @@ -0,0 +1,168 @@ +package app.lawnchair.ui.preferences + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.RadioButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.navigation.NavGraphBuilder +import app.lawnchair.preferences.getAdapter +import app.lawnchair.preferences2.preferenceManager2 +import app.lawnchair.qsb.providers.QsbSearchProvider +import app.lawnchair.qsb.providers.QsbSearchProviderType +import app.lawnchair.ui.preferences.components.ClickableIcon +import app.lawnchair.ui.preferences.components.DividerColumn +import app.lawnchair.ui.preferences.components.ExpandAndShrink +import app.lawnchair.ui.preferences.components.PreferenceDivider +import app.lawnchair.ui.preferences.components.PreferenceGroup +import app.lawnchair.ui.preferences.components.PreferenceLayout +import app.lawnchair.ui.preferences.components.PreferenceTemplate +import com.android.launcher3.R + +fun NavGraphBuilder.searchProviderGraph(route: String) { + preferenceGraph(route, { SearchProviderPreferences() }) +} + +@Composable +fun SearchProviderPreferences() { + val context = LocalContext.current + val adapter = preferenceManager2().hotseatQsbProvider.getAdapter() + val forceWebsiteAdapter = preferenceManager2().hotseatQsbForceWebsite.getAdapter() + PreferenceLayout(label = stringResource(R.string.search_provider)) { + PreferenceGroup { + QsbSearchProvider.values().forEach { qsbSearchProvider -> + val appInstalled = qsbSearchProvider.isDownloaded(context) + val selected = adapter.state.value == qsbSearchProvider + val hasAppAndWebsite = qsbSearchProvider.type == QsbSearchProviderType.APP_AND_WEBSITE + val showDownloadButton = qsbSearchProvider.type == QsbSearchProviderType.APP && !appInstalled + Column { + ListItem( + title = stringResource(id = qsbSearchProvider.name), + showDownloadButton = showDownloadButton, + enabled = qsbSearchProvider.type != QsbSearchProviderType.APP || appInstalled, + selected = selected, + onClick = { adapter.onChange(newValue = qsbSearchProvider) }, + onDownloadClick = { qsbSearchProvider.launchOnAppMarket(context = context) }, + description = if (showDownloadButton) { + stringResource(id = R.string.qsb_search_provider_app_required) + } else null, + ) + ExpandAndShrink(visible = selected && hasAppAndWebsite) { + Options( + appEnabled = appInstalled, + appSelected = !forceWebsiteAdapter.state.value && appInstalled, + onAppClick = { forceWebsiteAdapter.onChange(newValue = false) }, + onAppDownloadClick = { qsbSearchProvider.launchOnAppMarket(context = context) }, + onWebsiteClick = { forceWebsiteAdapter.onChange(newValue = true) }, + showAppDownloadButton = !appInstalled, + ) + } + } + } + } + } +} + +@Composable +@OptIn(ExperimentalMaterial3Api::class) +private fun ListItem( + title: String, + description: String?, + showDownloadButton: Boolean, + enabled: Boolean, + selected: Boolean, + onClick: () -> Unit, + onDownloadClick: () -> Unit, +) { + Column { + PreferenceTemplate( + title = { Text(text = title) }, + verticalPadding = if (showDownloadButton) 12.dp else 16.dp, + horizontalPadding = 0.dp, + enabled = enabled, + modifier = Modifier.clickable(enabled = enabled, onClick = onClick), + description = { if (description != null) Text(text = description) }, + startWidget = { + RadioButton( + selected = selected, + onClick = null, + enabled = enabled, + modifier = Modifier.padding(start = 16.dp) + ) + }, + endWidget = { + if (showDownloadButton) { + ClickableIcon( + painter = painterResource(id = R.drawable.ic_download), + onClick = onDownloadClick, + tint = MaterialTheme.colorScheme.primary, + modifier = Modifier.padding(end = 4.dp), + ) + } + }, + ) + } +} + +@Composable +@OptIn(ExperimentalMaterial3Api::class) +private fun Options( + appEnabled: Boolean, + appSelected: Boolean, + showAppDownloadButton: Boolean, + onAppClick: () -> Unit, + onAppDownloadClick: () -> Unit, + onWebsiteClick: () -> Unit, +) { + PreferenceDivider(startIndent = 40.dp) + DividerColumn(startIndent = 40.dp) { + PreferenceTemplate( + title = { Text(stringResource(id = R.string.app_label)) }, + enabled = appEnabled, + verticalPadding = if (!appEnabled) 4.dp else 16.dp, + horizontalPadding = 0.dp, + modifier = Modifier.clickable( + enabled = appEnabled, + onClick = onAppClick, + ), + startWidget = { + RadioButton( + selected = appSelected, + onClick = null, + enabled = appEnabled, + modifier = Modifier.padding(start = 56.dp), + ) + }, + endWidget = { + if (showAppDownloadButton) { + ClickableIcon( + painter = painterResource(R.drawable.ic_download), + onClick = onAppDownloadClick, + tint = MaterialTheme.colorScheme.primary, + modifier = Modifier.padding(end = 4.dp), + ) + } + }, + ) + PreferenceTemplate( + title = { Text(text = stringResource(id = R.string.website_label)) }, + modifier = Modifier.clickable(onClick = onWebsiteClick), + horizontalPadding = 0.dp, + startWidget = { + RadioButton( + selected = !appSelected, + onClick = null, + modifier = Modifier.padding(start = 56.dp), + ) + }, + ) + } +} diff --git a/lawnchair/src/app/lawnchair/ui/preferences/components/QsbProviderPreference.kt b/lawnchair/src/app/lawnchair/ui/preferences/components/QsbProviderPreference.kt deleted file mode 100644 index ae202fb314..0000000000 --- a/lawnchair/src/app/lawnchair/ui/preferences/components/QsbProviderPreference.kt +++ /dev/null @@ -1,137 +0,0 @@ -package app.lawnchair.ui.preferences.components - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.material.RadioButton -import androidx.compose.material3.Icon -import androidx.compose.material3.OutlinedButton -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import app.lawnchair.preferences.getAdapter -import app.lawnchair.preferences2.preferenceManager2 -import app.lawnchair.qsb.providers.QsbSearchProvider -import app.lawnchair.qsb.providers.QsbSearchProviderType -import app.lawnchair.ui.AlertBottomSheetContent -import app.lawnchair.ui.util.addIf -import app.lawnchair.ui.util.bottomSheetHandler -import com.android.launcher3.R - -@Composable -fun QsbProviderPreference() { - val adapter = preferenceManager2().hotseatQsbProvider.getAdapter() - val context = LocalContext.current - val entries = remember { - QsbSearchProvider.values().map { - // Enabled is true if provider type is not app or it is app & the app is installed - val enabled = it.type != QsbSearchProviderType.APP || it.isDownloaded(context) - ListPreferenceEntry(it, enabled) { stringResource(id = it.name) } - } - } - - QsbProviderListPreference( - entries = entries, - value = adapter.state.value, - onValueChange = adapter::onChange, - label = stringResource(R.string.search_provider), - ) -} - -@Composable -fun QsbProviderListPreference( - entries: List>, - value: QsbSearchProvider, - onValueChange: (QsbSearchProvider) -> Unit, - label: String, - enabled: Boolean = true, - description: String? = null, -) { - val context = LocalContext.current - - val bottomSheetHandler = bottomSheetHandler - val currentDescription = description ?: entries - .firstOrNull { it.value == value } - ?.label?.invoke() - - val paddingVertical = 16.dp - val paddingHorizontal = 16.dp - - PreferenceTemplate( - title = { Text(text = label) }, - description = { currentDescription?.let { Text(text = it) } }, - enabled = enabled, - modifier = Modifier.clickable(enabled) { - bottomSheetHandler.show { - AlertBottomSheetContent( - title = { Text(label) }, - buttons = { - OutlinedButton(onClick = { bottomSheetHandler.hide() }) { - Text(text = stringResource(id = android.R.string.cancel)) - } - } - ) { - LazyColumn { - itemsIndexed(entries) { index, item -> - if (index > 0) { - PreferenceDivider(startIndent = 40.dp) - } - PreferenceTemplate( - enabled = item.enabled, - title = { Text(item.label()) }, - description = { - if (item.value.type == QsbSearchProviderType.APP) { - Text(stringResource(id = R.string.qsb_search_provider_app_required)) - } - }, - applyPaddings = false, - modifier = Modifier - .clickable(item.enabled) { - onValueChange(item.value) - bottomSheetHandler.hide() - }, - startWidget = { - RadioButton( - modifier = Modifier.padding( - horizontal = paddingHorizontal, - vertical = paddingVertical - ), - selected = item.value == value, - onClick = null, - enabled = item.enabled, - ) - }, - endWidget = { - if (item.value.type.downloadable) { - val downloaded = item.value.isDownloaded(context) - Icon( - modifier = Modifier - .addIf(!downloaded) { - clickable { - item.value.launchOnAppMarket(context = context) - bottomSheetHandler.hide() - } - } - .padding( - horizontal = paddingHorizontal, - vertical = paddingVertical - ), - painter = painterResource(id = if (downloaded) R.drawable.ic_tick else R.drawable.ic_download), - contentDescription = null, - ) - } - } - ) - } - } - } - } - } - ) -} \ No newline at end of file From b3e1d03d223fca2fb931a4c50f7355fc4f3184c9 Mon Sep 17 00:00:00 2001 From: Chefski <100310118+Chefski@users.noreply.github.com> Date: Wed, 15 Jun 2022 14:38:34 +0100 Subject: [PATCH 6/9] Update LICENSE.txt Updated the year to 2022 --- LICENSE.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.txt b/LICENSE.txt index 59d011c7ae..664be2e509 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,6 +1,6 @@ Copyright (c) 2005-2008, The Android Open Source Project - Copyright (c) 2021, Lawnchair + Copyright (c) 2022, Lawnchair Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 1f5597a908f0ecc8dcebbe0253d7114b69a9ab45 Mon Sep 17 00:00:00 2001 From: Patryk Michalik Date: Fri, 17 Jun 2022 18:39:24 +0200 Subject: [PATCH 7/9] Update dependencies --- build.gradle | 10 +++++----- lawnchair/src/app/lawnchair/DeviceProfileOverrides.kt | 2 +- lawnchair/src/app/lawnchair/LawnchairLauncher.kt | 2 +- lawnchair/src/app/lawnchair/SearchBarStateHandler.kt | 2 +- .../src/app/lawnchair/allapps/AllAppsSearchInput.kt | 2 +- .../lawnchair/allapps/LawnchairAlphabeticalAppsList.kt | 3 +-- .../src/app/lawnchair/gestures/GestureController.kt | 4 ++-- .../src/app/lawnchair/icons/shape/IconShapeManager.kt | 2 +- .../lawnchair/nexuslauncher/OverlayCallbackImpl.java | 2 +- .../src/app/lawnchair/preferences/PreferenceAdapter.kt | 4 ++-- .../app/lawnchair/preferences2/PreferenceManager2.kt | 4 ++-- .../src/app/lawnchair/preferences2/PreferenceUtils.kt | 8 ++++---- lawnchair/src/app/lawnchair/qsb/QsbLayout.kt | 2 +- .../app/lawnchair/qsb/providers/QsbSearchProvider.kt | 2 +- .../lawnchair/search/LawnchairAppSearchAlgorithm.kt | 2 +- .../src/app/lawnchair/smartspace/IcuDateTextView.kt | 2 +- .../smartspace/provider/SmartspaceDataSource.kt | 4 ++-- lawnchair/src/app/lawnchair/theme/ThemeProvider.kt | 4 ++-- .../src/app/lawnchair/ui/popup/LawnchairShortcut.kt | 2 +- .../lawnchair/ui/preferences/DebugMenuPreferences.kt | 7 ++++--- lawnchair/src/app/lawnchair/util/LawnchairUtils.kt | 2 +- .../launcher3/statehandlers/DepthController.java | 8 +++++--- src/com/android/launcher3/DeviceProfile.java | 2 +- src/com/android/launcher3/Hotseat.java | 2 +- src/com/android/launcher3/LauncherRootView.java | 2 +- src/com/android/launcher3/SessionCommitReceiver.java | 2 +- src/com/android/launcher3/Workspace.java | 2 +- src/com/android/launcher3/config/FeatureFlags.java | 2 +- .../android/launcher3/folder/FolderNameEditText.java | 2 +- src/com/android/launcher3/graphics/IconShape.java | 2 +- src/com/android/launcher3/graphics/SysUiScrim.java | 2 +- .../launcher3/popup/PopupContainerWithArrow.java | 2 +- src/com/android/launcher3/popup/SystemShortcut.java | 2 +- .../launcher3/shortcuts/DeepShortcutTextView.java | 2 +- src/com/android/launcher3/views/OptionsPopupView.java | 4 ++-- 35 files changed, 55 insertions(+), 53 deletions(-) diff --git a/build.gradle b/build.gradle index 2bc482b5f1..4c1ece0ff2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,8 @@ buildscript { ext { kotlin_version = '1.6.21' - compose_version = '1.2.0-beta02' - accompanist_version = '0.24.9-beta' + compose_version = '1.2.0-rc01' + accompanist_version = '0.24.10-beta' libsu_version = '3.1.2' protocVersion = '3.18.0' room_version = '2.4.2' @@ -355,7 +355,7 @@ dependencies { implementation "androidx.compose.ui:ui-text-google-fonts:$compose_version" implementation "androidx.compose.foundation:foundation:$compose_version" implementation "androidx.compose.material:material:$compose_version" - implementation "androidx.compose.material3:material3:1.0.0-alpha12" + implementation "androidx.compose.material3:material3:1.0.0-alpha13" implementation "androidx.compose.runtime:runtime-livedata:$compose_version" implementation "androidx.compose.runtime:runtime-rxjava2:$compose_version" implementation "androidx.compose.compiler:compiler:$compose_version" @@ -372,12 +372,12 @@ dependencies { implementation "com.google.accompanist:accompanist-pager:$accompanist_version" implementation "com.google.accompanist:accompanist-placeholder-material:$accompanist_version" implementation "com.google.accompanist:accompanist-systemuicontroller:$accompanist_version" - implementation 'com.google.android.material:material:1.6.0' + implementation "com.google.android.material:material:1.6.1" implementation "io.github.fornewid:material-motion-compose-core:0.8.4" implementation 'dev.kdrag0n:colorkt:1.0.5' implementation 'io.coil-kt:coil-compose:2.0.0' implementation 'me.xdrop:fuzzywuzzy:1.4.0' - implementation "com.patrykmichalik:preference-manager:1.0.7" + implementation "com.patrykmichalik:opto:1.0.12" implementation "androidx.datastore:datastore-preferences:1.0.0" implementation "com.squareup.retrofit2:retrofit:2.9.0" implementation "com.squareup.retrofit2:converter-gson:2.9.0" diff --git a/lawnchair/src/app/lawnchair/DeviceProfileOverrides.kt b/lawnchair/src/app/lawnchair/DeviceProfileOverrides.kt index 4f0f69232a..13fc6e51c1 100644 --- a/lawnchair/src/app/lawnchair/DeviceProfileOverrides.kt +++ b/lawnchair/src/app/lawnchair/DeviceProfileOverrides.kt @@ -12,7 +12,7 @@ import com.android.launcher3.InvariantDeviceProfile.INDEX_TWO_PANEL_LANDSCAPE import com.android.launcher3.InvariantDeviceProfile.INDEX_ALL_APPS import com.android.launcher3.Utilities import com.android.launcher3.util.MainThreadInitializedObject -import com.patrykmichalik.preferencemanager.firstBlocking +import com.patrykmichalik.opto.core.firstBlocking class DeviceProfileOverrides(context: Context) { private val prefs = PreferenceManager.getInstance(context) diff --git a/lawnchair/src/app/lawnchair/LawnchairLauncher.kt b/lawnchair/src/app/lawnchair/LawnchairLauncher.kt index 95f08ddecc..781ba2ad01 100644 --- a/lawnchair/src/app/lawnchair/LawnchairLauncher.kt +++ b/lawnchair/src/app/lawnchair/LawnchairLauncher.kt @@ -67,7 +67,7 @@ import com.android.launcher3.util.TouchController import com.android.launcher3.widget.RoundedCornerEnforcement import com.android.systemui.plugins.shared.LauncherOverlayManager import com.android.systemui.shared.system.QuickStepContract -import com.patrykmichalik.preferencemanager.onEach +import com.patrykmichalik.opto.core.onEach import dev.kdrag0n.monet.theme.ColorScheme import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.launchIn diff --git a/lawnchair/src/app/lawnchair/SearchBarStateHandler.kt b/lawnchair/src/app/lawnchair/SearchBarStateHandler.kt index 18ba67323c..a70fe09046 100644 --- a/lawnchair/src/app/lawnchair/SearchBarStateHandler.kt +++ b/lawnchair/src/app/lawnchair/SearchBarStateHandler.kt @@ -13,7 +13,7 @@ import com.android.launcher3.anim.PendingAnimation import com.android.launcher3.statemanager.StateManager import com.android.launcher3.states.StateAnimationConfig import com.android.quickstep.AnimatedFloat -import com.patrykmichalik.preferencemanager.onEach +import com.patrykmichalik.opto.core.onEach import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers diff --git a/lawnchair/src/app/lawnchair/allapps/AllAppsSearchInput.kt b/lawnchair/src/app/lawnchair/allapps/AllAppsSearchInput.kt index eb7a2d630c..1803158761 100644 --- a/lawnchair/src/app/lawnchair/allapps/AllAppsSearchInput.kt +++ b/lawnchair/src/app/lawnchair/allapps/AllAppsSearchInput.kt @@ -34,7 +34,7 @@ import com.android.launcher3.allapps.* import com.android.launcher3.allapps.search.AllAppsSearchBarController import com.android.launcher3.search.SearchCallback import com.android.launcher3.util.Themes -import com.patrykmichalik.preferencemanager.firstBlocking +import com.patrykmichalik.opto.core.firstBlocking import java.util.* import kotlin.math.max diff --git a/lawnchair/src/app/lawnchair/allapps/LawnchairAlphabeticalAppsList.kt b/lawnchair/src/app/lawnchair/allapps/LawnchairAlphabeticalAppsList.kt index 96e12f8075..71e88effd8 100644 --- a/lawnchair/src/app/lawnchair/allapps/LawnchairAlphabeticalAppsList.kt +++ b/lawnchair/src/app/lawnchair/allapps/LawnchairAlphabeticalAppsList.kt @@ -8,9 +8,8 @@ import com.android.launcher3.allapps.AllAppsStore import com.android.launcher3.allapps.AlphabeticalAppsList import com.android.launcher3.allapps.WorkAdapterProvider import com.android.launcher3.model.data.AppInfo -import com.android.launcher3.util.ComponentKey import com.android.launcher3.util.ItemInfoMatcher -import com.patrykmichalik.preferencemanager.onEach +import com.patrykmichalik.opto.core.onEach class LawnchairAlphabeticalAppsList( context: Context, diff --git a/lawnchair/src/app/lawnchair/gestures/GestureController.kt b/lawnchair/src/app/lawnchair/gestures/GestureController.kt index 69eef8b275..1fdd0729bc 100644 --- a/lawnchair/src/app/lawnchair/gestures/GestureController.kt +++ b/lawnchair/src/app/lawnchair/gestures/GestureController.kt @@ -23,7 +23,7 @@ import app.lawnchair.gestures.config.GestureHandlerConfig import app.lawnchair.preferences2.PreferenceManager2 import com.android.quickstep.SysUINavigationMode import com.android.quickstep.util.VibratorWrapper -import com.patrykmichalik.preferencemanager.Preference +import com.patrykmichalik.opto.domain.Preference import kotlinx.coroutines.MainScope import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch @@ -72,7 +72,7 @@ class GestureController(private val launcher: LawnchairLauncher) { } } - private fun handler(pref: Preference) = pref.get() + private fun handler(pref: Preference) = pref.get() .distinctUntilChanged() .map { it.createHandler(launcher) } .shareIn( diff --git a/lawnchair/src/app/lawnchair/icons/shape/IconShapeManager.kt b/lawnchair/src/app/lawnchair/icons/shape/IconShapeManager.kt index d35b331913..a95df2d3df 100644 --- a/lawnchair/src/app/lawnchair/icons/shape/IconShapeManager.kt +++ b/lawnchair/src/app/lawnchair/icons/shape/IconShapeManager.kt @@ -28,7 +28,7 @@ import com.android.launcher3.Utilities import com.android.launcher3.icons.GraphicsUtils import com.android.launcher3.icons.IconProvider import com.android.launcher3.util.MainThreadInitializedObject -import com.patrykmichalik.preferencemanager.firstBlocking +import com.patrykmichalik.opto.core.firstBlocking class IconShapeManager(private val context: Context) { diff --git a/lawnchair/src/app/lawnchair/nexuslauncher/OverlayCallbackImpl.java b/lawnchair/src/app/lawnchair/nexuslauncher/OverlayCallbackImpl.java index 9dcc1ff1d1..dc5708c132 100644 --- a/lawnchair/src/app/lawnchair/nexuslauncher/OverlayCallbackImpl.java +++ b/lawnchair/src/app/lawnchair/nexuslauncher/OverlayCallbackImpl.java @@ -15,7 +15,7 @@ import com.google.android.libraries.launcherclient.ISerializableScrollCallback; import com.google.android.libraries.launcherclient.LauncherClient; import com.google.android.libraries.launcherclient.LauncherClientCallbacks; import com.google.android.libraries.launcherclient.StaticInteger; -import com.patrykmichalik.preferencemanager.PreferenceExtensionsKt; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import app.lawnchair.FeedBridge; import app.lawnchair.LawnchairLauncher; diff --git a/lawnchair/src/app/lawnchair/preferences/PreferenceAdapter.kt b/lawnchair/src/app/lawnchair/preferences/PreferenceAdapter.kt index 4541d0cffb..73ae36a5f4 100644 --- a/lawnchair/src/app/lawnchair/preferences/PreferenceAdapter.kt +++ b/lawnchair/src/app/lawnchair/preferences/PreferenceAdapter.kt @@ -22,7 +22,7 @@ import app.lawnchair.preferences2.IdpPreference import app.lawnchair.preferences2.asState import app.lawnchair.preferences2.firstBlocking import com.android.launcher3.InvariantDeviceProfile -import com.patrykmichalik.preferencemanager.Preference +import com.patrykmichalik.opto.domain.Preference import kotlinx.coroutines.launch import kotlin.reflect.KProperty @@ -109,7 +109,7 @@ private fun getAdapter( } @Composable -fun Preference.getAdapter(): PreferenceAdapter { +fun Preference.getAdapter(): PreferenceAdapter { return createStateAdapter(state = asState(), set = this::set) } diff --git a/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt b/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt index 392fc9051e..e3ad9a714e 100644 --- a/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt +++ b/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt @@ -35,8 +35,8 @@ import com.android.launcher3.R import com.android.launcher3.Utilities import com.android.launcher3.util.DynamicResource import com.android.launcher3.util.MainThreadInitializedObject -import com.patrykmichalik.preferencemanager.PreferenceManager -import com.patrykmichalik.preferencemanager.firstBlocking +import com.patrykmichalik.opto.core.PreferenceManager +import com.patrykmichalik.opto.core.firstBlocking import kotlinx.coroutines.MainScope import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.drop diff --git a/lawnchair/src/app/lawnchair/preferences2/PreferenceUtils.kt b/lawnchair/src/app/lawnchair/preferences2/PreferenceUtils.kt index 4a8cfe0b78..710f37646f 100644 --- a/lawnchair/src/app/lawnchair/preferences2/PreferenceUtils.kt +++ b/lawnchair/src/app/lawnchair/preferences2/PreferenceUtils.kt @@ -3,14 +3,14 @@ package app.lawnchair.preferences2 import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import app.lawnchair.util.subscribeBlocking -import com.patrykmichalik.preferencemanager.Preference -import com.patrykmichalik.preferencemanager.firstBlocking +import com.patrykmichalik.opto.core.firstBlocking +import com.patrykmichalik.opto.domain.Preference import kotlinx.coroutines.CoroutineScope @Composable -fun Preference.asState() = get().collectAsState(initial = firstBlocking()) +fun Preference.asState() = get().collectAsState(initial = firstBlocking()) -fun Preference.subscribeBlocking( +fun Preference.subscribeBlocking( scope: CoroutineScope, block: (C) -> Unit, ) { diff --git a/lawnchair/src/app/lawnchair/qsb/QsbLayout.kt b/lawnchair/src/app/lawnchair/qsb/QsbLayout.kt index f6015e04b9..60ba249d37 100644 --- a/lawnchair/src/app/lawnchair/qsb/QsbLayout.kt +++ b/lawnchair/src/app/lawnchair/qsb/QsbLayout.kt @@ -34,7 +34,7 @@ import com.android.launcher3.R import com.android.launcher3.qsb.QsbContainerView import com.android.launcher3.util.Themes import com.android.launcher3.views.ActivityContext -import com.patrykmichalik.preferencemanager.firstBlocking +import com.patrykmichalik.opto.core.firstBlocking import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.flatMapLatest diff --git a/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt b/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt index f6bd9e6b5f..23e94a61df 100644 --- a/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt +++ b/lawnchair/src/app/lawnchair/qsb/providers/QsbSearchProvider.kt @@ -14,7 +14,7 @@ import app.lawnchair.resolveIntent import app.lawnchair.util.isPackageInstalled import com.android.launcher3.Launcher import com.android.launcher3.R -import com.patrykmichalik.preferencemanager.first +import com.patrykmichalik.opto.core.first open class QsbSearchProvider( val id: String, diff --git a/lawnchair/src/app/lawnchair/search/LawnchairAppSearchAlgorithm.kt b/lawnchair/src/app/lawnchair/search/LawnchairAppSearchAlgorithm.kt index 81f28d35ec..bef33d38c1 100644 --- a/lawnchair/src/app/lawnchair/search/LawnchairAppSearchAlgorithm.kt +++ b/lawnchair/src/app/lawnchair/search/LawnchairAppSearchAlgorithm.kt @@ -23,7 +23,7 @@ import com.android.launcher3.shortcuts.ShortcutRequest import com.android.launcher3.util.ComponentKey import com.android.launcher3.util.Executors import com.android.launcher3.util.PackageManagerHelper -import com.patrykmichalik.preferencemanager.onEach +import com.patrykmichalik.opto.core.onEach import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import me.xdrop.fuzzywuzzy.FuzzySearch diff --git a/lawnchair/src/app/lawnchair/smartspace/IcuDateTextView.kt b/lawnchair/src/app/lawnchair/smartspace/IcuDateTextView.kt index 3d958845e8..7f669b7a93 100644 --- a/lawnchair/src/app/lawnchair/smartspace/IcuDateTextView.kt +++ b/lawnchair/src/app/lawnchair/smartspace/IcuDateTextView.kt @@ -13,7 +13,7 @@ import app.lawnchair.util.broadcastReceiverFlow import app.lawnchair.util.repeatOnAttached import app.lawnchair.util.subscribeBlocking import com.android.launcher3.R -import com.patrykmichalik.preferencemanager.firstBlocking +import com.patrykmichalik.opto.core.firstBlocking import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.launchIn diff --git a/lawnchair/src/app/lawnchair/smartspace/provider/SmartspaceDataSource.kt b/lawnchair/src/app/lawnchair/smartspace/provider/SmartspaceDataSource.kt index 7b710aa976..923d364041 100644 --- a/lawnchair/src/app/lawnchair/smartspace/provider/SmartspaceDataSource.kt +++ b/lawnchair/src/app/lawnchair/smartspace/provider/SmartspaceDataSource.kt @@ -5,14 +5,14 @@ import android.content.Context import android.util.Log import app.lawnchair.preferences2.PreferenceManager2 import app.lawnchair.smartspace.model.SmartspaceTarget -import com.patrykmichalik.preferencemanager.Preference +import com.patrykmichalik.opto.domain.Preference import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.* abstract class SmartspaceDataSource( val context: Context, val providerName: Int, - getEnabledPref: PreferenceManager2.() -> Preference + getEnabledPref: PreferenceManager2.() -> Preference ) { val enabledPref = getEnabledPref(PreferenceManager2.getInstance(context)) open val isAvailable: Boolean = true diff --git a/lawnchair/src/app/lawnchair/theme/ThemeProvider.kt b/lawnchair/src/app/lawnchair/theme/ThemeProvider.kt index c5abf9c2ca..9c4eb34d9c 100644 --- a/lawnchair/src/app/lawnchair/theme/ThemeProvider.kt +++ b/lawnchair/src/app/lawnchair/theme/ThemeProvider.kt @@ -18,8 +18,8 @@ import app.lawnchair.ui.theme.getSystemAccent import app.lawnchair.wallpaper.WallpaperManagerCompat import com.android.launcher3.Utilities import com.android.launcher3.util.MainThreadInitializedObject -import com.patrykmichalik.preferencemanager.firstBlocking -import com.patrykmichalik.preferencemanager.onEach +import com.patrykmichalik.opto.core.firstBlocking +import com.patrykmichalik.opto.core.onEach import dev.kdrag0n.colorkt.Color import dev.kdrag0n.colorkt.conversion.ConversionGraph.convert import dev.kdrag0n.colorkt.rgb.Srgb diff --git a/lawnchair/src/app/lawnchair/ui/popup/LawnchairShortcut.kt b/lawnchair/src/app/lawnchair/ui/popup/LawnchairShortcut.kt index e6e1b3f26e..74aad48a6b 100644 --- a/lawnchair/src/app/lawnchair/ui/popup/LawnchairShortcut.kt +++ b/lawnchair/src/app/lawnchair/ui/popup/LawnchairShortcut.kt @@ -17,7 +17,7 @@ import com.android.launcher3.model.data.AppInfo as ModelAppInfo import com.android.launcher3.model.data.ItemInfo import com.android.launcher3.popup.SystemShortcut import com.android.launcher3.util.ComponentKey -import com.patrykmichalik.preferencemanager.firstBlocking +import com.patrykmichalik.opto.core.firstBlocking class LawnchairShortcut { diff --git a/lawnchair/src/app/lawnchair/ui/preferences/DebugMenuPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/DebugMenuPreferences.kt index c55dbdc96b..f869bfd3ca 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/DebugMenuPreferences.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/DebugMenuPreferences.kt @@ -4,6 +4,7 @@ import android.content.Intent import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext +import androidx.datastore.preferences.core.Preferences import androidx.navigation.NavGraphBuilder import app.lawnchair.preferences.PreferenceManager import app.lawnchair.preferences.getAdapter @@ -13,7 +14,7 @@ import app.lawnchair.preferences2.preferenceManager2 import app.lawnchair.ui.preferences.components.* import com.android.launcher3.settings.DeveloperOptionsFragment import com.android.launcher3.settings.SettingsActivity -import com.patrykmichalik.preferencemanager.Preference +import com.patrykmichalik.opto.domain.Preference fun NavGraphBuilder.debugMenuGraph(route: String) { preferenceGraph(route, { DebugMenuPreferences() }) @@ -75,10 +76,10 @@ fun DebugMenuPreferences() { } } -private val PreferenceManager2.debugFlags: List> +private val PreferenceManager2.debugFlags: List>> get() = listOf(showComponentNames) -private val PreferenceManager2.textFlags: List> +private val PreferenceManager2.textFlags: List>> get() = listOf(additionalFonts) private val PreferenceManager.debugFlags diff --git a/lawnchair/src/app/lawnchair/util/LawnchairUtils.kt b/lawnchair/src/app/lawnchair/util/LawnchairUtils.kt index 83c5d92346..21b6b07f5f 100644 --- a/lawnchair/src/app/lawnchair/util/LawnchairUtils.kt +++ b/lawnchair/src/app/lawnchair/util/LawnchairUtils.kt @@ -44,7 +44,7 @@ import com.android.launcher3.R import com.android.launcher3.util.Executors.MAIN_EXECUTOR import com.android.launcher3.util.Themes import com.android.systemui.shared.system.QuickStepContract -import com.patrykmichalik.preferencemanager.firstBlocking +import com.patrykmichalik.opto.core.firstBlocking import org.json.JSONArray import java.util.concurrent.Callable import java.util.concurrent.ExecutionException diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java index a025e2a189..1759bfe73d 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java @@ -33,6 +33,8 @@ import android.view.View; import android.view.ViewRootImpl; import android.view.ViewTreeObserver; +import androidx.datastore.preferences.core.Preferences; + import com.android.launcher3.BaseActivity; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; @@ -43,8 +45,8 @@ import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.states.StateAnimationConfig; import com.android.systemui.shared.system.BlurUtils; import com.android.systemui.shared.system.WallpaperManagerCompat; -import com.patrykmichalik.preferencemanager.Preference; -import com.patrykmichalik.preferencemanager.PreferenceExtensionsKt; +import com.patrykmichalik.opto.domain.Preference; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import app.lawnchair.preferences.BasePreferenceManager; import app.lawnchair.preferences.PreferenceManager; @@ -172,7 +174,7 @@ public class DepthController implements StateHandler, public DepthController(Launcher l) { mLauncher = l; - Preference depthPref = PreferenceManager2.getInstance(l).getWallpaperDepthEffect(); + Preference depthPref = PreferenceManager2.getInstance(l).getWallpaperDepthEffect(); mEnableDepth = PreferenceExtensionsKt.firstBlocking(depthPref); } diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 0cffaadcff..487e0ce5aa 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -46,7 +46,7 @@ import com.android.launcher3.uioverrides.ApiWrapper; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.Info; import com.android.launcher3.util.WindowBounds; -import com.patrykmichalik.preferencemanager.PreferenceExtensionsKt; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import java.io.PrintWriter; diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java index 15e9b6c939..9ca306daa6 100644 --- a/src/com/android/launcher3/Hotseat.java +++ b/src/com/android/launcher3/Hotseat.java @@ -31,7 +31,7 @@ import android.widget.FrameLayout; import androidx.annotation.Nullable; -import com.patrykmichalik.preferencemanager.PreferenceExtensionsKt; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import java.util.function.Consumer; diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java index 9f6b7deaa4..ee5447ab1b 100644 --- a/src/com/android/launcher3/LauncherRootView.java +++ b/src/com/android/launcher3/LauncherRootView.java @@ -19,7 +19,7 @@ import androidx.annotation.RequiresApi; import com.android.launcher3.graphics.SysUiScrim; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.uioverrides.ApiWrapper; -import com.patrykmichalik.preferencemanager.PreferenceExtensionsKt; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import java.util.Collections; import java.util.List; diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java index 4efa798909..c8d56b9b52 100644 --- a/src/com/android/launcher3/SessionCommitReceiver.java +++ b/src/com/android/launcher3/SessionCommitReceiver.java @@ -31,7 +31,7 @@ import com.android.launcher3.logging.FileLog; import com.android.launcher3.model.ItemInstallQueue; import com.android.launcher3.pm.InstallSessionHelper; import com.android.launcher3.util.Executors; -import com.patrykmichalik.preferencemanager.PreferenceExtensionsKt; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import app.lawnchair.preferences2.PreferenceManager2; diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 8dd93cac46..dd13c8bd02 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -122,7 +122,7 @@ import com.android.launcher3.widget.WidgetManagerHelper; import com.android.launcher3.widget.dragndrop.AppWidgetHostViewDragListener; import com.android.launcher3.widget.util.WidgetSizes; import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlay; -import com.patrykmichalik.preferencemanager.PreferenceExtensionsKt; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import java.util.ArrayList; import java.util.Collections; diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 58b02291e7..b42d02a210 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -22,7 +22,7 @@ import com.android.launcher3.BuildConfig; import com.android.launcher3.Utilities; import com.android.launcher3.uioverrides.DeviceFlag; import com.android.systemui.shared.system.BlurUtils; -import com.patrykmichalik.preferencemanager.PreferenceExtensionsKt; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import java.io.PrintWriter; import java.util.ArrayList; diff --git a/src/com/android/launcher3/folder/FolderNameEditText.java b/src/com/android/launcher3/folder/FolderNameEditText.java index de5e1fde3e..b87207900f 100644 --- a/src/com/android/launcher3/folder/FolderNameEditText.java +++ b/src/com/android/launcher3/folder/FolderNameEditText.java @@ -27,7 +27,7 @@ import android.view.inputmethod.InputConnectionWrapper; import android.view.inputmethod.InputMethodManager; import com.android.launcher3.ExtendedEditText; -import com.patrykmichalik.preferencemanager.PreferenceExtensionsKt; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import java.util.List; diff --git a/src/com/android/launcher3/graphics/IconShape.java b/src/com/android/launcher3/graphics/IconShape.java index 87eed19527..da18c0cba7 100644 --- a/src/com/android/launcher3/graphics/IconShape.java +++ b/src/com/android/launcher3/graphics/IconShape.java @@ -47,7 +47,7 @@ import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; import com.android.launcher3.icons.GraphicsUtils; import com.android.launcher3.icons.IconNormalizer; import com.android.launcher3.views.ClipPathView; -import com.patrykmichalik.preferencemanager.PreferenceExtensionsKt; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; diff --git a/src/com/android/launcher3/graphics/SysUiScrim.java b/src/com/android/launcher3/graphics/SysUiScrim.java index 22b60202db..67e6dc7033 100644 --- a/src/com/android/launcher3/graphics/SysUiScrim.java +++ b/src/com/android/launcher3/graphics/SysUiScrim.java @@ -51,7 +51,7 @@ import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.DynamicResource; import com.android.launcher3.util.Themes; import com.android.systemui.plugins.ResourceProvider; -import com.patrykmichalik.preferencemanager.PreferenceExtensionsKt; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import app.lawnchair.preferences2.PreferenceManager2; import app.lawnchair.util.ViewExtensionsKt; diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index eabee75cea..93279d18e8 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -68,7 +68,7 @@ import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.ShortcutUtil; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.BaseDragLayer; -import com.patrykmichalik.preferencemanager.PreferenceExtensionsKt; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java index 81598a79bb..cf88016109 100644 --- a/src/com/android/launcher3/popup/SystemShortcut.java +++ b/src/com/android/launcher3/popup/SystemShortcut.java @@ -27,7 +27,7 @@ import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.widget.WidgetsBottomSheet; -import com.patrykmichalik.preferencemanager.PreferenceExtensionsKt; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import java.util.List; diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutTextView.java b/src/com/android/launcher3/shortcuts/DeepShortcutTextView.java index a194a630cd..f52708f46e 100644 --- a/src/com/android/launcher3/shortcuts/DeepShortcutTextView.java +++ b/src/com/android/launcher3/shortcuts/DeepShortcutTextView.java @@ -28,7 +28,7 @@ import android.widget.Toast; import com.android.launcher3.BubbleTextView; import com.android.launcher3.R; import com.android.launcher3.Utilities; -import com.patrykmichalik.preferencemanager.PreferenceExtensionsKt; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import app.lawnchair.preferences2.PreferenceManager2; diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java index 0b4f2e53cd..797c68e597 100644 --- a/src/com/android/launcher3/views/OptionsPopupView.java +++ b/src/com/android/launcher3/views/OptionsPopupView.java @@ -52,8 +52,8 @@ import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.widget.picker.WidgetsFullSheet; -import com.patrykmichalik.preferencemanager.Preference; -import com.patrykmichalik.preferencemanager.PreferenceExtensionsKt; +import com.patrykmichalik.opto.domain.Preference; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import java.util.ArrayList; import java.util.List; From 5a60c2301162d544dd0052a7577b0232c0882a11 Mon Sep 17 00:00:00 2001 From: Patryk Michalik Date: Fri, 17 Jun 2022 18:39:52 +0200 Subject: [PATCH 8/9] Use `-opt-in` instead of `-Xopt-in` --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4c1ece0ff2..1f8e146bf8 100644 --- a/build.gradle +++ b/build.gradle @@ -78,7 +78,7 @@ allprojects { tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { kotlinOptions { - freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn" + freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn" } } } From 4581609fba7386ae797df859e1066e1a3d387839 Mon Sep 17 00:00:00 2001 From: Patryk Michalik Date: Fri, 17 Jun 2022 18:41:46 +0200 Subject: [PATCH 9/9] Use function references in `serializablePreference` declaration --- .../src/app/lawnchair/preferences2/PreferenceManager2.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt b/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt index e3ad9a714e..a78a8e785e 100644 --- a/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt +++ b/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt @@ -347,12 +347,12 @@ class PreferenceManager2(private val context: Context) : PreferenceManager { private inline fun serializablePreference( key: Preferences.Key, - defaultValue: T + defaultValue: T, ) = preference( key = key, defaultValue = defaultValue, - parse = { Json.decodeFromString(it) }, - save = { Json.encodeToString(it) } + parse = Json::decodeFromString, + save = Json::encodeToString, ) init {