Added support for multiple notifications in positive feedback
This commit is contained in:
parent
f5fcaf992b
commit
24e35d01dd
@ -107,9 +107,7 @@ class TabState @Inject constructor(
|
||||
}
|
||||
|
||||
if (positiveFeedbackText != null) {
|
||||
launch {
|
||||
errorsManager.emitPositiveNotification(positiveFeedbackText)
|
||||
}
|
||||
errorsManager.emitPositiveNotification(positiveFeedbackText)
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
hasProcessFailed = true
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user