From 36f2a8caa83c185b5dc08e66cc6816e9bc02c7ea Mon Sep 17 00:00:00 2001 From: Guillermo Villafuerte Date: Sun, 31 Mar 2024 18:49:15 -0600 Subject: [PATCH] Added flags for app info fields visibility: package name, version name and version code. Signed-off-by: Guillermo Villafuerte --- .../ui/launcher/search/apps/AppItem.kt | 55 +++++++++++++------ .../ui/settings/icons/IconsSettingsScreen.kt | 25 +++++++++ .../settings/icons/IconsSettingsScreenVM.kt | 27 +++++++++ .../de/mm20/launcher2/search/Application.kt | 1 + core/i18n/src/main/res/values/strings.xml | 9 +++ .../preferences/LauncherSettingsData.kt | 4 ++ .../launcher2/preferences/ui/UiSettings.kt | 35 ++++++++++++ .../de/mm20/launcher2/applications/FakeApp.kt | 1 + .../launcher2/applications/LauncherApp.kt | 15 ++++- 9 files changed, 153 insertions(+), 19 deletions(-) diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/apps/AppItem.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/apps/AppItem.kt index 27dde7f08..4dece672f 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/apps/AppItem.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/apps/AppItem.kt @@ -66,6 +66,7 @@ import androidx.lifecycle.lifecycleScope import coil.compose.AsyncImage import com.google.accompanist.flowlayout.FlowRow import de.mm20.launcher2.crashreporter.CrashReporter +import de.mm20.launcher2.preferences.ui.UiSettings import de.mm20.launcher2.search.Application import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.component.DefaultToolbarAction @@ -82,6 +83,7 @@ import de.mm20.launcher2.ui.locals.LocalGridSettings import de.mm20.launcher2.ui.locals.LocalSnackbarHostState import de.mm20.launcher2.ui.modifier.scale import kotlinx.coroutines.launch +import org.koin.androidx.compose.inject @Composable fun AppItem( @@ -90,6 +92,7 @@ fun AppItem( onBack: () -> Unit ) { val viewModel: SearchableItemVM = listItemViewModel(key = "search-${app.key}") + val uiSettings: UiSettings by inject() val iconSize = LocalGridSettings.current.iconSize.dp.toPixels() LaunchedEffect(app) { @@ -124,25 +127,41 @@ fun AppItem( style = MaterialTheme.typography.labelSmall ) } - - - app.versionName?.let { - Text( - text = stringResource(R.string.app_info_version, it), - style = MaterialTheme.typography.bodySmall, - modifier = Modifier.padding(top = 4.dp), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) + val labelsSettings = uiSettings.devSettings.collectAsState(initial = null).value + if (labelsSettings?.anyFlagSet == true) { + Box(modifier = Modifier.padding(top = 4.dp)) + if (labelsSettings.showPackageName) { + Text( + text = app.componentName.packageName, + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.padding(top = 1.dp), + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } + if (labelsSettings.showVersionName) { + app.versionName?.let { + Text( + text = stringResource(R.string.app_info_version, it), + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.padding(top = 1.dp), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } + } + if (labelsSettings.showVersionCode) { + app.versionCode?.let { + Text( + text = stringResource(R.string.app_info_build, it), + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.padding(top = 1.dp), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } + } } - Text( - text = app.componentName.packageName, - style = MaterialTheme.typography.bodySmall, - modifier = Modifier.padding(top = 1.dp), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - FlowRow( modifier = Modifier .padding(top = 12.dp) diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/icons/IconsSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/icons/IconsSettingsScreen.kt index 434005950..db5778ab5 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/icons/IconsSettingsScreen.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/icons/IconsSettingsScreen.kt @@ -92,6 +92,10 @@ fun IconsSettingsScreen() { val shortcutBadges by viewModel.shortcutBadges.collectAsStateWithLifecycle(null) val pluginBadges by viewModel.pluginBadges.collectAsStateWithLifecycle(null) + val showPackageName by viewModel.showPackageName.collectAsState(initial = true) + val showVersionName by viewModel.showVersionName.collectAsState(initial = true) + val showVersionCode by viewModel.showVersionCode.collectAsState(initial = false) + val previewIcons by remember(grid?.iconSize) { viewModel.getPreviewIcons(with(density) { grid.iconSize.dp.toPx() }.toInt()) }.collectAsState( @@ -354,6 +358,27 @@ fun IconsSettingsScreen() { ) } } + item { + PreferenceCategory( + title = stringResource(R.string.preference_category_icons_advanced) + ) { + SwitchPreference( + title = stringResource(R.string.preference_show_package_name), + summary = stringResource(R.string.preference_show_package_name_summary), + value = showPackageName, + onValueChanged = { viewModel.setShowPackageName(it) }) + SwitchPreference( + title = stringResource(R.string.preference_show_version_name), + summary = stringResource(R.string.preference_show_version_name_summary), + value = showVersionName, + onValueChanged = { viewModel.setShowVersionName(it) }) + SwitchPreference( + title = stringResource(R.string.preference_show_version_code), + summary = stringResource(R.string.preference_show_version_code_summary), + value = showVersionCode, + onValueChanged = { viewModel.setShowVersionCode(it) }) + } + } } } diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/icons/IconsSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/icons/IconsSettingsScreenVM.kt index e367df1e7..c9a4acdc1 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/icons/IconsSettingsScreenVM.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/icons/IconsSettingsScreenVM.kt @@ -17,6 +17,7 @@ import de.mm20.launcher2.services.favorites.FavoritesService import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map import org.koin.core.component.KoinComponent import org.koin.core.component.get @@ -31,6 +32,7 @@ class IconsSettingsScreenVM( ) : ViewModel() { val grid = uiSettings.gridSettings + val dev = uiSettings.devSettings fun setColumnCount(columnCount: Int) { uiSettings.setGridColumnCount(columnCount) @@ -111,6 +113,31 @@ class IconsSettingsScreenVM( badgeSettings.setPlugins(plugins) } + val showPackageName: Flow = dev.map { + it.showPackageName + } + + fun setShowPackageName(showPackageName: Boolean) { + uiSettings.setShowPackageName(showPackageName) + } + + val showVersionName: Flow = dev.map { + it.showVersionName + } + + fun setShowVersionName(showVersionName: Boolean) { + uiSettings.setShowVersionName(showVersionName) + } + + val showVersionCode: Flow = dev.map { + it.showVersionCode + } + + fun setShowVersionCode(showVersionCode: Boolean) { + uiSettings.setShowVersionCode(showVersionCode) + } + + fun getPreviewIcons(size: Int): Flow> { return grid.flatMapLatest { grid -> favoritesService.getFavorites( diff --git a/core/base/src/main/java/de/mm20/launcher2/search/Application.kt b/core/base/src/main/java/de/mm20/launcher2/search/Application.kt index 4ad14fa61..b8d08cb71 100644 --- a/core/base/src/main/java/de/mm20/launcher2/search/Application.kt +++ b/core/base/src/main/java/de/mm20/launcher2/search/Application.kt @@ -26,6 +26,7 @@ interface Application: SavableSearchable { val profile: AppProfile val user: UserHandle val versionName: String? + val versionCode: String? override fun getPlaceholderIcon(context: Context): StaticLauncherIcon { return StaticLauncherIcon( diff --git a/core/i18n/src/main/res/values/strings.xml b/core/i18n/src/main/res/values/strings.xml index a65f9c9e9..20ea7790a 100644 --- a/core/i18n/src/main/res/values/strings.xml +++ b/core/i18n/src/main/res/values/strings.xml @@ -46,6 +46,8 @@ Search Version %1$s + + Build %1$s Settings @@ -570,6 +572,13 @@ Show a badge which indicates to which app a shortcut belongs Plugin badges Indicate by which plugin a search result was created + Advanced + Show app package name + Internal name used by Android to identify installed apps + Show app version + Used on store for app user to identify installed version + Show build number + Used internally by Android to compare versions during updates Sign in to Nextcloud Sign in to search your Nextcloud server Nextcloud 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 6c04462a0..a43719760 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 @@ -71,6 +71,10 @@ data class LauncherSettingsData( val gridIconSize: Int = 48, val gridLabels: Boolean = true, + val showPackageName: Boolean = true, + val showVersionName: Boolean = true, + val showVersionCode: Boolean = false, + val searchBarStyle: SearchBarStyle = SearchBarStyle.Transparent, val searchBarColors: SearchBarColors = SearchBarColors.Auto, val searchBarKeyboard: Boolean = true, diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/ui/UiSettings.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/ui/UiSettings.kt index 3d6e0162c..e906696a6 100644 --- a/core/preferences/src/main/java/de/mm20/launcher2/preferences/ui/UiSettings.kt +++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/ui/UiSettings.kt @@ -27,6 +27,15 @@ data class GridSettings( val showLabels: Boolean = true, ) +data class DevSettings( + val showPackageName: Boolean = true, + val showVersionName: Boolean = true, + val showVersionCode: Boolean = false +) { + val anyFlagSet: Boolean + get() = showPackageName || showVersionName || showVersionCode +} + class UiSettings internal constructor( private val launcherDataStore: LauncherDataStore, ) { @@ -71,6 +80,32 @@ class UiSettings internal constructor( } } + val devSettings + get() = launcherDataStore.data.map { + DevSettings( + showPackageName = it.showPackageName, + showVersionName = it.showVersionName, + showVersionCode = it.showVersionCode + ) + } + + fun setShowPackageName(showPackageName: Boolean) { + launcherDataStore.update { + it.copy(showPackageName = showPackageName) + } + } + + fun setShowVersionName(showVersionName: Boolean) { + launcherDataStore.update { + it.copy(showVersionName = showVersionName) + } + } + + fun setShowVersionCode(showVersionCode: Boolean) { + launcherDataStore.update { + it.copy(showVersionCode = showVersionCode) + } + } val cardStyle get() = launcherDataStore.data.map { diff --git a/data/applications/src/debug/java/de/mm20/launcher2/applications/FakeApp.kt b/data/applications/src/debug/java/de/mm20/launcher2/applications/FakeApp.kt index dd3afeef0..8862053d4 100644 --- a/data/applications/src/debug/java/de/mm20/launcher2/applications/FakeApp.kt +++ b/data/applications/src/debug/java/de/mm20/launcher2/applications/FakeApp.kt @@ -18,6 +18,7 @@ class FakeApp: Application { override val profile: AppProfile = AppProfile.Personal override val user: UserHandle = Process.myUserHandle() override val versionName: String = "1.0" + override val versionCode: String = "10000000" override val canUninstall: Boolean = false override fun uninstall(context: Context) { diff --git a/data/applications/src/main/java/de/mm20/launcher2/applications/LauncherApp.kt b/data/applications/src/main/java/de/mm20/launcher2/applications/LauncherApp.kt index 229a3a434..a0ba3df4f 100644 --- a/data/applications/src/main/java/de/mm20/launcher2/applications/LauncherApp.kt +++ b/data/applications/src/main/java/de/mm20/launcher2/applications/LauncherApp.kt @@ -1,5 +1,6 @@ package de.mm20.launcher2.applications +import android.annotation.SuppressLint import android.content.ActivityNotFoundException import android.content.ComponentName import android.content.Context @@ -16,6 +17,7 @@ import android.os.Process import android.os.UserHandle import androidx.core.content.FileProvider import androidx.core.content.getSystemService +import androidx.core.content.pm.PackageInfoCompat import de.mm20.launcher2.compat.PackageManagerCompat import de.mm20.launcher2.icons.ColorLayer import de.mm20.launcher2.icons.LauncherIcon @@ -35,6 +37,7 @@ import kotlinx.coroutines.withContext internal data class LauncherApp( private val launcherActivityInfo: LauncherActivityInfo, override val versionName: String?, + override val versionCode: String?, override val isSuspended: Boolean = false, internal val userSerialNumber: Long, override val labelOverride: String? = null, @@ -49,6 +52,7 @@ internal data class LauncherApp( constructor(context: Context, launcherActivityInfo: LauncherActivityInfo) : this( launcherActivityInfo, versionName = getPackageVersionName(context, launcherActivityInfo.applicationInfo.packageName), + versionCode = getPackageVersionCode(context, launcherActivityInfo.applicationInfo.packageName), userSerialNumber = launcherActivityInfo.user.getSerialNumber(context) ) @@ -185,7 +189,7 @@ internal data class LauncherApp( val launcherApps = context.getSystemService()!! val fileCopy = java.io.File( context.cacheDir, - "${componentName.packageName}-${versionName}.apk" + "${componentName.packageName}-${versionName}_${versionCode}.apk" ) withContext(Dispatchers.IO) { try { @@ -261,6 +265,15 @@ internal data class LauncherApp( } } + fun getPackageVersionCode(context: Context, packageName: String) : String? { + return try { + val info = context.packageManager.getPackageInfo(packageName, 0) + "${PackageInfoCompat.getLongVersionCode(info)}" + } catch (e: PackageManager.NameNotFoundException) { + null + } + } + const val Domain = "app" }