Skip to content

Commit f531ea7

Browse files
committed
Implemented Savings Filter in Bottom Sheet
1 parent 43af85e commit f531ea7

File tree

4 files changed

+82
-82
lines changed

4 files changed

+82
-82
lines changed

cmp-android/prodRelease-badging.txt

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
package: name='org.mifos.mobile' versionCode='1' versionName='2024.12.4-beta.0.4' platformBuildVersionName='15' platformBuildVersionCode='35' compileSdkVersion='35' compileSdkVersionCodename='15'
2-
sdkVersion:'26'
1+
package: name='org.mifos.mobile' versionCode='1' versionName='0.0.4-beta.0.8' platformBuildVersionName='15' platformBuildVersionCode='35' compileSdkVersion='35' compileSdkVersionCodename='15'
2+
minSdkVersion:'26'
33
targetSdkVersion:'34'
44
uses-permission: name='android.permission.INTERNET'
55
uses-permission: name='android.permission.CAMERA'
6+
uses-permission: name='android.permission.VIBRATE'
67
uses-permission: name='android.permission.READ_EXTERNAL_STORAGE' maxSdkVersion='32'
78
uses-permission: name='android.permission.WRITE_EXTERNAL_STORAGE' maxSdkVersion='32'
8-
uses-permission: name='android.permission.VIBRATE'
9-
uses-permission: name='android.permission.FLASHLIGHT'
109
uses-permission: name='android.permission.ACCESS_NETWORK_STATE'
1110
uses-permission: name='android.permission.WAKE_LOCK'
1211
uses-permission: name='com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE'
@@ -38,6 +37,7 @@ application-label-es-US:'Mifos Mobile'
3837
application-label-et:'Mifos Mobile'
3938
application-label-eu:'Mifos Mobile'
4039
application-label-fa:'Mifos Mobile'
40+
application-label-fa-AF:'Mifos Mobile'
4141
application-label-fi:'Mifos Mobile'
4242
application-label-fr:'Mifos Mobile'
4343
application-label-fr-CA:'Mifos Mobile'
@@ -106,24 +106,21 @@ application-icon-480:'res/mipmap-anydpi-v26/ic_launcher.xml'
106106
application-icon-640:'res/mipmap-anydpi-v26/ic_launcher.xml'
107107
application-icon-65534:'res/mipmap-anydpi-v26/ic_launcher.xml'
108108
application: label='Mifos Mobile' icon='res/mipmap-anydpi-v26/ic_launcher.xml'
109-
launchable-activity: name='org.mifospay.MainActivity' label='' icon=''
110-
property: name='android.adservices.AD_SERVICES_CONFIG' resource='res/xml/ga_ad_services_config.xml'
109+
launchable-activity: name='cmp.android.app.MainActivity' label='' icon=''
110+
uses-library-not-required:'org.apache.http.legacy'
111111
uses-library-not-required:'androidx.window.extensions'
112112
uses-library-not-required:'androidx.window.sidecar'
113113
uses-library-not-required:'android.ext.adservices'
114114
feature-group: label=''
115-
uses-feature: name='android.hardware.camera'
116-
uses-feature: name='android.hardware.camera.autofocus'
117-
uses-feature: name='android.hardware.faketouch'
118-
uses-implied-feature: name='android.hardware.faketouch' reason='default feature for all apps'
119-
uses-feature: name='android.hardware.screen.portrait'
120-
uses-implied-feature: name='android.hardware.screen.portrait' reason='one or more activities have specified a portrait orientation'
115+
uses-gl-es: '0x20000'
116+
uses-feature-not-required: name='android.hardware.camera'
117+
uses-feature-not-required: name='android.hardware.touchscreen'
121118
main
122119
other-activities
123120
other-receivers
124121
other-services
125122
supports-screens: 'small' 'normal' 'large' 'xlarge'
126123
supports-any-density: 'true'
127-
locales: '--_--' 'af' 'am' 'ar' 'as' 'az' 'be' 'bg' 'bn' 'bs' 'ca' 'cs' 'da' 'de' 'el' 'en-AU' 'en-CA' 'en-GB' 'en-IN' 'en-XC' 'es' 'es-US' 'et' 'eu' 'fa' 'fi' 'fr' 'fr-CA' 'gl' 'gu' 'hi' 'hr' 'hu' 'hy' 'in' 'is' 'it' 'iw' 'ja' 'ka' 'kk' 'km' 'kn' 'ko' 'ky' 'lo' 'lt' 'lv' 'mk' 'ml' 'mn' 'mr' 'ms' 'my' 'nb' 'ne' 'nl' 'or' 'pa' 'pl' 'pt' 'pt-BR' 'pt-PT' 'ro' 'ru' 'si' 'sk' 'sl' 'sq' 'sr' 'sr-Latn' 'sv' 'sw' 'ta' 'te' 'th' 'tl' 'tr' 'uk' 'ur' 'uz' 'vi' 'zh-CN' 'zh-HK' 'zh-TW' 'zu'
124+
locales: '--_--' 'af' 'am' 'ar' 'as' 'az' 'be' 'bg' 'bn' 'bs' 'ca' 'cs' 'da' 'de' 'el' 'en-AU' 'en-CA' 'en-GB' 'en-IN' 'en-XC' 'es' 'es-US' 'et' 'eu' 'fa' 'fa-AF' 'fi' 'fr' 'fr-CA' 'gl' 'gu' 'hi' 'hr' 'hu' 'hy' 'in' 'is' 'it' 'iw' 'ja' 'ka' 'kk' 'km' 'kn' 'ko' 'ky' 'lo' 'lt' 'lv' 'mk' 'ml' 'mn' 'mr' 'ms' 'my' 'nb' 'ne' 'nl' 'or' 'pa' 'pl' 'pt' 'pt-BR' 'pt-PT' 'ro' 'ru' 'si' 'sk' 'sl' 'sq' 'sr' 'sr-Latn' 'sv' 'sw' 'ta' 'te' 'th' 'tl' 'tr' 'uk' 'ur' 'uz' 'vi' 'zh-CN' 'zh-HK' 'zh-TW' 'zu'
128125
densities: '160' '240' '320' '480' '640' '65534'
129126
native-code: 'arm64-v8a' 'armeabi-v7a' 'x86' 'x86_64'

