Added support for multiple notifications in positive feedback

This commit is contained in:
Abdelilah El Aissaoui 2024-07-10 00:35:26 +02:00
parent f5fcaf992b
commit 24e35d01dd
No known key found for this signature in database
GPG Key ID: 7587FC860F594869
4 changed files with 57 additions and 47 deletions

View File

@ -107,9 +107,7 @@ class TabState @Inject constructor(
}
if (positiveFeedbackText != null) {
launch {
errorsManager.emitPositiveNotification(positiveFeedbackText)
}
errorsManager.emitPositiveNotification(positiveFeedbackText)
}
} catch (ex: Exception) {
hasProcessFailed = true

View File

@ -3,17 +3,16 @@ package com.jetpackduba.gitnuro.managers
import com.jetpackduba.gitnuro.TaskType
import com.jetpackduba.gitnuro.di.TabScope
import com.jetpackduba.gitnuro.exceptions.GitnuroException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.withContext
import com.jetpackduba.gitnuro.extensions.lockUse
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.sync.Mutex
import javax.inject.Inject
@TabScope
class ErrorsManager @Inject constructor() {
class ErrorsManager @Inject constructor(
private val coroutineScope: CoroutineScope
) {
private val _errorsList = MutableStateFlow(listOf<Error>())
val errorsList: StateFlow<List<Error>>
get() = _errorsList
@ -21,13 +20,32 @@ class ErrorsManager @Inject constructor() {
private val _error = MutableSharedFlow<Error?>()
val error: SharedFlow<Error?> = _error
private val _notification = MutableStateFlow<String?>(null)
val notification: StateFlow<String?> = _notification
private val _notification = MutableStateFlow<Map<Long, String>>(hashMapOf())
val notification: StateFlow<Map<Long, String>> = _notification
suspend fun emitPositiveNotification(text: String) {
_notification.emit(text)
delay(2000)
_notification.emit(null)
private val notificationsMutex = Mutex()
suspend fun emitPositiveNotification(text: String) = coroutineScope.launch {
val time = System.currentTimeMillis()
notificationsMutex.lockUse {
_notification.update { notifications ->
notifications
.toMutableMap()
.apply { put(time, text) }
}
}
launch {
delay(2000)
notificationsMutex.lockUse {
_notification.update { notifications ->
notifications
.toMutableMap()
.apply { remove(time) }
}
}
}
}
suspend fun addError(error: Error) = withContext(Dispatchers.IO) {

View File

@ -1,11 +1,8 @@
package com.jetpackduba.gitnuro.ui
import androidx.compose.animation.*
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.background
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.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
@ -36,20 +33,15 @@ fun AppTab(
val errorManager = tabViewModel.errorsManager
val lastError by errorManager.error.collectAsState(null)
val showError by tabViewModel.showError.collectAsState()
val notification = errorManager.notification.collectAsState().value
var visibleNotification by remember { mutableStateOf("") }
// val (tabPosition, setTabPosition) = remember { mutableStateOf<LayoutCoordinates?>(null) }
val notifications = errorManager.notification.collectAsState().value
.toList()
.sortedBy { it.first }
.map { it.second }
val repositorySelectionStatus = tabViewModel.repositorySelectionStatus.collectAsState()
val repositorySelectionStatusValue = repositorySelectionStatus.value
val processingState = tabViewModel.processing.collectAsState().value
LaunchedEffect(notification) {
if (notification != null) {
visibleNotification = notification
}
}
LaunchedEffect(tabViewModel) {
// Init the tab content when the tab is selected and also remove the "initialPath" to avoid opening the
// repository everytime the user changes between tabs
@ -135,22 +127,24 @@ fun AppTab(
)
}
AnimatedVisibility(
visible = notification != null,
modifier = Modifier.align(Alignment.BottomCenter),
enter = fadeIn() + slideInVertically { it * 2 },
exit = fadeOut() + slideOutVertically { it * 2 },
Column(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.BottomCenter)
.padding(bottom = 48.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = visibleNotification,
modifier = Modifier
.padding(bottom = 48.dp)
.clip(RoundedCornerShape(8.dp))
.background(MaterialTheme.colors.primary)
.padding(8.dp),
color = MaterialTheme.colors.onPrimary,
style = MaterialTheme.typography.body1,
)
for (notification in notifications)
Text(
text = notification,
modifier = Modifier
.padding(bottom = 12.dp)
.clip(RoundedCornerShape(8.dp))
.background(MaterialTheme.colors.primary)
.padding(8.dp),
color = MaterialTheme.colors.onPrimary,
style = MaterialTheme.typography.body1,
)
}
}
}

View File

@ -349,7 +349,7 @@ class StatusViewModel @Inject constructor(
fun commit(message: String) = tabState.safeProcessing(
refreshType = RefreshType.ALL_DATA,
taskType = TaskType.DO_COMMIT,
positiveFeedbackText = "New commit added",
positiveFeedbackText = if (isAmend.value) "Commit amended" else "New commit created",
) { git ->
val amend = isAmend.value