Skip to content

Commit ca4ac61

Browse files
refactor #1532: migrated profile screen to compose
1 parent b215617 commit ca4ac61

File tree

8 files changed

+441
-125
lines changed

8 files changed

+441
-125
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.mifos.mobilewallet.mifospay.designsystem.component
2+
3+
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.layout.Box
5+
import androidx.compose.foundation.layout.size
6+
import androidx.compose.foundation.shape.CircleShape
7+
import androidx.compose.material3.MaterialTheme
8+
import androidx.compose.material3.Text
9+
import androidx.compose.runtime.Composable
10+
import androidx.compose.ui.Alignment
11+
import androidx.compose.ui.Modifier
12+
import androidx.compose.ui.draw.clip
13+
import androidx.compose.ui.platform.LocalDensity
14+
import androidx.compose.ui.unit.Dp
15+
import androidx.compose.ui.unit.dp
16+
17+
@Composable
18+
fun MifosTextUserImage(modifier: Modifier = Modifier, text: String, size: Dp = 100.dp) {
19+
Box(
20+
modifier = modifier
21+
.size(size)
22+
.clip(CircleShape)
23+
.background(color = MaterialTheme.colorScheme.primary),
24+
contentAlignment = Alignment.Center
25+
) {
26+
Text(
27+
text = text,
28+
color = MaterialTheme.colorScheme.onPrimary,
29+
fontSize = with(LocalDensity.current) { (size / 2).toSp() }
30+
)
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package org.mifos.mobilewallet.mifospay.home.presenter
2+
3+
import android.graphics.Bitmap
4+
import android.graphics.BitmapFactory
5+
import androidx.lifecycle.ViewModel
6+
import androidx.lifecycle.viewModelScope
7+
import dagger.hilt.android.lifecycle.HiltViewModel
8+
import kotlinx.coroutines.flow.MutableStateFlow
9+
import kotlinx.coroutines.flow.StateFlow
10+
import kotlinx.coroutines.launch
11+
import okhttp3.ResponseBody
12+
import org.mifos.mobilewallet.core.base.UseCase
13+
import org.mifos.mobilewallet.core.base.UseCaseHandler
14+
import org.mifos.mobilewallet.core.domain.usecase.client.FetchClientImage
15+
import org.mifos.mobilewallet.datastore.PreferencesHelper
16+
import org.mifos.mobilewallet.mifospay.common.DebugUtil
17+
import org.mifos.mobilewallet.mifospay.data.local.LocalRepository
18+
import javax.inject.Inject
19+
20+
@HiltViewModel
21+
class ProfileViewModel @Inject constructor(
22+
private val mUsecaseHandler: UseCaseHandler,
23+
private val fetchClientImageUseCase: FetchClientImage,
24+
private val localRepository: LocalRepository,
25+
private val mPreferencesHelper: PreferencesHelper
26+
) : ViewModel() {
27+
28+
private val _profileState = MutableStateFlow<ProfileUiState>(ProfileUiState.Loading)
29+
val profileState: StateFlow<ProfileUiState> get() = _profileState
30+
31+
init {
32+
fetchClientImage()
33+
fetchProfileDetails()
34+
}
35+
36+
private fun fetchClientImage() {
37+
viewModelScope.launch {
38+
mUsecaseHandler.execute(fetchClientImageUseCase,
39+
FetchClientImage.RequestValues(localRepository.clientDetails.clientId),
40+
object : UseCase.UseCaseCallback<FetchClientImage.ResponseValue?> {
41+
override fun onSuccess(response: FetchClientImage.ResponseValue?) {
42+
val bitmap = convertResponseToBitmap(response?.responseBody)
43+
val currentState = _profileState.value as ProfileUiState.Success
44+
_profileState.value = currentState.copy(bitmapImage = bitmap)
45+
}
46+
47+
override fun onError(message: String) {
48+
DebugUtil.log("image", message)
49+
}
50+
})
51+
}
52+
}
53+
54+
private fun fetchProfileDetails() {
55+
val name = mPreferencesHelper.fullName ?: "-"
56+
val email = mPreferencesHelper.email ?: "-"
57+
val vpa = mPreferencesHelper.clientVpa ?: "-"
58+
val mobile = mPreferencesHelper.mobile ?: "-"
59+
60+
_profileState.value = ProfileUiState.Success(
61+
name = name,
62+
email = email,
63+
vpa = vpa,
64+
mobile = mobile
65+
)
66+
}
67+
68+
private fun convertResponseToBitmap(responseBody: ResponseBody?): Bitmap? {
69+
return try {
70+
responseBody?.byteStream()?.use { inputStream ->
71+
BitmapFactory.decodeStream(inputStream)
72+
}
73+
} catch (e: Exception) {
74+
null
75+
}
76+
}
77+
}
78+
79+
sealed class ProfileUiState {
80+
data object Loading : ProfileUiState()
81+
data class Success(
82+
val bitmapImage: Bitmap? = null,
83+
val name: String?,
84+
val email: String?,
85+
val vpa: String?,
86+
val mobile: String?
87+
) : ProfileUiState()
88+
}
89+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.mifos.mobilewallet.mifospay.designsystem.component
2+
3+
import android.graphics.Bitmap
4+
import androidx.compose.foundation.Image
5+
import androidx.compose.foundation.background
6+
import androidx.compose.foundation.shape.CircleShape
7+
import androidx.compose.material3.MaterialTheme
8+
import androidx.compose.runtime.Composable
9+
import androidx.compose.ui.Modifier
10+
import androidx.compose.ui.draw.clip
11+
import androidx.compose.ui.graphics.asImageBitmap
12+
import androidx.compose.ui.layout.ContentScale
13+
14+
/**
15+
* @author pratyush
16+
* @since 20/12/2023
17+
*/
18+
19+
@Composable
20+
fun MifosUserImage(
21+
bitmap: Bitmap?,
22+
modifier: Modifier = Modifier,
23+
username: String? = null
24+
) {
25+
if (bitmap == null) {
26+
MifosTextUserImage(
27+
modifier = modifier,
28+
text = username?.firstOrNull()?.toString() ?: "J"
29+
)
30+
} else {
31+
Image(
32+
modifier = modifier
33+
.clip(CircleShape)
34+
.background(MaterialTheme.colorScheme.primary),
35+
bitmap = bitmap.asImageBitmap(),
36+
contentDescription = "Profile Image",
37+
contentScale = ContentScale.Crop,
38+
)
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.mifos.mobilewallet.mifospay.home.ui
2+
3+
import android.graphics.Bitmap
4+
import androidx.compose.foundation.border
5+
import androidx.compose.foundation.layout.Arrangement
6+
import androidx.compose.foundation.layout.Box
7+
import androidx.compose.foundation.layout.Row
8+
import androidx.compose.foundation.layout.fillMaxWidth
9+
import androidx.compose.foundation.layout.padding
10+
import androidx.compose.foundation.layout.size
11+
import androidx.compose.foundation.shape.CircleShape
12+
import androidx.compose.runtime.Composable
13+
import androidx.compose.ui.Alignment
14+
import androidx.compose.ui.Modifier
15+
import androidx.compose.ui.graphics.Color
16+
import androidx.compose.ui.unit.dp
17+
import org.mifos.mobilewallet.mifospay.designsystem.component.MifosUserImage
18+
19+
@Composable
20+
fun ProfileImage(bitmap: Bitmap?) {
21+
Row(
22+
modifier = Modifier
23+
.fillMaxWidth()
24+
.padding(top = 64.dp, bottom = 12.dp),
25+
horizontalArrangement = Arrangement.Center
26+
) {
27+
Box(
28+
contentAlignment = Alignment.Center,
29+
modifier = Modifier
30+
.size(200.dp)
31+
.border(
32+
width = 2.dp,
33+
color = Color.Gray,
34+
shape = CircleShape
35+
)
36+
) {
37+
MifosUserImage(
38+
bitmap = bitmap,
39+
modifier = Modifier
40+
.size(200.dp)
41+
.padding(10.dp)
42+
)
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)