Skip to content
This repository has been archived by the owner on Mar 18, 2024. It is now read-only.

Commit

Permalink
Give life to some settings items in settings screen
Browse files Browse the repository at this point in the history
  • Loading branch information
AnkitSuda committed Nov 12, 2022
1 parent 637f0ec commit 652ff46
Show file tree
Hide file tree
Showing 10 changed files with 389 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright (c) 2022 Ankit Suda.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/

package com.ankitsuda.rebound.ui.components.settings

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp
import com.ankitsuda.base.util.isDark
import com.ankitsuda.rebound.ui.theme.LocalThemeState
import com.ankitsuda.rebound.ui.theme.ReboundTheme

@Composable
fun <A> PopupItemsSettingsItem(
modifier: Modifier = Modifier,
icon: ImageVector? = null,
text: String,
description: String = "",
selectedItem: A? = null,
items: List<Pair<A, String>>,
onItemSelected: (A) -> Unit
) {
var isMenuExpanded by remember {
mutableStateOf(false)
}

Box(modifier = modifier.clickable(onClick = {
isMenuExpanded = true
})) {
Row(
modifier = Modifier.padding(horizontal = 16.dp, vertical = 20.dp),
verticalAlignment = Alignment.CenterVertically
) {
if (icon != null) {
Icon(
imageVector = icon,
contentDescription = text,
tint = LocalThemeState.current.onBackgroundColor,
modifier = Modifier.padding(start = 2.dp, end = 18.dp)
)
}
Column(
modifier = Modifier.weight(1f)
) {
Text(
text = text,
color = LocalThemeState.current.onBackgroundColor
)
if (description.isNotEmpty()) {
Text(
text = description,
style = ReboundTheme.typography.caption,
color = ReboundTheme.colors.onBackground.copy(alpha = 0.8f),
)
}
}
Box {
DropdownMenu(
expanded = isMenuExpanded,
onDismissRequest = { isMenuExpanded = false }) {
for (item in items) {
val bgColor = if (selectedItem == item.first) {
if (MaterialTheme.colors.surface.isDark()) {
Color.White
} else {
Color.Black
}.copy(alpha = 0.1f)
} else {
Color.Transparent
}

DropdownMenuItem(
modifier = Modifier.background(bgColor),
onClick = {
isMenuExpanded = false
onItemSelected(item.first)
}) {
Text(text = item.second)
}
}
}
}
}
}
}
2 changes: 2 additions & 0 deletions modules/common-ui-resources/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,10 @@
<string name="defaults">Defaults</string>
<string name="weight_unit">Weight Unit</string>
<string name="metric_kg">Metric (kg)</string>
<string name="imperial_lbs">Imperial (lbs)</string>
<string name="distance_unit">Distance Unit</string>
<string name="metric_m_km">Metric (m/km)</string>
<string name="imperial_ft_miles">Metric (ft/miles)</string>
<string name="first_day_of_the_week">First Day of The Week</string>
<string name="sunday">Sunday</string>
<string name="your_data">Your Data</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ import androidx.datastore.preferences.core.*
import com.ankitsuda.base.ui.ThemeState
import com.ankitsuda.base.util.NONE_WORKOUT_ID
import com.ankitsuda.domain.models.Optional
import com.ankitsuda.rebound.domain.DistanceUnit
import com.ankitsuda.rebound.domain.DistanceUnitSerializer
import com.ankitsuda.rebound.domain.WeightUnit
import com.ankitsuda.rebound.domain.WeightUnitSerializer
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
Expand All @@ -39,29 +43,47 @@ class AppPreferences @Inject constructor(@ApplicationContext private val context

companion object {
val THEME_STATE_KEY = stringPreferencesKey(name = "theme_state")


// Current workout id
val CURRENT_WORKOUT_ID_KEY = stringPreferencesKey(name = "current_workout_id")
val WEIGHT_UNIT_KEY = stringPreferencesKey(name = "weight_unit")
val DISTANCE_UNIT_KEY = stringPreferencesKey(name = "distance_unit")
val FIRST_DAY_OF_WEEK_KEY = intPreferencesKey(name = "first_day_of_week")
}

override val themeState: Flow<ThemeState>
get() = getValue(THEME_STATE_KEY, ThemeState.serializer(), ThemeState())


override suspend fun setThemeState(value: ThemeState) {
setValue(THEME_STATE_KEY, value, ThemeState.serializer())

}


override val currentWorkoutId: Flow<String>
get() = getValue(CURRENT_WORKOUT_ID_KEY, NONE_WORKOUT_ID)

override suspend fun setCurrentWorkoutId(value: String) {
setValue(CURRENT_WORKOUT_ID_KEY, value)
}
// SMALL SHAPE ENDS

override val weightUnit: Flow<WeightUnit>
get() = getValue(WEIGHT_UNIT_KEY, WeightUnitSerializer, WeightUnit.KG)

override suspend fun setWeightUnit(value: WeightUnit) {
setValue(WEIGHT_UNIT_KEY, value, WeightUnitSerializer)
}

override val distanceUnit: Flow<DistanceUnit>
get() = getValue(DISTANCE_UNIT_KEY, DistanceUnitSerializer, DistanceUnit.KM)

override suspend fun setDistanceUnit(value: DistanceUnit) {
setValue(DISTANCE_UNIT_KEY, value, DistanceUnitSerializer)
}

override val firstDayOfWeek: Flow<Int>
get() = getValue(FIRST_DAY_OF_WEEK_KEY, 1)

override suspend fun setFirstDayOfWeek(value: Int) {
setValue(FIRST_DAY_OF_WEEK_KEY, value)
}

override suspend fun clearPreferenceStorage() {
datastoreUtils.clearPreferenceStorage()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
package com.ankitsuda.rebound.data.datastore

import com.ankitsuda.base.ui.ThemeState
import com.ankitsuda.rebound.domain.DistanceUnit
import com.ankitsuda.rebound.domain.WeightUnit
import kotlinx.coroutines.flow.Flow

interface PrefStorage {
Expand All @@ -25,6 +27,14 @@ interface PrefStorage {
val currentWorkoutId: Flow<String>
suspend fun setCurrentWorkoutId(value: String)

val weightUnit: Flow<WeightUnit>
suspend fun setWeightUnit(value: WeightUnit)

val distanceUnit: Flow<DistanceUnit>
suspend fun setDistanceUnit(value: DistanceUnit)

val firstDayOfWeek: Flow<Int>
suspend fun setFirstDayOfWeek(value: Int)

/***
* clears all the stored data
Expand Down
2 changes: 2 additions & 0 deletions modules/domain/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ plugins {
id "com.android.library"
id "kotlin-android"
id "kotlin-parcelize"
id "org.jetbrains.kotlin.plugin.serialization"

}

android {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2022 Ankit Suda.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/

package com.ankitsuda.rebound.domain

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.Serializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

@Serializable
enum class DistanceUnit(val value: String) {
KM("km"),
MILES("miles");

companion object {
fun fromValue(value: String): DistanceUnit {
return values().find { it.value == value } ?: KM
}
}
}

@OptIn(ExperimentalSerializationApi::class)
@Serializer(forClass = DistanceUnit::class)
object DistanceUnitSerializer : KSerializer<DistanceUnit> {
override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor("DistanceUnit", PrimitiveKind.STRING)

override fun serialize(encoder: Encoder, value: DistanceUnit) {
encoder.encodeString(value.value)
}

override fun deserialize(decoder: Decoder): DistanceUnit {
return try {
val key = decoder.decodeString()
DistanceUnit.fromValue(key)
} catch (e: IllegalArgumentException) {
DistanceUnit.KM
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2022 Ankit Suda.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/

package com.ankitsuda.rebound.domain

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.Serializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

@Serializable
enum class WeightUnit(val value: String) {
KG("kg"),
LBS("lbs");

companion object {
fun fromValue(value: String): WeightUnit {
return values().find { it.value == value } ?: KG
}
}
}

@OptIn(ExperimentalSerializationApi::class)
@Serializer(forClass = WeightUnit::class)
object WeightUnitSerializer : KSerializer<WeightUnit> {
override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor("WeightUnit", PrimitiveKind.STRING)

override fun serialize(encoder: Encoder, value: WeightUnit) {
encoder.encodeString(value.value)
}

override fun deserialize(decoder: Decoder): WeightUnit {
return try {
val key = decoder.decodeString()
WeightUnit.fromValue(key)
} catch (e: IllegalArgumentException) {
WeightUnit.KG
}
}
}
4 changes: 4 additions & 0 deletions modules/ui-settings/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ android {
}

compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
Expand All @@ -52,8 +53,11 @@ dependencies {
implementation project(":modules:common-ui-compose")
implementation project(":modules:common-ui-theme")
implementation project(":modules:common-ui-components")
implementation project(":modules:common-ui-components-settings")
implementation project(":modules:navigation")

coreLibraryDesugaring Deps.Android.desugaring

implementation Deps.Dagger.hilt
kapt Deps.Dagger.hiltCompiler
}
Loading

0 comments on commit 652ff46

Please sign in to comment.