mirror of
https://github.com/openMF/mobile-wallet.git
synced 2026-02-06 13:56:52 +00:00
refactor #1620: migrated notification screen to compose
This commit is contained in:
parent
3e0e3e9d84
commit
9652b268ae
@ -17,7 +17,7 @@ class FetchNotifications @Inject constructor(private val mFineractRepository: Fi
|
||||
|
||||
class RequestValues(val clientId: Long) : UseCase.RequestValues
|
||||
class ResponseValue(
|
||||
val notificationPayloadList: List<NotificationPayload?>
|
||||
val notificationPayloadList: List<NotificationPayload>?
|
||||
) : UseCase.ResponseValue
|
||||
|
||||
override fun executeUseCase(requestValues: RequestValues) {
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
package org.mifospay.notification.presenter
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.mifospay.core.model.domain.NotificationPayload
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import org.mifospay.core.data.base.UseCase
|
||||
import org.mifospay.core.data.base.UseCaseHandler
|
||||
import org.mifospay.core.data.domain.usecase.notification.FetchNotifications
|
||||
import org.mifospay.data.local.LocalRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class NotificationViewModel @Inject constructor(
|
||||
private val mUseCaseHandler: UseCaseHandler,
|
||||
private val mLocalRepository: LocalRepository,
|
||||
private val fetchNotificationsUseCase: FetchNotifications
|
||||
) : ViewModel() {
|
||||
|
||||
private val _notificationUiState: MutableStateFlow<NotificationUiState> =
|
||||
MutableStateFlow(NotificationUiState.Loading)
|
||||
val notificationUiState: StateFlow<NotificationUiState> = _notificationUiState
|
||||
|
||||
fun fetchNotifications() {
|
||||
mUseCaseHandler.execute(fetchNotificationsUseCase,
|
||||
FetchNotifications.RequestValues(
|
||||
mLocalRepository.clientDetails.clientId
|
||||
),
|
||||
object : UseCase.UseCaseCallback<FetchNotifications.ResponseValue> {
|
||||
override fun onSuccess(response: FetchNotifications.ResponseValue) {
|
||||
_notificationUiState.value =
|
||||
NotificationUiState.Success(response.notificationPayloadList.orEmpty())
|
||||
}
|
||||
|
||||
override fun onError(message: String) {
|
||||
_notificationUiState.value = NotificationUiState.Error(message)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface NotificationUiState {
|
||||
data object Loading : NotificationUiState
|
||||
data object Empty : NotificationUiState
|
||||
data class Success(val notificationList: List<NotificationPayload>) : NotificationUiState
|
||||
data class Error(val message: String) : NotificationUiState
|
||||
}
|
||||
@ -3,6 +3,7 @@ package org.mifospay.notification.ui
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@ -16,6 +17,7 @@ import org.mifospay.notification.NotificationContract
|
||||
import org.mifospay.notification.NotificationContract.NotificationView
|
||||
import org.mifospay.notification.presenter.NotificationPresenter
|
||||
import org.mifospay.common.Constants
|
||||
import org.mifospay.theme.MifosTheme
|
||||
import org.mifospay.utils.DebugUtil
|
||||
import org.mifospay.utils.Toaster
|
||||
import javax.inject.Inject
|
||||
@ -26,77 +28,21 @@ import javax.inject.Inject
|
||||
* This feature is yet to be implemented on the server side.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class NotificationActivity : BaseActivity(), NotificationView {
|
||||
@JvmField
|
||||
@Inject
|
||||
var mPresenter: NotificationPresenter? = null
|
||||
var mNotificationPresenter: NotificationContract.NotificationPresenter? = null
|
||||
class NotificationActivity : BaseActivity() {
|
||||
|
||||
@JvmField
|
||||
@BindView(R.id.rv_notification)
|
||||
var mRvNotification: RecyclerView? = null
|
||||
|
||||
@JvmField
|
||||
@BindView(R.id.tv_placeholder)
|
||||
var tvplaceholder: TextView? = null
|
||||
|
||||
@JvmField
|
||||
@Inject
|
||||
var mNotificationAdapter: NotificationAdapter? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_notification)
|
||||
ButterKnife.bind(this)
|
||||
setToolbarTitle("Notifications")
|
||||
showColoredBackButton(R.drawable.ic_arrow_back_black_24dp)
|
||||
setupRecyclerView()
|
||||
setupSwipeRefreshLayout()
|
||||
mPresenter?.attachView(this)
|
||||
showSwipeProgress()
|
||||
mNotificationPresenter?.fetchNotifications()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
mRvNotification?.layoutManager = LinearLayoutManager(this)
|
||||
mRvNotification?.adapter = mNotificationAdapter
|
||||
mRvNotification?.addItemDecoration(
|
||||
DividerItemDecoration(
|
||||
this,
|
||||
DividerItemDecoration.VERTICAL
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun setupSwipeRefreshLayout() {
|
||||
setSwipeRefreshEnabled(true)
|
||||
swipeRefreshLayout?.setOnRefreshListener { mNotificationPresenter?.fetchNotifications() }
|
||||
}
|
||||
|
||||
override fun fetchNotificationsSuccess(notificationPayloadList: List<NotificationPayload?>?) {
|
||||
hideSwipeProgress()
|
||||
if (notificationPayloadList.isNullOrEmpty()) {
|
||||
DebugUtil.log("null")
|
||||
mRvNotification?.visibility = View.GONE
|
||||
tvplaceholder?.visibility = View.VISIBLE
|
||||
} else {
|
||||
DebugUtil.log("yes")
|
||||
mRvNotification?.visibility = View.VISIBLE
|
||||
tvplaceholder?.visibility = View.GONE
|
||||
mNotificationAdapter?.setNotificationPayloadList(notificationPayloadList as List<NotificationPayload>)
|
||||
setContent {
|
||||
MifosTheme {
|
||||
NotificationScreen()
|
||||
}
|
||||
}
|
||||
mNotificationAdapter?.setNotificationPayloadList(notificationPayloadList as List<NotificationPayload>)
|
||||
// mNotificationPresenter?.fetchNotifications()
|
||||
}
|
||||
|
||||
override fun fetchNotificationsError(message: String?) {
|
||||
hideSwipeProgress()
|
||||
showToast(message)
|
||||
}
|
||||
// private fun setupSwipeRefreshLayout() {
|
||||
// setSwipeRefreshEnabled(true)
|
||||
// swipeRefreshLayout?.setOnRefreshListener { mNotificationPresenter?.fetchNotifications() }
|
||||
// }
|
||||
|
||||
override fun setPresenter(presenter: NotificationContract.NotificationPresenter?) {
|
||||
mNotificationPresenter = presenter
|
||||
}
|
||||
|
||||
fun showToast(message: String?) {
|
||||
Toaster.showToast(this, message)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,170 @@
|
||||
package org.mifospay.notification.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
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.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.Info
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.mifospay.core.model.domain.NotificationPayload
|
||||
import org.mifospay.R
|
||||
import org.mifospay.core.designsystem.component.MfLoadingWheel
|
||||
import org.mifospay.core.designsystem.component.MifosTopAppBar
|
||||
import org.mifospay.core.designsystem.theme.historyItemTextStyle
|
||||
import org.mifospay.core.designsystem.theme.styleMedium16sp
|
||||
import org.mifospay.core.ui.EmptyContentScreen
|
||||
import org.mifospay.notification.presenter.NotificationUiState
|
||||
import org.mifospay.notification.presenter.NotificationViewModel
|
||||
|
||||
@Composable
|
||||
fun NotificationScreen(viewmodel: NotificationViewModel = hiltViewModel()) {
|
||||
val uiState by viewmodel.notificationUiState.collectAsStateWithLifecycle()
|
||||
NotificationScreen(uiState = uiState)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun NotificationScreen(uiState: NotificationUiState) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
MifosTopAppBar(titleRes = R.string.notifications)
|
||||
when (uiState) {
|
||||
is NotificationUiState.Error -> {
|
||||
EmptyContentScreen(
|
||||
modifier = Modifier,
|
||||
title = stringResource(id = R.string.error_oops),
|
||||
subTitle = stringResource(id = R.string.unexpected_error_subtitle),
|
||||
iconTint = Color.Black,
|
||||
iconImageVector = Icons.Rounded.Info
|
||||
)
|
||||
}
|
||||
|
||||
NotificationUiState.Loading -> {
|
||||
MfLoadingWheel(
|
||||
contentDesc = stringResource(R.string.loading),
|
||||
backgroundColor = Color.White
|
||||
)
|
||||
}
|
||||
|
||||
is NotificationUiState.Success -> {
|
||||
if (uiState.notificationList.isEmpty()) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.no_notification_found),
|
||||
style = styleMedium16sp
|
||||
)
|
||||
}
|
||||
} else {
|
||||
LazyColumn {
|
||||
items(uiState.notificationList) { notification ->
|
||||
NotificationList(
|
||||
title = notification.title.toString(),
|
||||
body = notification.body.toString(),
|
||||
timestamp = notification.timestamp.toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NotificationUiState.Empty -> {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.no_notification_found),
|
||||
style = styleMedium16sp
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun NotificationList(title: String, body: String, timestamp: String) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp),
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(24.dp)
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
style = styleMedium16sp,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 8.dp)
|
||||
)
|
||||
Text(
|
||||
text = body, style = styleMedium16sp,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 8.dp)
|
||||
)
|
||||
Text(
|
||||
text = timestamp, style = historyItemTextStyle,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 8.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showSystemUi = true, showBackground = true)
|
||||
@Composable
|
||||
private fun NotificationEmptyScreenPreview() {
|
||||
NotificationScreen(uiState = NotificationUiState.Empty)
|
||||
}
|
||||
|
||||
@Preview(showSystemUi = true, showBackground = true)
|
||||
@Composable
|
||||
private fun NotificationLoadingPreview() {
|
||||
NotificationScreen(uiState = NotificationUiState.Loading)
|
||||
}
|
||||
|
||||
@Preview(showSystemUi = true, showBackground = true)
|
||||
@Composable
|
||||
private fun NotificationSuccessPreview() {
|
||||
NotificationScreen(uiState = NotificationUiState.Success(sampleNotificationList))
|
||||
}
|
||||
|
||||
@Preview(showSystemUi = true, showBackground = true)
|
||||
@Composable
|
||||
private fun NotificationErrorScreenPreview() {
|
||||
NotificationScreen(uiState = NotificationUiState.Error("Error Occurred"))
|
||||
}
|
||||
|
||||
val sampleNotificationList = List(10) {
|
||||
NotificationPayload("Title", "Body", "TimeStamp")
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user