Allow more flexible custom preference composables

(cherry picked from commit 8ff0c9d61a1d5b1cc08a3615ef4bfa3d1f04a5d2)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/more/settings/PreferenceItem.kt
#	app/src/main/java/eu/kanade/presentation/more/settings/PreferenceModel.kt
This commit is contained in:
arkon 2023-07-26 22:57:15 -04:00 committed by Jobobby04
parent 2e9c265a45
commit 12b2d368ab
6 changed files with 61 additions and 88 deletions

View File

@ -5,28 +5,18 @@ import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.PeopleAlt
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.structuralEqualityPolicy import androidx.compose.runtime.structuralEqualityPolicy
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.domain.track.service.TrackPreferences 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.BasePreferenceWidget
import eu.kanade.presentation.more.settings.widget.EditTextPreferenceWidget import eu.kanade.presentation.more.settings.widget.EditTextPreferenceWidget
import eu.kanade.presentation.more.settings.widget.InfoWidget import eu.kanade.presentation.more.settings.widget.InfoWidget
import eu.kanade.presentation.more.settings.widget.ListPreferenceWidget import eu.kanade.presentation.more.settings.widget.ListPreferenceWidget
import eu.kanade.presentation.more.settings.widget.MultiSelectListPreferenceWidget import eu.kanade.presentation.more.settings.widget.MultiSelectListPreferenceWidget
import eu.kanade.presentation.more.settings.widget.PrefsHorizontalPadding
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import eu.kanade.presentation.more.settings.widget.TrackingPreferenceWidget import eu.kanade.presentation.more.settings.widget.TrackingPreferenceWidget
@ -34,7 +24,6 @@ import kotlinx.coroutines.launch
import tachiyomi.core.preference.PreferenceStore import tachiyomi.core.preference.PreferenceStore
import tachiyomi.presentation.core.components.SliderItem import tachiyomi.presentation.core.components.SliderItem
import tachiyomi.presentation.core.util.collectAsState import tachiyomi.presentation.core.util.collectAsState
import tachiyomi.presentation.core.util.secondaryItemAlpha
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -167,16 +156,6 @@ internal fun PreferenceItem(
}, },
) )
} }
is Preference.PreferenceItem.AppThemePreference -> {
val value by item.pref.collectAsState()
val amoled by Injekt.get<UiPreferences>().themeDarkAmoled().collectAsState()
AppThemePreferenceWidget(
title = item.title,
value = value,
amoled = amoled,
onItemClick = { scope.launch { item.pref.set(it) } },
)
}
is Preference.PreferenceItem.TrackingPreference -> { is Preference.PreferenceItem.TrackingPreference -> {
val uName by Injekt.get<PreferenceStore>() val uName by Injekt.get<PreferenceStore>()
.getString(TrackPreferences.trackUsername(item.service.id)) .getString(TrackPreferences.trackUsername(item.service.id))
@ -192,33 +171,9 @@ internal fun PreferenceItem(
is Preference.PreferenceItem.InfoPreference -> { is Preference.PreferenceItem.InfoPreference -> {
InfoWidget(text = item.title) InfoWidget(text = item.title)
} }
// SY --> is Preference.PreferenceItem.CustomPreference -> {
is Preference.PreferenceItem.MangaDexPreference -> { item.content(item)
BasePreferenceWidget(
title = item.title,
widget = {
Icon(
imageVector = Icons.Outlined.PeopleAlt,
contentDescription = null,
modifier = Modifier
.padding(start = 12.dp, end = PrefsHorizontalPadding)
.secondaryItemAlpha(),
tint = if (item.loggedIn) {
MaterialTheme.colorScheme.primary
} else {
MaterialTheme.colorScheme.onSurface
},
)
},
subcomponent = null,
onClick = if (item.loggedIn) {
item.logout
} else {
item.login
},
)
} }
// SY <--
} }
} }
} }

View File

