Fixed status scroll state being lost when staging files + reduced blinking on status view.
This commit is contained in:
parent
49d4dba1df
commit
c28a2834ae
@ -8,6 +8,7 @@ import androidx.compose.animation.fadeIn
|
|||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.foundation.*
|
import androidx.compose.foundation.*
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.shape.CornerSize
|
import androidx.compose.foundation.shape.CornerSize
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
@ -55,17 +56,22 @@ fun UncommitedChanges(
|
|||||||
) {
|
) {
|
||||||
val stageStatusState = statusViewModel.stageStatus.collectAsState()
|
val stageStatusState = statusViewModel.stageStatus.collectAsState()
|
||||||
var commitMessage by remember { mutableStateOf(statusViewModel.savedCommitMessage.message) }
|
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 stageStatus = stageStatusState.value
|
||||||
val staged: List<StatusEntry>
|
val staged: List<StatusEntry>
|
||||||
val unstaged: List<StatusEntry>
|
val unstaged: List<StatusEntry>
|
||||||
|
val isLoading: Boolean
|
||||||
|
|
||||||
if (stageStatus is StageStatus.Loaded) {
|
if (stageStatus is StageStatus.Loaded) {
|
||||||
staged = stageStatus.staged
|
staged = stageStatus.staged
|
||||||
unstaged = stageStatus.unstaged
|
unstaged = stageStatus.unstaged
|
||||||
|
isLoading = stageStatus.isPartiallyReloading
|
||||||
} else {
|
} else {
|
||||||
staged = listOf()
|
staged = listOf()
|
||||||
unstaged = listOf() // return empty lists if still loading
|
unstaged = listOf() // return empty lists if still loading
|
||||||
|
isLoading = true
|
||||||
}
|
}
|
||||||
|
|
||||||
val doCommit = { amend: Boolean ->
|
val doCommit = { amend: Boolean ->
|
||||||
@ -85,7 +91,7 @@ fun UncommitedChanges(
|
|||||||
|
|
||||||
Column {
|
Column {
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = stageStatus is StageStatus.Loading,
|
visible = isLoading,
|
||||||
enter = fadeIn(),
|
enter = fadeIn(),
|
||||||
exit = fadeOut(),
|
exit = fadeOut(),
|
||||||
) {
|
) {
|
||||||
@ -103,6 +109,7 @@ fun UncommitedChanges(
|
|||||||
selectedEntryType = if (selectedEntryType is DiffEntryType.StagedDiff) selectedEntryType else null,
|
selectedEntryType = if (selectedEntryType is DiffEntryType.StagedDiff) selectedEntryType else null,
|
||||||
actionColor = MaterialTheme.colors.unstageButton,
|
actionColor = MaterialTheme.colors.unstageButton,
|
||||||
statusEntries = staged,
|
statusEntries = staged,
|
||||||
|
lazyListState = stagedListState,
|
||||||
onDiffEntrySelected = onStagedDiffEntrySelected,
|
onDiffEntrySelected = onStagedDiffEntrySelected,
|
||||||
onDiffEntryOptionSelected = {
|
onDiffEntryOptionSelected = {
|
||||||
statusViewModel.unstage(it)
|
statusViewModel.unstage(it)
|
||||||
@ -131,6 +138,7 @@ fun UncommitedChanges(
|
|||||||
selectedEntryType = if (selectedEntryType is DiffEntryType.UnstagedDiff) selectedEntryType else null,
|
selectedEntryType = if (selectedEntryType is DiffEntryType.UnstagedDiff) selectedEntryType else null,
|
||||||
actionColor = MaterialTheme.colors.stageButton,
|
actionColor = MaterialTheme.colors.stageButton,
|
||||||
statusEntries = unstaged,
|
statusEntries = unstaged,
|
||||||
|
lazyListState = unstagedListState,
|
||||||
onDiffEntrySelected = onUnstagedDiffEntrySelected,
|
onDiffEntrySelected = onUnstagedDiffEntrySelected,
|
||||||
onDiffEntryOptionSelected = {
|
onDiffEntryOptionSelected = {
|
||||||
statusViewModel.stage(it)
|
statusViewModel.stage(it)
|
||||||
@ -399,6 +407,7 @@ private fun EntriesList(
|
|||||||
actionTitle: String,
|
actionTitle: String,
|
||||||
actionColor: Color,
|
actionColor: Color,
|
||||||
statusEntries: List<StatusEntry>,
|
statusEntries: List<StatusEntry>,
|
||||||
|
lazyListState: LazyListState,
|
||||||
onDiffEntrySelected: (StatusEntry) -> Unit,
|
onDiffEntrySelected: (StatusEntry) -> Unit,
|
||||||
onDiffEntryOptionSelected: (StatusEntry) -> Unit,
|
onDiffEntryOptionSelected: (StatusEntry) -> Unit,
|
||||||
onGenerateContextMenu: (StatusEntry) -> List<ContextMenuItem>,
|
onGenerateContextMenu: (StatusEntry) -> List<ContextMenuItem>,
|
||||||
@ -435,6 +444,7 @@ private fun EntriesList(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(MaterialTheme.colors.background),
|
.background(MaterialTheme.colors.background),
|
||||||
|
state = lazyListState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(statusEntries) { index, statusEntry ->
|
itemsIndexed(statusEntries) { index, statusEntry ->
|
||||||
val isEntrySelected = selectedEntryType != null &&
|
val isEntrySelected = selectedEntryType != null &&
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package app.viewmodels
|
package app.viewmodels
|
||||||
|
|
||||||
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
|
import app.extensions.delayedStateChange
|
||||||
import app.extensions.isMerging
|
import app.extensions.isMerging
|
||||||
import app.git.*
|
import app.git.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -13,6 +15,8 @@ import org.eclipse.jgit.lib.RepositoryState
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
private const val MIN_TIME_IN_MS_TO_SHOW_LOAD = 500L
|
||||||
|
|
||||||
class StatusViewModel @Inject constructor(
|
class StatusViewModel @Inject constructor(
|
||||||
private val tabState: TabState,
|
private val tabState: TabState,
|
||||||
private val statusManager: StatusManager,
|
private val statusManager: StatusManager,
|
||||||
@ -20,7 +24,7 @@ class StatusViewModel @Inject constructor(
|
|||||||
private val mergeManager: MergeManager,
|
private val mergeManager: MergeManager,
|
||||||
private val logManager: LogManager,
|
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
|
val stageStatus: StateFlow<StageStatus> = _stageStatus
|
||||||
|
|
||||||
var savedCommitMessage = CommitMessage("", MessageType.NORMAL)
|
var savedCommitMessage = CommitMessage("", MessageType.NORMAL)
|
||||||
@ -29,6 +33,9 @@ class StatusViewModel @Inject constructor(
|
|||||||
|
|
||||||
private var lastUncommitedChangesState = false
|
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
|
* Notify the UI that the commit message has been changed by the view model
|
||||||
*/
|
*/
|
||||||
@ -103,12 +110,22 @@ class StatusViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_stageStatus.value = StageStatus.Loading
|
delayedStateChange(
|
||||||
val status = statusManager.getStatus(git)
|
delayMs = MIN_TIME_IN_MS_TO_SHOW_LOAD,
|
||||||
val staged = statusManager.getStaged(status)
|
onDelayTriggered = {
|
||||||
val unstaged = statusManager.getUnstaged(status)
|
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) {
|
} catch (ex: Exception) {
|
||||||
_stageStatus.value = previousStatus
|
_stageStatus.value = previousStatus
|
||||||
throw ex
|
throw ex
|
||||||
@ -205,7 +222,11 @@ class StatusViewModel @Inject constructor(
|
|||||||
|
|
||||||
sealed class StageStatus {
|
sealed class StageStatus {
|
||||||
object Loading : 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)
|
data class CommitMessage(val message: String, val messageType: MessageType)
|
||||||
|
Loading…
Reference in New Issue
Block a user