From 8637365cb7fc687378307bae01481795ce96e3f0 Mon Sep 17 00:00:00 2001 From: Abdelilah El Aissaoui Date: Sun, 24 Mar 2024 00:14:04 +0100 Subject: [PATCH] Added task type for most operations and reduced duplicated code --- .../com/jetpackduba/gitnuro/TaskType.kt | 60 ++++++++++ .../gitnuro/exceptions/ExceptionsUtils.kt | 20 ++++ .../com/jetpackduba/gitnuro/git/TabState.kt | 60 ++++------ .../gitnuro/git/log/CheckoutCommitUseCase.kt | 5 +- .../gitnuro/managers/ErrorsManager.kt | 13 +- .../com/jetpackduba/gitnuro/ui/SidePanel.kt | 10 +- .../gitnuro/ui/context_menu/TagContextMenu.kt | 2 +- .../gitnuro/ui/dialogs/ErrorDialog.kt | 4 +- .../com/jetpackduba/gitnuro/ui/log/Log.kt | 8 +- .../gitnuro/viewmodels/HistoryViewModel.kt | 2 + .../gitnuro/viewmodels/LogViewModel.kt | 111 ++++-------------- .../gitnuro/viewmodels/MenuViewModel.kt | 10 +- .../viewmodels/RebaseInteractiveViewModel.kt | 8 +- .../gitnuro/viewmodels/SettingsViewModel.kt | 8 +- .../viewmodels/SharedBranchesViewModel.kt | 67 +++++++++++ .../viewmodels/SharedRemotesViewModel.kt | 71 +++++++++++ .../viewmodels/SharedStashViewModel.kt | 4 + .../gitnuro/viewmodels/SharedTagsViewModel.kt | 28 +++++ .../gitnuro/viewmodels/StatusViewModel.kt | 8 ++ .../gitnuro/viewmodels/TabViewModel.kt | 17 ++- .../viewmodels/sidepanel/BranchesViewModel.kt | 60 +--------- .../viewmodels/sidepanel/RemotesViewModel.kt | 49 ++------ .../sidepanel/SubmodulesViewModel.kt | 7 ++ .../viewmodels/sidepanel/TagsViewModel.kt | 24 ++-- 24 files changed, 388 insertions(+), 268 deletions(-) create mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/TaskType.kt create mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/exceptions/ExceptionsUtils.kt create mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedBranchesViewModel.kt create mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedRemotesViewModel.kt create mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedTagsViewModel.kt diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/TaskType.kt b/src/main/kotlin/com/jetpackduba/gitnuro/TaskType.kt new file mode 100644 index 0000000..98df49c --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/TaskType.kt @@ -0,0 +1,60 @@ +package com.jetpackduba.gitnuro + +enum class TaskType { + UNSPECIFIED, + STAGE_ALL_FILES, + UNSTAGE_ALL_FILES, + STAGE_FILE, + UNSTAGE_FILE, + STAGE_HUNK, + UNSTAGE_HUNK, + STAGE_LINE, + UNSTAGE_LINE, + DISCARD_FILE, + DELETE_FILE, + BLAME_FILE, + HISTORY_FILE, + DO_COMMIT, + AMEND_COMMIT, + REVERT_COMMIT, + CHERRY_PICK_COMMIT, + CHECKOUT_COMMIT, + RESET_TO_COMMIT, + CHECKOUT_BRANCH, + CHECKOUT_REMOTE_BRANCH, + CREATE_BRANCH, + DELETE_BRANCH, + MERGE_BRANCH, + REBASE_BRANCH, + REBASE_INTERACTIVE, + CONTINUE_REBASE, + ABORT_REBASE, + SKIP_REBASE, + CHANGE_BRANCH_UPSTREAM, + PULL_FROM_BRANCH, + PUSH_TO_BRANCH, + DELETE_REMOTE_BRANCH, + PULL, + PUSH, + FETCH, + STASH, + APPLY_STASH, + POP_STASH, + DELETE_STASH, + CREATE_TAG, + CHECKOUT_TAG, + DELETE_TAG, + ADD_SUBMODULE, + DELETE_SUBMODULE, + INIT_SUBMODULE, + DEINIT_SUBMODULE, + SYNC_SUBMODULE, + UPDATE_SUBMODULE, + SAVE_CUSTOM_THEME, + RESET_REPO_STATE, + CHANGES_DETECTION, + REPOSITORY_OPEN, + REPOSITORY_CLONE, + ADD_REMOTE, + DELETE_REMOTE, +} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/exceptions/ExceptionsUtils.kt b/src/main/kotlin/com/jetpackduba/gitnuro/exceptions/ExceptionsUtils.kt new file mode 100644 index 0000000..57b62d4 --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/exceptions/ExceptionsUtils.kt @@ -0,0 +1,20 @@ +package com.jetpackduba.gitnuro.exceptions + +import kotlinx.coroutines.CancellationException + +/** + * Used to transform generic exceptions that methods may throw (such as IOException) to more specific custom exceptions + */ +fun mapException(transform: (Exception) -> Exception, block: () -> T) { + try { + block() + } catch (ex: Exception) { + if (ex is CancellationException) { + throw ex // Coroutines cancellation must be passed up + } else { + val newException = transform(ex) + + throw newException + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/git/TabState.kt b/src/main/kotlin/com/jetpackduba/gitnuro/git/TabState.kt index b3a7436..95255fa 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/git/TabState.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/git/TabState.kt @@ -1,5 +1,6 @@ package com.jetpackduba.gitnuro.git +import com.jetpackduba.gitnuro.TaskType import com.jetpackduba.gitnuro.di.TabScope import com.jetpackduba.gitnuro.exceptions.GitnuroException import com.jetpackduba.gitnuro.extensions.delayedStateChange @@ -18,11 +19,6 @@ import javax.inject.Inject private const val TAG = "TabState" -interface ProcessingInfo { - fun changeSubtitle(newSubtitle: String) - fun changeIsCancellable(newIsCancellable: Boolean) -} - sealed interface ProcessingState { data object None : ProcessingState data class Processing( @@ -80,46 +76,18 @@ class TabState @Inject constructor( // migrate the code that uses this function title: String = "", subtitle: String = "", + taskType: TaskType, // TODO For now have it always as false because the data refresh is cancelled even when the git process couldn't be cancelled isCancellable: Boolean = false, refreshEvenIfCrashes: Boolean = false, refreshEvenIfCrashesInteractive: ((Exception) -> Boolean)? = null, - callback: suspend ProcessingInfo.(git: Git) -> Unit + callback: suspend (git: Git) -> Unit ): Job { val job = scope.launch(Dispatchers.IO) { var hasProcessFailed = false var refreshEvenIfCrashesInteractiveResult = false operationRunning = true - val processingInfo: ProcessingInfo = object : ProcessingInfo { - override fun changeSubtitle(newSubtitle: String) { - _processing.update { processingState -> - if (processingState is ProcessingState.Processing) { - processingState.copy(subtitle = newSubtitle) - } else { - ProcessingState.Processing( - title = title, - isCancellable = isCancellable, - subtitle = newSubtitle - ) - } - } - } - - override fun changeIsCancellable(newIsCancellable: Boolean) { - _processing.update { processingState -> - if (processingState is ProcessingState.Processing) { - processingState.copy(isCancellable = newIsCancellable) - } else { - ProcessingState.Processing( - title = title, - isCancellable = newIsCancellable, - subtitle = subtitle - ) - } - } - } - } try { delayedStateChange( @@ -134,7 +102,7 @@ class TabState @Inject constructor( } } ) { - processingInfo.callback(git) + callback(git) } } catch (ex: Exception) { hasProcessFailed = true @@ -147,7 +115,7 @@ class TabState @Inject constructor( if (!containsCancellation) { val innerException = getInnerException(ex) - errorsManager.addError(newErrorNow(innerException, null, innerException.message.orEmpty())) + errorsManager.addError(newErrorNow(taskType, innerException)) } printError(TAG, ex.message.orEmpty(), ex) @@ -210,7 +178,11 @@ class TabState @Inject constructor( val containsCancellation = exceptionContainsCancellation(ex) if (!containsCancellation) - errorsManager.addError(newErrorNow(ex, null, ex.localizedMessage)) + errorsManager.addError( + newErrorNow( + taskType = TaskType.UNSPECIFIED, ex + ) + ) printError(TAG, ex.message.orEmpty(), ex) } finally { @@ -242,7 +214,11 @@ class TabState @Inject constructor( hasProcessFailed = true if (showError) - errorsManager.addError(newErrorNow(ex, null, ex.localizedMessage)) + errorsManager.addError( + newErrorNow( + taskType = TaskType.UNSPECIFIED, ex + ) + ) printError(TAG, ex.message.orEmpty(), ex) } finally { @@ -317,7 +293,11 @@ class TabState @Inject constructor( callback(it) } catch (ex: Exception) { ex.printStackTrace() - errorsManager.addError(newErrorNow(ex, null, ex.localizedMessage)) + errorsManager.addError( + newErrorNow( + taskType = TaskType.UNSPECIFIED, ex + ) + ) } } } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/git/log/CheckoutCommitUseCase.kt b/src/main/kotlin/com/jetpackduba/gitnuro/git/log/CheckoutCommitUseCase.kt index 47c2412..16ee294 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/git/log/CheckoutCommitUseCase.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/git/log/CheckoutCommitUseCase.kt @@ -8,9 +8,12 @@ import javax.inject.Inject class CheckoutCommitUseCase @Inject constructor() { suspend operator fun invoke(git: Git, revCommit: RevCommit): Unit = withContext(Dispatchers.IO) { + this@CheckoutCommitUseCase(git, revCommit.name) + } + suspend operator fun invoke(git: Git, hash: String): Unit = withContext(Dispatchers.IO) { git .checkout() - .setName(revCommit.name) + .setName(hash) .call() } } \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/managers/ErrorsManager.kt b/src/main/kotlin/com/jetpackduba/gitnuro/managers/ErrorsManager.kt index 30c8134..9881c2a 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/managers/ErrorsManager.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/managers/ErrorsManager.kt @@ -1,6 +1,8 @@ package com.jetpackduba.gitnuro.managers +import com.jetpackduba.gitnuro.TaskType import com.jetpackduba.gitnuro.di.TabScope +import com.jetpackduba.gitnuro.exceptions.GitnuroException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow @@ -35,21 +37,20 @@ class ErrorsManager @Inject constructor() { data class Error( + val taskType: TaskType, val date: Long, val exception: Exception, - val title: String?, - val message: String + val isUnhandled: Boolean, ) fun newErrorNow( + taskType: TaskType, exception: Exception, - title: String?, - message: String, ): Error { return Error( + taskType = taskType, date = System.currentTimeMillis(), exception = exception, - title = title, - message = message + isUnhandled = exception !is GitnuroException ) } \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/SidePanel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/SidePanel.kt index a8f81be..176a7c9 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/SidePanel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/SidePanel.kt @@ -206,8 +206,6 @@ fun LazyListScope.localBranches( onMergeBranch = { branchesViewModel.mergeBranch(branch) }, onRebaseBranch = { branchesViewModel.rebaseBranch(branch) }, onDeleteBranch = { branchesViewModel.deleteBranch(branch) }, - onPushToRemoteBranch = { branchesViewModel.pushToRemoteBranch(branch) }, - onPullFromRemoteBranch = { branchesViewModel.pullFromRemoteBranch(branch) } ) { onChangeDefaultUpstreamBranch(branch) } } } @@ -304,7 +302,7 @@ fun LazyListScope.tags( tag, isSelected = selectedItem is SelectedItem.Ref && selectedItem.ref == tag, onTagClicked = { tagsViewModel.selectTag(tag) }, - onCheckoutTag = { tagsViewModel.checkoutRef(tag) }, + onCheckoutTag = { tagsViewModel.checkoutTagCommit(tag) }, onDeleteTag = { tagsViewModel.deleteTag(tag) } ) } @@ -413,8 +411,6 @@ private fun Branch( onMergeBranch: () -> Unit, onRebaseBranch: () -> Unit, onDeleteBranch: () -> Unit, - onPushToRemoteBranch: () -> Unit, - onPullFromRemoteBranch: () -> Unit, onChangeDefaultUpstreamBranch: () -> Unit, ) { val isCurrentBranch = currentBranch?.name == branch.name @@ -430,8 +426,8 @@ private fun Branch( onMergeBranch = onMergeBranch, onDeleteBranch = onDeleteBranch, onRebaseBranch = onRebaseBranch, - onPushToRemoteBranch = onPushToRemoteBranch, - onPullFromRemoteBranch = onPullFromRemoteBranch, + onPushToRemoteBranch = {}, + onPullFromRemoteBranch = {}, onChangeDefaultUpstreamBranch = onChangeDefaultUpstreamBranch ) } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/context_menu/TagContextMenu.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/context_menu/TagContextMenu.kt index e5e1922..cc069f1 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/context_menu/TagContextMenu.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/context_menu/TagContextMenu.kt @@ -9,7 +9,7 @@ fun tagContextMenuItems( ): List { return mutableListOf( ContextMenuElement.ContextTextEntry( - label = "Checkout tag", + label = "Checkout tag's commit", icon = { painterResource(AppIcons.START) }, onClick = onCheckoutTag ), diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/ErrorDialog.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/ErrorDialog.kt index 44afc9a..af8de47 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/ErrorDialog.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/ErrorDialog.kt @@ -38,7 +38,7 @@ fun ErrorDialog( ) { Row { Text( - text = error.title ?: "Error", + text = "Error", // TODO error.title ?: "Error", fontSize = 16.sp, fontWeight = FontWeight.SemiBold, color = MaterialTheme.colors.onBackground, @@ -55,7 +55,7 @@ fun ErrorDialog( } Text( - text = error.message, + text = error.exception.message.orEmpty(), // TODO color = MaterialTheme.colors.onBackground, modifier = Modifier .padding(top = 16.dp) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/log/Log.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/log/Log.kt index 32d41bc..aa84229 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/log/Log.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/log/Log.kt @@ -846,7 +846,13 @@ private fun CommitLine( nodeColor = nodeColor, matchesSearchFilter = matchesSearchFilter, currentBranch = currentBranch, - onCheckoutRef = { ref -> logViewModel.checkoutRef(ref) }, + onCheckoutRef = { ref -> + if (ref.isRemote && ref.isBranch) { + logViewModel.checkoutRemoteBranch(ref) + } else { + logViewModel.checkoutRef(ref) + } + }, onMergeBranch = { ref -> onMergeBranch(ref) }, onDeleteBranch = { ref -> logViewModel.deleteBranch(ref) }, onDeleteRemoteBranch = { ref -> logViewModel.deleteRemoteBranch(ref) }, diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/HistoryViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/HistoryViewModel.kt index 888e5d5..835fa22 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/HistoryViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/HistoryViewModel.kt @@ -1,6 +1,7 @@ package com.jetpackduba.gitnuro.viewmodels import androidx.compose.foundation.lazy.LazyListState +import com.jetpackduba.gitnuro.TaskType import com.jetpackduba.gitnuro.exceptions.MissingDiffEntryException import com.jetpackduba.gitnuro.extensions.filePath import com.jetpackduba.gitnuro.git.DiffEntryType @@ -78,6 +79,7 @@ class HistoryViewModel @Inject constructor( refreshType = RefreshType.NONE, title = "History", subtitle = "Loading file history", + taskType = TaskType.HISTORY_FILE, ) { git -> this@HistoryViewModel.filePath = filePath _historyState.value = HistoryState.Loading(filePath) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/LogViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/LogViewModel.kt index 338803c..bf16775 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/LogViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/LogViewModel.kt @@ -2,21 +2,18 @@ package com.jetpackduba.gitnuro.viewmodels import androidx.compose.foundation.ScrollState import androidx.compose.foundation.lazy.LazyListState +import com.jetpackduba.gitnuro.TaskType import com.jetpackduba.gitnuro.extensions.delayedStateChange import com.jetpackduba.gitnuro.extensions.shortName -import com.jetpackduba.gitnuro.extensions.simpleName import com.jetpackduba.gitnuro.git.RefreshType import com.jetpackduba.gitnuro.git.TabState import com.jetpackduba.gitnuro.git.TaskEvent -import com.jetpackduba.gitnuro.git.branches.* +import com.jetpackduba.gitnuro.git.branches.CreateBranchOnCommitUseCase +import com.jetpackduba.gitnuro.git.branches.GetCurrentBranchUseCase import com.jetpackduba.gitnuro.git.graph.GraphCommitList import com.jetpackduba.gitnuro.git.graph.GraphNode import com.jetpackduba.gitnuro.git.log.* -import com.jetpackduba.gitnuro.git.rebase.RebaseBranchUseCase 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.tags.CreateTagOnCommitUseCase import com.jetpackduba.gitnuro.git.tags.DeleteTagUseCase import com.jetpackduba.gitnuro.git.workspace.CheckHasUncommittedChangesUseCase @@ -52,26 +49,25 @@ class LogViewModel @Inject constructor( private val getStatusSummaryUseCase: GetStatusSummaryUseCase, private val checkHasUncommittedChangesUseCase: CheckHasUncommittedChangesUseCase, private val getCurrentBranchUseCase: GetCurrentBranchUseCase, - private val checkoutRefUseCase: CheckoutRefUseCase, private val createBranchOnCommitUseCase: CreateBranchOnCommitUseCase, - private val deleteBranchUseCase: DeleteBranchUseCase, - private val pushToSpecificBranchUseCase: PushToSpecificBranchUseCase, - private val pullFromSpecificBranchUseCase: PullFromSpecificBranchUseCase, - private val deleteRemoteBranchUseCase: DeleteRemoteBranchUseCase, private val checkoutCommitUseCase: CheckoutCommitUseCase, private val revertCommitUseCase: RevertCommitUseCase, private val resetToCommitUseCase: ResetToCommitUseCase, private val cherryPickCommitUseCase: CherryPickCommitUseCase, - private val mergeBranchUseCase: MergeBranchUseCase, private val createTagOnCommitUseCase: CreateTagOnCommitUseCase, - private val deleteTagUseCase: DeleteTagUseCase, - private val rebaseBranchUseCase: RebaseBranchUseCase, private val startRebaseInteractiveUseCase: StartRebaseInteractiveUseCase, private val tabState: TabState, private val appSettings: AppSettings, - private val tabScope: CoroutineScope, - private val sharedStashViewModel: SharedStashViewModel, -) : ViewModel, ISharedStashViewModel by sharedStashViewModel { + tabScope: CoroutineScope, + sharedStashViewModel: SharedStashViewModel, + sharedBranchesViewModel: SharedBranchesViewModel, + sharedRemotesViewModel: SharedRemotesViewModel, + sharedTagsViewModel: SharedTagsViewModel, +) : ViewModel, + ISharedStashViewModel by sharedStashViewModel, + ISharedBranchesViewModel by sharedBranchesViewModel, + ISharedRemotesViewModel by sharedRemotesViewModel, + ISharedTagsViewModel by sharedTagsViewModel { private val _logStatus = MutableStateFlow(LogStatus.Loading) val logStatus: StateFlow @@ -163,36 +159,11 @@ class LogViewModel @Inject constructor( _logSearchFilterResults.value = LogSearch.NotSearching } - - fun pushToRemoteBranch(branch: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - title = "Push", - subtitle = "Pushing current branch to ${branch.simpleName}", - ) { git -> - pushToSpecificBranchUseCase( - git = git, - force = false, - pushTags = false, - remoteBranch = branch, - ) - } - - fun pullFromRemoteBranch(branch: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - title = "Pull", - subtitle = "Pulling changes from ${branch.simpleName} to the current branch", - ) { git -> - pullFromSpecificBranchUseCase( - git = git, - rebase = false, - remoteBranch = branch, - ) - } - fun checkoutCommit(revCommit: RevCommit) = tabState.safeProcessing( refreshType = RefreshType.ALL_DATA, title = "Commit checkout", subtitle = "Checking out commit ${revCommit.name}", + taskType = TaskType.CHECKOUT_COMMIT, ) { git -> checkoutCommitUseCase(git, revCommit) } @@ -202,6 +173,7 @@ class LogViewModel @Inject constructor( title = "Commit revert", subtitle = "Reverting commit ${revCommit.name}", refreshEvenIfCrashes = true, + taskType = TaskType.REVERT_COMMIT, ) { git -> revertCommitUseCase(git, revCommit) } @@ -210,22 +182,16 @@ class LogViewModel @Inject constructor( refreshType = RefreshType.ALL_DATA, title = "Branch reset", subtitle = "Reseting branch to commit ${revCommit.shortName}", + taskType = TaskType.RESET_TO_COMMIT, ) { git -> resetToCommitUseCase(git, revCommit, resetType = resetType) } - fun checkoutRef(ref: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - title = "Branch checkout", - subtitle = "Checking out branch ${ref.simpleName}", - ) { git -> - checkoutRefUseCase(git, ref) - } - fun cherrypickCommit(revCommit: RevCommit) = tabState.safeProcessing( refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG, title = "Cherry-pick", subtitle = "Cherry-picking commit ${revCommit.shortName}", + taskType = TaskType.CHERRY_PICK_COMMIT, ) { git -> cherryPickCommitUseCase(git, revCommit) } @@ -235,6 +201,7 @@ class LogViewModel @Inject constructor( title = "New branch", subtitle = "Creating new branch \"$branch\" on commit ${revCommit.shortName}", refreshEvenIfCrashesInteractive = { it is CheckoutConflictException }, + taskType = TaskType.CREATE_BRANCH, ) { git -> createBranchOnCommitUseCase(git, branch, revCommit) } @@ -243,34 +210,11 @@ class LogViewModel @Inject constructor( refreshType = RefreshType.ALL_DATA, title = "New tag", subtitle = "Creating new tag \"$tag\" on commit ${revCommit.shortName}", + taskType = TaskType.CREATE_TAG, ) { git -> createTagOnCommitUseCase(git, tag, revCommit) } - fun mergeBranch(ref: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - title = "Branch merge", - subtitle = "Merging branch ${ref.simpleName}", - ) { git -> - mergeBranchUseCase(git, ref, appSettings.ffMerge) - } - - fun deleteBranch(branch: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - title = "Branch delete", - subtitle = "Deleting branch ${branch.simpleName}", - ) { git -> - deleteBranchUseCase(git, branch) - } - - fun deleteTag(tag: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - title = "Tag delete", - subtitle = "Deleting tag ${tag.simpleName}", - ) { git -> - deleteTagUseCase(git, tag) - } - private suspend fun uncommittedChangesLoadLog(git: Git) { val currentBranch = getCurrentBranchUseCase(git) val hasUncommittedChanges = checkHasUncommittedChangesUseCase(git) @@ -301,14 +245,6 @@ class LogViewModel @Inject constructor( loadLog(git) } - fun rebaseBranch(ref: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - title = "Branch rebase", - subtitle = "Rebasing branch ${ref.simpleName}", - ) { git -> - rebaseBranchUseCase(git, ref) - } - fun selectUncommittedChanges() = tabState.runOperation( refreshType = RefreshType.NONE, ) { @@ -432,17 +368,10 @@ class LogViewModel @Inject constructor( fun rebaseInteractive(revCommit: RevCommit) = tabState.safeProcessing( refreshType = RefreshType.REBASE_INTERACTIVE_STATE, + taskType = TaskType.REBASE_INTERACTIVE, ) { git -> startRebaseInteractiveUseCase(git, revCommit) } - - fun deleteRemoteBranch(branch: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - title = "Deleting remote branch", - subtitle = "Remote branch ${branch.simpleName} will be deleted from the remote", - ) { git -> - deleteRemoteBranchUseCase(git, branch) - } } sealed interface LogStatus { diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/MenuViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/MenuViewModel.kt index b5f99bf..f5011ed 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/MenuViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/MenuViewModel.kt @@ -1,5 +1,6 @@ package com.jetpackduba.gitnuro.viewmodels +import com.jetpackduba.gitnuro.TaskType import com.jetpackduba.gitnuro.git.RefreshType import com.jetpackduba.gitnuro.git.TabState import com.jetpackduba.gitnuro.git.remote_operations.FetchAllBranchesUseCase @@ -30,7 +31,8 @@ class MenuViewModel @Inject constructor( refreshType = RefreshType.ALL_DATA, title = "Pulling", subtitle = "Pulling changes from the remote branch to the current branch", - refreshEvenIfCrashes = true + refreshEvenIfCrashes = true, + taskType = TaskType.PULL, ) { git -> pullBranchUseCase(git, pullType) } @@ -40,7 +42,8 @@ class MenuViewModel @Inject constructor( title = "Fetching", subtitle = "Updating references from the remote repositories...", isCancellable = false, - refreshEvenIfCrashes = true + refreshEvenIfCrashes = true, + taskType = TaskType.FETCH, ) { git -> fetchAllBranchesUseCase(git) } @@ -51,12 +54,14 @@ class MenuViewModel @Inject constructor( subtitle = "Pushing current branch to the remote repository", isCancellable = false, refreshEvenIfCrashes = true, + taskType = TaskType.PUSH, ) { git -> pushBranchUseCase(git, force, pushTags) } fun stash() = tabState.safeProcessing( refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG, + taskType = TaskType.STASH, ) { git -> stashChangesUseCase(git, null) } @@ -64,6 +69,7 @@ class MenuViewModel @Inject constructor( fun popStash() = tabState.safeProcessing( refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG, refreshEvenIfCrashes = true, + taskType = TaskType.POP_STASH, ) { git -> popLastStashUseCase(git) } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RebaseInteractiveViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RebaseInteractiveViewModel.kt index 39db00e..8e93e5f 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RebaseInteractiveViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RebaseInteractiveViewModel.kt @@ -1,5 +1,6 @@ package com.jetpackduba.gitnuro.viewmodels +import com.jetpackduba.gitnuro.TaskType import com.jetpackduba.gitnuro.exceptions.InvalidMessageException import com.jetpackduba.gitnuro.exceptions.RebaseCancelledException import com.jetpackduba.gitnuro.git.RefreshType @@ -65,6 +66,7 @@ class RebaseInteractiveViewModel @Inject constructor( fun loadRebaseInteractiveData() = tabState.safeProcessing( refreshType = RefreshType.NONE, + taskType = TaskType.REBASE_INTERACTIVE,// TODO Perhaps this should be more specific such as TaskType.LOAD_ABORT_REBASE ) { git -> val state = getRepositoryStateUseCase(git) @@ -122,6 +124,7 @@ class RebaseInteractiveViewModel @Inject constructor( fun continueRebaseInteractive() = tabState.safeProcessing( refreshType = RefreshType.ALL_DATA, + taskType = TaskType.REBASE_INTERACTIVE, // TODO Perhaps be more precise with the task type ) { git -> resumeRebaseInteractiveUseCase(git, interactiveHandlerContinue) _rebaseState.value = RebaseInteractiveViewState.Loading @@ -173,7 +176,10 @@ class RebaseInteractiveViewModel @Inject constructor( _rebaseState.value = RebaseInteractiveViewState.Loading } - fun selectLine(line: RebaseLine) = tabState.safeProcessing(refreshType = RefreshType.NONE) { git -> + fun selectLine(line: RebaseLine) = tabState.safeProcessing( + refreshType = RefreshType.NONE, + taskType = TaskType.ABORT_REBASE, // TODO Perhaps be more precise with the task type + ) { git -> val fullCommit = getCommitFromRebaseLineUseCase(git, line.commit, line.shortMessage) tabState.newSelectedCommit(fullCommit) } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt index 2701139..544ee23 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt @@ -1,6 +1,7 @@ package com.jetpackduba.gitnuro.viewmodels import com.jetpackduba.gitnuro.Logging +import com.jetpackduba.gitnuro.TaskType import com.jetpackduba.gitnuro.di.qualifiers.AppCoroutineScope import com.jetpackduba.gitnuro.git.RefreshType import com.jetpackduba.gitnuro.logging.printError @@ -148,9 +149,10 @@ class SettingsViewModel @Inject constructor( } catch (ex: Exception) { ex.printStackTrace() newErrorNow( - ex, - "Saving theme failed", - "Failed to parse selected theme JSON. Please check if it's valid and try again." + TaskType.SAVE_CUSTOM_THEME, + ex, // TODO Pass a proper exception with the commented strings +// "Saving theme failed", +// "Failed to parse selected theme JSON. Please check if it's valid and try again.", ) } } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedBranchesViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedBranchesViewModel.kt new file mode 100644 index 0000000..f0ed146 --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedBranchesViewModel.kt @@ -0,0 +1,67 @@ +package com.jetpackduba.gitnuro.viewmodels + +import com.jetpackduba.gitnuro.TaskType +import com.jetpackduba.gitnuro.extensions.simpleName +import com.jetpackduba.gitnuro.git.RefreshType +import com.jetpackduba.gitnuro.git.TabState +import com.jetpackduba.gitnuro.git.branches.CheckoutRefUseCase +import com.jetpackduba.gitnuro.git.branches.DeleteBranchUseCase +import com.jetpackduba.gitnuro.git.branches.MergeBranchUseCase +import com.jetpackduba.gitnuro.git.rebase.RebaseBranchUseCase +import com.jetpackduba.gitnuro.preferences.AppSettings +import kotlinx.coroutines.Job +import org.eclipse.jgit.lib.Ref +import javax.inject.Inject + +interface ISharedBranchesViewModel { + fun mergeBranch(ref: Ref): Job + fun deleteBranch(branch: Ref): Job + fun checkoutRef(ref: Ref): Job + fun rebaseBranch(ref: Ref): Job +} + +class SharedBranchesViewModel @Inject constructor( + private val rebaseBranchUseCase: RebaseBranchUseCase, + private val tabState: TabState, + private val appSettings: AppSettings, + private val mergeBranchUseCase: MergeBranchUseCase, + private val deleteBranchUseCase: DeleteBranchUseCase, + private val checkoutRefUseCase: CheckoutRefUseCase, +) : ISharedBranchesViewModel { + + override fun mergeBranch(ref: Ref) = tabState.safeProcessing( + refreshType = RefreshType.ALL_DATA, + title = "Branch merge", + subtitle = "Merging branch ${ref.simpleName}", + taskType = TaskType.MERGE_BRANCH, + ) { git -> + mergeBranchUseCase(git, ref, appSettings.ffMerge) + } + + override fun deleteBranch(branch: Ref) = tabState.safeProcessing( + refreshType = RefreshType.ALL_DATA, + title = "Branch delete", + subtitle = "Deleting branch ${branch.simpleName}", + taskType = TaskType.DELETE_BRANCH, + ) { git -> + deleteBranchUseCase(git, branch) + } + + override fun checkoutRef(ref: Ref) = tabState.safeProcessing( + refreshType = RefreshType.ALL_DATA, + title = "Branch checkout", + subtitle = "Checking out branch ${ref.simpleName}", + taskType = TaskType.CHECKOUT_BRANCH, + ) { git -> + checkoutRefUseCase(git, ref) + } + + override fun rebaseBranch(ref: Ref) = tabState.safeProcessing( + refreshType = RefreshType.ALL_DATA, + title = "Branch rebase", + subtitle = "Rebasing branch ${ref.simpleName}", + taskType = TaskType.REBASE_BRANCH, + ) { git -> + rebaseBranchUseCase(git, ref) + } +} diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedRemotesViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedRemotesViewModel.kt new file mode 100644 index 0000000..0a34feb --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedRemotesViewModel.kt @@ -0,0 +1,71 @@ +package com.jetpackduba.gitnuro.viewmodels + +import com.jetpackduba.gitnuro.TaskType +import com.jetpackduba.gitnuro.extensions.simpleName +import com.jetpackduba.gitnuro.git.RefreshType +import com.jetpackduba.gitnuro.git.TabState +import com.jetpackduba.gitnuro.git.branches.CheckoutRefUseCase +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 kotlinx.coroutines.Job +import org.eclipse.jgit.lib.Ref +import javax.inject.Inject + +interface ISharedRemotesViewModel { + fun deleteRemoteBranch(ref: Ref): Job + fun checkoutRemoteBranch(remoteBranch: Ref): Job + fun pushToRemoteBranch(branch: Ref): Job + fun pullFromRemoteBranch(branch: Ref): Job +} + +class SharedRemotesViewModel @Inject constructor( + private val tabState: TabState, + private val deleteRemoteBranchUseCase: DeleteRemoteBranchUseCase, + private val checkoutRefUseCase: CheckoutRefUseCase, + private val pushToSpecificBranchUseCase: PushToSpecificBranchUseCase, + private val pullFromSpecificBranchUseCase: PullFromSpecificBranchUseCase, +) : ISharedRemotesViewModel { + override fun deleteRemoteBranch(ref: Ref) = tabState.safeProcessing( + refreshType = RefreshType.ALL_DATA, + title = "Deleting remote branch", + subtitle = "Remote branch ${ref.simpleName} will be deleted from the remote", + taskType = TaskType.DELETE_REMOTE_BRANCH, + ) { git -> + deleteRemoteBranchUseCase(git, ref) + } + + override fun checkoutRemoteBranch(remoteBranch: Ref) = tabState.safeProcessing( + refreshType = RefreshType.ALL_DATA, + taskType = TaskType.CHECKOUT_REMOTE_BRANCH, + ) { git -> + checkoutRefUseCase(git, remoteBranch) + } + + override fun pushToRemoteBranch(branch: Ref) = tabState.safeProcessing( + refreshType = RefreshType.ALL_DATA, + title = "Push", + subtitle = "Pushing current branch to ${branch.simpleName}", + taskType = TaskType.PUSH_TO_BRANCH, + ) { git -> + pushToSpecificBranchUseCase( + git = git, + force = false, + pushTags = false, + remoteBranch = branch, + ) + } + + override fun pullFromRemoteBranch(branch: Ref) = tabState.safeProcessing( + refreshType = RefreshType.ALL_DATA, + title = "Pull", + subtitle = "Pulling changes from ${branch.simpleName} to the current branch", + taskType = TaskType.PULL_FROM_BRANCH, + ) { git -> + pullFromSpecificBranchUseCase( + git = git, + rebase = false, + remoteBranch = branch, + ) + } +} diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedStashViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedStashViewModel.kt index 7358277..84da7dc 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedStashViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedStashViewModel.kt @@ -1,5 +1,6 @@ package com.jetpackduba.gitnuro.viewmodels +import com.jetpackduba.gitnuro.TaskType import com.jetpackduba.gitnuro.git.RefreshType import com.jetpackduba.gitnuro.git.TabState import com.jetpackduba.gitnuro.git.stash.ApplyStashUseCase @@ -27,6 +28,7 @@ class SharedStashViewModel @Inject constructor( override fun applyStash(stashInfo: RevCommit) = tabState.safeProcessing( refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG, refreshEvenIfCrashes = true, + taskType = TaskType.APPLY_STASH, ) { git -> applyStashUseCase(git, stashInfo) } @@ -34,6 +36,7 @@ class SharedStashViewModel @Inject constructor( override fun popStash(stash: RevCommit) = tabState.safeProcessing( refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG, refreshEvenIfCrashes = true, + taskType = TaskType.POP_STASH, ) { git -> popStashUseCase(git, stash) @@ -42,6 +45,7 @@ class SharedStashViewModel @Inject constructor( override fun deleteStash(stash: RevCommit) = tabState.safeProcessing( refreshType = RefreshType.STASHES, + taskType = TaskType.DELETE_STASH, ) { git -> deleteStashUseCase(git, stash) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedTagsViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedTagsViewModel.kt new file mode 100644 index 0000000..b9fdb42 --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SharedTagsViewModel.kt @@ -0,0 +1,28 @@ +package com.jetpackduba.gitnuro.viewmodels + +import com.jetpackduba.gitnuro.TaskType +import com.jetpackduba.gitnuro.extensions.simpleName +import com.jetpackduba.gitnuro.git.RefreshType +import com.jetpackduba.gitnuro.git.TabState +import com.jetpackduba.gitnuro.git.branches.CheckoutRefUseCase +import kotlinx.coroutines.Job +import org.eclipse.jgit.lib.Ref +import javax.inject.Inject + +interface ISharedTagsViewModel { + fun deleteTag(tag: Ref): Job +} + +class SharedTagsViewModel @Inject constructor( + private val deleteTagUseCase: CheckoutRefUseCase, + private val tabState: TabState, +) : ISharedTagsViewModel { + override fun deleteTag(tag: Ref) = tabState.safeProcessing( + refreshType = RefreshType.ALL_DATA, + title = "Tag delete", + subtitle = "Deleting tag ${tag.simpleName}", + taskType = TaskType.DELETE_TAG, + ) { git -> + deleteTagUseCase(git, tag) + } +} diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/StatusViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/StatusViewModel.kt index 0bd5571..df0fe95 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/StatusViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/StatusViewModel.kt @@ -3,6 +3,7 @@ package com.jetpackduba.gitnuro.viewmodels import androidx.compose.foundation.lazy.LazyListState import androidx.compose.ui.text.input.TextFieldValue import com.jetpackduba.gitnuro.SharedRepositoryStateManager +import com.jetpackduba.gitnuro.TaskType import com.jetpackduba.gitnuro.extensions.delayedStateChange import com.jetpackduba.gitnuro.extensions.isMerging import com.jetpackduba.gitnuro.extensions.isReverting @@ -214,12 +215,14 @@ class StatusViewModel @Inject constructor( fun unstageAll() = tabState.safeProcessing( refreshType = RefreshType.UNCOMMITTED_CHANGES, + taskType = TaskType.UNSTAGE_ALL_FILES, ) { git -> unstageAllUseCase(git) } fun stageAll() = tabState.safeProcessing( refreshType = RefreshType.UNCOMMITTED_CHANGES, + taskType = TaskType.STAGE_ALL_FILES, ) { git -> stageAllUseCase(git) } @@ -333,6 +336,7 @@ class StatusViewModel @Inject constructor( fun commit(message: String) = tabState.safeProcessing( refreshType = RefreshType.ALL_DATA, + taskType = TaskType.DO_COMMIT, ) { git -> val amend = isAmend.value @@ -386,6 +390,7 @@ class StatusViewModel @Inject constructor( fun continueRebase(message: String) = tabState.safeProcessing( refreshType = RefreshType.ALL_DATA, + taskType = TaskType.CONTINUE_REBASE, ) { git -> val repositoryState = sharedRepositoryStateManager.repositoryState.value val rebaseInteractiveState = sharedRepositoryStateManager.rebaseInteractiveState.value @@ -408,18 +413,21 @@ class StatusViewModel @Inject constructor( fun abortRebase() = tabState.safeProcessing( refreshType = RefreshType.ALL_DATA, + taskType = TaskType.ABORT_REBASE, ) { git -> abortRebaseUseCase(git) } fun skipRebase() = tabState.safeProcessing( refreshType = RefreshType.ALL_DATA, + taskType = TaskType.SKIP_REBASE, ) { git -> skipRebaseUseCase(git) } fun resetRepoState() = tabState.safeProcessing( refreshType = RefreshType.ALL_DATA, + taskType = TaskType.RESET_REPO_STATE, ) { git -> resetRepositoryStateUseCase(git) } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt index b725855..fb53fb4 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt @@ -1,6 +1,7 @@ package com.jetpackduba.gitnuro.viewmodels import com.jetpackduba.gitnuro.SharedRepositoryStateManager +import com.jetpackduba.gitnuro.TaskType import com.jetpackduba.gitnuro.credentials.CredentialsAccepted import com.jetpackduba.gitnuro.credentials.CredentialsState import com.jetpackduba.gitnuro.credentials.CredentialsStateManager @@ -179,7 +180,13 @@ class TabViewModel @Inject constructor( } catch (ex: Exception) { onRepositoryChanged(null) ex.printStackTrace() - errorsManager.addError(newErrorNow(ex, null, ex.localizedMessage)) + + errorsManager.addError( + newErrorNow( + taskType = TaskType.REPOSITORY_OPEN, + exception = ex + ) + ) _repositorySelectionStatus.value = RepositorySelectionStatus.None } } @@ -259,8 +266,9 @@ class TabViewModel @Inject constructor( errorsManager.addError( newErrorNow( exception = ex, - title = "Repository changes detection has stopped working", - message = message, + taskType = TaskType.CHANGES_DETECTION, +// title = "Repository changes detection has stopped working", +// message = message, ), ) } @@ -342,6 +350,7 @@ class TabViewModel @Inject constructor( fun blameFile(filePath: String) = tabState.safeProcessing( refreshType = RefreshType.NONE, + taskType = TaskType.BLAME_FILE, ) { git -> _blameState.value = BlameState.Loading(filePath) try { @@ -405,12 +414,14 @@ class TabViewModel @Inject constructor( fun createBranch(branchName: String) = tabState.safeProcessing( refreshType = RefreshType.ALL_DATA, refreshEvenIfCrashesInteractive = { it is CheckoutConflictException }, + taskType = TaskType.CREATE_BRANCH, ) { git -> createBranchUseCase(git, branchName) } fun stashWithMessage(message: String) = tabState.safeProcessing( refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG, + taskType = TaskType.STASH, ) { git -> stageUntrackedFileUseCase(git) stashChangesUseCase(git, message) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/BranchesViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/BranchesViewModel.kt index df19baa..60881d0 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/BranchesViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/BranchesViewModel.kt @@ -9,6 +9,8 @@ import com.jetpackduba.gitnuro.git.rebase.RebaseBranchUseCase import com.jetpackduba.gitnuro.git.remote_operations.PullFromSpecificBranchUseCase import com.jetpackduba.gitnuro.git.remote_operations.PushToSpecificBranchUseCase import com.jetpackduba.gitnuro.preferences.AppSettings +import com.jetpackduba.gitnuro.viewmodels.ISharedBranchesViewModel +import com.jetpackduba.gitnuro.viewmodels.SharedBranchesViewModel import dagger.assisted.Assisted import dagger.assisted.AssistedInject import kotlinx.coroutines.CoroutineScope @@ -21,20 +23,14 @@ private const val TAG = "BranchesViewModel" class BranchesViewModel @AssistedInject constructor( - private val rebaseBranchUseCase: RebaseBranchUseCase, private val tabState: TabState, - private val appSettings: AppSettings, - private val pushToSpecificBranchUseCase: PushToSpecificBranchUseCase, - private val pullFromSpecificBranchUseCase: PullFromSpecificBranchUseCase, private val getCurrentBranchUseCase: GetCurrentBranchUseCase, - private val mergeBranchUseCase: MergeBranchUseCase, private val getBranchesUseCase: GetBranchesUseCase, - private val deleteBranchUseCase: DeleteBranchUseCase, - private val checkoutRefUseCase: CheckoutRefUseCase, - private val tabScope: CoroutineScope, + tabScope: CoroutineScope, + sharedBranchesViewModel: SharedBranchesViewModel, @Assisted private val filter: StateFlow -) : SidePanelChildViewModel(true) { +) : SidePanelChildViewModel(true), ISharedBranchesViewModel by sharedBranchesViewModel { private val _branches = MutableStateFlow>(listOf()) private val _currentBranch = MutableStateFlow(null) @@ -74,59 +70,13 @@ class BranchesViewModel @AssistedInject constructor( _branches.value = branchesList } - - fun mergeBranch(ref: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - ) { git -> - mergeBranchUseCase(git, ref, appSettings.ffMerge) - } - - fun deleteBranch(branch: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - ) { git -> - deleteBranchUseCase(git, branch) - } - - fun checkoutRef(ref: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - ) { git -> - checkoutRefUseCase(git, ref) - } - suspend fun refresh(git: Git) { loadBranches(git) } - fun rebaseBranch(ref: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - ) { git -> - rebaseBranchUseCase(git, ref) - } - fun selectBranch(ref: Ref) { tabState.newSelectedRef(ref, ref.objectId) } - - fun pushToRemoteBranch(branch: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - ) { git -> - pushToSpecificBranchUseCase( - git = git, - force = false, - pushTags = false, - remoteBranch = branch, - ) - } - - fun pullFromRemoteBranch(branch: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - ) { git -> - pullFromSpecificBranchUseCase( - git = git, - rebase = false, - remoteBranch = branch, - ) - } } data class BranchesState( diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/RemotesViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/RemotesViewModel.kt index e54222d..c2a9c6a 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/RemotesViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/RemotesViewModel.kt @@ -1,5 +1,6 @@ package com.jetpackduba.gitnuro.viewmodels.sidepanel +import com.jetpackduba.gitnuro.TaskType import com.jetpackduba.gitnuro.exceptions.InvalidRemoteUrlException import com.jetpackduba.gitnuro.extensions.lowercaseContains import com.jetpackduba.gitnuro.extensions.simpleName @@ -14,6 +15,8 @@ import com.jetpackduba.gitnuro.git.remote_operations.PullFromSpecificBranchUseCa import com.jetpackduba.gitnuro.git.remote_operations.PushToSpecificBranchUseCase import com.jetpackduba.gitnuro.git.remotes.* import com.jetpackduba.gitnuro.ui.dialogs.RemoteWrapper +import com.jetpackduba.gitnuro.viewmodels.ISharedRemotesViewModel +import com.jetpackduba.gitnuro.viewmodels.SharedRemotesViewModel import dagger.assisted.Assisted import dagger.assisted.AssistedInject import kotlinx.coroutines.CoroutineScope @@ -27,7 +30,6 @@ import org.eclipse.jgit.lib.Ref class RemotesViewModel @AssistedInject constructor( private val tabState: TabState, - private val deleteRemoteBranchUseCase: DeleteRemoteBranchUseCase, private val getRemoteBranchesUseCase: GetRemoteBranchesUseCase, private val getRemotesUseCase: GetRemotesUseCase, private val getCurrentBranchUseCase: GetCurrentBranchUseCase, @@ -35,13 +37,11 @@ class RemotesViewModel @AssistedInject constructor( private val addRemoteUseCase: AddRemoteUseCase, private val updateRemoteUseCase: UpdateRemoteUseCase, private val deleteLocallyRemoteBranchesUseCase: DeleteLocallyRemoteBranchesUseCase, - private val checkoutRefUseCase: CheckoutRefUseCase, - private val pushToSpecificBranchUseCase: PushToSpecificBranchUseCase, - private val pullFromSpecificBranchUseCase: PullFromSpecificBranchUseCase, - private val tabScope: CoroutineScope, + tabScope: CoroutineScope, + sharedRemotesViewModel: SharedRemotesViewModel, @Assisted private val filter: StateFlow -) : SidePanelChildViewModel(false) { +) : SidePanelChildViewModel(false), ISharedRemotesViewModel by sharedRemotesViewModel { private val remotes = MutableStateFlow>(listOf()) private val currentBranch = MutableStateFlow(null) @@ -92,14 +92,6 @@ class RemotesViewModel @AssistedInject constructor( this@RemotesViewModel.currentBranch.value = currentBranch } - fun deleteRemoteBranch(ref: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - title = "Deleting remote branch", - subtitle = "Remote branch ${ref.simpleName} will be deleted from the remote", - ) { git -> - deleteRemoteBranchUseCase(git, ref) - } - suspend fun refresh(git: Git) = withContext(Dispatchers.IO) { loadRemotes(git) } @@ -125,6 +117,7 @@ class RemotesViewModel @AssistedInject constructor( fun deleteRemote(remoteName: String, isNew: Boolean) = tabState.safeProcessing( refreshType = if (isNew) RefreshType.REMOTES else RefreshType.ALL_DATA, + taskType = TaskType.DELETE_REMOTE, ) { git -> deleteRemoteUseCase(git, remoteName) @@ -183,34 +176,6 @@ class RemotesViewModel @AssistedInject constructor( uriType = RemoteSetUrlCommand.UriType.PUSH ) } - - fun checkoutRemoteBranch(remoteBranch: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - ) { git -> - checkoutRefUseCase(git, remoteBranch) - } - - - fun pushToRemoteBranch(branch: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - ) { git -> - pushToSpecificBranchUseCase( - git = git, - force = false, - pushTags = false, - remoteBranch = branch, - ) - } - - fun pullFromRemoteBranch(branch: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - ) { git -> - pullFromSpecificBranchUseCase( - git = git, - rebase = false, - remoteBranch = branch, - ) - } } data class RemoteView(val remoteInfo: RemoteInfo, val isExpanded: Boolean) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/SubmodulesViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/SubmodulesViewModel.kt index 1bf600c..f7c0317 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/SubmodulesViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/SubmodulesViewModel.kt @@ -1,5 +1,6 @@ package com.jetpackduba.gitnuro.viewmodels.sidepanel +import com.jetpackduba.gitnuro.TaskType import com.jetpackduba.gitnuro.extensions.lowercaseContains import com.jetpackduba.gitnuro.git.RefreshType import com.jetpackduba.gitnuro.git.TabState @@ -59,6 +60,7 @@ class SubmodulesViewModel @AssistedInject constructor( fun initializeSubmodule(path: String) = tabState.safeProcessing( refreshType = RefreshType.SUBMODULES, + taskType = TaskType.INIT_SUBMODULE, ) { git -> initializeSubmoduleUseCase(git, path) updateSubmoduleUseCase(git, path) @@ -75,6 +77,7 @@ class SubmodulesViewModel @AssistedInject constructor( fun onDeinitializeSubmodule(path: String) = tabState.safeProcessing( refreshType = RefreshType.SUBMODULES, title = "Deinitializing submodule $path", + taskType = TaskType.DEINIT_SUBMODULE, ) { git -> deInitializeSubmoduleUseCase(git, path) } @@ -83,6 +86,7 @@ class SubmodulesViewModel @AssistedInject constructor( refreshType = RefreshType.SUBMODULES, title = "Syncing submodule $path", subtitle = "Please wait until synchronization has finished", + taskType = TaskType.SYNC_SUBMODULE, ) { git -> syncSubmoduleUseCase(git, path) } @@ -91,12 +95,14 @@ class SubmodulesViewModel @AssistedInject constructor( refreshType = RefreshType.SUBMODULES, title = "Updating submodule $path", subtitle = "Please wait until update has finished", + taskType = TaskType.UPDATE_SUBMODULE, ) { git -> updateSubmoduleUseCase(git, path) } fun onCreateSubmodule(repository: String, directory: String) = tabState.safeProcessing( refreshType = RefreshType.ALL_DATA, + taskType = TaskType.ADD_SUBMODULE, ) { git -> addSubmoduleUseCase( git = git, @@ -108,6 +114,7 @@ class SubmodulesViewModel @AssistedInject constructor( fun onDeleteSubmodule(path: String) = tabState.safeProcessing( refreshType = RefreshType.ALL_DATA, + taskType = TaskType.DELETE_SUBMODULE, ) { git -> deleteSubmoduleUseCase(git, path) } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/TagsViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/TagsViewModel.kt index 3cf46cb..b3888b7 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/TagsViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/sidepanel/TagsViewModel.kt @@ -1,12 +1,15 @@ package com.jetpackduba.gitnuro.viewmodels.sidepanel +import com.jetpackduba.gitnuro.TaskType import com.jetpackduba.gitnuro.extensions.lowercaseContains import com.jetpackduba.gitnuro.extensions.simpleName import com.jetpackduba.gitnuro.git.RefreshType import com.jetpackduba.gitnuro.git.TabState -import com.jetpackduba.gitnuro.git.branches.CheckoutRefUseCase +import com.jetpackduba.gitnuro.git.log.CheckoutCommitUseCase import com.jetpackduba.gitnuro.git.tags.DeleteTagUseCase import com.jetpackduba.gitnuro.git.tags.GetTagsUseCase +import com.jetpackduba.gitnuro.viewmodels.ISharedTagsViewModel +import com.jetpackduba.gitnuro.viewmodels.SharedTagsViewModel import dagger.assisted.Assisted import dagger.assisted.AssistedInject import kotlinx.coroutines.CoroutineScope @@ -20,12 +23,12 @@ import org.eclipse.jgit.lib.Ref class TagsViewModel @AssistedInject constructor( private val tabState: TabState, private val getTagsUseCase: GetTagsUseCase, - private val deleteTagUseCase: DeleteTagUseCase, - private val checkoutRefUseCase: CheckoutRefUseCase, - private val tabScope: CoroutineScope, + private val checkoutCommitUseCase: CheckoutCommitUseCase, + tabScope: CoroutineScope, + sharedTagsViewModel: SharedTagsViewModel, @Assisted private val filter: StateFlow -) : SidePanelChildViewModel(false) { +) : SidePanelChildViewModel(false), ISharedTagsViewModel by sharedTagsViewModel { private val tags = MutableStateFlow>(listOf()) val tagsState: StateFlow = combine(tags, isExpanded, filter) { tags, isExpanded, filter -> @@ -54,16 +57,11 @@ class TagsViewModel @AssistedInject constructor( tags.value = tagsList } - fun checkoutRef(ref: Ref) = tabState.safeProcessing( + fun checkoutTagCommit(ref: Ref) = tabState.safeProcessing( refreshType = RefreshType.ALL_DATA, + taskType = TaskType.INIT_SUBMODULE, ) { git -> - checkoutRefUseCase(git, ref) - } - - fun deleteTag(tag: Ref) = tabState.safeProcessing( - refreshType = RefreshType.ALL_DATA, - ) { git -> - deleteTagUseCase(git, tag) + checkoutCommitUseCase(git, ref.objectId.name) } fun selectTag(tag: Ref) {