@ -4,8 +4,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import eu.kanade.domain.ui.model.AppTheme
import eu.kanade.presentation.more.settings.Preference.PreferenceItem
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import tachiyomi.core.preference.Preference as PreferenceData import tachiyomi.core.preference.Preference as PreferenceData
@ -136,19 +134,6 @@ sealed class Preference {
override val onValueChanged: suspend (newValue: String) -> Boolean = { true }, override val onValueChanged: suspend (newValue: String) -> Boolean = { true },
) : PreferenceItem<String>() ) : PreferenceItem<String>()
/**
* A [PreferenceItem] that shows previews of [AppTheme] selection.
*/
data class AppThemePreference(
val pref: PreferenceData<AppTheme>,
override val title: String,
) : PreferenceItem<AppTheme>() {
override val enabled: Boolean = true
override val subtitle: String? = null
override val icon: ImageVector? = null
override val onValueChanged: suspend (newValue: AppTheme) -> Boolean = { true }
}
/** /**
* A [PreferenceItem] for individual tracking service. * A [PreferenceItem] for individual tracking service.
*/ */
@ -173,22 +158,15 @@ sealed class Preference {
override val onValueChanged: suspend (newValue: String) -> Boolean = { true } override val onValueChanged: suspend (newValue: String) -> Boolean = { true }
} }
// SY --> data class CustomPreference(
/**
* A [PreferenceItem] for mangadex login.
*/
data class MangaDexPreference(
override val title: String, override val title: String,
val loggedIn: Boolean, val content: @Composable (PreferenceItem<String>) -> Unit,
val login: () -> Unit,
val logout: () -> Unit,
) : PreferenceItem<String>() { ) : PreferenceItem<String>() {
override val enabled: Boolean = true override val enabled: Boolean = true
override val subtitle: String? = null override val subtitle: String? = null
override val icon: ImageVector? = null override val icon: ImageVector? = null
override val onValueChanged: suspend (newValue: String) -> Boolean = { true } override val onValueChanged: suspend (newValue: String) -> Boolean = { true }
} }
// SY <--
} }
data class PreferenceGroup( data class PreferenceGroup(

View File

@ -21,6 +21,7 @@ import eu.kanade.domain.ui.model.TabletUiMode
import eu.kanade.domain.ui.model.ThemeMode import eu.kanade.domain.ui.model.ThemeMode
import eu.kanade.domain.ui.model.setAppCompatDelegateThemeMode import eu.kanade.domain.ui.model.setAppCompatDelegateThemeMode
import eu.kanade.presentation.more.settings.Preference import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.more.settings.widget.AppThemePreferenceWidget
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.system.LocaleHelper
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
@ -63,8 +64,11 @@ object SettingsAppearanceScreen : SearchableSettings {
): Preference.PreferenceGroup { ): Preference.PreferenceGroup {
val themeModePref = uiPreferences.themeMode() val themeModePref = uiPreferences.themeMode()
val themeMode by themeModePref.collectAsState() val themeMode by themeModePref.collectAsState()
val appThemePref = uiPreferences.appTheme() val appThemePref = uiPreferences.appTheme()
val amoledPref = uiPreferences.themeDarkAmoled() val amoledPref = uiPreferences.themeDarkAmoled()
val amoled by amoledPref.collectAsState()
LaunchedEffect(themeMode) { LaunchedEffect(themeMode) {
setAppCompatDelegateThemeMode(themeMode) setAppCompatDelegateThemeMode(themeMode)
@ -95,10 +99,17 @@ object SettingsAppearanceScreen : SearchableSettings {
) )
}, },
), ),
Preference.PreferenceItem.AppThemePreference( Preference.PreferenceItem.CustomPreference(
title = stringResource(R.string.pref_app_theme), title = stringResource(R.string.pref_app_theme),
pref = appThemePref, ) { item ->
), val value by appThemePref.collectAsState()
AppThemePreferenceWidget(
title = item.title,
value = value,
amoled = amoled,
onItemClick = { appThemePref.set(it) },
)
},
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
pref = amoledPref, pref = amoledPref,
title = stringResource(R.string.pref_dark_theme_pure_black), title = stringResource(R.string.pref_dark_theme_pure_black),

View File

