Fixed status scroll state being lost when staging files + reduced blinking on status view.

This commit is contained in:
Abdelilah El Aissaoui 2022-06-11 12:38:37 +02:00
parent 49d4dba1df
commit c28a2834ae
2 changed files with 39 additions and 8 deletions

View File

@ -8,6 +8,7 @@ import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.material.*
@ -55,17 +56,22 @@ fun UncommitedChanges(
) {
val stageStatusState = statusViewModel.stageStatus.collectAsState()
var commitMessage by remember { mutableStateOf(statusViewModel.savedCommitMessage.message) }
val stagedListState by statusViewModel.stagedLazyListState.collectAsState()
val unstagedListState by statusViewModel.unstagedLazyListState.collectAsState()
val stageStatus = stageStatusState.value
val staged: List<StatusEntry>
val unstaged: List<StatusEntry>
val isLoading: Boolean
if (stageStatus is StageStatus.Loaded) {
staged = stageStatus.staged
unstaged = stageStatus.unstaged
isLoading = stageStatus.isPartiallyReloading
} else {
staged = listOf()
unstaged = listOf() // return empty lists if still loading
isLoading = true
}
val doCommit = { amend: Boolean ->
@ -85,7 +91,7 @@ fun UncommitedChanges(
Column {
AnimatedVisibility(
visible = stageStatus is StageStatus.Loading,
visible = isLoading,
enter = fadeIn(),
exit = fadeOut(),
) {
@ -103,6 +109,7 @@ fun UncommitedChanges(
selectedEntryType = if (selectedEntryType is DiffEntryType.StagedDiff) selectedEntryType else null,
actionColor = MaterialTheme.colors.unstageButton,
statusEntries = staged,
lazyListState = stagedListState,
onDiffEntrySelected = onStagedDiffEntrySelected,
onDiffEntryOptionSelected = {
statusViewModel.unstage(it)
@ -131,6 +138,7 @@ fun UncommitedChanges(
selectedEntryType = if (selectedEntryType is DiffEntryType.UnstagedDiff) selectedEntryType else null,
actionColor = MaterialTheme.colors.stageButton,
statusEntries = unstaged,
lazyListState = unstagedListState,
onDiffEntrySelected = onUnstagedDiffEntrySelected,
onDiffEntryOptionSelected = {
statusViewModel.stage(it)
@ -399,6 +407,7 @@ private fun EntriesList(
actionTitle: String,
actionColor: Color,
statusEntries: List<StatusEntry>,
lazyListState: LazyListState,
onDiffEntrySelected: (StatusEntry) -> Unit,
onDiffEntryOptionSelected: (StatusEntry) -> Unit,
onGenerateContextMenu: (StatusEntry) -> List<ContextMenuItem>,
@ -435,6 +444,7 @@ private fun EntriesList(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colors.background),
state = lazyListState,
) {
itemsIndexed(statusEntries) { index, statusEntry ->
val isEntrySelected = selectedEntryType != null &&

View File

@ -1,5 +1,7 @@
package app.viewmodels
import androidx.compose.foundation.lazy.LazyListState
import app.extensions.delayedStateChange
import app.extensions.isMerging
import app.git.*
import kotlinx.coroutines.Dispatchers
@ -13,6 +15,8 @@ import org.eclipse.jgit.lib.RepositoryState
import java.io.File
import javax.inject.Inject
private const val MIN_TIME_IN_MS_TO_SHOW_LOAD = 500L
class StatusViewModel @Inject constructor(
private val tabState: TabState,
private val statusManager: StatusManager,
@ -20,7 +24,7 @@ class StatusViewModel @Inject constructor(
private val mergeManager: MergeManager,
private val logManager: LogManager,
) {
private val _stageStatus = MutableStateFlow<StageStatus>(StageStatus.Loaded(listOf(), listOf()))
private val _stageStatus = MutableStateFlow<StageStatus>(StageStatus.Loaded(listOf(), listOf(), false))
val stageStatus: StateFlow<StageStatus> = _stageStatus
var savedCommitMessage = CommitMessage("", MessageType.NORMAL)
@ -29,6 +33,9 @@ class StatusViewModel @Inject constructor(
private var lastUncommitedChangesState = false
val stagedLazyListState = MutableStateFlow(LazyListState(0, 0))
val unstagedLazyListState = MutableStateFlow(LazyListState(0, 0))
/**
* Notify the UI that the commit message has been changed by the view model
*/
@ -103,12 +110,22 @@ class StatusViewModel @Inject constructor(
}
try {
_stageStatus.value = StageStatus.Loading
val status = statusManager.getStatus(git)
val staged = statusManager.getStaged(status)
val unstaged = statusManager.getUnstaged(status)
delayedStateChange(
delayMs = MIN_TIME_IN_MS_TO_SHOW_LOAD,
onDelayTriggered = {
if (previousStatus is StageStatus.Loaded) {
_stageStatus.value = previousStatus.copy(isPartiallyReloading = true)
} else {
_stageStatus.value = StageStatus.Loading
}
}
) {
val status = statusManager.getStatus(git)
val staged = statusManager.getStaged(status)
val unstaged = statusManager.getUnstaged(status)
_stageStatus.value = StageStatus.Loaded(staged, unstaged)
_stageStatus.value = StageStatus.Loaded(staged, unstaged, isPartiallyReloading = false)
}
} catch (ex: Exception) {
_stageStatus.value = previousStatus
throw ex
@ -205,7 +222,11 @@ class StatusViewModel @Inject constructor(
sealed class StageStatus {
object Loading : StageStatus()
data class Loaded(val staged: List<StatusEntry>, val unstaged: List<StatusEntry>) : StageStatus()
data class Loaded(
val staged: List<StatusEntry>,
val unstaged: List<StatusEntry>,
val isPartiallyReloading: Boolean
) : StageStatus()
}
data class CommitMessage(val message: String, val messageType: MessageType)