Implemented context menu for stash operations

Moved selected item to TabState, so every ViewModel can update the current selected tab state without having to use callbacks to the RepoOpened component. This allows to set currently selected item to "None" when droping a stash that has been selected
This commit is contained in:
Abdelilah El Aissaoui 2022-02-06 22:57:46 +01:00
parent fff18b7fef
commit 02313fe632
19 changed files with 225 additions and 80 deletions

View File

@ -3,6 +3,7 @@ package app.git
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
import org.eclipse.jgit.revwalk.RevCommit
import javax.inject.Inject import javax.inject.Inject
class StashManager @Inject constructor() { class StashManager @Inject constructor() {
@ -22,9 +23,29 @@ class StashManager @Inject constructor() {
.call() .call()
} }
suspend fun popStash(git: Git, stash: RevCommit) = withContext(Dispatchers.IO) {
applyStash(git, stash)
deleteStash(git, stash)
}
suspend fun getStashList(git: Git) = withContext(Dispatchers.IO) { suspend fun getStashList(git: Git) = withContext(Dispatchers.IO) {
return@withContext git return@withContext git
.stashList() .stashList()
.call() .call()
} }
suspend fun applyStash(git: Git, stashInfo: RevCommit) = withContext(Dispatchers.IO) {
git.stashApply()
.setStashRef(stashInfo.name)
.call()
}
suspend fun deleteStash(git: Git, stashInfo: RevCommit) = withContext(Dispatchers.IO) {
val stashList = getStashList(git)
val indexOfStashToDelete = stashList.indexOf(stashInfo)
git.stashDrop()
.setStashRef(indexOfStashToDelete)
.call()
}
} }

View File

