From aea0cadbfbf7e30263e88db5d11fadcf3c2dab50 Mon Sep 17 00:00:00 2001 From: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com> Date: Mon, 17 Oct 2022 02:32:48 +0700 Subject: [PATCH] Settings: Tint icon with primary color and separate info item layout (#8217) --- .../more/settings/PreferenceItem.kt | 4 + .../more/settings/PreferenceModel.kt | 19 ++-- .../settings/screen/SettingsBackupScreen.kt | 2 +- .../settings/screen/SettingsBrowseScreen.kt | 2 +- .../settings/screen/SettingsDownloadScreen.kt | 2 +- .../settings/screen/SettingsSearchScreen.kt | 3 +- .../settings/screen/SettingsSecurityScreen.kt | 2 +- .../settings/screen/SettingsTrackingScreen.kt | 4 +- .../settings/widget/BasePreferenceWidget.kt | 90 ++++--------------- .../more/settings/widget/InfoWidget.kt | 58 ++++++++++++ .../settings/widget/SwitchPreferenceWidget.kt | 21 ++--- .../settings/widget/TextPreferenceWidget.kt | 41 +++++++-- 12 files changed, 142 insertions(+), 106 deletions(-) create mode 100644 app/src/main/java/eu/kanade/presentation/more/settings/widget/InfoWidget.kt diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/PreferenceItem.kt b/app/src/main/java/eu/kanade/presentation/more/settings/PreferenceItem.kt index f4af9996e..acfc83f33 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/PreferenceItem.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/PreferenceItem.kt @@ -15,6 +15,7 @@ import eu.kanade.domain.track.service.TrackPreferences import eu.kanade.domain.ui.UiPreferences import eu.kanade.presentation.more.settings.widget.AppThemePreferenceWidget import eu.kanade.presentation.more.settings.widget.EditTextPreferenceWidget +import eu.kanade.presentation.more.settings.widget.InfoWidget import eu.kanade.presentation.more.settings.widget.ListPreferenceWidget import eu.kanade.presentation.more.settings.widget.MultiSelectListPreferenceWidget import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget @@ -163,6 +164,9 @@ internal fun PreferenceItem( ) } } + is Preference.PreferenceItem.InfoPreference -> { + InfoWidget(text = item.title) + } } } } diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/PreferenceModel.kt b/app/src/main/java/eu/kanade/presentation/more/settings/PreferenceModel.kt index 9c8337ab1..89c88c7f7 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/PreferenceModel.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/PreferenceModel.kt @@ -1,7 +1,5 @@ package eu.kanade.presentation.more.settings -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.outlined.Info import androidx.compose.ui.graphics.vector.ImageVector import eu.kanade.domain.ui.model.AppTheme import eu.kanade.tachiyomi.data.track.TrackService @@ -127,6 +125,15 @@ sealed class Preference { override val icon: ImageVector? = null override val onValueChanged: suspend (newValue: String) -> Boolean = { true } } + + data class InfoPreference( + override val title: String, + ) : PreferenceItem() { + override val enabled: Boolean = true + override val subtitle: String? = null + override val icon: ImageVector? = null + override val onValueChanged: suspend (newValue: String) -> Boolean = { true } + } } data class PreferenceGroup( @@ -135,12 +142,4 @@ sealed class Preference { val preferenceItems: List>, ) : Preference() - - companion object { - fun infoPreference(info: String) = PreferenceItem.TextPreference( - title = "", - subtitle = info, - icon = Icons.Outlined.Info, - ) - } } diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt index 02da01b1b..ef1389aab 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt @@ -356,7 +356,7 @@ class SettingsBackupScreen : SearchableSettings { title = stringResource(R.string.pref_backup_slots), entries = listOf(2, 3, 4, 5).associateWith { it.toString() }, ), - Preference.infoPreference(stringResource(R.string.backup_info)), + Preference.PreferenceItem.InfoPreference(stringResource(R.string.backup_info)), ), ) } diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBrowseScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBrowseScreen.kt index 01c7f0d15..f775903c6 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBrowseScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBrowseScreen.kt @@ -74,7 +74,7 @@ class SettingsBrowseScreen : SearchableSettings { ) }, ), - Preference.infoPreference(stringResource(R.string.parental_controls_info)), + Preference.PreferenceItem.InfoPreference(stringResource(R.string.parental_controls_info)), ), ), ) diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsDownloadScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsDownloadScreen.kt index 544a9413f..8a6e5a89a 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsDownloadScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsDownloadScreen.kt @@ -265,7 +265,7 @@ class SettingsDownloadScreen : SearchableSettings { } }, ), - Preference.infoPreference(stringResource(R.string.download_ahead_info)), + Preference.PreferenceItem.InfoPreference(stringResource(R.string.download_ahead_info)), ), ) } diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSearchScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSearchScreen.kt index 72bd4084f..8782dcba7 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSearchScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSearchScreen.kt @@ -182,9 +182,10 @@ private fun SearchResult( } } is Preference.PreferenceItem<*> -> sequenceOf(null to p) - else -> emptySequence() // Ignore other prefs } } + // Don't show info preference + .filterNot { it.second is Preference.PreferenceItem.InfoPreference } // Filter by search query .filter { (_, p) -> val inTitle = p.title.contains(searchKey, true) diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSecurityScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSecurityScreen.kt index 13503950e..0ac7d20a9 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSecurityScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSecurityScreen.kt @@ -76,7 +76,7 @@ class SettingsSecurityScreen : SearchableSettings { entries = SecurityPreferences.SecureScreenMode.values() .associateWith { stringResource(it.titleResId) }, ), - Preference.infoPreference(stringResource(R.string.secure_screen_summary)), + Preference.PreferenceItem.InfoPreference(stringResource(R.string.secure_screen_summary)), ) } } diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsTrackingScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsTrackingScreen.kt index 8eeb4054b..0a4ce1fb0 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsTrackingScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsTrackingScreen.kt @@ -145,7 +145,7 @@ class SettingsTrackingScreen : SearchableSettings { login = { context.openInBrowser(BangumiApi.authUrl(), forceDefaultBrowser = true) }, logout = { dialog = LogoutDialog(trackManager.bangumi) }, ), - Preference.infoPreference(stringResource(R.string.tracking_info)), + Preference.PreferenceItem.InfoPreference(stringResource(R.string.tracking_info)), ), ), Preference.PreferenceGroup( @@ -168,7 +168,7 @@ class SettingsTrackingScreen : SearchableSettings { }, logout = trackManager.komga::logout, ), - Preference.infoPreference(stringResource(R.string.enhanced_tracking_info)), + Preference.PreferenceItem.InfoPreference(stringResource(R.string.enhanced_tracking_info)), ), ), ) diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/widget/BasePreferenceWidget.kt b/app/src/main/java/eu/kanade/presentation/more/settings/widget/BasePreferenceWidget.kt index 3685813d7..ef720e77a 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/widget/BasePreferenceWidget.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/widget/BasePreferenceWidget.kt @@ -15,7 +15,6 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.sizeIn -import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -28,68 +27,18 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.composed import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import eu.kanade.presentation.more.settings.LocalPreferenceHighlighted -import eu.kanade.presentation.util.secondaryItemAlpha import kotlinx.coroutines.delay @Composable internal fun BasePreferenceWidget( modifier: Modifier = Modifier, - title: String, - subtitle: String? = null, - icon: ImageVector? = null, - onClick: (() -> Unit)? = null, - widget: @Composable (() -> Unit)? = null, -) { - BasePreferenceWidget( - modifier = modifier, - title = title, - subcomponent = if (!subtitle.isNullOrBlank()) { - { - Text( - text = subtitle, - modifier = Modifier - .padding( - start = HorizontalPadding, - top = 0.dp, - end = HorizontalPadding, - ) - .secondaryItemAlpha(), - style = MaterialTheme.typography.bodyMedium, - maxLines = 10, - ) - } - } else { - null - }, - icon = icon, - onClick = onClick, - widget = widget, - ) -} - -@Composable -internal fun BasePreferenceWidget( - modifier: Modifier = Modifier, - title: String, + title: String? = null, subcomponent: @Composable (ColumnScope.() -> Unit)? = null, - icon: ImageVector? = null, - onClick: (() -> Unit)? = null, - widget: @Composable (() -> Unit)? = null, -) { - BasePreferenceWidgetImpl(modifier, title, subcomponent, icon, onClick, widget) -} - -@Composable -private fun BasePreferenceWidgetImpl( - modifier: Modifier = Modifier, - title: String, - subcomponent: @Composable (ColumnScope.() -> Unit)? = null, - icon: ImageVector? = null, + icon: @Composable (() -> Unit)? = null, onClick: (() -> Unit)? = null, widget: @Composable (() -> Unit)? = null, ) { @@ -103,11 +52,9 @@ private fun BasePreferenceWidgetImpl( verticalAlignment = Alignment.CenterVertically, ) { if (icon != null) { - Icon( - imageVector = icon, - contentDescription = null, - modifier = Modifier - .padding(start = HorizontalPadding, end = 0.dp), + Box( + modifier = Modifier.padding(start = HorizontalPadding), + content = { icon() }, ) } Column( @@ -115,26 +62,23 @@ private fun BasePreferenceWidgetImpl( .weight(1f) .padding(vertical = 16.dp), ) { - if (title.isNotBlank()) { - Row( + if (!title.isNullOrBlank()) { + Text( modifier = Modifier.padding(horizontal = HorizontalPadding), - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - text = title, - overflow = TextOverflow.Ellipsis, - maxLines = 2, - style = MaterialTheme.typography.titleLarge, - fontSize = 20.sp, - ) - } + text = title, + overflow = TextOverflow.Ellipsis, + maxLines = 2, + style = MaterialTheme.typography.titleLarge, + fontSize = 20.sp, + ) } subcomponent?.invoke(this) } if (widget != null) { - Box(modifier = Modifier.padding(end = HorizontalPadding)) { - widget() - } + Box( + modifier = Modifier.padding(end = HorizontalPadding), + content = { widget() }, + ) } } } diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/widget/InfoWidget.kt b/app/src/main/java/eu/kanade/presentation/more/settings/widget/InfoWidget.kt new file mode 100644 index 000000000..243caaf4c --- /dev/null +++ b/app/src/main/java/eu/kanade/presentation/more/settings/widget/InfoWidget.kt @@ -0,0 +1,58 @@ +package eu.kanade.presentation.more.settings.widget + +import android.content.res.Configuration.UI_MODE_NIGHT_YES +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.Info +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +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.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import eu.kanade.presentation.theme.TachiyomiTheme +import eu.kanade.presentation.util.secondaryItemAlpha +import eu.kanade.tachiyomi.R + +@Composable +internal fun InfoWidget(text: String) { + Column( + modifier = Modifier + .padding(horizontal = HorizontalPadding, vertical = 16.dp) + .secondaryItemAlpha(), + verticalArrangement = Arrangement.spacedBy(16.dp), + ) { + Icon( + imageVector = Icons.Outlined.Info, + contentDescription = null, + ) + Text( + text = text, + style = MaterialTheme.typography.bodyMedium, + ) + } +} + +@Preview( + name = "Light", + showBackground = true, +) +@Preview( + name = "Dark", + showBackground = true, + uiMode = UI_MODE_NIGHT_YES, + +) +@Composable +private fun InfoWidgetPreview() { + TachiyomiTheme { + Surface { + InfoWidget(text = stringResource(id = R.string.download_ahead_info)) + } + } +} diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/widget/SwitchPreferenceWidget.kt b/app/src/main/java/eu/kanade/presentation/more/settings/widget/SwitchPreferenceWidget.kt index b1e6f8f66..da6b59189 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/widget/SwitchPreferenceWidget.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/widget/SwitchPreferenceWidget.kt @@ -20,23 +20,24 @@ fun SwitchPreferenceWidget( checked: Boolean = false, onCheckedChanged: (Boolean) -> Unit, ) { - BasePreferenceWidget( + TextPreferenceWidget( title = title, subtitle = subtitle, icon = icon, - onClick = { onCheckedChanged(!checked) }, - ) { - Switch( - checked = checked, - onCheckedChange = null, - modifier = Modifier.padding(start = TrailingWidgetBuffer), - ) - } + widget = { + Switch( + checked = checked, + onCheckedChange = null, + modifier = Modifier.padding(start = TrailingWidgetBuffer), + ) + }, + onPreferenceClick = { onCheckedChanged(!checked) }, + ) } @Preview @Composable -fun SwitchPreferenceWidgetPreview() { +private fun SwitchPreferenceWidgetPreview() { MaterialTheme { Surface { Column { diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/widget/TextPreferenceWidget.kt b/app/src/main/java/eu/kanade/presentation/more/settings/widget/TextPreferenceWidget.kt index 30f749a2f..ef5e1e526 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/widget/TextPreferenceWidget.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/widget/TextPreferenceWidget.kt @@ -1,37 +1,66 @@ package eu.kanade.presentation.more.settings.widget import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Preview +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface +import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.tooling.preview.Preview +import eu.kanade.presentation.util.secondaryItemAlpha @Composable fun TextPreferenceWidget( modifier: Modifier = Modifier, - title: String, + title: String? = null, subtitle: String? = null, icon: ImageVector? = null, + iconTint: Color = MaterialTheme.colorScheme.primary, + widget: @Composable (() -> Unit)? = null, onPreferenceClick: (() -> Unit)? = null, ) { BasePreferenceWidget( modifier = modifier, title = title, - subtitle = subtitle, - icon = icon, + subcomponent = if (!subtitle.isNullOrBlank()) { + { + Text( + text = subtitle, + modifier = Modifier + .padding(horizontal = HorizontalPadding) + .secondaryItemAlpha(), + style = MaterialTheme.typography.bodyMedium, + maxLines = 10, + ) + } + } else { + null + }, + icon = if (icon != null) { + { + Icon( + imageVector = icon, + tint = iconTint, + contentDescription = null, + ) + } + } else { + null + }, onClick = onPreferenceClick, + widget = widget, ) } @Preview @Composable -fun TextPreferenceWidgetPreview() { +private fun TextPreferenceWidgetPreview() { MaterialTheme { Surface { Column {