Skip to content

Commit 24e35d0

Browse files
committed
Added support for multiple notifications in positive feedback
1 parent f5fcaf9 commit 24e35d0

File tree

4 files changed

+57
-47
lines changed

4 files changed

+57
-47
lines changed

src/main/kotlin/com/jetpackduba/gitnuro/git/TabState.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,7 @@ class TabState @Inject constructor(
107107
}
108108

109109
if (positiveFeedbackText != null) {
110-
launch {
111-
errorsManager.emitPositiveNotification(positiveFeedbackText)
112-
}
110+
errorsManager.emitPositiveNotification(positiveFeedbackText)
113111
}
114112
} catch (ex: Exception) {
115113
hasProcessFailed = true

src/main/kotlin/com/jetpackduba/gitnuro/managers/ErrorsManager.kt

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,49 @@ package com.jetpackduba.gitnuro.managers
33
import com.jetpackduba.gitnuro.TaskType
44
import com.jetpackduba.gitnuro.di.TabScope
55
import com.jetpackduba.gitnuro.exceptions.GitnuroException
6-
import kotlinx.coroutines.Dispatchers
7-
import kotlinx.coroutines.delay
8-
import kotlinx.coroutines.flow.MutableSharedFlow
9-
import kotlinx.coroutines.flow.MutableStateFlow
10-
import kotlinx.coroutines.flow.SharedFlow
11-
import kotlinx.coroutines.flow.StateFlow
12-
import kotlinx.coroutines.withContext
6+
import com.jetpackduba.gitnuro.extensions.lockUse
7+
import kotlinx.coroutines.*
8+
import kotlinx.coroutines.flow.*
9+
import kotlinx.coroutines.sync.Mutex
1310
import javax.inject.Inject
1411

1512
@TabScope
16-
class ErrorsManager @Inject constructor() {
13+
class ErrorsManager @Inject constructor(
14+
private val coroutineScope: CoroutineScope
15+
) {
1716
private val _errorsList = MutableStateFlow(listOf<Error>())
1817
val errorsList: StateFlow<List<Error>>
1918
get() = _errorsList
2019

2120
private val _error = MutableSharedFlow<Error?>()
2221
val error: SharedFlow<Error?> = _error
2322

24-
private val _notification = MutableStateFlow<String?>(null)
25-
val notification: StateFlow<String?> = _notification
23+
private val _notification = MutableStateFlow<Map<Long, String>>(hashMapOf())
24+
val notification: StateFlow<Map<Long, String>> = _notification
25+
26+
private val notificationsMutex = Mutex()
27+
28+
suspend fun emitPositiveNotification(text: String) = coroutineScope.launch {
29+
val time = System.currentTimeMillis()
30+
notificationsMutex.lockUse {
31+
_notification.update { notifications ->
32+
notifications
33+
.toMutableMap()
34+
.apply { put(time, text) }
35+
}
36+
}
37+
38+
launch {
39+
delay(2000)
2640

27-
suspend fun emitPositiveNotification(text: String) {
28-
_notification.emit(text)
29-
delay(2000)
30-
_notification.emit(null)
41+
notificationsMutex.lockUse {
42+
_notification.update { notifications ->
43+
notifications
44+
.toMutableMap()
45+
.apply { remove(time) }
46+
}
47+
}
48+
}
3149
}
3250

3351
suspend fun addError(error: Error) = withContext(Dispatchers.IO) {

src/main/kotlin/com/jetpackduba/gitnuro/ui/AppTab.kt

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
package com.jetpackduba.gitnuro.ui
22

3-
import androidx.compose.animation.*
3+
import androidx.compose.animation.Crossfade
44
import androidx.compose.foundation.background
5-
import androidx.compose.foundation.layout.Box
6-
import androidx.compose.foundation.layout.Column
7-
import androidx.compose.foundation.layout.fillMaxSize
8-
import androidx.compose.foundation.layout.padding
5+
import androidx.compose.foundation.layout.*
96
import androidx.compose.foundation.shape.RoundedCornerShape
107
import androidx.compose.material.MaterialTheme
118
import androidx.compose.material.Text
@@ -36,20 +33,15 @@ fun AppTab(
3633
val errorManager = tabViewModel.errorsManager
3734
val lastError by errorManager.error.collectAsState(null)
3835
val showError by tabViewModel.showError.collectAsState()
39-
val notification = errorManager.notification.collectAsState().value
40-
var visibleNotification by remember { mutableStateOf("") }
41-
// val (tabPosition, setTabPosition) = remember { mutableStateOf<LayoutCoordinates?>(null) }
36+
val notifications = errorManager.notification.collectAsState().value
37+
.toList()
38+
.sortedBy { it.first }
39+
.map { it.second }
4240

4341
val repositorySelectionStatus = tabViewModel.repositorySelectionStatus.collectAsState()
4442
val repositorySelectionStatusValue = repositorySelectionStatus.value
4543
val processingState = tabViewModel.processing.collectAsState().value
4644

47-
LaunchedEffect(notification) {
48-
if (notification != null) {
49-
visibleNotification = notification
50-
}
51-
}
52-
5345
LaunchedEffect(tabViewModel) {
5446
// Init the tab content when the tab is selected and also remove the "initialPath" to avoid opening the
5547
// repository everytime the user changes between tabs
@@ -135,22 +127,24 @@ fun AppTab(
135127
)
136128
}
137129

138-
AnimatedVisibility(
139-
visible = notification != null,
140-
modifier = Modifier.align(Alignment.BottomCenter),
141-
enter = fadeIn() + slideInVertically { it * 2 },
142-
exit = fadeOut() + slideOutVertically { it * 2 },
130+
Column(
131+
modifier = Modifier
132+
.fillMaxWidth()
133+
.align(Alignment.BottomCenter)
134+
.padding(bottom = 48.dp),
135+
horizontalAlignment = Alignment.CenterHorizontally,
143136
) {
144-
Text(
145-
text = visibleNotification,
146-
modifier = Modifier
147-
.padding(bottom = 48.dp)
148-
.clip(RoundedCornerShape(8.dp))
149-
.background(MaterialTheme.colors.primary)
150-
.padding(8.dp),
151-
color = MaterialTheme.colors.onPrimary,
152-
style = MaterialTheme.typography.body1,
153-
)
137+
for (notification in notifications)
138+
Text(
139+
text = notification,
140+
modifier = Modifier
141+
.padding(bottom = 12.dp)
142+
.clip(RoundedCornerShape(8.dp))
143+
.background(MaterialTheme.colors.primary)
144+
.padding(8.dp),
145+
color = MaterialTheme.colors.onPrimary,
146+
style = MaterialTheme.typography.body1,
147+
)
154148
}
155149
}
156150
}

src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/StatusViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ class StatusViewModel @Inject constructor(
349349
fun commit(message: String) = tabState.safeProcessing(
350350
refreshType = RefreshType.ALL_DATA,
351351
taskType = TaskType.DO_COMMIT,
352-
positiveFeedbackText = "New commit added",
352+
positiveFeedbackText = if (isAmend.value) "Commit amended" else "New commit created",
353353
) { git ->
354354
val amend = isAmend.value
355355

0 commit comments

Comments
 (0)