From 02313fe632fdfdddd5d5f1eca533b69b47cf3432 Mon Sep 17 00:00:00 2001 From: Abdelilah El Aissaoui Date: Sun, 6 Feb 2022 22:57:46 +0100 Subject: [PATCH] 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 --- src/main/kotlin/app/git/StashManager.kt | 21 ++++++++ src/main/kotlin/app/git/StatusManager.kt | 2 - src/main/kotlin/app/git/TabState.kt | 40 ++++++++++++++- src/main/kotlin/app/ui/Branches.kt | 3 +- src/main/kotlin/app/ui/CommitChanges.kt | 12 +++-- src/main/kotlin/app/ui/Remotes.kt | 3 +- src/main/kotlin/app/ui/RepositoryOpen.kt | 18 +------ src/main/kotlin/app/ui/Stashes.kt | 43 ++++++++++++---- src/main/kotlin/app/ui/Tags.kt | 3 +- .../app/ui/context_menu/StashesContextMenu.kt | 26 ++++++++++ src/main/kotlin/app/ui/log/Log.kt | 7 +-- .../app/viewmodels/BranchesViewModel.kt | 4 ++ .../kotlin/app/viewmodels/LogViewModel.kt | 5 ++ .../kotlin/app/viewmodels/MenuViewModel.kt | 4 +- .../kotlin/app/viewmodels/RemotesViewModel.kt | 4 ++ .../kotlin/app/viewmodels/StashesViewModel.kt | 39 ++++++++++++++ .../kotlin/app/viewmodels/StatusViewModel.kt | 16 ++++++ .../kotlin/app/viewmodels/TabViewModel.kt | 51 +++++++------------ .../kotlin/app/viewmodels/TagsViewModel.kt | 4 ++ 19 files changed, 225 insertions(+), 80 deletions(-) create mode 100644 src/main/kotlin/app/ui/context_menu/StashesContextMenu.kt diff --git a/src/main/kotlin/app/git/StashManager.kt b/src/main/kotlin/app/git/StashManager.kt index b1eef14..c3b4fba 100644 --- a/src/main/kotlin/app/git/StashManager.kt +++ b/src/main/kotlin/app/git/StashManager.kt @@ -3,6 +3,7 @@ package app.git import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.eclipse.jgit.api.Git +import org.eclipse.jgit.revwalk.RevCommit import javax.inject.Inject class StashManager @Inject constructor() { @@ -22,9 +23,29 @@ class StashManager @Inject constructor() { .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) { return@withContext git .stashList() .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() + } } \ No newline at end of file diff --git a/src/main/kotlin/app/git/StatusManager.kt b/src/main/kotlin/app/git/StatusManager.kt index a1d7206..f141280 100644 --- a/src/main/kotlin/app/git/StatusManager.kt +++ b/src/main/kotlin/app/git/StatusManager.kt @@ -281,10 +281,8 @@ class StatusManager @Inject constructor( suspend fun getStatusSummary(git: Git, currentBranch: Ref?, repositoryState: RepositoryState): StatusSummary { val staged = getStaged(git, currentBranch, repositoryState) val allChanges = staged.toMutableList() - println("Staged: $staged") val unstaged = getUnstaged(git, repositoryState) - println("Unstaged: $unstaged") allChanges.addAll(unstaged) val groupedChanges = allChanges.groupBy { diff --git a/src/main/kotlin/app/git/TabState.kt b/src/main/kotlin/app/git/TabState.kt index bc5e5e0..f74cc8f 100644 --- a/src/main/kotlin/app/git/TabState.kt +++ b/src/main/kotlin/app/git/TabState.kt @@ -3,6 +3,7 @@ package app.git import app.ErrorsManager import app.di.TabScope import app.newErrorNow +import app.ui.SelectedItem import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob @@ -14,6 +15,8 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import org.eclipse.jgit.api.Git +import org.eclipse.jgit.lib.ObjectId +import org.eclipse.jgit.revwalk.RevCommit import javax.inject.Inject import kotlin.coroutines.cancellation.CancellationException @@ -21,12 +24,14 @@ import kotlin.coroutines.cancellation.CancellationException class TabState @Inject constructor( val errorsManager: ErrorsManager, ) { + private val _selectedItem = MutableStateFlow(SelectedItem.None) + val selectedItem: StateFlow = _selectedItem + var git: Git? = null val safeGit: Git get() { val git = this.git if (git == null) { -// _repositorySelectionStatus.value = RepositorySelectionStatus.None throw CancellationException("Null git object") } else return git @@ -128,11 +133,44 @@ class TabState @Inject constructor( _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 { NONE, ALL_DATA, ONLY_LOG, + STASHES, UNCOMMITED_CHANGES, + UNCOMMITED_CHANGES_AND_LOG, } \ No newline at end of file diff --git a/src/main/kotlin/app/ui/Branches.kt b/src/main/kotlin/app/ui/Branches.kt index 433ed0f..38230d8 100644 --- a/src/main/kotlin/app/ui/Branches.kt +++ b/src/main/kotlin/app/ui/Branches.kt @@ -22,7 +22,6 @@ import org.eclipse.jgit.lib.Ref @Composable fun Branches( branchesViewModel: BranchesViewModel, - onBranchClicked: (Ref) -> Unit, ) { val branches by branchesViewModel.branches.collectAsState() val currentBranch by branchesViewModel.currentBranch.collectAsState() @@ -37,7 +36,7 @@ fun Branches( BranchLineEntry( branch = branch, isCurrentBranch = currentBranch == branch.name, - onBranchClicked = { onBranchClicked(branch) }, + onBranchClicked = { branchesViewModel.selectBranch(branch) }, onCheckoutBranch = { branchesViewModel.checkoutRef(branch) }, onMergeBranch = { setMergeBranch(branch) }, onDeleteBranch = { branchesViewModel.deleteBranch(branch) }, diff --git a/src/main/kotlin/app/ui/CommitChanges.kt b/src/main/kotlin/app/ui/CommitChanges.kt index dd0f19b..804dc2c 100644 --- a/src/main/kotlin/app/ui/CommitChanges.kt +++ b/src/main/kotlin/app/ui/CommitChanges.kt @@ -8,10 +8,7 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.foundation.verticalScroll import androidx.compose.material.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember +import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight @@ -34,8 +31,13 @@ import org.eclipse.jgit.revwalk.RevCommit @Composable fun CommitChanges( commitChangesViewModel: CommitChangesViewModel, - onDiffSelected: (DiffEntry) -> Unit + onDiffSelected: (DiffEntry) -> Unit, + selectedItem: SelectedItem.CommitBasedItem ) { + LaunchedEffect(selectedItem) { + commitChangesViewModel.loadChanges(selectedItem.revCommit) + } + val commitChangesStatusState = commitChangesViewModel.commitChangesStatus.collectAsState() when (val commitChangesStatus = commitChangesStatusState.value) { diff --git a/src/main/kotlin/app/ui/Remotes.kt b/src/main/kotlin/app/ui/Remotes.kt index de62123..e9a937c 100644 --- a/src/main/kotlin/app/ui/Remotes.kt +++ b/src/main/kotlin/app/ui/Remotes.kt @@ -21,7 +21,6 @@ import org.eclipse.jgit.lib.Ref @Composable fun Remotes( remotesViewModel: RemotesViewModel, - onBranchClicked: (Ref) -> Unit, ) { val remotes by remotesViewModel.remotes.collectAsState() @@ -43,7 +42,7 @@ fun Remotes( itemContent = { remoteInfo -> RemoteRow( remote = remoteInfo, - onBranchClicked = { branch -> onBranchClicked(branch) }, + onBranchClicked = { branch -> remotesViewModel.selectBranch(branch) }, onDeleteBranch = { branch -> remotesViewModel.deleteRemoteBranch(branch) }, onRemoteClicked = { remotesViewModel.onRemoteClicked(remoteInfo) } ) diff --git a/src/main/kotlin/app/ui/RepositoryOpen.kt b/src/main/kotlin/app/ui/RepositoryOpen.kt index 7649dea..cbc3459 100644 --- a/src/main/kotlin/app/ui/RepositoryOpen.kt +++ b/src/main/kotlin/app/ui/RepositoryOpen.kt @@ -51,7 +51,7 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) { ) Row { - HorizontalSplitPane() { + HorizontalSplitPane { first(minSize = 200.dp) { Column( modifier = Modifier @@ -61,27 +61,15 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) { ) { Branches( branchesViewModel = tabViewModel.branchesViewModel, - onBranchClicked = { - tabViewModel.newSelectedRef(it.objectId) - } ) Remotes( remotesViewModel = tabViewModel.remotesViewModel, - onBranchClicked = { - tabViewModel.newSelectedRef(it.objectId) - } ) Tags( tagsViewModel = tabViewModel.tagsViewModel, - onTagClicked = { - tabViewModel.newSelectedRef(it.objectId) - } ) Stashes( stashesViewModel = tabViewModel.stashesViewModel, - onStashSelected = { stash -> - tabViewModel.newSelectedStash(stash) - } ) } } @@ -104,9 +92,6 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) { Log( logViewModel = tabViewModel.logViewModel, selectedItem = selectedItem, - onItemSelected = { - tabViewModel.newSelectedItem(it) - }, repositoryState = repositoryState, ) } @@ -143,6 +128,7 @@ fun RepositoryOpenPage(tabViewModel: TabViewModel) { } else if (safeSelectedItem is SelectedItem.CommitBasedItem) { CommitChanges( commitChangesViewModel = tabViewModel.commitChangesViewModel, + selectedItem = safeSelectedItem, onDiffSelected = { diffEntry -> tabViewModel.newDiffSelected = DiffEntryType.CommitDiff(diffEntry) } diff --git a/src/main/kotlin/app/ui/Stashes.kt b/src/main/kotlin/app/ui/Stashes.kt index 3aea50f..e7fc914 100644 --- a/src/main/kotlin/app/ui/Stashes.kt +++ b/src/main/kotlin/app/ui/Stashes.kt @@ -1,10 +1,16 @@ +@file:OptIn(ExperimentalFoundationApi::class) + 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.collectAsState import androidx.compose.ui.res.painterResource import app.ui.components.SideMenuPanel import app.ui.components.SideMenuSubentry +import app.ui.context_menu.stashesContextMenuItems import app.viewmodels.StashStatus import app.viewmodels.StashesViewModel import org.eclipse.jgit.revwalk.RevCommit @@ -12,7 +18,6 @@ import org.eclipse.jgit.revwalk.RevCommit @Composable fun Stashes( stashesViewModel: StashesViewModel, - onStashSelected: (commit: RevCommit) -> Unit, ) { val stashStatusState = stashesViewModel.stashStatus.collectAsState() val stashStatus = stashStatusState.value @@ -22,15 +27,23 @@ fun Stashes( else listOf() - SideMenuPanel( title = "Stashes", icon = painterResource("stash.svg"), items = stashList, - itemContent = { stashInfo -> + itemContent = { stash -> StashRow( - stash = stashInfo, - onClick = { onStashSelected(stashInfo) } + stash = stash, + 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 -private fun StashRow(stash: RevCommit, onClick: () -> Unit) { - SideMenuSubentry( - text = stash.shortMessage, - iconResourcePath = "stash.svg", - onClick = onClick, - ) +private fun StashRow( + stash: RevCommit, + onClick: () -> Unit, + contextItems: List, +) { + ContextMenuArea( + items = { contextItems } + ) { + SideMenuSubentry( + text = stash.shortMessage, + iconResourcePath = "stash.svg", + onClick = onClick, + ) + } } \ No newline at end of file diff --git a/src/main/kotlin/app/ui/Tags.kt b/src/main/kotlin/app/ui/Tags.kt index acfe859..6dd28e5 100644 --- a/src/main/kotlin/app/ui/Tags.kt +++ b/src/main/kotlin/app/ui/Tags.kt @@ -15,7 +15,6 @@ import org.eclipse.jgit.lib.Ref @Composable fun Tags( tagsViewModel: TagsViewModel, - onTagClicked: (Ref) -> Unit, ) { val tagsState = tagsViewModel.tags.collectAsState() val tags = tagsState.value @@ -27,7 +26,7 @@ fun Tags( itemContent = { tag -> TagRow( tag = tag, - onTagClicked = { onTagClicked(tag) }, + onTagClicked = { tagsViewModel.selectTag(tag) }, onCheckoutTag = { tagsViewModel.checkoutRef(tag) }, onDeleteTag = { tagsViewModel.deleteTag(tag) } ) diff --git a/src/main/kotlin/app/ui/context_menu/StashesContextMenu.kt b/src/main/kotlin/app/ui/context_menu/StashesContextMenu.kt new file mode 100644 index 0000000..fca97c6 --- /dev/null +++ b/src/main/kotlin/app/ui/context_menu/StashesContextMenu.kt @@ -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 { + return mutableListOf( + ContextMenuItem( + label = "Apply stash", + onClick = onApply + ), + ContextMenuItem( + label = "Pop stash", + onClick = onPop + ), + ContextMenuItem( + label = "Drop stash", + onClick = onDelete + ), + ) +} \ No newline at end of file diff --git a/src/main/kotlin/app/ui/log/Log.kt b/src/main/kotlin/app/ui/log/Log.kt index 6030cb1..ec811a2 100644 --- a/src/main/kotlin/app/ui/log/Log.kt +++ b/src/main/kotlin/app/ui/log/Log.kt @@ -72,7 +72,6 @@ private const val CANVAS_MIN_WIDTH = 100 fun Log( logViewModel: LogViewModel, selectedItem: SelectedItem, - onItemSelected: (SelectedItem) -> Unit, repositoryState: RepositoryState, ) { val logStatusState = logViewModel.logStatus.collectAsState() @@ -114,7 +113,6 @@ fun Log( .background(MaterialTheme.colors.background) .fillMaxSize() ) { -// val hasUncommitedChanges by tabViewModel.hasUncommitedChanges.collectAsState() val weightMod = remember { mutableStateOf(0f) } var graphWidth = (CANVAS_MIN_WIDTH + weightMod.value).dp @@ -131,7 +129,6 @@ fun Log( .background(MaterialTheme.colors.background) .fillMaxSize(), ) { - //TODO: Shouldn't this be an item of the graph? if (hasUncommitedChanges) item { UncommitedChangesLine( @@ -142,7 +139,7 @@ fun Log( weightMod = weightMod, repositoryState = repositoryState, onUncommitedChangesSelected = { - onItemSelected(SelectedItem.UncommitedChanges) + logViewModel.selectLogLine(SelectedItem.UncommitedChanges) } ) } @@ -160,7 +157,7 @@ fun Log( onMergeBranch = { ref -> showLogDialog.value = LogDialog.MergeBranch(ref) }, onRebaseBranch = { ref -> showLogDialog.value = LogDialog.RebaseBranch(ref) }, onRevCommitSelected = { - onItemSelected(SelectedItem.Commit(graphNode)) + logViewModel.selectLogLine(SelectedItem.Commit(graphNode)) } ) } diff --git a/src/main/kotlin/app/viewmodels/BranchesViewModel.kt b/src/main/kotlin/app/viewmodels/BranchesViewModel.kt index bd06bbd..94daad3 100644 --- a/src/main/kotlin/app/viewmodels/BranchesViewModel.kt +++ b/src/main/kotlin/app/viewmodels/BranchesViewModel.kt @@ -71,4 +71,8 @@ class BranchesViewModel @Inject constructor( ) { git -> rebaseManager.rebaseBranch(git, ref) } + + fun selectBranch(ref: Ref) { + tabState.newSelectedRef(ref.objectId) + } } \ No newline at end of file diff --git a/src/main/kotlin/app/viewmodels/LogViewModel.kt b/src/main/kotlin/app/viewmodels/LogViewModel.kt index eac523a..eee3141 100644 --- a/src/main/kotlin/app/viewmodels/LogViewModel.kt +++ b/src/main/kotlin/app/viewmodels/LogViewModel.kt @@ -2,6 +2,7 @@ package app.viewmodels import app.git.* import app.git.graph.GraphCommitList +import app.ui.SelectedItem import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import org.eclipse.jgit.api.Git @@ -143,6 +144,10 @@ class LogViewModel @Inject constructor( ) { git -> rebaseManager.rebaseBranch(git, ref) } + + fun selectLogLine(selectedItem: SelectedItem) { + tabState.newSelectedItem(selectedItem) + } } sealed class LogStatus { diff --git a/src/main/kotlin/app/viewmodels/MenuViewModel.kt b/src/main/kotlin/app/viewmodels/MenuViewModel.kt index eb827f3..683e61d 100644 --- a/src/main/kotlin/app/viewmodels/MenuViewModel.kt +++ b/src/main/kotlin/app/viewmodels/MenuViewModel.kt @@ -34,13 +34,13 @@ class MenuViewModel @Inject constructor( } fun stash() = tabState.safeProcessing( - refreshType = RefreshType.UNCOMMITED_CHANGES, + refreshType = RefreshType.UNCOMMITED_CHANGES_AND_LOG, ) { git -> stashManager.stash(git) } fun popStash() = tabState.safeProcessing( - refreshType = RefreshType.UNCOMMITED_CHANGES, + refreshType = RefreshType.UNCOMMITED_CHANGES_AND_LOG, ) { git -> stashManager.popStash(git) } diff --git a/src/main/kotlin/app/viewmodels/RemotesViewModel.kt b/src/main/kotlin/app/viewmodels/RemotesViewModel.kt index 4333eb7..800da98 100644 --- a/src/main/kotlin/app/viewmodels/RemotesViewModel.kt +++ b/src/main/kotlin/app/viewmodels/RemotesViewModel.kt @@ -58,6 +58,10 @@ class RemotesViewModel @Inject constructor( _remotes.value = newRemotesList } + + fun selectBranch(ref: Ref) { + tabState.newSelectedRef(ref.objectId) + } } data class RemoteView(val remoteInfo: RemoteInfo, val isExpanded: Boolean) \ No newline at end of file diff --git a/src/main/kotlin/app/viewmodels/StashesViewModel.kt b/src/main/kotlin/app/viewmodels/StashesViewModel.kt index f145566..223cc4d 100644 --- a/src/main/kotlin/app/viewmodels/StashesViewModel.kt +++ b/src/main/kotlin/app/viewmodels/StashesViewModel.kt @@ -1,6 +1,9 @@ package app.viewmodels +import app.git.RefreshType import app.git.StashManager +import app.git.TabState +import app.ui.SelectedItem import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import org.eclipse.jgit.api.Git @@ -9,6 +12,7 @@ import javax.inject.Inject class StashesViewModel @Inject constructor( private val stashManager: StashManager, + private val tabState: TabState, ) { private val _stashStatus = MutableStateFlow(StashStatus.Loaded(listOf())) val stashStatus: StateFlow @@ -23,6 +27,41 @@ class StashesViewModel @Inject constructor( suspend fun refresh(git: 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() + } + } } diff --git a/src/main/kotlin/app/viewmodels/StatusViewModel.kt b/src/main/kotlin/app/viewmodels/StatusViewModel.kt index b9a5f9c..7b0ac5d 100644 --- a/src/main/kotlin/app/viewmodels/StatusViewModel.kt +++ b/src/main/kotlin/app/viewmodels/StatusViewModel.kt @@ -108,6 +108,22 @@ class StatusViewModel @Inject constructor( 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( refreshType = RefreshType.ALL_DATA, ) { git -> diff --git a/src/main/kotlin/app/viewmodels/TabViewModel.kt b/src/main/kotlin/app/viewmodels/TabViewModel.kt index 0064c76..5fdb5fc 100644 --- a/src/main/kotlin/app/viewmodels/TabViewModel.kt +++ b/src/main/kotlin/app/viewmodels/TabViewModel.kt @@ -41,8 +41,7 @@ class TabViewModel @Inject constructor( private val fileChangesWatcher: FileChangesWatcher, ) { val errorsManager: ErrorsManager = tabState.errorsManager - private val _selectedItem = MutableStateFlow(SelectedItem.None) - val selectedItem: StateFlow = _selectedItem + val selectedItem: StateFlow = tabState.selectedItem private val credentialsStateManager = CredentialsStateManager @@ -75,12 +74,20 @@ class TabViewModel @Inject constructor( RefreshType.NONE -> println("Not refreshing...") RefreshType.ALL_DATA -> refreshRepositoryInfo() RefreshType.ONLY_LOG -> refreshLog() + RefreshType.STASHES -> refreshStashes() 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( refreshType = RefreshType.NONE, ) { 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, ) { git -> - statusViewModel.refresh(git) - logViewModel.refreshUncommitedChanges(git) + val uncommitedChangesStateChanged = statusViewModel.updateHasUncommitedChanges(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() @@ -195,10 +209,6 @@ class TabViewModel @Inject constructor( remoteOperationsManager.clone(directory, url) } - private fun findCommit(git: Git, objectId: ObjectId): RevCommit { - return git.repository.parseCommit(objectId) - } - private fun updateDiffEntry() { val diffSelected = diffSelected.value @@ -206,29 +216,6 @@ class TabViewModel @Inject constructor( 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) - } - } } diff --git a/src/main/kotlin/app/viewmodels/TagsViewModel.kt b/src/main/kotlin/app/viewmodels/TagsViewModel.kt index e1309c4..3e676ab 100644 --- a/src/main/kotlin/app/viewmodels/TagsViewModel.kt +++ b/src/main/kotlin/app/viewmodels/TagsViewModel.kt @@ -39,6 +39,10 @@ class TagsViewModel @Inject constructor( tagsManager.deleteTag(git, tag) } + fun selectTag(tag: Ref) { + tabState.newSelectedRef(tag.objectId) + } + suspend fun refresh(git: Git) { loadTags(git) }