Skip to content

Commit

Permalink
Added stashes context menu option to stash in log
Browse files Browse the repository at this point in the history
  • Loading branch information
JetpackDuba committed Nov 29, 2023
1 parent 21ce125 commit 1fcf0fc
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 60 deletions.
36 changes: 25 additions & 11 deletions src/main/kotlin/com/jetpackduba/gitnuro/ui/log/Log.kt
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,10 @@ fun MessagesList(
onRebaseBranch = onRebase,
onRebaseInteractive = { logViewModel.rebaseInteractive(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) },
)
}

Expand Down Expand Up @@ -737,6 +740,9 @@ fun CommitLine(
showCreateNewBranch: () -> Unit,
showCreateNewTag: () -> Unit,
resetBranch: () -> Unit,
onApplyStash: () -> Unit,
onPopStash: () -> Unit,
onDeleteStash: () -> Unit,
onMergeBranch: (Ref) -> Unit,
onRebaseBranch: (Ref) -> Unit,
onRevCommitSelected: () -> Unit,
Expand All @@ -748,16 +754,24 @@ fun CommitLine(

ContextMenu(
items = {
logContextMenu(
onCheckoutCommit = { logViewModel.checkoutCommit(graphNode) },
onCreateNewBranch = showCreateNewBranch,
onCreateNewTag = showCreateNewTag,
onRevertCommit = { logViewModel.revertCommit(graphNode) },
onCherryPickCommit = { logViewModel.cherrypickCommit(graphNode) },
onRebaseInteractive = onRebaseInteractive,
onResetBranch = { resetBranch() },
isLastCommit = isLastCommitOfCurrentBranch
)
if (graphNode.isStash) {
stashesContextMenuItems(
onApply = onApplyStash,
onPop = onPopStash,
onDelete = onDeleteStash,
)
} else {
logContextMenu(
onCheckoutCommit = { logViewModel.checkoutCommit(graphNode) },
onCreateNewBranch = showCreateNewBranch,
onCreateNewTag = showCreateNewTag,
onRevertCommit = { logViewModel.revertCommit(graphNode) },
onCherryPickCommit = { logViewModel.cherrypickCommit(graphNode) },
onRebaseInteractive = onRebaseInteractive,
onResetBranch = { resetBranch() },
isLastCommit = isLastCommitOfCurrentBranch
)
}
},
) {
Box(
Expand Down
13 changes: 10 additions & 3 deletions src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/LogViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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.PullFromSpecificBranchUseCase
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.DeleteTagUseCase
import com.jetpackduba.gitnuro.git.workspace.CheckHasUncommitedChangesUseCase
Expand Down Expand Up @@ -67,10 +70,14 @@ class LogViewModel @Inject constructor(
private val deleteTagUseCase: DeleteTagUseCase,
private val rebaseBranchUseCase: RebaseBranchUseCase,
private val startRebaseInteractiveUseCase: StartRebaseInteractiveUseCase,
private val applyStashUseCase: ApplyStashUseCase,
private val popStashUseCase: PopStashUseCase,
private val deleteStashUseCase: DeleteStashUseCase,
private val tabState: TabState,
private val appSettings: AppSettings,
private val tabScope: CoroutineScope,
) : ViewModel {
sharedStashViewModel: SharedStashViewModel,
) : ViewModel, ISharedStashViewModel by sharedStashViewModel {
private val _logStatus = MutableStateFlow<LogStatus>(LogStatus.Loading)

val logStatus: StateFlow<LogStatus>
Expand Down Expand Up @@ -445,7 +452,7 @@ class LogViewModel @Inject constructor(
}

sealed class LogStatus {
object Loading : LogStatus()
data object Loading : LogStatus()
class Loaded(
val hasUncommittedChanges: Boolean,
val plotCommitList: GraphCommitList,
Expand All @@ -456,7 +463,7 @@ sealed class LogStatus {
}

sealed class LogSearch {
object NotSearching : LogSearch()
data object NotSearching : LogSearch()
data class SearchResults(
val commits: List<GraphNode>,
val index: Int,
Expand Down
Original file line number Diff line number Diff line change
@@ -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()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,25 @@ import com.jetpackduba.gitnuro.git.stash.DeleteStashUseCase
import com.jetpackduba.gitnuro.git.stash.GetStashListUseCase
import com.jetpackduba.gitnuro.git.stash.PopStashUseCase
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.AssistedInject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.revwalk.RevCommit

class StashesViewModel @AssistedInject constructor(
private val getStashListUseCase: GetStashListUseCase,
private val applyStashUseCase: ApplyStashUseCase,
private val popStashUseCase: PopStashUseCase,
private val deleteStashUseCase: DeleteStashUseCase,
private val tabState: TabState,
private val tabScope: CoroutineScope,
@Assisted
private val filter: StateFlow<String>,
) : SidePanelChildViewModel(true) {
sharedStashViewModel: SharedStashViewModel,
) : SidePanelChildViewModel(true), ISharedStashViewModel by sharedStashViewModel {
private val stashes = MutableStateFlow<List<RevCommit>>(emptyList())

val stashesState: StateFlow<StashesState> = combine(stashes, isExpanded, filter) { stashes, isExpanded, filter ->
Expand Down Expand Up @@ -59,48 +60,6 @@ class StashesViewModel @AssistedInject constructor(
suspend fun refresh(git: 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()
}
}
}


Expand Down

0 comments on commit 1fcf0fc

Please sign in to comment.