Added task type for most operations and reduced duplicated code
This commit is contained in:
parent
de20be8e9a
commit
8637365cb7
60
src/main/kotlin/com/jetpackduba/gitnuro/TaskType.kt
Normal file
60
src/main/kotlin/com/jetpackduba/gitnuro/TaskType.kt
Normal 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,
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
@ -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
|
||||
)
|
||||
}
|
@ -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
|
||||
)
|
||||
}
|
||||
|
@ -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
|
||||
),
|
||||
|
@ -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)
|
||||
|
@ -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) },
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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.",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user