From 78bf1462f40f96251847cd0a458c99ef9e5cc61d Mon Sep 17 00:00:00 2001 From: Suyash Mittal Date: Sun, 28 Jul 2024 23:37:00 +0530 Subject: [PATCH] fixed NPE and added soring to transactions --- app/build.gradle.kts | 15 ++- .../domain/util/order/CreditCardOrder.kt | 2 +- .../domain/util/order/EMIOrder.kt | 5 +- .../creditmanager/domain/util/order/Order.kt | 2 +- .../domain/util/order/TransactionOrder.kt | 19 +++- .../components/CustomActionBottomSheet.kt | 2 +- .../components/CustomSortingBottomSheet.kt | 11 +-- .../presentation/emis/EMIsScreen.kt | 2 +- .../presentation/emis/EMIsState.kt | 2 + .../transactions/TransactionsScreen.kt | 97 ++++++++++--------- .../transactions/TransactionsState.kt | 2 + 11 files changed, 93 insertions(+), 66 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 880d829..d5a26dc 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -16,8 +16,8 @@ android { applicationId = "com.suyash.creditmanager" minSdk = 26 targetSdk = 35 - versionCode = 24 - versionName = "1.0.23" + versionCode = 25 + versionName = "1.0.24" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { @@ -36,6 +36,16 @@ android { "proguard-rules.pro" ) } + create("staging") { + applicationIdSuffix = ".staging" + isDebuggable = true + isMinifyEnabled = true + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules-staging.pro" + ) + signingConfig = signingConfigs.getByName("debug") + } } compileOptions { sourceCompatibility = JavaVersion.VERSION_17 @@ -63,7 +73,6 @@ dependencies { val roomVersion = "2.6.1" val navVersion = "2.7.7" val workVersion = "2.9.0" - implementation("org.jetbrains.kotlin:kotlin-reflect:2.0.0") implementation("androidx.core:core-ktx:1.13.1") implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.4") implementation("androidx.appcompat:appcompat:1.7.0") diff --git a/app/src/main/java/com/suyash/creditmanager/domain/util/order/CreditCardOrder.kt b/app/src/main/java/com/suyash/creditmanager/domain/util/order/CreditCardOrder.kt index 0b6f0e3..62b88c9 100644 --- a/app/src/main/java/com/suyash/creditmanager/domain/util/order/CreditCardOrder.kt +++ b/app/src/main/java/com/suyash/creditmanager/domain/util/order/CreditCardOrder.kt @@ -1,7 +1,7 @@ package com.suyash.creditmanager.domain.util.order sealed class CreditCardOrder( - override val orderType: OrderType, + override var orderType: OrderType, override val label: String ) : Order { class Name(orderType: OrderType, label: String = "Name") : CreditCardOrder(orderType, label) diff --git a/app/src/main/java/com/suyash/creditmanager/domain/util/order/EMIOrder.kt b/app/src/main/java/com/suyash/creditmanager/domain/util/order/EMIOrder.kt index 1b18702..cd3a87d 100644 --- a/app/src/main/java/com/suyash/creditmanager/domain/util/order/EMIOrder.kt +++ b/app/src/main/java/com/suyash/creditmanager/domain/util/order/EMIOrder.kt @@ -1,13 +1,14 @@ package com.suyash.creditmanager.domain.util.order -sealed class EMIOrder(override val orderType: OrderType, override val label: String) : Order { +sealed class EMIOrder(override var orderType: OrderType, override val label: String) : Order { class Name(orderType: OrderType, label: String = "Name") : EMIOrder(orderType, label) class Amount(orderType: OrderType, label: String = "Amount") : EMIOrder(orderType, label) class Rate(orderType: OrderType, label: String = "Rate") : EMIOrder(orderType, label) class Months(orderType: OrderType, label: String = "Months") : EMIOrder(orderType, label) class Date(orderType: OrderType, label: String = "Date") : EMIOrder(orderType, label) class EMIsPaid(orderType: OrderType, label: String = "EMIs Paid") : EMIOrder(orderType, label) - class EMIsRemaining(orderType: OrderType, label: String = "EMIs Remaining") : EMIOrder(orderType, label) + class EMIsRemaining(orderType: OrderType, label: String = "EMIs Remaining") : + EMIOrder(orderType, label) companion object { fun getOrderList(): List { diff --git a/app/src/main/java/com/suyash/creditmanager/domain/util/order/Order.kt b/app/src/main/java/com/suyash/creditmanager/domain/util/order/Order.kt index f72abc6..49b3cf4 100644 --- a/app/src/main/java/com/suyash/creditmanager/domain/util/order/Order.kt +++ b/app/src/main/java/com/suyash/creditmanager/domain/util/order/Order.kt @@ -2,6 +2,6 @@ package com.suyash.creditmanager.domain.util.order sealed interface Order { - val orderType: OrderType + var orderType: OrderType val label: String } \ No newline at end of file diff --git a/app/src/main/java/com/suyash/creditmanager/domain/util/order/TransactionOrder.kt b/app/src/main/java/com/suyash/creditmanager/domain/util/order/TransactionOrder.kt index aa21ee0..7b0ee1f 100644 --- a/app/src/main/java/com/suyash/creditmanager/domain/util/order/TransactionOrder.kt +++ b/app/src/main/java/com/suyash/creditmanager/domain/util/order/TransactionOrder.kt @@ -1,6 +1,19 @@ package com.suyash.creditmanager.domain.util.order -sealed class TransactionOrder(val orderType: OrderType) { - class Date(orderType: OrderType): TransactionOrder(orderType) - class Amount(orderType: OrderType): TransactionOrder(orderType) +sealed class TransactionOrder( + override var orderType: OrderType, + override val label: String +) : Order { + class Date(orderType: OrderType, label: String = "Date") : TransactionOrder(orderType, label) + class Amount(orderType: OrderType, label: String = "Amount") : + TransactionOrder(orderType, label) + + companion object { + fun getOrderList(): List { + return listOf( + Date(OrderType.Descending), + Amount(OrderType.Ascending), + ) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/suyash/creditmanager/presentation/commons/components/CustomActionBottomSheet.kt b/app/src/main/java/com/suyash/creditmanager/presentation/commons/components/CustomActionBottomSheet.kt index d7b9847..437a95a 100644 --- a/app/src/main/java/com/suyash/creditmanager/presentation/commons/components/CustomActionBottomSheet.kt +++ b/app/src/main/java/com/suyash/creditmanager/presentation/commons/components/CustomActionBottomSheet.kt @@ -39,7 +39,7 @@ fun CustomActionBottomSheet( it.onClick() } .fillMaxWidth() - .padding(16.dp) + .padding(horizontal = 16.dp, vertical = 8.dp) ) { Icon(it.icon, it.iconName) Text(text = it.title, modifier = Modifier.padding(start = 16.dp)) diff --git a/app/src/main/java/com/suyash/creditmanager/presentation/commons/components/CustomSortingBottomSheet.kt b/app/src/main/java/com/suyash/creditmanager/presentation/commons/components/CustomSortingBottomSheet.kt index 1ff8c0e..af01a72 100644 --- a/app/src/main/java/com/suyash/creditmanager/presentation/commons/components/CustomSortingBottomSheet.kt +++ b/app/src/main/java/com/suyash/creditmanager/presentation/commons/components/CustomSortingBottomSheet.kt @@ -18,7 +18,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.suyash.creditmanager.domain.util.order.Order import com.suyash.creditmanager.domain.util.order.OrderType -import kotlin.reflect.full.primaryConstructor @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -44,15 +43,9 @@ fun CustomSortingBottomSheet( .clickable { onDismissRequest() if (currentOrder::class == it::class) { - sort( - currentOrder::class.primaryConstructor!!.call( - currentOrder.orderType.getReverse(), - currentOrder.label - ) - ) - } else { - sort(it) + it.orderType = currentOrder.orderType.getReverse() } + sort(it) } .fillMaxWidth() .padding(16.dp) diff --git a/app/src/main/java/com/suyash/creditmanager/presentation/emis/EMIsScreen.kt b/app/src/main/java/com/suyash/creditmanager/presentation/emis/EMIsScreen.kt index 8cf9c3c..aed4e8e 100644 --- a/app/src/main/java/com/suyash/creditmanager/presentation/emis/EMIsScreen.kt +++ b/app/src/main/java/com/suyash/creditmanager/presentation/emis/EMIsScreen.kt @@ -72,7 +72,7 @@ fun EMIsScreen( IconButton(onClick = { isSortBottomSheetOpen = true }) { Icon( imageVector = Icons.AutoMirrored.Filled.Sort, - contentDescription = "Sort Credit Cards" + contentDescription = "Sort EMIs" ) } } diff --git a/app/src/main/java/com/suyash/creditmanager/presentation/emis/EMIsState.kt b/app/src/main/java/com/suyash/creditmanager/presentation/emis/EMIsState.kt index 2244cca..c13ba72 100644 --- a/app/src/main/java/com/suyash/creditmanager/presentation/emis/EMIsState.kt +++ b/app/src/main/java/com/suyash/creditmanager/presentation/emis/EMIsState.kt @@ -1,10 +1,12 @@ package com.suyash.creditmanager.presentation.emis +import androidx.compose.runtime.Immutable import com.suyash.creditmanager.domain.model.EMI import com.suyash.creditmanager.domain.util.DateFormat import com.suyash.creditmanager.domain.util.order.EMIOrder import com.suyash.creditmanager.domain.util.order.OrderType +@Immutable data class EMIsState( val emis: List = emptyList(), val emiOrder: EMIOrder = EMIOrder.Name(OrderType.Ascending), diff --git a/app/src/main/java/com/suyash/creditmanager/presentation/transactions/TransactionsScreen.kt b/app/src/main/java/com/suyash/creditmanager/presentation/transactions/TransactionsScreen.kt index 280eade..20a5ad6 100644 --- a/app/src/main/java/com/suyash/creditmanager/presentation/transactions/TransactionsScreen.kt +++ b/app/src/main/java/com/suyash/creditmanager/presentation/transactions/TransactionsScreen.kt @@ -2,28 +2,25 @@ package com.suyash.creditmanager.presentation.transactions import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.Sort import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Edit import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar -import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf @@ -41,9 +38,13 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController +import com.suyash.creditmanager.domain.util.order.TransactionOrder import com.suyash.creditmanager.presentation.transactions.component.TransactionItem import com.suyash.creditmanager.presentation.commons.Screen +import com.suyash.creditmanager.presentation.commons.components.CustomActionBottomSheet import com.suyash.creditmanager.presentation.commons.components.CustomConfirmationDialog +import com.suyash.creditmanager.presentation.commons.components.CustomSortingBottomSheet +import com.suyash.creditmanager.presentation.commons.model.ItemAction @Composable @OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) @@ -52,8 +53,10 @@ fun TransactionsScreen( viewModel: TransactionsViewModel = hiltViewModel() ) { val haptics = LocalHapticFeedback.current - val bottomSheetState = rememberModalBottomSheetState() - var isBottomSheetOpen by rememberSaveable { + var isItemBottomSheetOpen by rememberSaveable { + mutableStateOf(false) + } + var isSortBottomSheetOpen by rememberSaveable { mutableStateOf(false) } var openDeleteConfirmationDialog by rememberSaveable { @@ -69,6 +72,14 @@ fun TransactionsScreen( topBar = { TopAppBar( title = { Text(text = "Transactions") }, + actions = { + IconButton(onClick = { isSortBottomSheetOpen = true }) { + Icon( + imageVector = Icons.AutoMirrored.Filled.Sort, + contentDescription = "Sort Transactions" + ) + } + } ) }, floatingActionButton = { @@ -116,7 +127,7 @@ fun TransactionsScreen( transaction ) ) - isBottomSheetOpen = true + isItemBottomSheetOpen = true } ) ) @@ -139,43 +150,39 @@ fun TransactionsScreen( onDismissButton = { openDeleteConfirmationDialog = false } ) } - if (isBottomSheetOpen) { - ModalBottomSheet( - sheetState = bottomSheetState, - onDismissRequest = { isBottomSheetOpen = false } - ) { - Column( - modifier = Modifier.padding(bottom = 16.dp) - ) { - Row( - modifier = Modifier - .clickable { - isBottomSheetOpen = false - navController.navigate( - Screen.AddEditTxnScreen.route + - "?txnId=${viewModel.state.value.selectedTransaction?.id}" - ) - } - .fillMaxWidth() - .padding(16.dp) - ) { - Icon(Icons.Filled.Edit, "Edit Txn") - Text(text = "Edit", modifier = Modifier.padding(start = 16.dp)) - } - Row( - modifier = Modifier - .clickable { - isBottomSheetOpen = false - openDeleteConfirmationDialog = true - } - .fillMaxWidth() - .padding(16.dp) - ) { - Icon(Icons.Filled.Delete, "Delete Txn") - Text(text = "Delete", modifier = Modifier.padding(start = 16.dp)) - } - } - } + if (isItemBottomSheetOpen) { + CustomActionBottomSheet( + onDismissRequest = { isItemBottomSheetOpen = false }, + actions = listOf( + ItemAction( + icon = Icons.Filled.Edit, + iconName = "Edit Transaction", + title = "Edit", + onClick = { + navController.navigate( + Screen.AddEditCCScreen.route + + "?ccId=${viewModel.state.value.selectedTransaction?.id}" + ) + } + ), + ItemAction( + icon = Icons.Filled.Delete, + iconName = "Delete Transaction", + title = "Delete", + onClick = { + openDeleteConfirmationDialog = true + } + ) + ) + ) + } + if (isSortBottomSheetOpen) { + CustomSortingBottomSheet( + onDismissRequest = { isSortBottomSheetOpen = false }, + orderList = TransactionOrder.getOrderList(), + currentOrder = viewModel.state.value.transactionOrder, + sort = { viewModel.onEvent(TransactionsEvent.Order(it)) } + ) } } } \ No newline at end of file diff --git a/app/src/main/java/com/suyash/creditmanager/presentation/transactions/TransactionsState.kt b/app/src/main/java/com/suyash/creditmanager/presentation/transactions/TransactionsState.kt index 480a32a..ebdf5a4 100644 --- a/app/src/main/java/com/suyash/creditmanager/presentation/transactions/TransactionsState.kt +++ b/app/src/main/java/com/suyash/creditmanager/presentation/transactions/TransactionsState.kt @@ -1,11 +1,13 @@ package com.suyash.creditmanager.presentation.transactions +import androidx.compose.runtime.Immutable import com.suyash.creditmanager.domain.model.CreditCard import com.suyash.creditmanager.domain.model.Transaction import com.suyash.creditmanager.domain.util.DateFormat import com.suyash.creditmanager.domain.util.order.OrderType import com.suyash.creditmanager.domain.util.order.TransactionOrder +@Immutable data class TransactionsState( val creditCards: Map = emptyMap(), val transactions: List = emptyList(),