Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Migrated Payments Module to KMP #1791

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 52 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,63 @@ Mobile Wallet is an Android-based framework for mobile wallets based on top of <
<a href='https://github.com/openMF/mobile-wallet/wiki/Architecture'>clean architecture</a> and contains a core library module
that can be used as a dependency in any other wallet based project. It is developed at <a href='https://mifos.org/'>MIFOS</a> together with a global community.

## KMP Status for modules

| Module | Progress | Desktop supported | Android supported | iOS supported | Web supported(JS) | Web supported(WASM-JS) |
|-------------------------------|-------------------|-------------------|--------------------|-------------------|-------------------|------------------------|
| mifospay-android | In progress | ✔️ | ✔️ | ✔️ | ✔️ | ❔ |
| mifospay-desktop | In progress | ✔️ | ✔️ | ✔️ | ✔️ | ❔ |
| mifospay-web | In progress | ✔️ | ✔️ | ✔️ | ✔️ | ❔ |
| mifospay-ios | No implementation | No implementation | No implementation | No implementation | No implementation | No implementation |
| :core:analytics | Done | ❌ | ✔️ | ❌ | ❌ | ❌ |
| :core:common | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :core:data | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :core:datastore | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :core:datastore-proto | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :core:designsystem | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :core:domain | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :core:model | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :core:network | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :core:ui | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :feature:auth | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :feature:editpassword | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :feature:faq | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :feature:history | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :feature:home | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :feature:profile | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :feature:settings | Done | ✅ | ✅ | ❔ | ✅ | ❔ |
| :feature:payments | Done | ✅ | ✅ | ✅ | ✅ | ❔ |
| :feature:account | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |
| :feature:finance | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |
| :feature:invoices | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |
| :feature:kyc | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |
| :feature:make-transfer | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |
| :feature:merchants | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |
| :feature:notification | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |
| :feature:qr | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |
| :feature:receipt | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |
| :feature:request-money | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |
| :feature:saved-cards | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |
| :feature:search | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |
| :feature:send-money | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |
| :feature:standing-instruction | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |
| :feature:upi-setup | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |
| lint | Not started | ❌ | ❌ | ❌ | ❌ | ❌ |

✅: Functioning properly
❔: Not yet tested, but expected to work
✔️: Successfully compiled
❌: Not functioning, requires further attention

## Notice

