Browse Source

Settings: Tint icon with primary color and separate info item layout (#8217)

Ivan Iskandar 2 years ago
parent
commit
aea0cadbfb

+ 4 - 0
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)
+            }
         }
     }
 }

+ 9 - 10
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<String>() {
+            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<PreferenceItem<out Any>>,
     ) : Preference()
-
-    companion object {
-        fun infoPreference(info: String) = PreferenceItem.TextPreference(
-            title = "",
-            subtitle = info,
-            icon = Icons.Outlined.Info,
-        )
-    }
 }

+ 1 - 1
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)),
             ),
         )
     }

+ 1 - 1
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)),
                 ),
             ),
         )

+ 1 - 1
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)),
             ),
         )
     }

+ 2 - 1
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)

+ 1 - 1
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)),
         )
     }
 }

+ 2 - 2
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)),
                 ),
             ),
         )

+ 17 - 73
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() },
+                )
             }
         }
     }

+ 58 - 0
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))
+        }
+    }
+}

+ 11 - 10
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 {

+ 35 - 6
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 {