Added stashes context menu option to stash in log

This commit is contained in:
Abdelilah El Aissaoui 2023-11-29 23:38:22 +01:00
parent 21ce125931
commit 1fcf0fc921
No known key found for this signature in database
GPG Key ID: 7587FC860F594869
4 changed files with 108 additions and 60 deletions

View File

@ -495,7 +495,10 @@ fun MessagesList(
onRebaseBranch = onRebase, onRebaseBranch = onRebase,
onRebaseInteractive = { logViewModel.rebaseInteractive(graphNode) }, onRebaseInteractive = { logViewModel.rebaseInteractive(graphNode) },
onRevCommitSelected = { logViewModel.selectLogLine(graphNode) }, onRevCommitSelected = { logViewModel.selectLogLine(graphNode) },
onChangeDefaultUpstreamBranch = { onShowLogDialog(LogDialog.ChangeDefaultBranch(it)) } onChangeDefaultUpstreamBranch = { onShowLogDialog(LogDialog.ChangeDefaultBranch(it)) },
onDeleteStash = { logViewModel.deleteStash(graphNode) },
onApplyStash = { logViewModel.applyStash(graphNode) },
onPopStash = { logViewModel.popStash(graphNode) },
) )
} }
@ -737,6 +740,9 @@ fun CommitLine(
showCreateNewBranch: () -> Unit, showCreateNewBranch: () -> Unit,
showCreateNewTag: () -> Unit, showCreateNewTag: () -> Unit,
resetBranch: () -> Unit, resetBranch: () -> Unit,
onApplyStash: () -> Unit,
onPopStash: () -> Unit,
onDeleteStash: () -> Unit,
onMergeBranch: (Ref) -> Unit, onMergeBranch: (Ref) -> Unit,
onRebaseBranch: (Ref) -> Unit, onRebaseBranch: (Ref) -> Unit,
onRevCommitSelected: () -> Unit, onRevCommitSelected: () -> Unit,
@ -748,16 +754,24 @@ fun CommitLine(
ContextMenu( ContextMenu(
items = { items = {
logContextMenu( if (graphNode.isStash) {
onCheckoutCommit = { logViewModel.checkoutCommit(graphNode) }, stashesContextMenuItems(
onCreateNewBranch = showCreateNewBranch, onApply = onApplyStash,
onCreateNewTag = showCreateNewTag, onPop = onPopStash,
onRevertCommit = { logViewModel.revertCommit(graphNode) }, onDelete = onDeleteStash,
onCherryPickCommit = { logViewModel.cherrypickCommit(graphNode) }, )
onRebaseInteractive = onRebaseInteractive, } else {
onResetBranch = { resetBranch() }, logContextMenu(
isLastCommit = isLastCommitOfCurrentBranch onCheckoutCommit = { logViewModel.checkoutCommit(graphNode) },
) onCreateNewBranch = showCreateNewBranch,
onCreateNewTag = showCreateNewTag,
onRevertCommit = { logViewModel.revertCommit(graphNode) },
onCherryPickCommit = { logViewModel.cherrypickCommit(graphNode) },
onRebaseInteractive = onRebaseInteractive,
onResetBranch = { resetBranch() },
isLastCommit = isLastCommitOfCurrentBranch
)
}
}, },
) { ) {
Box( Box(

View File

@ -17,6 +17,9 @@ import com.jetpackduba.gitnuro.git.rebase.StartRebaseInteractiveUseCase
import com.jetpackduba.gitnuro.git.remote_operations.DeleteRemoteBranchUseCase import com.jetpackduba.gitnuro.git.remote_operations.DeleteRemoteBranchUseCase
import com.jetpackduba.gitnuro.git.remote_operations.PullFromSpecificBranchUseCase import com.jetpackduba.gitnuro.git.remote_operations.PullFromSpecificBranchUseCase
import com.jetpackduba.gitnuro.git.remote_operations.PushToSpecificBranchUseCase import com.jetpackduba.gitnuro.git.remote_operations.PushToSpecificBranchUseCase
import com.jetpackduba.gitnuro.git.stash.ApplyStashUseCase
import com.jetpackduba.gitnuro.git.stash.DeleteStashUseCase
import com.jetpackduba.gitnuro.git.stash.PopStashUseCase
import com.jetpackduba.gitnuro.git.tags.CreateTagOnCommitUseCase import com.jetpackduba.gitnuro.git.tags.CreateTagOnCommitUseCase
import com.jetpackduba.gitnuro.git.tags.DeleteTagUseCase import com.jetpackduba.gitnuro.git.tags.DeleteTagUseCase
import com.jetpackduba.gitnuro.git.workspace.CheckHasUncommitedChangesUseCase import com.jetpackduba.gitnuro.git.workspace.CheckHasUncommitedChangesUseCase
@ -67,10 +70,14 @@ class LogViewModel @Inject constructor(
private val deleteTagUseCase: DeleteTagUseCase, private val deleteTagUseCase: DeleteTagUseCase,
private val rebaseBranchUseCase: RebaseBranchUseCase, private val rebaseBranchUseCase: RebaseBranchUseCase,
private val startRebaseInteractiveUseCase: StartRebaseInteractiveUseCase, private val startRebaseInteractiveUseCase: StartRebaseInteractiveUseCase,
private val applyStashUseCase: ApplyStashUseCase,
private val popStashUseCase: PopStashUseCase,
private val deleteStashUseCase: DeleteStashUseCase,
private val tabState: TabState, private val tabState: TabState,
private val appSettings: AppSettings, private val appSettings: AppSettings,
private val tabScope: CoroutineScope, private val tabScope: CoroutineScope,
) : ViewModel { sharedStashViewModel: SharedStashViewModel,
) : ViewModel, ISharedStashViewModel by sharedStashViewModel {
private val _logStatus = MutableStateFlow<LogStatus>(LogStatus.Loading) private val _logStatus = MutableStateFlow<LogStatus>(LogStatus.Loading)
val logStatus: StateFlow<LogStatus> val logStatus: StateFlow<LogStatus>
@ -445,7 +452,7 @@ class LogViewModel @Inject constructor(
} }
sealed class LogStatus { sealed class LogStatus {
object Loading : LogStatus() data object Loading : LogStatus()
class Loaded( class Loaded(
val hasUncommittedChanges: Boolean, val hasUncommittedChanges: Boolean,
val plotCommitList: GraphCommitList, val plotCommitList: GraphCommitList,
@ -456,7 +463,7 @@ sealed class LogStatus {
} }
sealed class LogSearch { sealed class LogSearch {
object NotSearching : LogSearch() data object NotSearching : LogSearch()
data class SearchResults( data class SearchResults(
val commits: List<GraphNode>, val commits: List<GraphNode>,
val index: Int, val index: Int,

View File

@ -0,0 +1,68 @@
package com.jetpackduba.gitnuro.viewmodels
import com.jetpackduba.gitnuro.git.RefreshType
import com.jetpackduba.gitnuro.git.TabState
import com.jetpackduba.gitnuro.git.stash.ApplyStashUseCase
import com.jetpackduba.gitnuro.git.stash.DeleteStashUseCase
import com.jetpackduba.gitnuro.git.stash.PopStashUseCase
import com.jetpackduba.gitnuro.ui.SelectedItem
import kotlinx.coroutines.Job
import org.eclipse.jgit.revwalk.RevCommit
import javax.inject.Inject
interface ISharedStashViewModel {
fun applyStash(stashInfo: RevCommit): Job
fun popStash(stash: RevCommit): Job
fun deleteStash(stash: RevCommit): Job
fun selectStash(stash: RevCommit): Job
fun stashDropped(stash: RevCommit): Job
}
class SharedStashViewModel @Inject constructor(
private val applyStashUseCase: ApplyStashUseCase,
private val popStashUseCase: PopStashUseCase,
private val deleteStashUseCase: DeleteStashUseCase,
private val tabState: TabState,
) : ISharedStashViewModel {
override fun applyStash(stashInfo: RevCommit) = tabState.safeProcessing(
refreshType = RefreshType.UNCOMMITED_CHANGES_AND_LOG,
refreshEvenIfCrashes = true,
) { git ->
applyStashUseCase(git, stashInfo)
}
override fun popStash(stash: RevCommit) = tabState.safeProcessing(
refreshType = RefreshType.UNCOMMITED_CHANGES_AND_LOG,
refreshEvenIfCrashes = true,
) { git ->
popStashUseCase(git, stash)
stashDropped(stash)
}
override fun deleteStash(stash: RevCommit) = tabState.safeProcessing(
refreshType = RefreshType.STASHES,
) { git ->
deleteStashUseCase(git, stash)
stashDropped(stash)
}
override fun selectStash(stash: RevCommit) = tabState.runOperation(
refreshType = RefreshType.NONE,
) {
tabState.newSelectedStash(stash)
}
override fun stashDropped(stash: RevCommit) = tabState.runOperation(
refreshType = RefreshType.NONE,
) {
val selectedValue = tabState.selectedItem.value
if (
selectedValue is SelectedItem.Stash &&
selectedValue.revCommit.name == stash.name
) {
tabState.noneSelected()
}
}
}

View File

@ -8,9 +8,12 @@ import com.jetpackduba.gitnuro.git.stash.DeleteStashUseCase
import com.jetpackduba.gitnuro.git.stash.GetStashListUseCase import com.jetpackduba.gitnuro.git.stash.GetStashListUseCase
import com.jetpackduba.gitnuro.git.stash.PopStashUseCase import com.jetpackduba.gitnuro.git.stash.PopStashUseCase
import com.jetpackduba.gitnuro.ui.SelectedItem import com.jetpackduba.gitnuro.ui.SelectedItem
import com.jetpackduba.gitnuro.viewmodels.ISharedStashViewModel
import com.jetpackduba.gitnuro.viewmodels.SharedStashViewModel
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
@ -18,14 +21,12 @@ import org.eclipse.jgit.revwalk.RevCommit
class StashesViewModel @AssistedInject constructor( class StashesViewModel @AssistedInject constructor(
private val getStashListUseCase: GetStashListUseCase, private val getStashListUseCase: GetStashListUseCase,
private val applyStashUseCase: ApplyStashUseCase,
private val popStashUseCase: PopStashUseCase,
private val deleteStashUseCase: DeleteStashUseCase,
private val tabState: TabState, private val tabState: TabState,
private val tabScope: CoroutineScope, private val tabScope: CoroutineScope,
@Assisted @Assisted
private val filter: StateFlow<String>, private val filter: StateFlow<String>,
) : SidePanelChildViewModel(true) { sharedStashViewModel: SharedStashViewModel,
) : SidePanelChildViewModel(true), ISharedStashViewModel by sharedStashViewModel {
private val stashes = MutableStateFlow<List<RevCommit>>(emptyList()) private val stashes = MutableStateFlow<List<RevCommit>>(emptyList())
val stashesState: StateFlow<StashesState> = combine(stashes, isExpanded, filter) { stashes, isExpanded, filter -> val stashesState: StateFlow<StashesState> = combine(stashes, isExpanded, filter) { stashes, isExpanded, filter ->
@ -59,48 +60,6 @@ class StashesViewModel @AssistedInject 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,
refreshEvenIfCrashes = true,
) { git ->
applyStashUseCase(git, stashInfo)
}
fun popStash(stash: RevCommit) = tabState.safeProcessing(
refreshType = RefreshType.UNCOMMITED_CHANGES_AND_LOG,
refreshEvenIfCrashes = true,
) { git ->
popStashUseCase(git, stash)
stashDropped(stash)
}
fun deleteStash(stash: RevCommit) = tabState.safeProcessing(
refreshType = RefreshType.STASHES,
) { git ->
deleteStashUseCase(git, stash)
stashDropped(stash)
}
fun selectStash(stash: RevCommit) = tabState.runOperation(
refreshType = RefreshType.NONE,
) {
tabState.newSelectedStash(stash)
}
private fun stashDropped(stash: RevCommit) = tabState.runOperation(
refreshType = RefreshType.NONE,
) {
val selectedValue = tabState.selectedItem.value
if (
selectedValue is SelectedItem.Stash &&
selectedValue.revCommit.name == stash.name
) {
tabState.noneSelected()
}
}
} }