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
|
package com.jetpackduba.gitnuro.git
|
||||||
|
|
||||||
|
import com.jetpackduba.gitnuro.TaskType
|
||||||
import com.jetpackduba.gitnuro.di.TabScope
|
import com.jetpackduba.gitnuro.di.TabScope
|
||||||
import com.jetpackduba.gitnuro.exceptions.GitnuroException
|
import com.jetpackduba.gitnuro.exceptions.GitnuroException
|
||||||
import com.jetpackduba.gitnuro.extensions.delayedStateChange
|
import com.jetpackduba.gitnuro.extensions.delayedStateChange
|
||||||
@ -18,11 +19,6 @@ import javax.inject.Inject
|
|||||||
|
|
||||||
private const val TAG = "TabState"
|
private const val TAG = "TabState"
|
||||||
|
|
||||||
interface ProcessingInfo {
|
|
||||||
fun changeSubtitle(newSubtitle: String)
|
|
||||||
fun changeIsCancellable(newIsCancellable: Boolean)
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed interface ProcessingState {
|
sealed interface ProcessingState {
|
||||||
data object None : ProcessingState
|
data object None : ProcessingState
|
||||||
data class Processing(
|
data class Processing(
|
||||||
@ -80,46 +76,18 @@ class TabState @Inject constructor(
|
|||||||
// migrate the code that uses this function
|
// migrate the code that uses this function
|
||||||
title: String = "",
|
title: String = "",
|
||||||
subtitle: 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
|
// 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,
|
isCancellable: Boolean = false,
|
||||||
refreshEvenIfCrashes: Boolean = false,
|
refreshEvenIfCrashes: Boolean = false,
|
||||||
refreshEvenIfCrashesInteractive: ((Exception) -> Boolean)? = null,
|
refreshEvenIfCrashesInteractive: ((Exception) -> Boolean)? = null,
|
||||||
callback: suspend ProcessingInfo.(git: Git) -> Unit
|
callback: suspend (git: Git) -> Unit
|
||||||
): Job {
|
): Job {
|
||||||
val job = scope.launch(Dispatchers.IO) {
|
val job = scope.launch(Dispatchers.IO) {
|
||||||
var hasProcessFailed = false
|
var hasProcessFailed = false
|
||||||
var refreshEvenIfCrashesInteractiveResult = false
|
var refreshEvenIfCrashesInteractiveResult = false
|
||||||
operationRunning = true
|
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 {
|
try {
|
||||||
delayedStateChange(
|
delayedStateChange(
|
||||||
@ -134,7 +102,7 @@ class TabState @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
processingInfo.callback(git)
|
callback(git)
|
||||||
}
|
}
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
hasProcessFailed = true
|
hasProcessFailed = true
|
||||||
@ -147,7 +115,7 @@ class TabState @Inject constructor(
|
|||||||
if (!containsCancellation) {
|
if (!containsCancellation) {
|
||||||
val innerException = getInnerException(ex)
|
val innerException = getInnerException(ex)
|
||||||
|
|
||||||
errorsManager.addError(newErrorNow(innerException, null, innerException.message.orEmpty()))
|
errorsManager.addError(newErrorNow(taskType, innerException))
|
||||||
}
|
}
|
||||||
|
|
||||||
printError(TAG, ex.message.orEmpty(), ex)
|
printError(TAG, ex.message.orEmpty(), ex)
|
||||||
@ -210,7 +178,11 @@ class TabState @Inject constructor(
|
|||||||
val containsCancellation = exceptionContainsCancellation(ex)
|
val containsCancellation = exceptionContainsCancellation(ex)
|
||||||
|
|
||||||
if (!containsCancellation)
|
if (!containsCancellation)
|
||||||
errorsManager.addError(newErrorNow(ex, null, ex.localizedMessage))
|
errorsManager.addError(
|
||||||
|
newErrorNow(
|
||||||
|
taskType = TaskType.UNSPECIFIED, ex
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
printError(TAG, ex.message.orEmpty(), ex)
|
printError(TAG, ex.message.orEmpty(), ex)
|
||||||
} finally {
|
} finally {
|
||||||
@ -242,7 +214,11 @@ class TabState @Inject constructor(
|
|||||||
hasProcessFailed = true
|
hasProcessFailed = true
|
||||||
|
|
||||||
if (showError)
|
if (showError)
|
||||||
errorsManager.addError(newErrorNow(ex, null, ex.localizedMessage))
|
errorsManager.addError(
|
||||||
|
newErrorNow(
|
||||||
|
taskType = TaskType.UNSPECIFIED, ex
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
printError(TAG, ex.message.orEmpty(), ex)
|
printError(TAG, ex.message.orEmpty(), ex)
|
||||||
} finally {
|
} finally {
|
||||||
@ -317,7 +293,11 @@ class TabState @Inject constructor(
|
|||||||
callback(it)
|
callback(it)
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
ex.printStackTrace()
|
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() {
|
class CheckoutCommitUseCase @Inject constructor() {
|
||||||
suspend operator fun invoke(git: Git, revCommit: RevCommit): Unit = withContext(Dispatchers.IO) {
|
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
|
git
|
||||||
.checkout()
|
.checkout()
|
||||||
.setName(revCommit.name)
|
.setName(hash)
|
||||||
.call()
|
.call()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,8 @@
|
|||||||
package com.jetpackduba.gitnuro.managers
|
package com.jetpackduba.gitnuro.managers
|
||||||
|
|
||||||
|
import com.jetpackduba.gitnuro.TaskType
|
||||||
import com.jetpackduba.gitnuro.di.TabScope
|
import com.jetpackduba.gitnuro.di.TabScope
|
||||||
|
import com.jetpackduba.gitnuro.exceptions.GitnuroException
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@ -35,21 +37,20 @@ class ErrorsManager @Inject constructor() {
|
|||||||
|
|
||||||
|
|
||||||
data class Error(
|
data class Error(
|
||||||
|
val taskType: TaskType,
|
||||||
val date: Long,
|
val date: Long,
|
||||||
val exception: Exception,
|
val exception: Exception,
|
||||||
val title: String?,
|
val isUnhandled: Boolean,
|
||||||
val message: String
|
|
||||||
)
|
)
|
||||||
|
|
||||||
fun newErrorNow(
|
fun newErrorNow(
|
||||||
|
taskType: TaskType,
|
||||||
exception: Exception,
|
exception: Exception,
|
||||||
title: String?,
|
|
||||||
message: String,
|
|
||||||
): Error {
|
): Error {
|
||||||
return Error(
|
return Error(
|
||||||
|
taskType = taskType,
|
||||||
date = System.currentTimeMillis(),
|
date = System.currentTimeMillis(),
|
||||||
exception = exception,
|
exception = exception,
|
||||||
title = title,
|
isUnhandled = exception !is GitnuroException
|
||||||
message = message
|
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -206,8 +206,6 @@ fun LazyListScope.localBranches(
|
|||||||
onMergeBranch = { branchesViewModel.mergeBranch(branch) },
|
onMergeBranch = { branchesViewModel.mergeBranch(branch) },
|
||||||
onRebaseBranch = { branchesViewModel.rebaseBranch(branch) },
|
onRebaseBranch = { branchesViewModel.rebaseBranch(branch) },
|
||||||
onDeleteBranch = { branchesViewModel.deleteBranch(branch) },
|
onDeleteBranch = { branchesViewModel.deleteBranch(branch) },
|
||||||
onPushToRemoteBranch = { branchesViewModel.pushToRemoteBranch(branch) },
|
|
||||||
onPullFromRemoteBranch = { branchesViewModel.pullFromRemoteBranch(branch) }
|
|
||||||
) { onChangeDefaultUpstreamBranch(branch) }
|
) { onChangeDefaultUpstreamBranch(branch) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -304,7 +302,7 @@ fun LazyListScope.tags(
|
|||||||
tag,
|
tag,
|
||||||
isSelected = selectedItem is SelectedItem.Ref && selectedItem.ref == tag,
|
isSelected = selectedItem is SelectedItem.Ref && selectedItem.ref == tag,
|
||||||
onTagClicked = { tagsViewModel.selectTag(tag) },
|
onTagClicked = { tagsViewModel.selectTag(tag) },
|
||||||
onCheckoutTag = { tagsViewModel.checkoutRef(tag) },
|
onCheckoutTag = { tagsViewModel.checkoutTagCommit(tag) },
|
||||||
onDeleteTag = { tagsViewModel.deleteTag(tag) }
|
onDeleteTag = { tagsViewModel.deleteTag(tag) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -413,8 +411,6 @@ private fun Branch(
|
|||||||
onMergeBranch: () -> Unit,
|
onMergeBranch: () -> Unit,
|
||||||
onRebaseBranch: () -> Unit,
|
onRebaseBranch: () -> Unit,
|
||||||
onDeleteBranch: () -> Unit,
|
onDeleteBranch: () -> Unit,
|
||||||
onPushToRemoteBranch: () -> Unit,
|
|
||||||
onPullFromRemoteBranch: () -> Unit,
|
|
||||||
onChangeDefaultUpstreamBranch: () -> Unit,
|
onChangeDefaultUpstreamBranch: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val isCurrentBranch = currentBranch?.name == branch.name
|
val isCurrentBranch = currentBranch?.name == branch.name
|
||||||
@ -430,8 +426,8 @@ private fun Branch(
|
|||||||
onMergeBranch = onMergeBranch,
|
onMergeBranch = onMergeBranch,
|
||||||
onDeleteBranch = onDeleteBranch,
|
onDeleteBranch = onDeleteBranch,
|
||||||
onRebaseBranch = onRebaseBranch,
|
onRebaseBranch = onRebaseBranch,
|
||||||
onPushToRemoteBranch = onPushToRemoteBranch,
|
onPushToRemoteBranch = {},
|
||||||
onPullFromRemoteBranch = onPullFromRemoteBranch,
|
onPullFromRemoteBranch = {},
|
||||||
onChangeDefaultUpstreamBranch = onChangeDefaultUpstreamBranch
|
onChangeDefaultUpstreamBranch = onChangeDefaultUpstreamBranch
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ fun tagContextMenuItems(
|
|||||||
): List<ContextMenuElement> {
|
): List<ContextMenuElement> {
|
||||||
return mutableListOf(
|
return mutableListOf(
|
||||||
ContextMenuElement.ContextTextEntry(
|
ContextMenuElement.ContextTextEntry(
|
||||||
label = "Checkout tag",
|
label = "Checkout tag's commit",
|
||||||
icon = { painterResource(AppIcons.START) },
|
icon = { painterResource(AppIcons.START) },
|
||||||
onClick = onCheckoutTag
|
onClick = onCheckoutTag
|
||||||
),
|
),
|
||||||
|
@ -38,7 +38,7 @@ fun ErrorDialog(
|
|||||||
) {
|
) {
|
||||||
Row {
|
Row {
|
||||||
Text(
|
Text(
|
||||||
text = error.title ?: "Error",
|
text = "Error", // TODO error.title ?: "Error",
|
||||||
fontSize = 16.sp,
|
fontSize = 16.sp,
|
||||||
fontWeight = FontWeight.SemiBold,
|
fontWeight = FontWeight.SemiBold,
|
||||||
color = MaterialTheme.colors.onBackground,
|
color = MaterialTheme.colors.onBackground,
|
||||||
@ -55,7 +55,7 @@ fun ErrorDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = error.message,
|
text = error.exception.message.orEmpty(), // TODO
|
||||||
color = MaterialTheme.colors.onBackground,
|
color = MaterialTheme.colors.onBackground,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(top = 16.dp)
|
.padding(top = 16.dp)
|
||||||
|
@ -846,7 +846,13 @@ private fun CommitLine(
|
|||||||
nodeColor = nodeColor,
|
nodeColor = nodeColor,
|
||||||
matchesSearchFilter = matchesSearchFilter,
|
matchesSearchFilter = matchesSearchFilter,
|
||||||
currentBranch = currentBranch,
|
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) },
|
onMergeBranch = { ref -> onMergeBranch(ref) },
|
||||||
onDeleteBranch = { ref -> logViewModel.deleteBranch(ref) },
|
onDeleteBranch = { ref -> logViewModel.deleteBranch(ref) },
|
||||||
onDeleteRemoteBranch = { ref -> logViewModel.deleteRemoteBranch(ref) },
|
onDeleteRemoteBranch = { ref -> logViewModel.deleteRemoteBranch(ref) },
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.jetpackduba.gitnuro.viewmodels
|
package com.jetpackduba.gitnuro.viewmodels
|
||||||
|
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
|
import com.jetpackduba.gitnuro.TaskType
|
||||||
import com.jetpackduba.gitnuro.exceptions.MissingDiffEntryException
|
import com.jetpackduba.gitnuro.exceptions.MissingDiffEntryException
|
||||||
import com.jetpackduba.gitnuro.extensions.filePath
|
import com.jetpackduba.gitnuro.extensions.filePath
|
||||||
import com.jetpackduba.gitnuro.git.DiffEntryType
|
import com.jetpackduba.gitnuro.git.DiffEntryType
|
||||||
@ -78,6 +79,7 @@ class HistoryViewModel @Inject constructor(
|
|||||||
refreshType = RefreshType.NONE,
|
refreshType = RefreshType.NONE,
|
||||||
title = "History",
|
title = "History",
|
||||||
subtitle = "Loading file history",
|
subtitle = "Loading file history",
|
||||||
|
taskType = TaskType.HISTORY_FILE,
|
||||||
) { git ->
|
) { git ->
|
||||||
this@HistoryViewModel.filePath = filePath
|
this@HistoryViewModel.filePath = filePath
|
||||||
_historyState.value = HistoryState.Loading(filePath)
|
_historyState.value = HistoryState.Loading(filePath)
|
||||||
|
@ -2,21 +2,18 @@ package com.jetpackduba.gitnuro.viewmodels
|
|||||||
|
|
||||||
import androidx.compose.foundation.ScrollState
|
import androidx.compose.foundation.ScrollState
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
|
import com.jetpackduba.gitnuro.TaskType
|
||||||
import com.jetpackduba.gitnuro.extensions.delayedStateChange
|
import com.jetpackduba.gitnuro.extensions.delayedStateChange
|
||||||
import com.jetpackduba.gitnuro.extensions.shortName
|
import com.jetpackduba.gitnuro.extensions.shortName
|
||||||
import com.jetpackduba.gitnuro.extensions.simpleName
|
|
||||||
import com.jetpackduba.gitnuro.git.RefreshType
|
import com.jetpackduba.gitnuro.git.RefreshType
|
||||||
import com.jetpackduba.gitnuro.git.TabState
|
import com.jetpackduba.gitnuro.git.TabState
|
||||||
import com.jetpackduba.gitnuro.git.TaskEvent
|
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.GraphCommitList
|
||||||
import com.jetpackduba.gitnuro.git.graph.GraphNode
|
import com.jetpackduba.gitnuro.git.graph.GraphNode
|
||||||
import com.jetpackduba.gitnuro.git.log.*
|
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.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.CreateTagOnCommitUseCase
|
||||||
import com.jetpackduba.gitnuro.git.tags.DeleteTagUseCase
|
import com.jetpackduba.gitnuro.git.tags.DeleteTagUseCase
|
||||||
import com.jetpackduba.gitnuro.git.workspace.CheckHasUncommittedChangesUseCase
|
import com.jetpackduba.gitnuro.git.workspace.CheckHasUncommittedChangesUseCase
|
||||||
@ -52,26 +49,25 @@ class LogViewModel @Inject constructor(
|
|||||||
private val getStatusSummaryUseCase: GetStatusSummaryUseCase,
|
private val getStatusSummaryUseCase: GetStatusSummaryUseCase,
|
||||||
private val checkHasUncommittedChangesUseCase: CheckHasUncommittedChangesUseCase,
|
private val checkHasUncommittedChangesUseCase: CheckHasUncommittedChangesUseCase,
|
||||||
private val getCurrentBranchUseCase: GetCurrentBranchUseCase,
|
private val getCurrentBranchUseCase: GetCurrentBranchUseCase,
|
||||||
private val checkoutRefUseCase: CheckoutRefUseCase,
|
|
||||||
private val createBranchOnCommitUseCase: CreateBranchOnCommitUseCase,
|
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 checkoutCommitUseCase: CheckoutCommitUseCase,
|
||||||
private val revertCommitUseCase: RevertCommitUseCase,
|
private val revertCommitUseCase: RevertCommitUseCase,
|
||||||
private val resetToCommitUseCase: ResetToCommitUseCase,
|
private val resetToCommitUseCase: ResetToCommitUseCase,
|
||||||
private val cherryPickCommitUseCase: CherryPickCommitUseCase,
|
private val cherryPickCommitUseCase: CherryPickCommitUseCase,
|
||||||
private val mergeBranchUseCase: MergeBranchUseCase,
|
|
||||||
private val createTagOnCommitUseCase: CreateTagOnCommitUseCase,
|
private val createTagOnCommitUseCase: CreateTagOnCommitUseCase,
|
||||||
private val deleteTagUseCase: DeleteTagUseCase,
|
|
||||||
private val rebaseBranchUseCase: RebaseBranchUseCase,
|
|
||||||
private val startRebaseInteractiveUseCase: StartRebaseInteractiveUseCase,
|
private val startRebaseInteractiveUseCase: StartRebaseInteractiveUseCase,
|
||||||
private val tabState: TabState,
|
private val tabState: TabState,
|
||||||
private val appSettings: AppSettings,
|
private val appSettings: AppSettings,
|
||||||
private val tabScope: CoroutineScope,
|
tabScope: CoroutineScope,
|
||||||
private val sharedStashViewModel: SharedStashViewModel,
|
sharedStashViewModel: SharedStashViewModel,
|
||||||
) : ViewModel, ISharedStashViewModel by 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)
|
private val _logStatus = MutableStateFlow<LogStatus>(LogStatus.Loading)
|
||||||
|
|
||||||
val logStatus: StateFlow<LogStatus>
|
val logStatus: StateFlow<LogStatus>
|
||||||
@ -163,36 +159,11 @@ class LogViewModel @Inject constructor(
|
|||||||
_logSearchFilterResults.value = LogSearch.NotSearching
|
_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(
|
fun checkoutCommit(revCommit: RevCommit) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
title = "Commit checkout",
|
title = "Commit checkout",
|
||||||
subtitle = "Checking out commit ${revCommit.name}",
|
subtitle = "Checking out commit ${revCommit.name}",
|
||||||
|
taskType = TaskType.CHECKOUT_COMMIT,
|
||||||
) { git ->
|
) { git ->
|
||||||
checkoutCommitUseCase(git, revCommit)
|
checkoutCommitUseCase(git, revCommit)
|
||||||
}
|
}
|
||||||
@ -202,6 +173,7 @@ class LogViewModel @Inject constructor(
|
|||||||
title = "Commit revert",
|
title = "Commit revert",
|
||||||
subtitle = "Reverting commit ${revCommit.name}",
|
subtitle = "Reverting commit ${revCommit.name}",
|
||||||
refreshEvenIfCrashes = true,
|
refreshEvenIfCrashes = true,
|
||||||
|
taskType = TaskType.REVERT_COMMIT,
|
||||||
) { git ->
|
) { git ->
|
||||||
revertCommitUseCase(git, revCommit)
|
revertCommitUseCase(git, revCommit)
|
||||||
}
|
}
|
||||||
@ -210,22 +182,16 @@ class LogViewModel @Inject constructor(
|
|||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
title = "Branch reset",
|
title = "Branch reset",
|
||||||
subtitle = "Reseting branch to commit ${revCommit.shortName}",
|
subtitle = "Reseting branch to commit ${revCommit.shortName}",
|
||||||
|
taskType = TaskType.RESET_TO_COMMIT,
|
||||||
) { git ->
|
) { git ->
|
||||||
resetToCommitUseCase(git, revCommit, resetType = resetType)
|
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(
|
fun cherrypickCommit(revCommit: RevCommit) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
||||||
title = "Cherry-pick",
|
title = "Cherry-pick",
|
||||||
subtitle = "Cherry-picking commit ${revCommit.shortName}",
|
subtitle = "Cherry-picking commit ${revCommit.shortName}",
|
||||||
|
taskType = TaskType.CHERRY_PICK_COMMIT,
|
||||||
) { git ->
|
) { git ->
|
||||||
cherryPickCommitUseCase(git, revCommit)
|
cherryPickCommitUseCase(git, revCommit)
|
||||||
}
|
}
|
||||||
@ -235,6 +201,7 @@ class LogViewModel @Inject constructor(
|
|||||||
title = "New branch",
|
title = "New branch",
|
||||||
subtitle = "Creating new branch \"$branch\" on commit ${revCommit.shortName}",
|
subtitle = "Creating new branch \"$branch\" on commit ${revCommit.shortName}",
|
||||||
refreshEvenIfCrashesInteractive = { it is CheckoutConflictException },
|
refreshEvenIfCrashesInteractive = { it is CheckoutConflictException },
|
||||||
|
taskType = TaskType.CREATE_BRANCH,
|
||||||
) { git ->
|
) { git ->
|
||||||
createBranchOnCommitUseCase(git, branch, revCommit)
|
createBranchOnCommitUseCase(git, branch, revCommit)
|
||||||
}
|
}
|
||||||
@ -243,34 +210,11 @@ class LogViewModel @Inject constructor(
|
|||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
title = "New tag",
|
title = "New tag",
|
||||||
subtitle = "Creating new tag \"$tag\" on commit ${revCommit.shortName}",
|
subtitle = "Creating new tag \"$tag\" on commit ${revCommit.shortName}",
|
||||||
|
taskType = TaskType.CREATE_TAG,
|
||||||
) { git ->
|
) { git ->
|
||||||
createTagOnCommitUseCase(git, tag, revCommit)
|
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) {
|
private suspend fun uncommittedChangesLoadLog(git: Git) {
|
||||||
val currentBranch = getCurrentBranchUseCase(git)
|
val currentBranch = getCurrentBranchUseCase(git)
|
||||||
val hasUncommittedChanges = checkHasUncommittedChangesUseCase(git)
|
val hasUncommittedChanges = checkHasUncommittedChangesUseCase(git)
|
||||||
@ -301,14 +245,6 @@ class LogViewModel @Inject constructor(
|
|||||||
loadLog(git)
|
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(
|
fun selectUncommittedChanges() = tabState.runOperation(
|
||||||
refreshType = RefreshType.NONE,
|
refreshType = RefreshType.NONE,
|
||||||
) {
|
) {
|
||||||
@ -432,17 +368,10 @@ class LogViewModel @Inject constructor(
|
|||||||
|
|
||||||
fun rebaseInteractive(revCommit: RevCommit) = tabState.safeProcessing(
|
fun rebaseInteractive(revCommit: RevCommit) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.REBASE_INTERACTIVE_STATE,
|
refreshType = RefreshType.REBASE_INTERACTIVE_STATE,
|
||||||
|
taskType = TaskType.REBASE_INTERACTIVE,
|
||||||
) { git ->
|
) { git ->
|
||||||
startRebaseInteractiveUseCase(git, revCommit)
|
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 {
|
sealed interface LogStatus {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.jetpackduba.gitnuro.viewmodels
|
package com.jetpackduba.gitnuro.viewmodels
|
||||||
|
|
||||||
|
import com.jetpackduba.gitnuro.TaskType
|
||||||
import com.jetpackduba.gitnuro.git.RefreshType
|
import com.jetpackduba.gitnuro.git.RefreshType
|
||||||
import com.jetpackduba.gitnuro.git.TabState
|
import com.jetpackduba.gitnuro.git.TabState
|
||||||
import com.jetpackduba.gitnuro.git.remote_operations.FetchAllBranchesUseCase
|
import com.jetpackduba.gitnuro.git.remote_operations.FetchAllBranchesUseCase
|
||||||
@ -30,7 +31,8 @@ class MenuViewModel @Inject constructor(
|
|||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
title = "Pulling",
|
title = "Pulling",
|
||||||
subtitle = "Pulling changes from the remote branch to the current branch",
|
subtitle = "Pulling changes from the remote branch to the current branch",
|
||||||
refreshEvenIfCrashes = true
|
refreshEvenIfCrashes = true,
|
||||||
|
taskType = TaskType.PULL,
|
||||||
) { git ->
|
) { git ->
|
||||||
pullBranchUseCase(git, pullType)
|
pullBranchUseCase(git, pullType)
|
||||||
}
|
}
|
||||||
@ -40,7 +42,8 @@ class MenuViewModel @Inject constructor(
|
|||||||
title = "Fetching",
|
title = "Fetching",
|
||||||
subtitle = "Updating references from the remote repositories...",
|
subtitle = "Updating references from the remote repositories...",
|
||||||
isCancellable = false,
|
isCancellable = false,
|
||||||
refreshEvenIfCrashes = true
|
refreshEvenIfCrashes = true,
|
||||||
|
taskType = TaskType.FETCH,
|
||||||
) { git ->
|
) { git ->
|
||||||
fetchAllBranchesUseCase(git)
|
fetchAllBranchesUseCase(git)
|
||||||
}
|
}
|
||||||
@ -51,12 +54,14 @@ class MenuViewModel @Inject constructor(
|
|||||||
subtitle = "Pushing current branch to the remote repository",
|
subtitle = "Pushing current branch to the remote repository",
|
||||||
isCancellable = false,
|
isCancellable = false,
|
||||||
refreshEvenIfCrashes = true,
|
refreshEvenIfCrashes = true,
|
||||||
|
taskType = TaskType.PUSH,
|
||||||
) { git ->
|
) { git ->
|
||||||
pushBranchUseCase(git, force, pushTags)
|
pushBranchUseCase(git, force, pushTags)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stash() = tabState.safeProcessing(
|
fun stash() = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
||||||
|
taskType = TaskType.STASH,
|
||||||
) { git ->
|
) { git ->
|
||||||
stashChangesUseCase(git, null)
|
stashChangesUseCase(git, null)
|
||||||
}
|
}
|
||||||
@ -64,6 +69,7 @@ class MenuViewModel @Inject constructor(
|
|||||||
fun popStash() = tabState.safeProcessing(
|
fun popStash() = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
||||||
refreshEvenIfCrashes = true,
|
refreshEvenIfCrashes = true,
|
||||||
|
taskType = TaskType.POP_STASH,
|
||||||
) { git ->
|
) { git ->
|
||||||
popLastStashUseCase(git)
|
popLastStashUseCase(git)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.jetpackduba.gitnuro.viewmodels
|
package com.jetpackduba.gitnuro.viewmodels
|
||||||
|
|
||||||
|
import com.jetpackduba.gitnuro.TaskType
|
||||||
import com.jetpackduba.gitnuro.exceptions.InvalidMessageException
|
import com.jetpackduba.gitnuro.exceptions.InvalidMessageException
|
||||||
import com.jetpackduba.gitnuro.exceptions.RebaseCancelledException
|
import com.jetpackduba.gitnuro.exceptions.RebaseCancelledException
|
||||||
import com.jetpackduba.gitnuro.git.RefreshType
|
import com.jetpackduba.gitnuro.git.RefreshType
|
||||||
@ -65,6 +66,7 @@ class RebaseInteractiveViewModel @Inject constructor(
|
|||||||
|
|
||||||
fun loadRebaseInteractiveData() = tabState.safeProcessing(
|
fun loadRebaseInteractiveData() = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.NONE,
|
refreshType = RefreshType.NONE,
|
||||||
|
taskType = TaskType.REBASE_INTERACTIVE,// TODO Perhaps this should be more specific such as TaskType.LOAD_ABORT_REBASE
|
||||||
) { git ->
|
) { git ->
|
||||||
val state = getRepositoryStateUseCase(git)
|
val state = getRepositoryStateUseCase(git)
|
||||||
|
|
||||||
@ -122,6 +124,7 @@ class RebaseInteractiveViewModel @Inject constructor(
|
|||||||
|
|
||||||
fun continueRebaseInteractive() = tabState.safeProcessing(
|
fun continueRebaseInteractive() = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
|
taskType = TaskType.REBASE_INTERACTIVE, // TODO Perhaps be more precise with the task type
|
||||||
) { git ->
|
) { git ->
|
||||||
resumeRebaseInteractiveUseCase(git, interactiveHandlerContinue)
|
resumeRebaseInteractiveUseCase(git, interactiveHandlerContinue)
|
||||||
_rebaseState.value = RebaseInteractiveViewState.Loading
|
_rebaseState.value = RebaseInteractiveViewState.Loading
|
||||||
@ -173,7 +176,10 @@ class RebaseInteractiveViewModel @Inject constructor(
|
|||||||
_rebaseState.value = RebaseInteractiveViewState.Loading
|
_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)
|
val fullCommit = getCommitFromRebaseLineUseCase(git, line.commit, line.shortMessage)
|
||||||
tabState.newSelectedCommit(fullCommit)
|
tabState.newSelectedCommit(fullCommit)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.jetpackduba.gitnuro.viewmodels
|
package com.jetpackduba.gitnuro.viewmodels
|
||||||
|
|
||||||
import com.jetpackduba.gitnuro.Logging
|
import com.jetpackduba.gitnuro.Logging
|
||||||
|
import com.jetpackduba.gitnuro.TaskType
|
||||||
import com.jetpackduba.gitnuro.di.qualifiers.AppCoroutineScope
|
import com.jetpackduba.gitnuro.di.qualifiers.AppCoroutineScope
|
||||||
import com.jetpackduba.gitnuro.git.RefreshType
|
import com.jetpackduba.gitnuro.git.RefreshType
|
||||||
import com.jetpackduba.gitnuro.logging.printError
|
import com.jetpackduba.gitnuro.logging.printError
|
||||||
@ -148,9 +149,10 @@ class SettingsViewModel @Inject constructor(
|
|||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
ex.printStackTrace()
|
ex.printStackTrace()
|
||||||
newErrorNow(
|
newErrorNow(
|
||||||
ex,
|
TaskType.SAVE_CUSTOM_THEME,
|
||||||
"Saving theme failed",
|
ex, // TODO Pass a proper exception with the commented strings
|
||||||
"Failed to parse selected theme JSON. Please check if it's valid and try again."
|
// "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
|
package com.jetpackduba.gitnuro.viewmodels
|
||||||
|
|
||||||
|
import com.jetpackduba.gitnuro.TaskType
|
||||||
import com.jetpackduba.gitnuro.git.RefreshType
|
import com.jetpackduba.gitnuro.git.RefreshType
|
||||||
import com.jetpackduba.gitnuro.git.TabState
|
import com.jetpackduba.gitnuro.git.TabState
|
||||||
import com.jetpackduba.gitnuro.git.stash.ApplyStashUseCase
|
import com.jetpackduba.gitnuro.git.stash.ApplyStashUseCase
|
||||||
@ -27,6 +28,7 @@ class SharedStashViewModel @Inject constructor(
|
|||||||
override fun applyStash(stashInfo: RevCommit) = tabState.safeProcessing(
|
override fun applyStash(stashInfo: RevCommit) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
||||||
refreshEvenIfCrashes = true,
|
refreshEvenIfCrashes = true,
|
||||||
|
taskType = TaskType.APPLY_STASH,
|
||||||
) { git ->
|
) { git ->
|
||||||
applyStashUseCase(git, stashInfo)
|
applyStashUseCase(git, stashInfo)
|
||||||
}
|
}
|
||||||
@ -34,6 +36,7 @@ class SharedStashViewModel @Inject constructor(
|
|||||||
override fun popStash(stash: RevCommit) = tabState.safeProcessing(
|
override fun popStash(stash: RevCommit) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
||||||
refreshEvenIfCrashes = true,
|
refreshEvenIfCrashes = true,
|
||||||
|
taskType = TaskType.POP_STASH,
|
||||||
) { git ->
|
) { git ->
|
||||||
popStashUseCase(git, stash)
|
popStashUseCase(git, stash)
|
||||||
|
|
||||||
@ -42,6 +45,7 @@ class SharedStashViewModel @Inject constructor(
|
|||||||
|
|
||||||
override fun deleteStash(stash: RevCommit) = tabState.safeProcessing(
|
override fun deleteStash(stash: RevCommit) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.STASHES,
|
refreshType = RefreshType.STASHES,
|
||||||
|
taskType = TaskType.DELETE_STASH,
|
||||||
) { git ->
|
) { git ->
|
||||||
deleteStashUseCase(git, stash)
|
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.foundation.lazy.LazyListState
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import com.jetpackduba.gitnuro.SharedRepositoryStateManager
|
import com.jetpackduba.gitnuro.SharedRepositoryStateManager
|
||||||
|
import com.jetpackduba.gitnuro.TaskType
|
||||||
import com.jetpackduba.gitnuro.extensions.delayedStateChange
|
import com.jetpackduba.gitnuro.extensions.delayedStateChange
|
||||||
import com.jetpackduba.gitnuro.extensions.isMerging
|
import com.jetpackduba.gitnuro.extensions.isMerging
|
||||||
import com.jetpackduba.gitnuro.extensions.isReverting
|
import com.jetpackduba.gitnuro.extensions.isReverting
|
||||||
@ -214,12 +215,14 @@ class StatusViewModel @Inject constructor(
|
|||||||
|
|
||||||
fun unstageAll() = tabState.safeProcessing(
|
fun unstageAll() = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.UNCOMMITTED_CHANGES,
|
refreshType = RefreshType.UNCOMMITTED_CHANGES,
|
||||||
|
taskType = TaskType.UNSTAGE_ALL_FILES,
|
||||||
) { git ->
|
) { git ->
|
||||||
unstageAllUseCase(git)
|
unstageAllUseCase(git)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stageAll() = tabState.safeProcessing(
|
fun stageAll() = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.UNCOMMITTED_CHANGES,
|
refreshType = RefreshType.UNCOMMITTED_CHANGES,
|
||||||
|
taskType = TaskType.STAGE_ALL_FILES,
|
||||||
) { git ->
|
) { git ->
|
||||||
stageAllUseCase(git)
|
stageAllUseCase(git)
|
||||||
}
|
}
|
||||||
@ -333,6 +336,7 @@ class StatusViewModel @Inject constructor(
|
|||||||
|
|
||||||
fun commit(message: String) = tabState.safeProcessing(
|
fun commit(message: String) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
|
taskType = TaskType.DO_COMMIT,
|
||||||
) { git ->
|
) { git ->
|
||||||
val amend = isAmend.value
|
val amend = isAmend.value
|
||||||
|
|
||||||
@ -386,6 +390,7 @@ class StatusViewModel @Inject constructor(
|
|||||||
|
|
||||||
fun continueRebase(message: String) = tabState.safeProcessing(
|
fun continueRebase(message: String) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
|
taskType = TaskType.CONTINUE_REBASE,
|
||||||
) { git ->
|
) { git ->
|
||||||
val repositoryState = sharedRepositoryStateManager.repositoryState.value
|
val repositoryState = sharedRepositoryStateManager.repositoryState.value
|
||||||
val rebaseInteractiveState = sharedRepositoryStateManager.rebaseInteractiveState.value
|
val rebaseInteractiveState = sharedRepositoryStateManager.rebaseInteractiveState.value
|
||||||
@ -408,18 +413,21 @@ class StatusViewModel @Inject constructor(
|
|||||||
|
|
||||||
fun abortRebase() = tabState.safeProcessing(
|
fun abortRebase() = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
|
taskType = TaskType.ABORT_REBASE,
|
||||||
) { git ->
|
) { git ->
|
||||||
abortRebaseUseCase(git)
|
abortRebaseUseCase(git)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun skipRebase() = tabState.safeProcessing(
|
fun skipRebase() = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
|
taskType = TaskType.SKIP_REBASE,
|
||||||
) { git ->
|
) { git ->
|
||||||
skipRebaseUseCase(git)
|
skipRebaseUseCase(git)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resetRepoState() = tabState.safeProcessing(
|
fun resetRepoState() = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
|
taskType = TaskType.RESET_REPO_STATE,
|
||||||
) { git ->
|
) { git ->
|
||||||
resetRepositoryStateUseCase(git)
|
resetRepositoryStateUseCase(git)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.jetpackduba.gitnuro.viewmodels
|
package com.jetpackduba.gitnuro.viewmodels
|
||||||
|
|
||||||
import com.jetpackduba.gitnuro.SharedRepositoryStateManager
|
import com.jetpackduba.gitnuro.SharedRepositoryStateManager
|
||||||
|
import com.jetpackduba.gitnuro.TaskType
|
||||||
import com.jetpackduba.gitnuro.credentials.CredentialsAccepted
|
import com.jetpackduba.gitnuro.credentials.CredentialsAccepted
|
||||||
import com.jetpackduba.gitnuro.credentials.CredentialsState
|
import com.jetpackduba.gitnuro.credentials.CredentialsState
|
||||||
import com.jetpackduba.gitnuro.credentials.CredentialsStateManager
|
import com.jetpackduba.gitnuro.credentials.CredentialsStateManager
|
||||||
@ -179,7 +180,13 @@ class TabViewModel @Inject constructor(
|
|||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
onRepositoryChanged(null)
|
onRepositoryChanged(null)
|
||||||
ex.printStackTrace()
|
ex.printStackTrace()
|
||||||
errorsManager.addError(newErrorNow(ex, null, ex.localizedMessage))
|
|
||||||
|
errorsManager.addError(
|
||||||
|
newErrorNow(
|
||||||
|
taskType = TaskType.REPOSITORY_OPEN,
|
||||||
|
exception = ex
|
||||||
|
)
|
||||||
|
)
|
||||||
_repositorySelectionStatus.value = RepositorySelectionStatus.None
|
_repositorySelectionStatus.value = RepositorySelectionStatus.None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -259,8 +266,9 @@ class TabViewModel @Inject constructor(
|
|||||||
errorsManager.addError(
|
errorsManager.addError(
|
||||||
newErrorNow(
|
newErrorNow(
|
||||||
exception = ex,
|
exception = ex,
|
||||||
title = "Repository changes detection has stopped working",
|
taskType = TaskType.CHANGES_DETECTION,
|
||||||
message = message,
|
// title = "Repository changes detection has stopped working",
|
||||||
|
// message = message,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -342,6 +350,7 @@ class TabViewModel @Inject constructor(
|
|||||||
|
|
||||||
fun blameFile(filePath: String) = tabState.safeProcessing(
|
fun blameFile(filePath: String) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.NONE,
|
refreshType = RefreshType.NONE,
|
||||||
|
taskType = TaskType.BLAME_FILE,
|
||||||
) { git ->
|
) { git ->
|
||||||
_blameState.value = BlameState.Loading(filePath)
|
_blameState.value = BlameState.Loading(filePath)
|
||||||
try {
|
try {
|
||||||
@ -405,12 +414,14 @@ class TabViewModel @Inject constructor(
|
|||||||
fun createBranch(branchName: String) = tabState.safeProcessing(
|
fun createBranch(branchName: String) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
refreshEvenIfCrashesInteractive = { it is CheckoutConflictException },
|
refreshEvenIfCrashesInteractive = { it is CheckoutConflictException },
|
||||||
|
taskType = TaskType.CREATE_BRANCH,
|
||||||
) { git ->
|
) { git ->
|
||||||
createBranchUseCase(git, branchName)
|
createBranchUseCase(git, branchName)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stashWithMessage(message: String) = tabState.safeProcessing(
|
fun stashWithMessage(message: String) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
||||||
|
taskType = TaskType.STASH,
|
||||||
) { git ->
|
) { git ->
|
||||||
stageUntrackedFileUseCase(git)
|
stageUntrackedFileUseCase(git)
|
||||||
stashChangesUseCase(git, message)
|
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.PullFromSpecificBranchUseCase
|
||||||
import com.jetpackduba.gitnuro.git.remote_operations.PushToSpecificBranchUseCase
|
import com.jetpackduba.gitnuro.git.remote_operations.PushToSpecificBranchUseCase
|
||||||
import com.jetpackduba.gitnuro.preferences.AppSettings
|
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.Assisted
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -21,20 +23,14 @@ private const val TAG = "BranchesViewModel"
|
|||||||
|
|
||||||
|
|
||||||
class BranchesViewModel @AssistedInject constructor(
|
class BranchesViewModel @AssistedInject constructor(
|
||||||
private val rebaseBranchUseCase: RebaseBranchUseCase,
|
|
||||||
private val tabState: TabState,
|
private val tabState: TabState,
|
||||||
private val appSettings: AppSettings,
|
|
||||||
private val pushToSpecificBranchUseCase: PushToSpecificBranchUseCase,
|
|
||||||
private val pullFromSpecificBranchUseCase: PullFromSpecificBranchUseCase,
|
|
||||||
private val getCurrentBranchUseCase: GetCurrentBranchUseCase,
|
private val getCurrentBranchUseCase: GetCurrentBranchUseCase,
|
||||||
private val mergeBranchUseCase: MergeBranchUseCase,
|
|
||||||
private val getBranchesUseCase: GetBranchesUseCase,
|
private val getBranchesUseCase: GetBranchesUseCase,
|
||||||
private val deleteBranchUseCase: DeleteBranchUseCase,
|
tabScope: CoroutineScope,
|
||||||
private val checkoutRefUseCase: CheckoutRefUseCase,
|
sharedBranchesViewModel: SharedBranchesViewModel,
|
||||||
private val tabScope: CoroutineScope,
|
|
||||||
@Assisted
|
@Assisted
|
||||||
private val filter: StateFlow<String>
|
private val filter: StateFlow<String>
|
||||||
) : SidePanelChildViewModel(true) {
|
) : SidePanelChildViewModel(true), ISharedBranchesViewModel by sharedBranchesViewModel {
|
||||||
private val _branches = MutableStateFlow<List<Ref>>(listOf())
|
private val _branches = MutableStateFlow<List<Ref>>(listOf())
|
||||||
private val _currentBranch = MutableStateFlow<Ref?>(null)
|
private val _currentBranch = MutableStateFlow<Ref?>(null)
|
||||||
|
|
||||||
@ -74,59 +70,13 @@ class BranchesViewModel @AssistedInject constructor(
|
|||||||
_branches.value = branchesList
|
_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) {
|
suspend fun refresh(git: Git) {
|
||||||
loadBranches(git)
|
loadBranches(git)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun rebaseBranch(ref: Ref) = tabState.safeProcessing(
|
|
||||||
refreshType = RefreshType.ALL_DATA,
|
|
||||||
) { git ->
|
|
||||||
rebaseBranchUseCase(git, ref)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun selectBranch(ref: Ref) {
|
fun selectBranch(ref: Ref) {
|
||||||
tabState.newSelectedRef(ref, ref.objectId)
|
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(
|
data class BranchesState(
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.jetpackduba.gitnuro.viewmodels.sidepanel
|
package com.jetpackduba.gitnuro.viewmodels.sidepanel
|
||||||
|
|
||||||
|
import com.jetpackduba.gitnuro.TaskType
|
||||||
import com.jetpackduba.gitnuro.exceptions.InvalidRemoteUrlException
|
import com.jetpackduba.gitnuro.exceptions.InvalidRemoteUrlException
|
||||||
import com.jetpackduba.gitnuro.extensions.lowercaseContains
|
import com.jetpackduba.gitnuro.extensions.lowercaseContains
|
||||||
import com.jetpackduba.gitnuro.extensions.simpleName
|
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.remote_operations.PushToSpecificBranchUseCase
|
||||||
import com.jetpackduba.gitnuro.git.remotes.*
|
import com.jetpackduba.gitnuro.git.remotes.*
|
||||||
import com.jetpackduba.gitnuro.ui.dialogs.RemoteWrapper
|
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.Assisted
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -27,7 +30,6 @@ import org.eclipse.jgit.lib.Ref
|
|||||||
|
|
||||||
class RemotesViewModel @AssistedInject constructor(
|
class RemotesViewModel @AssistedInject constructor(
|
||||||
private val tabState: TabState,
|
private val tabState: TabState,
|
||||||
private val deleteRemoteBranchUseCase: DeleteRemoteBranchUseCase,
|
|
||||||
private val getRemoteBranchesUseCase: GetRemoteBranchesUseCase,
|
private val getRemoteBranchesUseCase: GetRemoteBranchesUseCase,
|
||||||
private val getRemotesUseCase: GetRemotesUseCase,
|
private val getRemotesUseCase: GetRemotesUseCase,
|
||||||
private val getCurrentBranchUseCase: GetCurrentBranchUseCase,
|
private val getCurrentBranchUseCase: GetCurrentBranchUseCase,
|
||||||
@ -35,13 +37,11 @@ class RemotesViewModel @AssistedInject constructor(
|
|||||||
private val addRemoteUseCase: AddRemoteUseCase,
|
private val addRemoteUseCase: AddRemoteUseCase,
|
||||||
private val updateRemoteUseCase: UpdateRemoteUseCase,
|
private val updateRemoteUseCase: UpdateRemoteUseCase,
|
||||||
private val deleteLocallyRemoteBranchesUseCase: DeleteLocallyRemoteBranchesUseCase,
|
private val deleteLocallyRemoteBranchesUseCase: DeleteLocallyRemoteBranchesUseCase,
|
||||||
private val checkoutRefUseCase: CheckoutRefUseCase,
|
tabScope: CoroutineScope,
|
||||||
private val pushToSpecificBranchUseCase: PushToSpecificBranchUseCase,
|
sharedRemotesViewModel: SharedRemotesViewModel,
|
||||||
private val pullFromSpecificBranchUseCase: PullFromSpecificBranchUseCase,
|
|
||||||
private val tabScope: CoroutineScope,
|
|
||||||
@Assisted
|
@Assisted
|
||||||
private val filter: StateFlow<String>
|
private val filter: StateFlow<String>
|
||||||
) : SidePanelChildViewModel(false) {
|
) : SidePanelChildViewModel(false), ISharedRemotesViewModel by sharedRemotesViewModel {
|
||||||
private val remotes = MutableStateFlow<List<RemoteView>>(listOf())
|
private val remotes = MutableStateFlow<List<RemoteView>>(listOf())
|
||||||
private val currentBranch = MutableStateFlow<Ref?>(null)
|
private val currentBranch = MutableStateFlow<Ref?>(null)
|
||||||
|
|
||||||
@ -92,14 +92,6 @@ class RemotesViewModel @AssistedInject constructor(
|
|||||||
this@RemotesViewModel.currentBranch.value = currentBranch
|
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) {
|
suspend fun refresh(git: Git) = withContext(Dispatchers.IO) {
|
||||||
loadRemotes(git)
|
loadRemotes(git)
|
||||||
}
|
}
|
||||||
@ -125,6 +117,7 @@ class RemotesViewModel @AssistedInject constructor(
|
|||||||
|
|
||||||
fun deleteRemote(remoteName: String, isNew: Boolean) = tabState.safeProcessing(
|
fun deleteRemote(remoteName: String, isNew: Boolean) = tabState.safeProcessing(
|
||||||
refreshType = if (isNew) RefreshType.REMOTES else RefreshType.ALL_DATA,
|
refreshType = if (isNew) RefreshType.REMOTES else RefreshType.ALL_DATA,
|
||||||
|
taskType = TaskType.DELETE_REMOTE,
|
||||||
) { git ->
|
) { git ->
|
||||||
deleteRemoteUseCase(git, remoteName)
|
deleteRemoteUseCase(git, remoteName)
|
||||||
|
|
||||||
@ -183,34 +176,6 @@ class RemotesViewModel @AssistedInject constructor(
|
|||||||
uriType = RemoteSetUrlCommand.UriType.PUSH
|
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)
|
data class RemoteView(val remoteInfo: RemoteInfo, val isExpanded: Boolean)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.jetpackduba.gitnuro.viewmodels.sidepanel
|
package com.jetpackduba.gitnuro.viewmodels.sidepanel
|
||||||
|
|
||||||
|
import com.jetpackduba.gitnuro.TaskType
|
||||||
import com.jetpackduba.gitnuro.extensions.lowercaseContains
|
import com.jetpackduba.gitnuro.extensions.lowercaseContains
|
||||||
import com.jetpackduba.gitnuro.git.RefreshType
|
import com.jetpackduba.gitnuro.git.RefreshType
|
||||||
import com.jetpackduba.gitnuro.git.TabState
|
import com.jetpackduba.gitnuro.git.TabState
|
||||||
@ -59,6 +60,7 @@ class SubmodulesViewModel @AssistedInject constructor(
|
|||||||
|
|
||||||
fun initializeSubmodule(path: String) = tabState.safeProcessing(
|
fun initializeSubmodule(path: String) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.SUBMODULES,
|
refreshType = RefreshType.SUBMODULES,
|
||||||
|
taskType = TaskType.INIT_SUBMODULE,
|
||||||
) { git ->
|
) { git ->
|
||||||
initializeSubmoduleUseCase(git, path)
|
initializeSubmoduleUseCase(git, path)
|
||||||
updateSubmoduleUseCase(git, path)
|
updateSubmoduleUseCase(git, path)
|
||||||
@ -75,6 +77,7 @@ class SubmodulesViewModel @AssistedInject constructor(
|
|||||||
fun onDeinitializeSubmodule(path: String) = tabState.safeProcessing(
|
fun onDeinitializeSubmodule(path: String) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.SUBMODULES,
|
refreshType = RefreshType.SUBMODULES,
|
||||||
title = "Deinitializing submodule $path",
|
title = "Deinitializing submodule $path",
|
||||||
|
taskType = TaskType.DEINIT_SUBMODULE,
|
||||||
) { git ->
|
) { git ->
|
||||||
deInitializeSubmoduleUseCase(git, path)
|
deInitializeSubmoduleUseCase(git, path)
|
||||||
}
|
}
|
||||||
@ -83,6 +86,7 @@ class SubmodulesViewModel @AssistedInject constructor(
|
|||||||
refreshType = RefreshType.SUBMODULES,
|
refreshType = RefreshType.SUBMODULES,
|
||||||
title = "Syncing submodule $path",
|
title = "Syncing submodule $path",
|
||||||
subtitle = "Please wait until synchronization has finished",
|
subtitle = "Please wait until synchronization has finished",
|
||||||
|
taskType = TaskType.SYNC_SUBMODULE,
|
||||||
) { git ->
|
) { git ->
|
||||||
syncSubmoduleUseCase(git, path)
|
syncSubmoduleUseCase(git, path)
|
||||||
}
|
}
|
||||||
@ -91,12 +95,14 @@ class SubmodulesViewModel @AssistedInject constructor(
|
|||||||
refreshType = RefreshType.SUBMODULES,
|
refreshType = RefreshType.SUBMODULES,
|
||||||
title = "Updating submodule $path",
|
title = "Updating submodule $path",
|
||||||
subtitle = "Please wait until update has finished",
|
subtitle = "Please wait until update has finished",
|
||||||
|
taskType = TaskType.UPDATE_SUBMODULE,
|
||||||
) { git ->
|
) { git ->
|
||||||
updateSubmoduleUseCase(git, path)
|
updateSubmoduleUseCase(git, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onCreateSubmodule(repository: String, directory: String) = tabState.safeProcessing(
|
fun onCreateSubmodule(repository: String, directory: String) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
|
taskType = TaskType.ADD_SUBMODULE,
|
||||||
) { git ->
|
) { git ->
|
||||||
addSubmoduleUseCase(
|
addSubmoduleUseCase(
|
||||||
git = git,
|
git = git,
|
||||||
@ -108,6 +114,7 @@ class SubmodulesViewModel @AssistedInject constructor(
|
|||||||
|
|
||||||
fun onDeleteSubmodule(path: String) = tabState.safeProcessing(
|
fun onDeleteSubmodule(path: String) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
|
taskType = TaskType.DELETE_SUBMODULE,
|
||||||
) { git ->
|
) { git ->
|
||||||
deleteSubmoduleUseCase(git, path)
|
deleteSubmoduleUseCase(git, path)
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package com.jetpackduba.gitnuro.viewmodels.sidepanel
|
package com.jetpackduba.gitnuro.viewmodels.sidepanel
|
||||||
|
|
||||||
|
import com.jetpackduba.gitnuro.TaskType
|
||||||
import com.jetpackduba.gitnuro.extensions.lowercaseContains
|
import com.jetpackduba.gitnuro.extensions.lowercaseContains
|
||||||
import com.jetpackduba.gitnuro.extensions.simpleName
|
import com.jetpackduba.gitnuro.extensions.simpleName
|
||||||
import com.jetpackduba.gitnuro.git.RefreshType
|
import com.jetpackduba.gitnuro.git.RefreshType
|
||||||
import com.jetpackduba.gitnuro.git.TabState
|
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.DeleteTagUseCase
|
||||||
import com.jetpackduba.gitnuro.git.tags.GetTagsUseCase
|
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.Assisted
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -20,12 +23,12 @@ import org.eclipse.jgit.lib.Ref
|
|||||||
class TagsViewModel @AssistedInject constructor(
|
class TagsViewModel @AssistedInject constructor(
|
||||||
private val tabState: TabState,
|
private val tabState: TabState,
|
||||||
private val getTagsUseCase: GetTagsUseCase,
|
private val getTagsUseCase: GetTagsUseCase,
|
||||||
private val deleteTagUseCase: DeleteTagUseCase,
|
private val checkoutCommitUseCase: CheckoutCommitUseCase,
|
||||||
private val checkoutRefUseCase: CheckoutRefUseCase,
|
tabScope: CoroutineScope,
|
||||||
private val tabScope: CoroutineScope,
|
sharedTagsViewModel: SharedTagsViewModel,
|
||||||
@Assisted
|
@Assisted
|
||||||
private val filter: StateFlow<String>
|
private val filter: StateFlow<String>
|
||||||
) : SidePanelChildViewModel(false) {
|
) : SidePanelChildViewModel(false), ISharedTagsViewModel by sharedTagsViewModel {
|
||||||
private val tags = MutableStateFlow<List<Ref>>(listOf())
|
private val tags = MutableStateFlow<List<Ref>>(listOf())
|
||||||
|
|
||||||
val tagsState: StateFlow<TagsState> = combine(tags, isExpanded, filter) { tags, isExpanded, filter ->
|
val tagsState: StateFlow<TagsState> = combine(tags, isExpanded, filter) { tags, isExpanded, filter ->
|
||||||
@ -54,16 +57,11 @@ class TagsViewModel @AssistedInject constructor(
|
|||||||
tags.value = tagsList
|
tags.value = tagsList
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkoutRef(ref: Ref) = tabState.safeProcessing(
|
fun checkoutTagCommit(ref: Ref) = tabState.safeProcessing(
|
||||||
refreshType = RefreshType.ALL_DATA,
|
refreshType = RefreshType.ALL_DATA,
|
||||||
|
taskType = TaskType.INIT_SUBMODULE,
|
||||||
) { git ->
|
) { git ->
|
||||||
checkoutRefUseCase(git, ref)
|
checkoutCommitUseCase(git, ref.objectId.name)
|
||||||
}
|
|
||||||
|
|
||||||
fun deleteTag(tag: Ref) = tabState.safeProcessing(
|
|
||||||
refreshType = RefreshType.ALL_DATA,
|
|
||||||
) { git ->
|
|
||||||
deleteTagUseCase(git, tag)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun selectTag(tag: Ref) {
|
fun selectTag(tag: Ref) {
|
||||||
|
Loading…
Reference in New Issue
Block a user