Added task type for most operations and reduced duplicated code

This commit is contained in:
Abdelilah El Aissaoui 2024-03-24 00:14:04 +01:00
parent de20be8e9a
commit 8637365cb7
No known key found for this signature in database
GPG Key ID: 7587FC860F594869
24 changed files with 388 additions and 268 deletions

View File

@ -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,
}

View File

@ -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 <T> 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
}
}
}

View File

@ -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
)
)
}
}
}

View File

@ -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()
}
}

View File

@ -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
)
}

View File

@ -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
)
}

View File

@ -9,7 +9,7 @@ fun tagContextMenuItems(
): List<ContextMenuElement> {
return mutableListOf(
ContextMenuElement.ContextTextEntry(
label = "Checkout tag",
label = "Checkout tag's commit",
icon = { painterResource(AppIcons.START) },
onClick = onCheckoutTag
),

View File

@ -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)

View File

@ -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) },

View File

@ -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)

View File

@ -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>(LogStatus.Loading)
val logStatus: StateFlow<LogStatus>
@ -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 {

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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.",
)
}
}

View File

@ -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)
}
}

View File

@ -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,
)
}
}

View File

@ -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)

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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<String>
) : SidePanelChildViewModel(true) {
) : SidePanelChildViewModel(true), ISharedBranchesViewModel by sharedBranchesViewModel {
private val _branches = MutableStateFlow<List<Ref>>(listOf())
private val _currentBranch = MutableStateFlow<Ref?>(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(

View File

@ -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<String>
) : SidePanelChildViewModel(false) {
) : SidePanelChildViewModel(false), ISharedRemotesViewModel by sharedRemotesViewModel {
private val remotes = MutableStateFlow<List<RemoteView>>(listOf())
private val currentBranch = MutableStateFlow<Ref?>(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)

View File

@ -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)
}

View File

@ -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<String>
) : SidePanelChildViewModel(false) {
) : SidePanelChildViewModel(false), ISharedTagsViewModel by sharedTagsViewModel {
private val tags = MutableStateFlow<List<Ref>>(listOf())
val tagsState: StateFlow<TagsState> = 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) {