core/designsystem/src/commonMain/kotlin/org/mifos/mobile/core/designsystem/component/MifosBottomSheet.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ fun MifosBottomSheet(
5454

5555
AnimatedVisibility(visible = showBottomSheet) {
5656
ModalBottomSheet(
57-
containerColor = Color.White,
57+
containerColor = Color.Black,
5858
onDismissRequest = {
5959
showBottomSheet = false
6060
dismissSheet()

feature/accounts/src/commonMain/kotlin/org/mifos/mobile/feature/accounts/accounts/AccountsScreen.kt

Lines changed: 51 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,19 @@ import androidx.compose.material3.HorizontalDivider
2222
import androidx.compose.material3.Surface
2323
import androidx.compose.runtime.Composable
2424
import androidx.compose.runtime.getValue
25-
import androidx.compose.runtime.mutableStateOf
2625
import androidx.compose.runtime.remember
27-
import androidx.compose.runtime.saveable.rememberSaveable
28-
import androidx.compose.runtime.setValue
2926
import androidx.compose.ui.Modifier
3027
import androidx.compose.ui.unit.dp
3128
import androidx.lifecycle.compose.collectAsStateWithLifecycle
3229
import mifos_mobile.feature.accounts.generated.resources.Res
33-
import mifos_mobile.feature.accounts.generated.resources.feature_account_title
3430
import mifos_mobile.feature.accounts.generated.resources.feature_loan_account_title
3531
import mifos_mobile.feature.accounts.generated.resources.feature_saving_account_title
3632
import mifos_mobile.feature.accounts.generated.resources.feature_share_account_title
3733
import org.jetbrains.compose.resources.stringResource
3834
import org.koin.compose.viewmodel.koinViewModel
3935
import org.mifos.mobile.core.designsystem.component.BasicDialogState
4036
import org.mifos.mobile.core.designsystem.component.MifosBasicDialog
37+
import org.mifos.mobile.core.designsystem.component.MifosBottomSheet
4138
import org.mifos.mobile.core.designsystem.component.MifosElevatedScaffold
4239
import org.mifos.mobile.core.designsystem.component.rememberMifosPullToRefreshState
4340
import org.mifos.mobile.core.designsystem.theme.DesignToken
@@ -115,17 +112,22 @@ internal fun AccountsDialog(
115112
onDismissRequest = { onAction(AccountsAction.DismissDialog) },
116113
)
117114
}
118-
AccountsState.DialogState.Filters -> SavingsAccountFilters(
119-
state = state,
120-
onAction = onAction,
115+
AccountsState.DialogState.Filters -> MifosBottomSheet(
116+
content = {
117+
SavingsAccountFilters(
118+
state = state,
119+
onAction = onAction,
120+
)
121+
},
121122
modifier = modifier,
123+
onDismiss = { onAction(AccountsAction.DismissDialog) },
122124
)
123125
null -> {}
124126
}
125127
}
126128

127129
/**
128-
* Composable function that displays the Savings Account Filters Dialog.
130+
* Composable function that displays the Savings Account Filters Bottom Bar.
129131
*
130132
* @param state The state of the screen.
131133
* @param onAction The function to be called when an action is performed.
@@ -137,68 +139,51 @@ internal fun SavingsAccountFilters(
137139
onAction: (AccountsAction) -> Unit,
138140
modifier: Modifier = Modifier,
139141
) {
140-
var isTypeExpanded by rememberSaveable { mutableStateOf(true) }
141-
var isStatusExpanded by rememberSaveable { mutableStateOf(true) }
142-
143-
MifosElevatedScaffold(
144-
onNavigateBack = { onAction(AccountsAction.OnNavigateBack) },
145-
topBarTitle = stringResource(Res.string.feature_account_title),
146-
bottomBar = {
147-
Surface {
148-
MifosPoweredCard(
149-
modifier = modifier
150-
.fillMaxWidth()
151-
.navigationBarsPadding(),
152-
)
153-
}
154-
},
142+
Column(
143+
modifier = modifier
144+
.fillMaxSize()
145+
.verticalScroll(rememberScrollState())
146+
.padding(DesignToken.padding.large)
147+
.padding(top = DesignToken.padding.large),
155148
) {
156-
Column(
157-
modifier = Modifier
158-
.fillMaxSize()
159-
.verticalScroll(rememberScrollState())
160-
.padding(DesignToken.padding.large)
161-
.padding(top = DesignToken.padding.large),
162-
) {
163-
FilterTopSection(
164-
isAnyFilterSelected = state.isAnyFilterSelected,
165-
resetFilters = {
166-
onAction(AccountsAction.ResetFilters)
167-
},
168-
onApplyFilter = {
169-
onAction(AccountsAction.GetFilterResults)
170-
},
171-
dismissDialog = {
172-
onAction(AccountsAction.DismissDialog)
173-
},
174-
)
149+
FilterTopSection(
150+
isAnyFilterSelected = state.isAnyFilterSelected,
151+
resetFilters = {
152+
onAction(AccountsAction.ResetFilters)
153+
},
154+
onApplyFilter = {
155+
onAction(AccountsAction.GetFilterResults)
156+
},
157+
dismissDialog = {
158+
onAction(AccountsAction.DismissDialog)
159+
},
160+
)
175161

176-
Spacer(Modifier.height(DesignToken.spacing.largeIncreased))
162+
Spacer(Modifier.height(DesignToken.spacing.largeIncreased))
177163

178-
HorizontalDivider(modifier = Modifier.height(1.dp))
164+
HorizontalDivider(modifier = Modifier.height(1.dp))
179165

180-
FilterSection(
181-
title = "Type",
182-
filtersSelected = state.accountTypeFiltersCount ?: 0,
183-
isExpanded = isTypeExpanded,
184-
onToggle = { isTypeExpanded = !isTypeExpanded },
185-
filters = state.checkboxOptions.filter { it.type == FilterType.ACCOUNT_TYPE },
186-
onCheckChanged = { label ->
187-
onAction(AccountsAction.ToggleCheckbox(label, FilterType.ACCOUNT_TYPE))
188-
},
189-
)
166+
FilterSection(
167+
title = "Type",
168+
filtersSelected = state.accountTypeFiltersCount ?: 0,
169+
isExpanded = state.isTypeExpanded,
170+
onToggle = { onAction(AccountsAction.ToggleTypeExpanded) },
171+
filters = state.checkboxOptions.filter { it.type == FilterType.ACCOUNT_TYPE },
172+
onCheckChanged = { label ->
173+
onAction(AccountsAction.ToggleCheckbox(label, FilterType.ACCOUNT_TYPE))
174+
},
175+
)
190176

191-
FilterSection(
192-
title = "Status",
193-
filtersSelected = state.accountStatusFiltersCount ?: 0,
194-
isExpanded = isStatusExpanded,
195-
onToggle = { isStatusExpanded = !isStatusExpanded },
196-
filters = state.checkboxOptions.filter { it.type == FilterType.ACCOUNT_STATUS },
197-
onCheckChanged = { label ->
198-
onAction(AccountsAction.ToggleCheckbox(label, FilterType.ACCOUNT_STATUS))
199-
},
200-
)
201-
}
177+
FilterSection(
178+
title = "Status",
179+
filtersSelected = state.accountStatusFiltersCount ?: 0,
180+
isExpanded = state.isStatusExpanded,
181+
onToggle = { onAction(AccountsAction.ToggleStatusExpanded) },
182+
filters = state.checkboxOptions.filter { it.type == FilterType.ACCOUNT_STATUS },
183+
onCheckChanged = { label ->
184+
onAction(AccountsAction.ToggleCheckbox(label, FilterType.ACCOUNT_STATUS))
185+
},
186+
)
202187
}
203188
}
204189

@@ -207,13 +192,11 @@ internal fun SavingsAccountFilters(
207192
*
208193
* @param state The state of the screen.
209194
* @param onAction The function to be called when an action is performed.
210-
* @param modifier Modifier to be applied to the layout.
211195
*/
212196
@Composable
213197
internal fun AccountScreenContent(
214198
state: AccountsState,
215199
onAction: (AccountsAction) -> Unit,
216-
modifier: Modifier = Modifier,
217200
) {
218201
val isRefreshing = state.isRefreshing
219202
val pullToRefreshState = rememberMifosPullToRefreshState(
@@ -235,7 +218,7 @@ internal fun AccountScreenContent(
235218
bottomBar = {
236219
Surface {
237220
MifosPoweredCard(
238-
modifier = modifier
221+
modifier = Modifier
239222
.fillMaxWidth()
240223
.navigationBarsPadding(),
241224
)

feature/accounts/src/commonMain/kotlin/org/mifos/mobile/feature/accounts/accounts/AccountsViewModel.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ internal class AccountsViewModel(
8383
is AccountsAction.OnNavigateBack -> sendEvent(AccountsEvent.NavigateBack)
8484

8585
is AccountsAction.ToggleCheckbox -> toggleCheckbox(action.label, action.type)
86+
AccountsAction.ToggleTypeExpanded -> handleToggleTypeExpanded()
87+
AccountsAction.ToggleStatusExpanded -> handleToggleStatusExpanded()
8688
}
8789
}
8890

@@ -97,6 +99,20 @@ internal class AccountsViewModel(
9799
}
98100
}
99101

102+
/**
103+
* Toggles the expanded state of the type filter section.
104+
*/
105+
private fun handleToggleTypeExpanded() {
106+
mutableStateFlow.update { it.copy(isTypeExpanded = !it.isTypeExpanded) }
107+
}
108+
109+
/**
110+
* Toggles the expanded state of the status filter section.
111+
*/
112+
private fun handleToggleStatusExpanded() {
113+
mutableStateFlow.update { it.copy(isStatusExpanded = !it.isStatusExpanded) }
114+
}
115+
100116
/**
101117
* Resets all filter checkboxes and filter counters.
102118
*/
@@ -231,6 +247,8 @@ constructor(
231247
val refreshSignal: Long = Clock.System.now().epochSeconds,
232248
val dialogState: DialogState? = null,
233249
val uiState: ScreenUiState = ScreenUiState.Loading,
250+
val isTypeExpanded: Boolean = true,
251+
val isStatusExpanded: Boolean = true,
234252
) {
235253

236254
sealed interface DialogState {
@@ -258,6 +276,8 @@ constructor(
258276
internal sealed interface AccountsAction {
259277

260278
data object ToggleFilter : AccountsAction
279+
data object ToggleTypeExpanded : AccountsAction
280+
data object ToggleStatusExpanded : AccountsAction
261281

262282
data object ResetFilters : AccountsAction
263283

0 commit comments

Comments
 (0)