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

This commit is contained in:
Ivan Iskandar 2022-10-17 02:32:48 +07:00 committed by GitHub
parent e4292719d3
commit aea0cadbfb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 142 additions and 106 deletions

View file

@ -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)
}
}
}
}

View file

@ -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,
)
}
}

View file

@ -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)),
),
)
}

View file

@ -74,7 +74,7 @@ class SettingsBrowseScreen : SearchableSettings {
)
},
),
Preference.infoPreference(stringResource(R.string.parental_controls_info)),
Preference.PreferenceItem.InfoPreference(stringResource(R.string.parental_controls_info)),
),
),
)

View file

@ -265,7 +265,7 @@ class SettingsDownloadScreen : SearchableSettings {
}
},
),
Preference.infoPreference(stringResource(R.string.download_ahead_info)),
Preference.PreferenceItem.InfoPreference(stringResource(R.string.download_ahead_info)),
),
)
}

View file

@ -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)

View file

@ -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)),
)
}
}

View file

@ -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)),
),
),
)

View file

@ -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() },
)
}
}
}

View file

@ -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))
}
}
}

View file

@ -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 {

View file

@ -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 {