:warning: We are fully committed to implement [Jetpack Compose](https://developer.android.com/jetpack/compose) and moving ourself to support
`kotlin multi-platform`. **If you are sending any PR regarding `XML changes` we will `not` consider at this moment but converting XML to jetpack compose are most welcome.** If you sending any PR regarding logical changes in Activity/Fragment you are most welcome.

`kotlin multi-platform`. **If you are sending any PR regarding `XML changes` we will `not` consider at this moment but converting XML to jetpack compose are most welcome.** If you sending any PR regarding logical changes in Activity/Fragment you are most welcome.


Development | Chat |
|-----------------|-----------------|
![Mobile-Wallet CI[Master/Dev]](https://github.com/openMF/mobile-wallet/workflows/Mobile-Wallet%20CI%5BMaster/Dev%5D/badge.svg?branch=dev) | [![Join the chat at https://mifos.slack.com/](https://img.shields.io/badge/Join%20Our%20Community-Slack-blue)](https://mifos.slack.com/) |
| Development | Chat |
|--------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------|
| ![Mobile-Wallet CI[Master/Dev]](https://github.com/openMF/mobile-wallet/workflows/Mobile-Wallet%20CI%5BMaster/Dev%5D/badge.svg?branch=dev) | [![Join the chat at https://mifos.slack.com/](https://img.shields.io/badge/Join%20Our%20Community-Slack-blue)](https://mifos.slack.com/) |


## Join Us on Slack
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,39 @@
*/
package org.mifospay.core.designsystem.component

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Tab
import androidx.compose.material3.Text
import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

@Composable
fun MifosTab(
text: String,
selected: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier,
selectedContentColor: Color = MaterialTheme.colorScheme.onSurface,
unselectedContentColor: Color = Color.LightGray,
selectedColor: Color = MaterialTheme.colorScheme.primary,
unselectedColor: Color = MaterialTheme.colorScheme.primaryContainer,
) {
Tab(
text = {
Text(
text = text,
color = MaterialTheme.colorScheme.onSurface,
)
Text(text = text)
},
selected = selected,
modifier = modifier,
selectedContentColor = selectedContentColor,
unselectedContentColor = unselectedContentColor,
onClick = onClick,
selectedContentColor = contentColorFor(selectedColor),
unselectedContentColor = contentColorFor(unselectedColor),
modifier = modifier
.clip(RoundedCornerShape(25.dp))
.background(if (selected) selectedColor else unselectedColor)
.padding(horizontal = 20.dp),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
*/
package org.mifospay.core.ui

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState
import androidx.compose.material3.MaterialTheme
Expand All @@ -24,16 +23,15 @@ import kotlinx.coroutines.launch
import org.mifospay.core.designsystem.component.MifosTab
import org.mifospay.core.ui.utility.TabContent

@OptIn(ExperimentalFoundationApi::class)
@Suppress("MultipleEmitters")
@Composable
fun MifosScrollableTabRow(
tabContents: List<TabContent>,
pagerState: PagerState,
modifier: Modifier = Modifier,
containerColor: Color = MaterialTheme.colorScheme.surface,
selectedContentColor: Color = MaterialTheme.colorScheme.onSurface,
unselectedContentColor: Color = Color.LightGray,
containerColor: Color = MaterialTheme.colorScheme.primaryContainer,
selectedContentColor: Color = MaterialTheme.colorScheme.primary,
unselectedContentColor: Color = MaterialTheme.colorScheme.primaryContainer,
edgePadding: Dp = 8.dp,
) {
val scope = rememberCoroutineScope()
Expand All @@ -43,13 +41,15 @@ fun MifosScrollableTabRow(
containerColor = containerColor,
selectedTabIndex = pagerState.currentPage,
edgePadding = edgePadding,
indicator = {},
divider = {},
) {
tabContents.forEachIndexed { index, currentTab ->
MifosTab(
text = currentTab.tabName,
selected = pagerState.currentPage == index,
selectedContentColor = selectedContentColor,
unselectedContentColor = unselectedContentColor,
selectedColor = selectedContentColor,
unselectedColor = unselectedContentColor,
onClick = {
scope.launch {
pagerState.animateScrollToPage(index)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
Expand All @@ -37,7 +38,7 @@ import org.mifospay.feature.history.components.HistoryScreenFilter
import org.mifospay.feature.history.components.TransactionList

@Composable
internal fun HistoryScreen(
fun HistoryScreen(
viewTransferDetail: (Long) -> Unit,
modifier: Modifier = Modifier,
viewModel: HistoryViewModel = koinViewModel(),
Expand Down Expand Up @@ -125,6 +126,7 @@ private fun HistoryScreenContent(
HistoryScreenFilter(
selectedTransactionType = selectedTransactionType,
onAction = onAction,
modifier = Modifier.padding(top = 8.dp),
)

TransactionList(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import org.mifospay.core.model.savingsaccount.Transaction
import org.mifospay.core.model.savingsaccount.TransactionType
import org.mifospay.core.ui.utils.BaseViewModel

internal class HistoryViewModel(
class HistoryViewModel(
private val preferencesRepository: UserPreferencesRepository,
private val repository: SelfServiceRepository,
) : BaseViewModel<HistoryState, HistoryEvent, HistoryAction>(
Expand Down Expand Up @@ -114,7 +114,7 @@ internal class HistoryViewModel(
}
}

internal data class HistoryState(
data class HistoryState(
val clientId: Long,
val viewState: ViewState,
val transactionType: TransactionType,
Expand Down
19 changes: 15 additions & 4 deletions feature/payments/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,25 @@
* See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md
*/
plugins {
alias(libs.plugins.mifospay.android.feature)
alias(libs.plugins.mifospay.android.library.compose)
alias(libs.plugins.mifospay.cmp.feature)
alias(libs.plugins.kotlin.parcelize)
}

android {
namespace = "org.mifospay.feature.payments"
}

dependencies {
implementation(libs.accompanist.pager)
kotlin {
sourceSets {
commonMain.dependencies {
implementation(compose.ui)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.components.resources)
implementation(compose.components.uiToolingPreview)

implementation(libs.koin.compose.viewmodel)
implementation(libs.koin.compose)
}
}
}
Empty file.
21 changes: 0 additions & 21 deletions feature/payments/proguard-rules.pro

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2024 Mifos Initiative

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file,
You can obtain one at https://mozilla.org/MPL/2.0/.

See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">

<path android:fillColor="#FFFFFF" android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z"/>

</vector>
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md
-->
<resources>
<string name="feature_payments_virtual_payment_address_vpa">Virtual Payment Address (VPA)</string>
<string name="feature_payments_vpa">Virtual Payment Address (VPA)</string>
<string name="feature_payments_mobile_number">Mobile Number</string>
<string name="feature_payments_receive">Receive</string>
<string name="feature_payments_show_code">Show code</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ package org.mifospay.feature.payments

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.google.accompanist.pager.rememberPagerState
import org.jetbrains.compose.ui.tooling.preview.Preview
import org.mifospay.core.ui.MifosScrollableTabRow
import org.mifospay.core.ui.utility.TabContent

Expand All @@ -34,9 +34,12 @@ private fun PaymentScreenContent(
tabContents: List<TabContent>,
modifier: Modifier = Modifier,
) {
val pagerState = rememberPagerState(initialPage = 0)
val pagerState = rememberPagerState(pageCount = { tabContents.size })

Column(modifier = modifier.fillMaxSize()) {
Column(
modifier = modifier
.fillMaxSize(),
) {
MifosScrollableTabRow(
tabContents = tabContents,
pagerState = pagerState,
Expand All @@ -52,7 +55,7 @@ enum class PaymentsScreenContents {
INVOICES,
}

@Preview(showBackground = true)
@Preview
@Composable
private fun PaymentsScreenPreview() {
PaymentScreenContent(
Expand Down
Loading
Loading