Skip to content

Commit 857a8b5

Browse files
committed
writing category values on bottomsheet
1 parent 2369ef8 commit 857a8b5

File tree

24 files changed

+407
-170
lines changed

24 files changed

+407
-170
lines changed

Diff for: core/androidx/src/main/kotlin/br/com/mob1st/core/androidx/parcelables/BundleExtensions.kt

+16
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package br.com.mob1st.core.androidx.parcelables
22

33
import android.os.Build
44
import android.os.Bundle
5+
import android.os.Parcel
56
import android.os.Parcelable
67

78
/**
@@ -18,3 +19,18 @@ inline fun <reified T : Parcelable> Bundle.getParcelableAs(key: String): T? =
1819
@Suppress("DEPRECATION")
1920
getParcelable(key) as? T
2021
}
22+
23+
/**
24+
* Reads a [Parcelable] from the [Parcel].
25+
* It casts the result to the type [T], using different [Parcelable] methods depending on the Android version.
26+
* The android version is checked in order to safely call the correct [Parcel.readParcelable] method.
27+
* @param T The type of the [Parcelable] to be returned.
28+
* @return The [Parcelable] casted to the type [T] or null if the [Parcelable] is not found or if the cast fails.
29+
*/
30+
inline fun <reified T : Parcelable> Parcel.readParcelableAs(): T? =
31+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
32+
readParcelable(T::class.java.classLoader, T::class.java)
33+
} else {
34+
@Suppress("DEPRECATION")
35+
readParcelable(T::class.java.classLoader)
36+
}

Diff for: core/kotlinx/src/main/kotlin/br/com/mob1st/core/kotlinx/errors/Checks.kt renamed to core/kotlinx/src/main/kotlin/br/com/mob1st/core/kotlinx/checks/Checks.kt

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package br.com.mob1st.core.kotlinx.errors
1+
package br.com.mob1st.core.kotlinx.checks
22

33
/**
44
* Checks if the value is not null and is of type [T].
@@ -11,3 +11,13 @@ inline fun <reified T> checkIs(value: Any?): T {
1111
}
1212
return value
1313
}
14+
15+
/**
16+
* Invokes the given [block] if the this receiver is a type of [T]
17+
* @param block The block to be invoked
18+
*/
19+
inline fun <reified T> Any.ifIs(block: (T) -> Unit) {
20+
if (this is T) {
21+
block(this)
22+
}
23+
}

Diff for: core/kotlinx/src/main/kotlin/br/com/mob1st/core/kotlinx/errors/Exceptions.kt

-45
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package br.com.mob1st.core.kotlinx.structures
2+
3+
enum class AsyncTaskStatus {
4+
IDLE,
5+
RUNNING,
6+
COMPLETED,
7+
}

