Skip to content

Commit

Permalink
improved settings color selection
Browse files Browse the repository at this point in the history
  • Loading branch information
DatL4g committed Apr 29, 2024
1 parent a4f1190 commit 4456fc1
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 51 deletions.
2 changes: 1 addition & 1 deletion composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ kotlin {
implementation(libs.oidc)

implementation("dev.datlag.sheets-compose-dialogs:rating:2.0.0-SNAPSHOT")
// implementation("dev.datlag.sheets-compose-dialogs:option:2.0.0-SNAPSHOT")
implementation("dev.datlag.sheets-compose-dialogs:option:2.0.0-SNAPSHOT")

implementation(project(":firebase"))
implementation(project(":anilist"))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
package dev.datlag.aniflow.common

import androidx.compose.ui.graphics.Color
import dev.datlag.aniflow.SharedRes
import dev.icerock.moko.resources.StringResource
import dev.datlag.aniflow.settings.model.AppSettings

@OptIn(ExperimentalStdlibApi::class)
fun AppSettings.Color.toComposeColor() = Color(
this.hex.substringAfter('#').hexToLong() or 0x00000000FF000000
)
)

fun AppSettings.Color.toComposeString(): StringResource = when (this) {
is AppSettings.Color.Blue -> SharedRes.strings.color_blue
is AppSettings.Color.Purple -> SharedRes.strings.color_purple
is AppSettings.Color.Pink -> SharedRes.strings.color_pink
is AppSettings.Color.Orange -> SharedRes.strings.color_orange
is AppSettings.Color.Red -> SharedRes.strings.color_red
is AppSettings.Color.Green -> SharedRes.strings.color_green
is AppSettings.Color.Gray -> SharedRes.strings.color_gray
is AppSettings.Color.Custom -> SharedRes.strings.color_custom
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import kotlinx.coroutines.flow.Flow
interface SettingsComponent : Component {
val user: Flow<User?>
val adultContent: Flow<Boolean>
val selectedColor: Flow<AppSettings.Color?>

fun changeAdultContent(value: Boolean)
fun changeProfileColor(value: AppSettings.Color?)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Cancel
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.NoAdultContent
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.*
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
Expand All @@ -28,19 +25,27 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
import coil3.compose.rememberAsyncImagePainter
import com.maxkeppeker.sheets.core.models.base.IconSource
import com.maxkeppeker.sheets.core.models.base.rememberUseCaseState
import com.maxkeppeler.sheets.option.OptionDialog
import com.maxkeppeler.sheets.option.models.DisplayMode
import com.maxkeppeler.sheets.option.models.Option
import com.maxkeppeler.sheets.option.models.OptionConfig
import com.maxkeppeler.sheets.option.models.OptionSelection
import dev.chrisbanes.haze.haze
import dev.datlag.aniflow.LocalHaze
import dev.datlag.aniflow.LocalPaddingValues
import dev.datlag.aniflow.SharedRes
import dev.datlag.aniflow.common.plus
import dev.datlag.aniflow.common.toComposeColor
import dev.datlag.aniflow.common.toComposeString
import dev.datlag.aniflow.other.StateSaver
import dev.datlag.aniflow.settings.model.AppSettings
import dev.datlag.tooling.compose.onClick
import dev.datlag.tooling.decompose.lifecycle.collectAsStateWithLifecycle
import dev.icerock.moko.resources.compose.stringResource

@OptIn(ExperimentalLayoutApi::class, ExperimentalMaterial3WindowSizeClassApi::class)
@OptIn(ExperimentalLayoutApi::class, ExperimentalMaterial3WindowSizeClassApi::class, ExperimentalMaterial3Api::class)
@Composable
fun SettingsScreen(component: SettingsComponent) {
val padding = PaddingValues(16.dp)
Expand Down Expand Up @@ -120,29 +125,52 @@ fun SettingsScreen(component: SettingsComponent) {
}
}
item {
Text(
modifier = Modifier.padding(vertical = 16.dp),
text = "Profile Color",
style = MaterialTheme.typography.headlineSmall,
fontWeight = FontWeight.SemiBold
val selectedColor by component.selectedColor.collectAsStateWithLifecycle(null)
val useCase = rememberUseCaseState()
val colors = AppSettings.Color.all.toList()

OptionDialog(
state = useCase,
selection = OptionSelection.Single(
options = colors.map {
Option(
icon = IconSource(
imageVector = Icons.Filled.Circle,
tint = it.toComposeColor()
),
titleText = stringResource(it.toComposeString())
)
},
onSelectOption = { option, _ ->
component.changeProfileColor(colors[option])
}
),
config = OptionConfig(
mode = DisplayMode.GRID_VERTICAL,
gridColumns = 4
)
)
}
item {
FlowRow(

Row(
modifier = Modifier.fillParentMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically),
maxItemsInEachRow = when (calculateWindowSizeClass().widthSizeClass) {
WindowWidthSizeClass.Compact -> 4
else -> Int.MAX_VALUE
}
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
AppSettings.Color.all.forEach {
ColorItem(
color = it,
onClick = { chosen ->
component.changeProfileColor(chosen)
}
Icon(
imageVector = Icons.Default.Palette,
contentDescription = null,
)
Text(
text = "Profile Color"
)
Spacer(modifier = Modifier.weight(1F))
IconButton(
onClick = { useCase.show() }
) {
Icon(
imageVector = Icons.Filled.Circle,
contentDescription = null,
tint = selectedColor?.toComposeColor() ?: LocalContentColor.current
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class SettingsScreenComponent(

override val user: Flow<User?> = userHelper.user.flowOn(ioDispatcher())
override val adultContent: Flow<Boolean> = appSettings.adultContent.flowOn(ioDispatcher())
override val selectedColor: Flow<AppSettings.Color?> = appSettings.color.flowOn(ioDispatcher())

@Composable
override fun render() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import com.maxkeppeler.sheets.rating.RatingDialog
import com.maxkeppeler.sheets.rating.models.RatingBody
import com.maxkeppeler.sheets.rating.models.RatingConfig
import com.maxkeppeler.sheets.rating.models.RatingSelection
import com.maxkeppeler.sheets.rating.models.RatingViewStyle
import dev.chrisbanes.haze.haze
import dev.chrisbanes.haze.hazeChild
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
Expand All @@ -43,33 +42,10 @@ import dev.datlag.tooling.decompose.lifecycle.collectAsStateWithLifecycle
@Composable
fun MediumScreen(component: MediumComponent) {
val coverImage by component.coverImage.collectAsStateWithLifecycle()
val ratingState = rememberUseCaseState()
val userRating by component.rating.collectAsStateWithLifecycle()
val dialogState by component.dialog.subscribeAsState()

dialogState.child?.instance?.render()

RatingDialog(
state = ratingState,
selection = RatingSelection(
onSelectRating = { rating, _ ->
component.rate(rating)
}
),
header = Header.Default(
title = "Rate this Anime",
icon = IconSource(Icons.Filled.Star)
),
body = RatingBody.Default(
bodyText = ""
),
config = RatingConfig(
ratingOptionsCount = 5,
ratingOptionsSelected = userRating.takeIf { it > 0 },
ratingZeroValid = true
)
)

Box(
modifier = Modifier.fillMaxSize(),
) {
Expand Down Expand Up @@ -101,11 +77,35 @@ fun MediumScreen(component: MediumComponent) {
)
},
floatingActionButton = {
val userRating by component.rating.collectAsStateWithLifecycle()
val ratingState = rememberUseCaseState()

val alreadyAdded by component.alreadyAdded.collectAsStateWithLifecycle()
val notReleased by component.status.mapCollect {
it == MediaStatus.UNKNOWN__ || it == MediaStatus.NOT_YET_RELEASED
}

RatingDialog(
state = ratingState,
selection = RatingSelection(
onSelectRating = { rating, _ ->
component.rate(rating)
}
),
header = Header.Default(
title = "Rate this Anime",
icon = IconSource(Icons.Filled.Star)
),
body = RatingBody.Default(
bodyText = ""
),
config = RatingConfig(
ratingOptionsCount = 5,
ratingOptionsSelected = userRating.takeIf { it > 0 },
ratingZeroValid = true
)
)

if (!notReleased) {
EditFAB(
displayAdd = !alreadyAdded,
Expand Down
8 changes: 8 additions & 0 deletions composeApp/src/commonMain/moko-resources/base/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,12 @@
<string name="adult_content_setting">NSFW / Adult Content</string>
<string name="adult_content_prevent">NSFW / Adult Content is not enabled.</string>
<string name="back">Back</string>
<string name="color_blue">Blue</string>
<string name="color_purple">Purple</string>
<string name="color_pink">Pink</string>
<string name="color_orange">Orange</string>
<string name="color_red">Red</string>
<string name="color_green">Green</string>
<string name="color_gray">Gray</string>
<string name="color_custom">Custom</string>
</resources>

0 comments on commit 4456fc1

Please sign in to comment.