@ -281,10 +281,8 @@ class StatusManager @Inject constructor(
suspend fun getStatusSummary(git: Git, currentBranch: Ref?, repositoryState: RepositoryState): StatusSummary { suspend fun getStatusSummary(git: Git, currentBranch: Ref?, repositoryState: RepositoryState): StatusSummary {
val staged = getStaged(git, currentBranch, repositoryState) val staged = getStaged(git, currentBranch, repositoryState)
val allChanges = staged.toMutableList() val allChanges = staged.toMutableList()
println("Staged: $staged")
val unstaged = getUnstaged(git, repositoryState) val unstaged = getUnstaged(git, repositoryState)
println("Unstaged: $unstaged")
allChanges.addAll(unstaged) allChanges.addAll(unstaged)
val groupedChanges = allChanges.groupBy { val groupedChanges = allChanges.groupBy {

View File

@ -3,6 +3,7 @@ package app.git
import app.ErrorsManager import app.ErrorsManager
import app.di.TabScope import app.di.TabScope
import app.newErrorNow import app.newErrorNow
import app.ui.SelectedItem
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
@ -14,6 +15,8 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
import org.eclipse.jgit.lib.ObjectId
import org.eclipse.jgit.revwalk.RevCommit
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.cancellation.CancellationException import kotlin.coroutines.cancellation.CancellationException
@ -21,12 +24,14 @@ import kotlin.coroutines.cancellation.CancellationException
class TabState @Inject constructor( class TabState @Inject constructor(
val errorsManager: ErrorsManager, val errorsManager: ErrorsManager,
) { ) {
private val _selectedItem = MutableStateFlow<SelectedItem>(SelectedItem.None)
val selectedItem: StateFlow<SelectedItem> = _selectedItem
var git: Git? = null var git: Git? = null
val safeGit: Git val safeGit: Git
get() { get() {
val git = this.git val git = this.git
if (git == null) { if (git == null) {
// _repositorySelectionStatus.value = RepositorySelectionStatus.None
throw CancellationException("Null git object") throw CancellationException("Null git object")
} else } else
return git return git
@ -128,11 +133,44 @@ class TabState @Inject constructor(
_refreshData.emit(refreshType) _refreshData.emit(refreshType)
} }
} }
fun newSelectedStash(stash: RevCommit) {
newSelectedItem(SelectedItem.Stash(stash))
}
fun noneSelected() {
newSelectedItem(SelectedItem.None)
}
fun newSelectedRef(objectId: ObjectId?) = runOperation(
refreshType = RefreshType.NONE,
) { git ->
if (objectId == null) {
newSelectedItem(SelectedItem.None)
} else {
val commit = findCommit(git, objectId)
newSelectedItem(SelectedItem.Ref(commit))
}
}
private fun findCommit(git: Git, objectId: ObjectId): RevCommit {
return git.repository.parseCommit(objectId)
}
fun newSelectedItem(selectedItem: SelectedItem) {
_selectedItem.value = selectedItem
println(selectedItem)
// if (selectedItem is SelectedItem.CommitBasedItem) {
// commitChangesViewModel.loadChanges(selectedItem.revCommit)
// }
}
} }
enum class RefreshType { enum class RefreshType {
NONE, NONE,
ALL_DATA, ALL_DATA,
ONLY_LOG, ONLY_LOG,
STASHES,
UNCOMMITED_CHANGES, UNCOMMITED_CHANGES,
UNCOMMITED_CHANGES_AND_LOG,
} }

View File

@ -22,7 +22,6 @@ import org.eclipse.jgit.lib.Ref
@Composable @Composable
fun Branches( fun Branches(
branchesViewModel: BranchesViewModel, branchesViewModel: BranchesViewModel,
onBranchClicked: (Ref) -> Unit,
) { ) {
val branches by branchesViewModel.branches.collectAsState() val branches by branchesViewModel.branches.collectAsState()
val currentBranch by branchesViewModel.currentBranch.collectAsState() val currentBranch by branchesViewModel.currentBranch.collectAsState()
@ -37,7 +36,7 @@ fun Branches(
BranchLineEntry( BranchLineEntry(
branch = branch, branch = branch,
isCurrentBranch = currentBranch == branch.name, isCurrentBranch = currentBranch == branch.name,
onBranchClicked = { onBranchClicked(branch) }, onBranchClicked = { branchesViewModel.selectBranch(branch) },
onCheckoutBranch = { branchesViewModel.checkoutRef(branch) }, onCheckoutBranch = { branchesViewModel.checkoutRef(branch) },
onMergeBranch = { setMergeBranch(branch) }, onMergeBranch = { setMergeBranch(branch) },
onDeleteBranch = { branchesViewModel.deleteBranch(branch) }, onDeleteBranch = { branchesViewModel.deleteBranch(branch) },

View File

@ -8,10 +8,7 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@ -34,8 +31,13 @@ import org.eclipse.jgit.revwalk.RevCommit
@Composable @Composable
fun CommitChanges( fun CommitChanges(
commitChangesViewModel: CommitChangesViewModel, commitChangesViewModel: CommitChangesViewModel,
onDiffSelected: (DiffEntry) -> Unit onDiffSelected: (DiffEntry) -> Unit,
selectedItem: SelectedItem.CommitBasedItem
) { ) {
LaunchedEffect(selectedItem) {
commitChangesViewModel.loadChanges(selectedItem.revCommit)
}
val commitChangesStatusState = commitChangesViewModel.commitChangesStatus.collectAsState() val commitChangesStatusState = commitChangesViewModel.commitChangesStatus.collectAsState()
when (val commitChangesStatus = commitChangesStatusState.value) { when (val commitChangesStatus = commitChangesStatusState.value) {

View File

@ -21,7 +21,6 @@ import org.eclipse.jgit.lib.Ref
@Composable @Composable
fun Remotes( fun Remotes(
remotesViewModel: RemotesViewModel, remotesViewModel: RemotesViewModel,
onBranchClicked: (Ref) -> Unit,
) { ) {
val remotes by remotesViewModel.remotes.collectAsState() val remotes by remotesViewModel.remotes.collectAsState()
@ -43,7 +42,7 @@ fun Remotes(
itemContent = { remoteInfo -> itemContent = { remoteInfo ->
RemoteRow( RemoteRow(
remote = remoteInfo, remote = remoteInfo,
onBranchClicked = { branch -> onBranchClicked(branch) }, onBranchClicked = { branch -> remotesViewModel.selectBranch(branch) },
onDeleteBranch = { branch -> remotesViewModel.deleteRemoteBranch(branch) }, onDeleteBranch = { branch -> remotesViewModel.deleteRemoteBranch(branch) },
onRemoteClicked = { remotesViewModel.onRemoteClicked(remoteInfo) } onRemoteClicked = { remotesViewModel.onRemoteClicked(remoteInfo) }
) )

View File

@ -51,7 +51,7 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
) )
Row { Row {
HorizontalSplitPane() { HorizontalSplitPane {
first(minSize = 200.dp) { first(minSize = 200.dp) {
Column( Column(
modifier = Modifier modifier = Modifier
@ -61,27 +61,15 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
) { ) {
Branches( Branches(
branchesViewModel = tabViewModel.branchesViewModel, branchesViewModel = tabViewModel.branchesViewModel,
onBranchClicked = {
tabViewModel.newSelectedRef(it.objectId)
}
) )
Remotes( Remotes(
remotesViewModel = tabViewModel.remotesViewModel, remotesViewModel = tabViewModel.remotesViewModel,
onBranchClicked = {
tabViewModel.newSelectedRef(it.objectId)
}
) )
Tags( Tags(
tagsViewModel = tabViewModel.tagsViewModel, tagsViewModel = tabViewModel.tagsViewModel,
onTagClicked = {
tabViewModel.newSelectedRef(it.objectId)
}
) )
Stashes( Stashes(
stashesViewModel = tabViewModel.stashesViewModel, stashesViewModel = tabViewModel.stashesViewModel,
onStashSelected = { stash ->
tabViewModel.newSelectedStash(stash)
}
) )
} }
} }
@ -104,9 +92,6 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
Log( Log(
logViewModel = tabViewModel.logViewModel, logViewModel = tabViewModel.logViewModel,
selectedItem = selectedItem, selectedItem = selectedItem,
onItemSelected = {
tabViewModel.newSelectedItem(it)
},
repositoryState = repositoryState, repositoryState = repositoryState,
) )
} }
@ -143,6 +128,7 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) {
} else if (safeSelectedItem is SelectedItem.CommitBasedItem) { } else if (safeSelectedItem is SelectedItem.CommitBasedItem) {
CommitChanges( CommitChanges(
commitChangesViewModel = tabViewModel.commitChangesViewModel, commitChangesViewModel = tabViewModel.commitChangesViewModel,
selectedItem = safeSelectedItem,
onDiffSelected = { diffEntry -> onDiffSelected = { diffEntry ->
tabViewModel.newDiffSelected = DiffEntryType.CommitDiff(diffEntry) tabViewModel.newDiffSelected = DiffEntryType.CommitDiff(diffEntry)
} }

View File

@ -1,10 +1,16 @@
@file:OptIn(ExperimentalFoundationApi::class)
package app.ui package app.ui
import androidx.compose.foundation.ContextMenuArea
import androidx.compose.foundation.ContextMenuItem
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import app.ui.components.SideMenuPanel import app.ui.components.SideMenuPanel
import app.ui.components.SideMenuSubentry import app.ui.components.SideMenuSubentry
import app.ui.context_menu.stashesContextMenuItems
import app.viewmodels.StashStatus import app.viewmodels.StashStatus
import app.viewmodels.StashesViewModel import app.viewmodels.StashesViewModel
import org.eclipse.jgit.revwalk.RevCommit import org.eclipse.jgit.revwalk.RevCommit
@ -12,7 +18,6 @@ import org.eclipse.jgit.revwalk.RevCommit
@Composable @Composable
fun Stashes( fun Stashes(
stashesViewModel: StashesViewModel, stashesViewModel: StashesViewModel,
onStashSelected: (commit: RevCommit) -> Unit,
) { ) {
val stashStatusState = stashesViewModel.stashStatus.collectAsState() val stashStatusState = stashesViewModel.stashStatus.collectAsState()
val stashStatus = stashStatusState.value val stashStatus = stashStatusState.value
@ -22,15 +27,23 @@ fun Stashes(
else else
listOf() listOf()
SideMenuPanel( SideMenuPanel(
title = "Stashes", title = "Stashes",
icon = painterResource("stash.svg"), icon = painterResource("stash.svg"),
items = stashList, items = stashList,
itemContent = { stashInfo -> itemContent = { stash ->
StashRow( StashRow(
stash = stashInfo, stash = stash,
onClick = { onStashSelected(stashInfo) } onClick = { stashesViewModel.selectTab(stash) },
contextItems = stashesContextMenuItems(
onApply = { stashesViewModel.applyStash(stash) },
onPop = {
stashesViewModel.popStash(stash)
},
onDelete = {
stashesViewModel.deleteStash(stash)
},
)
) )
} }
) )
@ -38,10 +51,18 @@ fun Stashes(
} }
@Composable @Composable
private fun StashRow(stash: RevCommit, onClick: () -> Unit) { private fun StashRow(
SideMenuSubentry( stash: RevCommit,
text = stash.shortMessage, onClick: () -> Unit,
iconResourcePath = "stash.svg", contextItems: List<ContextMenuItem>,
onClick = onClick, ) {
) ContextMenuArea(
items = { contextItems }
) {
SideMenuSubentry(
text = stash.shortMessage,
iconResourcePath = "stash.svg",
onClick = onClick,
)
}
} }

View File

@ -15,7 +15,6 @@ import org.eclipse.jgit.lib.Ref
@Composable @Composable
fun Tags( fun Tags(
tagsViewModel: TagsViewModel, tagsViewModel: TagsViewModel,
onTagClicked: (Ref) -> Unit,
) { ) {
val tagsState = tagsViewModel.tags.collectAsState() val tagsState = tagsViewModel.tags.collectAsState()
val tags = tagsState.value val tags = tagsState.value
@ -27,7 +26,7 @@ fun Tags(
itemContent = { tag -> itemContent = { tag ->
TagRow( TagRow(
tag = tag, tag = tag,
onTagClicked = { onTagClicked(tag) }, onTagClicked = { tagsViewModel.selectTag(tag) },
onCheckoutTag = { tagsViewModel.checkoutRef(tag) }, onCheckoutTag = { tagsViewModel.checkoutRef(tag) },
onDeleteTag = { tagsViewModel.deleteTag(tag) } onDeleteTag = { tagsViewModel.deleteTag(tag) }
) )

View File

@ -0,0 +1,26 @@
package app.ui.context_menu
import androidx.compose.foundation.ContextMenuItem
import androidx.compose.foundation.ExperimentalFoundationApi
@OptIn(ExperimentalFoundationApi::class)
fun stashesContextMenuItems(
onApply: () -> Unit,
onPop: () -> Unit,
onDelete: () -> Unit,
): List<ContextMenuItem> {
return mutableListOf(
ContextMenuItem(
label = "Apply stash",
onClick = onApply
),
ContextMenuItem(
label = "Pop stash",
onClick = onPop
),
ContextMenuItem(
label = "Drop stash",
onClick = onDelete
),
)
}

View File

@ -72,7 +72,6 @@ private const val CANVAS_MIN_WIDTH = 100
fun Log( fun Log(
logViewModel: LogViewModel, logViewModel: LogViewModel,
selectedItem: SelectedItem, selectedItem: SelectedItem,
onItemSelected: (SelectedItem) -> Unit,
repositoryState: RepositoryState, repositoryState: RepositoryState,
) { ) {
val logStatusState = logViewModel.logStatus.collectAsState() val logStatusState = logViewModel.logStatus.collectAsState()
@ -114,7 +113,6 @@ fun Log(
.background(MaterialTheme.colors.background) .background(MaterialTheme.colors.background)
.fillMaxSize() .fillMaxSize()
) { ) {
// val hasUncommitedChanges by tabViewModel.hasUncommitedChanges.collectAsState()
val weightMod = remember { mutableStateOf(0f) } val weightMod = remember { mutableStateOf(0f) }
var graphWidth = (CANVAS_MIN_WIDTH + weightMod.value).dp var graphWidth = (CANVAS_MIN_WIDTH + weightMod.value).dp
@ -131,7 +129,6 @@ fun Log(
.background(MaterialTheme.colors.background) .background(MaterialTheme.colors.background)
.fillMaxSize(), .fillMaxSize(),
) { ) {
//TODO: Shouldn't this be an item of the graph?
if (hasUncommitedChanges) if (hasUncommitedChanges)
item { item {
UncommitedChangesLine( UncommitedChangesLine(
@ -142,7 +139,7 @@ fun Log(
weightMod = weightMod, weightMod = weightMod,
repositoryState = repositoryState, repositoryState = repositoryState,
onUncommitedChangesSelected = { onUncommitedChangesSelected = {
onItemSelected(SelectedItem.UncommitedChanges) logViewModel.selectLogLine(SelectedItem.UncommitedChanges)
} }
) )
} }
@ -160,7 +157,7 @@ fun Log(
onMergeBranch = { ref -> showLogDialog.value = LogDialog.MergeBranch(ref) }, onMergeBranch = { ref -> showLogDialog.value = LogDialog.MergeBranch(ref) },
onRebaseBranch = { ref -> showLogDialog.value = LogDialog.RebaseBranch(ref) }, onRebaseBranch = { ref -> showLogDialog.value = LogDialog.RebaseBranch(ref) },
onRevCommitSelected = { onRevCommitSelected = {
onItemSelected(SelectedItem.Commit(graphNode)) logViewModel.selectLogLine(SelectedItem.Commit(graphNode))
} }
) )
} }

View File

@ -71,4 +71,8 @@ class BranchesViewModel @Inject constructor(
) { git -> ) { git ->
rebaseManager.rebaseBranch(git, ref) rebaseManager.rebaseBranch(git, ref)
} }
fun selectBranch(ref: Ref) {
tabState.newSelectedRef(ref.objectId)
}
} }

View File

@ -2,6 +2,7 @@ package app.viewmodels
import app.git.* import app.git.*
import app.git.graph.GraphCommitList import app.git.graph.GraphCommitList
import app.ui.SelectedItem
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
@ -143,6 +144,10 @@ class LogViewModel @Inject constructor(
) { git -> ) { git ->
rebaseManager.rebaseBranch(git, ref) rebaseManager.rebaseBranch(git, ref)
} }
fun selectLogLine(selectedItem: SelectedItem) {
tabState.newSelectedItem(selectedItem)
}
} }
sealed class LogStatus { sealed class LogStatus {

View File

@ -34,13 +34,13 @@ class MenuViewModel @Inject constructor(
} }
fun stash() = tabState.safeProcessing( fun stash() = tabState.safeProcessing(
refreshType = RefreshType.UNCOMMITED_CHANGES, refreshType = RefreshType.UNCOMMITED_CHANGES_AND_LOG,
) { git -> ) { git ->
stashManager.stash(git) stashManager.stash(git)
} }
fun popStash() = tabState.safeProcessing( fun popStash() = tabState.safeProcessing(
refreshType = RefreshType.UNCOMMITED_CHANGES, refreshType = RefreshType.UNCOMMITED_CHANGES_AND_LOG,
) { git -> ) { git ->
stashManager.popStash(git) stashManager.popStash(git)
} }

View File

@ -58,6 +58,10 @@ class RemotesViewModel @Inject constructor(
_remotes.value = newRemotesList _remotes.value = newRemotesList
} }
fun selectBranch(ref: Ref) {
tabState.newSelectedRef(ref.objectId)
}
} }
data class RemoteView(val remoteInfo: RemoteInfo, val isExpanded: Boolean) data class RemoteView(val remoteInfo: RemoteInfo, val isExpanded: Boolean)

View File

@ -1,6 +1,9 @@
package app.viewmodels package app.viewmodels
import app.git.RefreshType
import app.git.StashManager import app.git.StashManager
import app.git.TabState
import app.ui.SelectedItem
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
@ -9,6 +12,7 @@ import javax.inject.Inject
class StashesViewModel @Inject constructor( class StashesViewModel @Inject constructor(
private val stashManager: StashManager, private val stashManager: StashManager,
private val tabState: TabState,
) { ) {
private val _stashStatus = MutableStateFlow<StashStatus>(StashStatus.Loaded(listOf())) private val _stashStatus = MutableStateFlow<StashStatus>(StashStatus.Loaded(listOf()))
val stashStatus: StateFlow<StashStatus> val stashStatus: StateFlow<StashStatus>
@ -23,6 +27,41 @@ class StashesViewModel @Inject constructor(
suspend fun refresh(git: Git) { suspend fun refresh(git: Git) {
loadStashes(git) loadStashes(git)
} }
fun applyStash(stashInfo: RevCommit) = tabState.safeProcessing(
refreshType = RefreshType.UNCOMMITED_CHANGES_AND_LOG,
) { git ->
stashManager.applyStash(git, stashInfo)
}
fun popStash(stash: RevCommit) = tabState.safeProcessing(
refreshType = RefreshType.UNCOMMITED_CHANGES_AND_LOG,
) { git ->
stashManager.popStash(git, stash)
stashDropped(stash)
}
fun deleteStash(stash: RevCommit) = tabState.safeProcessing(
refreshType = RefreshType.STASHES,
) { git ->
stashManager.deleteStash(git, stash)
stashDropped(stash)
}
fun selectTab(stash: RevCommit) {
tabState.newSelectedStash(stash)
}
private fun stashDropped(stash: RevCommit) {
val selectedValue = tabState.selectedItem.value
if (
selectedValue is SelectedItem.Stash &&
selectedValue.revCommit.name == stash.name
) {
tabState.noneSelected()
}
}
} }

View File

@ -108,6 +108,22 @@ class StatusViewModel @Inject constructor(
loadHasUncommitedChanges(git) loadHasUncommitedChanges(git)
} }
/**
* Checks if there are uncommited changes and returns if the state has changed (
*/
suspend fun updateHasUncommitedChanges(git: Git): Boolean {
val hadUncommitedChanges = this.lastUncommitedChangesState
loadStatus(git)
loadHasUncommitedChanges(git)
val hasNowUncommitedChanges = this.lastUncommitedChangesState
hasPreviousCommits = logManager.hasPreviousCommits(git)
// Return true to update the log only if the uncommitedChanges status has changed
return (hasNowUncommitedChanges != hadUncommitedChanges)
}
fun continueRebase() = tabState.safeProcessing( fun continueRebase() = tabState.safeProcessing(
refreshType = RefreshType.ALL_DATA, refreshType = RefreshType.ALL_DATA,
) { git -> ) { git ->

View File

@ -41,8 +41,7 @@ class TabViewModel @Inject constructor(
private val fileChangesWatcher: FileChangesWatcher, private val fileChangesWatcher: FileChangesWatcher,
) { ) {
val errorsManager: ErrorsManager = tabState.errorsManager val errorsManager: ErrorsManager = tabState.errorsManager
private val _selectedItem = MutableStateFlow<SelectedItem>(SelectedItem.None) val selectedItem: StateFlow<SelectedItem> = tabState.selectedItem
val selectedItem: StateFlow<SelectedItem> = _selectedItem
private val credentialsStateManager = CredentialsStateManager private val credentialsStateManager = CredentialsStateManager
@ -75,12 +74,20 @@ class TabViewModel @Inject constructor(
RefreshType.NONE -> println("Not refreshing...") RefreshType.NONE -> println("Not refreshing...")
RefreshType.ALL_DATA -> refreshRepositoryInfo() RefreshType.ALL_DATA -> refreshRepositoryInfo()
RefreshType.ONLY_LOG -> refreshLog() RefreshType.ONLY_LOG -> refreshLog()
RefreshType.STASHES -> refreshStashes()
RefreshType.UNCOMMITED_CHANGES -> checkUncommitedChanges() RefreshType.UNCOMMITED_CHANGES -> checkUncommitedChanges()
RefreshType.UNCOMMITED_CHANGES_AND_LOG -> checkUncommitedChanges(true)
} }
} }
} }
} }
private fun refreshStashes() = tabState.runOperation(
refreshType = RefreshType.NONE
) { git ->
stashesViewModel.refresh(git)
}
private fun refreshLog() = tabState.runOperation( private fun refreshLog() = tabState.runOperation(
refreshType = RefreshType.NONE, refreshType = RefreshType.NONE,
) { git -> ) { git ->
@ -147,11 +154,18 @@ class TabViewModel @Inject constructor(
} }
} }
private suspend fun checkUncommitedChanges() = tabState.runOperation( private suspend fun checkUncommitedChanges(fullUpdateLog: Boolean = false) = tabState.runOperation(
refreshType = RefreshType.NONE, refreshType = RefreshType.NONE,
) { git -> ) { git ->
statusViewModel.refresh(git) val uncommitedChangesStateChanged = statusViewModel.updateHasUncommitedChanges(git)
logViewModel.refreshUncommitedChanges(git)
println("Has uncommitedChangesStateChanged $uncommitedChangesStateChanged")
// Update the log only if the uncommitedChanges status has changed or requested
if (uncommitedChangesStateChanged || fullUpdateLog)
logViewModel.refresh(git)
else
logViewModel.refreshUncommitedChanges(git)
updateDiffEntry() updateDiffEntry()
@ -195,10 +209,6 @@ class TabViewModel @Inject constructor(
remoteOperationsManager.clone(directory, url) remoteOperationsManager.clone(directory, url)
} }
private fun findCommit(git: Git, objectId: ObjectId): RevCommit {
return git.repository.parseCommit(objectId)
}
private fun updateDiffEntry() { private fun updateDiffEntry() {
val diffSelected = diffSelected.value val diffSelected = diffSelected.value
@ -206,29 +216,6 @@ class TabViewModel @Inject constructor(
diffViewModel.updateDiff(diffSelected) diffViewModel.updateDiff(diffSelected)
} }
} }
fun newSelectedRef(objectId: ObjectId?) = tabState.runOperation(
refreshType = RefreshType.NONE,
) { git ->
if (objectId == null) {
newSelectedItem(SelectedItem.None)
} else {
val commit = findCommit(git, objectId)
newSelectedItem(SelectedItem.Ref(commit))
}
}
fun newSelectedStash(stash: RevCommit) {
newSelectedItem(SelectedItem.Stash(stash))
}
fun newSelectedItem(selectedItem: SelectedItem) {
_selectedItem.value = selectedItem
if (selectedItem is SelectedItem.CommitBasedItem) {
commitChangesViewModel.loadChanges(selectedItem.revCommit)
}
}
} }

View File

@ -39,6 +39,10 @@ class TagsViewModel @Inject constructor(
tagsManager.deleteTag(git, tag) tagsManager.deleteTag(git, tag)
} }
fun selectTag(tag: Ref) {
tabState.newSelectedRef(tag.objectId)
}
suspend fun refresh(git: Git) { suspend fun refresh(git: Git) {
loadTags(git) loadTags(git)
} }