Diff for: core/kotlinx/src/main/kotlin/br/com/mob1st/core/kotlinx/structures/Money.kt

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ value class Money(
1313
*/
1414
operator fun plus(other: Money) = Money(cents + other.cents)
1515

16+
operator fun plus(other: Int) = Money(cents + other)
17+
1618
/**
1719
* Subtracts two [Money] values generating a new one.
1820
*/

Diff for: core/navigation/android/src/main/kotlin/br/com/mob1st/twocents/core/navigation/android/StandardAndroidNavigationApi.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class StandardAndroidNavigationApi(
1414
}
1515

1616
override fun back() {
17-
navHostController.popBackStack(route = false, inclusive = false)
17+
navHostController.popBackStack()
1818
}
1919

2020
override fun up() {

Diff for: features/finances/impl/src/main/kotlin/br/com/mob1st/features/finances/impl/dependencies/UiModule.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ private val categoriesModule = module {
3131
CategoryViewModel(
3232
default = get(),
3333
consumableDelegate = CategoryViewModel.consumableDelegate(),
34-
intent = params.get(),
34+
args = params.get(),
3535
getCategoryDetail = get(),
3636
setCategory = get(),
3737
categoryStateHandle = CategoryStateHandle(get()),

Diff for: features/finances/impl/src/main/kotlin/br/com/mob1st/features/finances/impl/domain/usecases/SetCategoryUseCase.kt

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package br.com.mob1st.features.finances.impl.domain.usecases
22

3+
import br.com.mob1st.core.observability.events.AnalyticsEvent
34
import br.com.mob1st.core.observability.events.AnalyticsReporter
45
import br.com.mob1st.features.finances.impl.domain.entities.Category
6+
import br.com.mob1st.features.finances.impl.domain.entities.Recurrences
57
import br.com.mob1st.features.finances.impl.domain.infra.repositories.CategoryRepository
68

79
internal class SetCategoryUseCase(
@@ -12,6 +14,24 @@ internal class SetCategoryUseCase(
1214
category: Category,
1315
) {
1416
categoryRepository.set(category)
15-
TODO()
17+
analyticsReporter.report(AnalyticsEvent.categorySent(category))
18+
}
19+
20+
private fun AnalyticsEvent.Companion.categorySent(
21+
category: Category,
22+
) = AnalyticsEvent(
23+
name = "category_sent",
24+
params = mapOf(
25+
"category_id" to category.id,
26+
"category_name" to category.name,
27+
"amount" to category.amount.cents,
28+
category.recurrences.keyValue(),
29+
),
30+
)
31+
32+
private fun Recurrences.keyValue() = when (this) {
33+
is Recurrences.Fixed -> "fixed" to day.value
34+
Recurrences.Variable -> "variable" to "weekly"
35+
is Recurrences.Seasonal -> "seasonal" to daysOfYear.map { it.value }.joinToString { "," }
1636
}
1737
}

Diff for: features/finances/impl/src/main/kotlin/br/com/mob1st/features/finances/impl/ui/builder/steps/BudgetBuilderStepViewModel.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ package br.com.mob1st.features.finances.impl.ui.builder.steps
33
import androidx.lifecycle.ViewModel
44
import androidx.lifecycle.viewModelScope
55
import br.com.mob1st.core.androidx.viewmodels.launchIn
6+
import br.com.mob1st.core.kotlinx.checks.checkIs
67
import br.com.mob1st.core.kotlinx.coroutines.DefaultCoroutineDispatcher
78
import br.com.mob1st.core.kotlinx.coroutines.stateInWhileSubscribed
8-
import br.com.mob1st.core.kotlinx.errors.checkIs
99
import br.com.mob1st.core.state.extensions.errorHandler
1010
import br.com.mob1st.core.state.managers.AsyncLoadingState
1111
import br.com.mob1st.core.state.managers.ConsumableDelegate

Diff for: features/finances/impl/src/main/kotlin/br/com/mob1st/features/finances/impl/ui/builder/steps/BuilderStepConsumables.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import arrow.optics.copy
99
import arrow.optics.optics
1010
import br.com.mob1st.core.design.organisms.snack.SnackbarState
1111
import br.com.mob1st.core.design.organisms.snack.snackbar
12-
import br.com.mob1st.core.kotlinx.errors.checkIs
12+
import br.com.mob1st.core.kotlinx.checks.checkIs
1313
import br.com.mob1st.features.finances.impl.R
1414
import br.com.mob1st.features.finances.impl.domain.entities.BudgetBuilderAction
1515
import br.com.mob1st.features.finances.impl.domain.entities.CategoryDefaultValues

Diff for: features/finances/impl/src/main/kotlin/br/com/mob1st/features/finances/impl/ui/category/detail/CategoryDetailConsumables.kt

+32-2
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,55 @@ package br.com.mob1st.features.finances.impl.ui.category.detail
22

33
import androidx.compose.runtime.Immutable
44
import arrow.optics.optics
5+
import br.com.mob1st.core.design.organisms.snack.SnackbarState
56
import br.com.mob1st.features.finances.impl.domain.entities.Recurrences
6-
import br.com.mob1st.features.utils.errors.CommonErrorSnackbarState
77

8+
/**
9+
* Consumables for the category detail screen.
10+
* @property dialog The dialog to be shown.
11+
* @property snackbarState The snackbar to be shown.
12+
* @property isSubmitted Indicates if the form was submitted or not.
13+
*/
814
@Immutable
915
@optics
1016
data class CategoryDetailConsumables(
1117
val dialog: Dialog? = null,
12-
val commonErrorSnackbarState: CommonErrorSnackbarState? = null,
18+
val snackbarState: SnackbarState? = null,
19+
val isSubmitted: Boolean = false,
1320
) {
21+
/**
22+
* The possible dialogs that can be consumed in the category detail screen.
23+
*/
1424
sealed interface Dialog
1525

26+
/**
27+
* Show the proper [Dialog] for the given [recurrences].
28+
* @param recurrences The recurrences to be shown.
29+
* @return A new [CategoryDetailConsumables] with the dialog set.
30+
*/
31+
fun showDialog(recurrences: Recurrences): CategoryDetailConsumables {
32+
return copy(dialog = CategoryCalendarDialog(recurrences))
33+
}
34+
35+
/**
36+
* For [optics] generation.
37+
*/
1638
companion object
1739
}
1840

41+
/**
42+
* Allows the user to type a new name for the category
43+
* @property name The name typed by the user that can be set as the new category name.
44+
*/
1945
@Immutable
2046
data class CategoryNameDialog(
2147
val name: String,
2248
) : CategoryDetailConsumables.Dialog
2349

50+
/**
51+
* Allows the user to set a new recurrence date for the category.
52+
* @property recurrences The recurrences that can be set as the new category recurrences.
53+
*/
2454
@Immutable
2555
data class CategoryCalendarDialog(
2656
val recurrences: Recurrences,

Diff for: features/finances/impl/src/main/kotlin/br/com/mob1st/features/finances/impl/ui/category/detail/CategoryDetailPage.kt

+12-11
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ internal fun CategoryDetailPage(
3939
onSubmit: () -> Unit,
4040
) {
4141
val viewModel = koinViewModel<CategoryViewModel>(
42-
parameters = { parametersOf(args.toIntent()) },
42+
parameters = { parametersOf(args) },
4343
)
4444
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
4545
val consumables by viewModel.consumableUiState.collectAsStateWithLifecycle()
@@ -58,18 +58,18 @@ internal fun CategoryDetailPage(
5858
CategoryPageSideEffects(
5959
snackbarHostState = snackbarHostState,
6060
args = args,
61-
isSubmitted = uiState.isDone,
61+
isSubmitted = consumables.isSubmitted,
6262
consumables = consumables,
6363
onDismissSnackbar = {
64-
viewModel.consume(CategoryDetailConsumables.nullableCommonErrorSnackbarState)
64+
viewModel.consume(CategoryDetailConsumables.nullableSnackbarState)
6565
},
6666
onSubmit = onSubmit,
6767
)
6868
}
6969

7070
@Composable
7171
private fun CategoryDetailPageScaffold(
72-
uiState: CategoryDetailState,
72+
uiState: CategoryDetailUiState,
7373
dialog: CategoryDetailConsumables.Dialog?,
7474
snackbarHostState: SnackbarHostState,
7575
onClickKey: (Key) -> Unit,
@@ -94,7 +94,7 @@ private fun CategoryDetailPageScaffold(
9494
@Composable
9595
private fun CategoryDetailPageContent(
9696
modifier: Modifier,
97-
uiState: CategoryDetailState,
97+
uiState: CategoryDetailUiState,
9898
dialog: CategoryDetailConsumables.Dialog?,
9999
onClickKey: (Key) -> Unit,
100100
onDismissDialog: () -> Unit,
@@ -117,22 +117,22 @@ private fun CategoryDetailPageContent(
117117
@Composable
118118
private fun Header(
119119
modifier: Modifier,
120-
uiState: CategoryDetailState,
120+
uiState: CategoryDetailUiState,
121121
) {
122122
Box(modifier = modifier) {
123123
when (uiState) {
124-
is CategoryDetailState.Loaded -> {
124+
is CategoryDetailUiState.Loaded -> {
125125
LoadedHeader(uiState = uiState)
126126
}
127127

128-
CategoryDetailState.Loading -> {}
128+
CategoryDetailUiState.Loading -> {}
129129
}
130130
}
131131
}
132132

133133
@Composable
134134
private fun LoadedHeader(
135-
uiState: CategoryDetailState.Loaded,
135+
uiState: CategoryDetailUiState.Loaded,
136136
) {
137137
Column(
138138
modifier = Modifier.fillMaxSize(),
@@ -186,7 +186,7 @@ private fun CategoryPageSideEffects(
186186
}
187187
SnackbarSideEffect(
188188
snackbarHostState = snackbarHostState,
189-
snackbarVisuals = consumables.commonErrorSnackbarState?.resolve(),
189+
snackbarVisuals = consumables.snackbarState?.resolve(),
190190
onDismiss = onDismissSnackbar,
191191
onPerformAction = {},
192192
)
@@ -211,8 +211,9 @@ private fun CategoryViewModel.onClickKey(key: Key) {
211211
private fun CategoryDetailScaffoldPreview() {
212212
PreviewTheme {
213213
CategoryDetailPageScaffold(
214-
uiState = CategoryDetailState.Loaded(
214+
uiState = CategoryDetailUiState.Loaded(
215215
category = CategoryFixtures.category,
216+
entry = CategoryEntry(CategoryFixtures.category),
216217
),
217218
dialog = null,
218219
snackbarHostState = SnackbarHostState(),

Diff for: features/finances/impl/src/main/kotlin/br/com/mob1st/features/finances/impl/ui/category/detail/CategoryDetailState.kt

-25
This file was deleted.

0 commit comments

Comments
 (0)