Skip to content

Commit

Permalink
Feat: Migrated Accounts Module to KMP (#1793)
Browse files Browse the repository at this point in the history
* Feat: Migrated Accounts Module to KMP

* Updated README.md

* Update README.md
  • Loading branch information
niyajali authored Oct 19, 2024
1 parent 723b13b commit 20ba4ee
Show file tree
Hide file tree
Showing 196 changed files with 7,947 additions and 3,785 deletions.
86 changes: 46 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,54 @@ 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.

# Run the project
![Screenshot 2024-10-19 005524](https://github.com/user-attachments/assets/8023c529-1215-4c4b-b212-630f0233223f)
- To run the android-app select the `mifospay-android` run configuration and click run.
- To run the desktop-app select the `mifospay-desktop` run configuration and click run.
- To run the web-app-js select the `mifospay-web-js` run configuration and click run.

## 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:finance | Done || ||||
| :feature:account | 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 || ||||
| 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:finance | Done ||||||
| :feature:account | Done | | | | | |
| :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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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
*/
package org.mifospay.core.common

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart

sealed class DataState<out T> {
abstract val data: T?

data object Loading : DataState<Nothing>() {
override val data: Nothing? get() = null
}

data class Success<T>(
override val data: T,
) : DataState<T>()

data class Error<T>(
val exception: Throwable,
override val data: T? = null,
) : DataState<T>()
}

fun <T> Flow<T>.asDataStateFlow(): Flow<DataState<T>> =
map<T, DataState<T>> { DataState.Success(it) }
.onStart { emit(DataState.Loading) }
.catch { emit(DataState.Error(it, null)) }
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* 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
*/
package org.mifospay.core.common

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.transformWhile

inline fun <T : Any?, R : Any?> DataState<T>.map(
transform: (T) -> R,
): DataState<R> = when (this) {
is DataState.Success -> DataState.Success(transform(data))
is DataState.Loading -> DataState.Loading
is DataState.Error -> DataState.Error(exception, data?.let(transform))
}

inline fun <T : Any?, R : Any?> DataState<T>.mapNullable(
transform: (T?) -> R,
): DataState<R> = when (this) {
is DataState.Success -> DataState.Success(data = transform(data))
is DataState.Loading -> DataState.Loading
is DataState.Error -> DataState.Error(exception = exception, data = transform(data))
}

fun <T : Any?> Flow<DataState<T>>.takeUntilResultSuccess(): Flow<DataState<T>> = transformWhile {
emit(it)
it !is DataState.Success
}

fun <T1, T2, R> combineResults(
dataState1: DataState<T1>,
dataState2: DataState<T2>,
transform: (t1: T1, t2: T2) -> R,
): DataState<R> {
val nullableTransform: (T1?, T2?) -> R? = { t1, t2 ->
if (t1 != null && t2 != null) transform(t1, t2) else null
}

return when {
// Error states have highest priority, fail fast.
dataState1 is DataState.Error -> {
DataState.Error(
exception = dataState1.exception,
data = nullableTransform(dataState1.data, dataState2.data),
)
}

dataState2 is DataState.Error -> {
DataState.Error(
exception = dataState2.exception,
data = nullableTransform(dataState1.data, dataState2.data),
)
}

// Something is still loading, we will wait for all the data.
dataState1 is DataState.Loading || dataState2 is DataState.Loading -> DataState.Loading

// Pending state for everything while any one piece of data is updating.
// Both states are _root_ide_package_.org.mifospay.core.common.Result.Success and have data
else -> {
@Suppress("UNCHECKED_CAST")
DataState.Success(transform(dataState1.data as T1, dataState2.data as T2))
}
}
}

fun <T1, T2, T3, R> combineResults(
dataState1: DataState<T1>,
dataState2: DataState<T2>,
dataState3: DataState<T3>,
transform: (t1: T1, t2: T2, t3: T3) -> R,
): DataState<R> =
dataState1
.combineResultsWith(dataState2) { t1, t2 -> t1 to t2 }
.combineResultsWith(dataState3) { t1t2Pair, t3 ->
transform(t1t2Pair.first, t1t2Pair.second, t3)
}

fun <T1, T2, T3, T4, R> combineResults(
dataState1: DataState<T1>,
dataState2: DataState<T2>,
dataState3: DataState<T3>,
dataState4: DataState<T4>,
transform: (t1: T1, t2: T2, t3: T3, t4: T4) -> R,
): DataState<R> =
dataState1
.combineResultsWith(dataState2) { t1, t2 -> t1 to t2 }
.combineResultsWith(dataState3) { t1t2Pair, t3 ->
Triple(t1t2Pair.first, t1t2Pair.second, t3)
}
.combineResultsWith(dataState4) { t1t2t3Triple, t3 ->
transform(t1t2t3Triple.first, t1t2t3Triple.second, t1t2t3Triple.third, t3)
}

fun <T1, T2, R> DataState<T1>.combineResultsWith(
dataState2: DataState<T2>,
transform: (t1: T1, t2: T2) -> R,
): DataState<R> =
combineResults(this, dataState2, transform)
Loading

0 comments on commit 20ba4ee

Please sign in to comment.