@ -8,8 +8,11 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.PeopleAlt
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Checkbox import androidx.compose.material3.Checkbox
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
@ -25,9 +28,12 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.domain.track.service.TrackPreferences import eu.kanade.domain.track.service.TrackPreferences
import eu.kanade.presentation.more.settings.Preference import eu.kanade.presentation.more.settings.Preference
import eu.kanade.presentation.more.settings.widget.BasePreferenceWidget
import eu.kanade.presentation.more.settings.widget.PrefsHorizontalPadding
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
import eu.kanade.tachiyomi.source.online.all.MangaDex import eu.kanade.tachiyomi.source.online.all.MangaDex
@ -42,6 +48,7 @@ import tachiyomi.core.util.system.logcat
import tachiyomi.domain.UnsortedPreferences import tachiyomi.domain.UnsortedPreferences
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.util.collectAsState import tachiyomi.presentation.core.util.collectAsState
import tachiyomi.presentation.core.util.secondaryItemAlpha
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -93,7 +100,7 @@ object SettingsMangadexScreen : SearchableSettings {
} }
@Composable @Composable
fun loginPreference(mdex: MangaDex, trackPreferences: TrackPreferences): Preference.PreferenceItem.MangaDexPreference { fun loginPreference(mdex: MangaDex, trackPreferences: TrackPreferences): Preference.PreferenceItem.CustomPreference {
val context = LocalContext.current val context = LocalContext.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val loggedIn by remember { trackPreferences.trackToken(mdex.mdList) }.collectAsState() val loggedIn by remember { trackPreferences.trackToken(mdex.mdList) }.collectAsState()
@ -124,17 +131,39 @@ object SettingsMangadexScreen : SearchableSettings {
}, },
) )
} }
return Preference.PreferenceItem.MangaDexPreference( return Preference.PreferenceItem.CustomPreference(
title = mdex.name + " Login", title = mdex.name + " Login",
loggedIn = loggedIn.isNotEmpty(), content = {
login = { BasePreferenceWidget(
title = it.title,
widget = {
Icon(
imageVector = Icons.Outlined.PeopleAlt,
contentDescription = null,
modifier = Modifier
.padding(start = 12.dp, end = PrefsHorizontalPadding)
.secondaryItemAlpha(),
tint = if (loggedIn.isNotEmpty()) {
MaterialTheme.colorScheme.primary
} else {
MaterialTheme.colorScheme.onSurface
},
)
},
subcomponent = null,
onClick = if (loggedIn.isNotEmpty()) {
{
logoutDialogOpen = true
}
} else {
{
context.openInBrowser( context.openInBrowser(
MdConstants.Login.authUrl(MdUtil.getPkceChallengeCode()), MdConstants.Login.authUrl(MdUtil.getPkceChallengeCode()),
forceDefaultBrowser = true, forceDefaultBrowser = true,
) )
}
}, },
logout = { )
logoutDialogOpen = true
}, },
) )
} }

View File

@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
@ -30,7 +31,6 @@ import nl.adaptivity.xmlutil.serialization.XML
import nl.adaptivity.xmlutil.serialization.XmlSerialName import nl.adaptivity.xmlutil.serialization.XmlSerialName
import nl.adaptivity.xmlutil.serialization.XmlValue import nl.adaptivity.xmlutil.serialization.XmlValue
import tachiyomi.core.util.lang.withIOContext import tachiyomi.core.util.lang.withIOContext
import tachiyomi.presentation.core.components.material.Divider
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
@Composable @Composable
@ -72,7 +72,7 @@ fun WhatsNewDialog(onDismissRequest: () -> Unit) {
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
style = MaterialTheme.typography.titleSmall, style = MaterialTheme.typography.titleSmall,
) )
Divider(Modifier.padding(vertical = 8.dp)) HorizontalDivider(Modifier.padding(vertical = 8.dp))
Column( Column(
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small), verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
) { ) {

View File

@ -25,6 +25,7 @@ import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Switch import androidx.compose.material3.Switch
import androidx.compose.material3.Text import androidx.compose.material3.Text
@ -56,7 +57,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import tachiyomi.presentation.core.components.ScrollbarLazyColumn import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.Divider
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.topSmallPaddingValues import tachiyomi.presentation.core.components.material.topSmallPaddingValues
import tachiyomi.presentation.core.screens.LoadingScreen import tachiyomi.presentation.core.screens.LoadingScreen
@ -153,7 +153,7 @@ class SettingsDebugScreen : Screen() {
) )
} }
item { item {
Divider() HorizontalDivider()
} }
item { item {
Text( Text(