Refactored user feedback.
Added warning/error messages Change UI design
This commit is contained in:
parent
20830be926
commit
e59fe7df69
@ -0,0 +1,3 @@
|
||||
package com.jetpackduba.gitnuro.exceptions
|
||||
|
||||
class ConflictsException(message: String) : GitnuroException(message)
|
@ -7,7 +7,7 @@ import kotlinx.coroutines.*
|
||||
* Use case: Sometimes is not worth updating the UI with a state to "loading" if the load code executed afterwards is really
|
||||
* fast.
|
||||
*/
|
||||
suspend fun delayedStateChange(delayMs: Long, onDelayTriggered: suspend () -> Unit, block: suspend () -> Unit) {
|
||||
suspend fun <T> delayedStateChange(delayMs: Long, onDelayTriggered: suspend () -> Unit, block: suspend () -> T): T {
|
||||
val scope = CoroutineScope(Dispatchers.IO)
|
||||
var completed = false
|
||||
|
||||
@ -17,9 +17,10 @@ suspend fun delayedStateChange(delayMs: Long, onDelayTriggered: suspend () -> Un
|
||||
onDelayTriggered()
|
||||
}
|
||||
}
|
||||
try {
|
||||
block()
|
||||
return try {
|
||||
val result = block()
|
||||
scope.cancel()
|
||||
result
|
||||
} finally {
|
||||
completed = true
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import com.jetpackduba.gitnuro.git.log.FindCommitUseCase
|
||||
import com.jetpackduba.gitnuro.logging.printError
|
||||
import com.jetpackduba.gitnuro.managers.ErrorsManager
|
||||
import com.jetpackduba.gitnuro.managers.newErrorNow
|
||||
import com.jetpackduba.gitnuro.models.Notification
|
||||
import com.jetpackduba.gitnuro.ui.SelectedItem
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
@ -77,12 +78,11 @@ class TabState @Inject constructor(
|
||||
title: String = "",
|
||||
subtitle: String = "",
|
||||
taskType: TaskType,
|
||||
positiveFeedbackText: String?,
|
||||
// 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 (git: Git) -> Unit
|
||||
callback: suspend (git: Git) -> Notification?,
|
||||
): Job {
|
||||
val job = scope.launch(Dispatchers.IO) {
|
||||
var hasProcessFailed = false
|
||||
@ -91,7 +91,7 @@ class TabState @Inject constructor(
|
||||
|
||||
|
||||
try {
|
||||
delayedStateChange(
|
||||
val notification = delayedStateChange(
|
||||
delayMs = 300,
|
||||
onDelayTriggered = {
|
||||
_processing.update { processingState ->
|
||||
@ -106,8 +106,8 @@ class TabState @Inject constructor(
|
||||
callback(git)
|
||||
}
|
||||
|
||||
if (positiveFeedbackText != null) {
|
||||
errorsManager.emitPositiveNotification(positiveFeedbackText)
|
||||
if (notification != null) {
|
||||
errorsManager.emitNotification(notification)
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
hasProcessFailed = true
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.jetpackduba.gitnuro.git.branches
|
||||
|
||||
import com.jetpackduba.gitnuro.exceptions.ConflictsException
|
||||
import com.jetpackduba.gitnuro.exceptions.UncommittedChangesDetectedException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
@ -10,6 +11,9 @@ import org.eclipse.jgit.lib.Ref
|
||||
import javax.inject.Inject
|
||||
|
||||
class MergeBranchUseCase @Inject constructor() {
|
||||
/**
|
||||
* @return true if success has conflicts, false if success without conflicts
|
||||
*/
|
||||
suspend operator fun invoke(git: Git, branch: Ref, fastForward: Boolean) = withContext(Dispatchers.IO) {
|
||||
val fastForwardMode = if (fastForward)
|
||||
MergeCommand.FastForwardMode.FF
|
||||
@ -25,5 +29,7 @@ class MergeBranchUseCase @Inject constructor() {
|
||||
if (mergeResult.mergeStatus == MergeResult.MergeStatus.FAILED) {
|
||||
throw UncommittedChangesDetectedException("Merge failed, makes sure you repository doesn't contain uncommitted changes.")
|
||||
}
|
||||
|
||||
mergeResult.mergeStatus == MergeResult.MergeStatus.CONFLICTING
|
||||
}
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
package com.jetpackduba.gitnuro.git.rebase
|
||||
|
||||
import com.jetpackduba.gitnuro.exceptions.ConflictsException
|
||||
import com.jetpackduba.gitnuro.exceptions.UncommittedChangesDetectedException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.api.MergeResult
|
||||
import org.eclipse.jgit.api.RebaseCommand
|
||||
import org.eclipse.jgit.api.RebaseResult
|
||||
import org.eclipse.jgit.lib.Ref
|
||||
@ -19,5 +21,11 @@ class RebaseBranchUseCase @Inject constructor() {
|
||||
if (rebaseResult.status == RebaseResult.Status.UNCOMMITTED_CHANGES) {
|
||||
throw UncommittedChangesDetectedException("Rebase failed, the repository contains uncommitted changes.")
|
||||
}
|
||||
|
||||
when (rebaseResult.status) {
|
||||
RebaseResult.Status.UNCOMMITTED_CHANGES -> throw UncommittedChangesDetectedException("Merge failed, makes sure you repository doesn't contain uncommitted changes.")
|
||||
RebaseResult.Status.CONFLICTS -> throw ConflictsException("Rebase produced conflicts, please fix them to continue.")
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
package com.jetpackduba.gitnuro.git.stash
|
||||
|
||||
import com.jetpackduba.gitnuro.models.Success
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.eclipse.jgit.api.Git
|
||||
import javax.inject.Inject
|
||||
|
||||
class StashChangesUseCase @Inject constructor() {
|
||||
suspend operator fun invoke(git: Git, message: String?): Unit = withContext(Dispatchers.IO) {
|
||||
suspend operator fun invoke(git: Git, message: String?): Success = withContext(Dispatchers.IO) {
|
||||
val commit = git
|
||||
.stashCreate()
|
||||
.setIncludeUntracked(true)
|
||||
@ -16,8 +17,6 @@ class StashChangesUseCase @Inject constructor() {
|
||||
}
|
||||
.call()
|
||||
|
||||
if (commit == null) {
|
||||
throw Exception("No changes to stash")
|
||||
}
|
||||
commit != null
|
||||
}
|
||||
}
|
@ -4,11 +4,15 @@ import com.jetpackduba.gitnuro.TaskType
|
||||
import com.jetpackduba.gitnuro.di.TabScope
|
||||
import com.jetpackduba.gitnuro.exceptions.GitnuroException
|
||||
import com.jetpackduba.gitnuro.extensions.lockUse
|
||||
import com.jetpackduba.gitnuro.models.Notification
|
||||
import com.jetpackduba.gitnuro.models.NotificationType
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import javax.inject.Inject
|
||||
|
||||
const val NOTIFICATION_DURATION = 2_500L
|
||||
|
||||
@TabScope
|
||||
class ErrorsManager @Inject constructor(
|
||||
private val coroutineScope: CoroutineScope
|
||||
@ -20,23 +24,23 @@ class ErrorsManager @Inject constructor(
|
||||
private val _error = MutableSharedFlow<Error?>()
|
||||
val error: SharedFlow<Error?> = _error
|
||||
|
||||
private val _notification = MutableStateFlow<Map<Long, String>>(hashMapOf())
|
||||
val notification: StateFlow<Map<Long, String>> = _notification
|
||||
private val _notification = MutableStateFlow<Map<Long, Notification>>(hashMapOf())
|
||||
val notification: StateFlow<Map<Long, Notification>> = _notification
|
||||
|
||||
private val notificationsMutex = Mutex()
|
||||
|
||||
suspend fun emitPositiveNotification(text: String) = coroutineScope.launch {
|
||||
suspend fun emitNotification(notification: Notification) = coroutineScope.launch {
|
||||
val time = System.currentTimeMillis()
|
||||
notificationsMutex.lockUse {
|
||||
_notification.update { notifications ->
|
||||
notifications
|
||||
.toMutableMap()
|
||||
.apply { put(time, text) }
|
||||
.apply { put(time, notification) }
|
||||
}
|
||||
}
|
||||
|
||||
launch {
|
||||
delay(2000)
|
||||
delay(NOTIFICATION_DURATION)
|
||||
|
||||
notificationsMutex.lockUse {
|
||||
_notification.update { notifications ->
|
||||
@ -142,4 +146,4 @@ fun newErrorNow(
|
||||
exception = exception,
|
||||
isUnhandled = exception !is GitnuroException
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
package com.jetpackduba.gitnuro.models
|
||||
|
||||
|
||||
data class Notification(val type: NotificationType, val text: String)
|
||||
|
||||
enum class NotificationType {
|
||||
Warning,
|
||||
Positive,
|
||||
Error,
|
||||
}
|
||||
|
||||
fun positiveNotification(text: String) = Notification(NotificationType.Positive, text)
|
||||
fun errorNotification(text: String) = Notification(NotificationType.Error, text)
|
||||
fun warningNotification(text: String) = Notification(NotificationType.Warning, text)
|
@ -0,0 +1,3 @@
|
||||
package com.jetpackduba.gitnuro.models
|
||||
|
||||
typealias Success = Boolean
|
@ -7,6 +7,7 @@ val lightTheme = ColorsScheme(
|
||||
primaryVariant = Color(0xFF0070D8),
|
||||
onPrimary = Color(0xFFFFFFFFF),
|
||||
secondary = Color(0xFF9c27b0),
|
||||
onSecondary = Color(0xFFFFFFFF),
|
||||
onBackground = Color(0xFF212934),
|
||||
onBackgroundSecondary = Color(0xFF595858),
|
||||
error = Color(0xFFc93838),
|
||||
@ -37,6 +38,7 @@ val darkBlueTheme = ColorsScheme(
|
||||
primaryVariant = Color(0xFF9FD1FF),
|
||||
onPrimary = Color(0xFFFFFFFFF),
|
||||
secondary = Color(0xFFe9c754),
|
||||
onSecondary = Color(0xFF0E1621),
|
||||
onBackground = Color(0xFFFFFFFF),
|
||||
onBackgroundSecondary = Color(0xFFCCCBCB),
|
||||
error = Color(0xFFc93838),
|
||||
@ -66,6 +68,7 @@ val darkGrayTheme = ColorsScheme(
|
||||
primaryVariant = Color(0xFFCDEAFF),
|
||||
onPrimary = Color(0xFFFFFFFFF),
|
||||
secondary = Color(0xFFe9c754),
|
||||
onSecondary = Color(0xFF0E1621),
|
||||
onBackground = Color(0xFFFFFFFF),
|
||||
onBackgroundSecondary = Color(0xFFCCCBCB),
|
||||
error = Color(0xFFc93838),
|
||||
|
@ -20,6 +20,7 @@ data class ColorsScheme(
|
||||
val primaryVariant: Color,
|
||||
val onPrimary: Color,
|
||||
val secondary: Color,
|
||||
val onSecondary: Color,
|
||||
val onBackground: Color,
|
||||
val onBackgroundSecondary: Color,
|
||||
val error: Color,
|
||||
@ -48,12 +49,12 @@ data class ColorsScheme(
|
||||
primary = this.primary,
|
||||
primaryVariant = this.primaryVariant,
|
||||
secondary = this.secondary,
|
||||
onSecondary = this.onSecondary,
|
||||
secondaryVariant = this.secondary,
|
||||
background = this.background,
|
||||
surface = this.surface,
|
||||
error = this.error,
|
||||
onPrimary = this.onPrimary,
|
||||
onSecondary = this.onPrimary,
|
||||
onBackground = this.onBackground,
|
||||
onSurface = this.onBackground,
|
||||
onError = this.onError,
|
||||
|
@ -1,22 +1,30 @@
|
||||
package com.jetpackduba.gitnuro.ui
|
||||
|
||||
import androidx.compose.animation.Crossfade
|
||||
import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.jetpackduba.gitnuro.AppIcons
|
||||
import com.jetpackduba.gitnuro.LoadingRepository
|
||||
import com.jetpackduba.gitnuro.ProcessingScreen
|
||||
import com.jetpackduba.gitnuro.credentials.CredentialsAccepted
|
||||
import com.jetpackduba.gitnuro.credentials.CredentialsRequested
|
||||
import com.jetpackduba.gitnuro.credentials.CredentialsState
|
||||
import com.jetpackduba.gitnuro.git.ProcessingState
|
||||
import com.jetpackduba.gitnuro.models.Notification
|
||||
import com.jetpackduba.gitnuro.models.NotificationType
|
||||
import com.jetpackduba.gitnuro.theme.AppTheme
|
||||
import com.jetpackduba.gitnuro.ui.dialogs.CloneDialog
|
||||
import com.jetpackduba.gitnuro.ui.dialogs.GpgPasswordDialog
|
||||
import com.jetpackduba.gitnuro.ui.dialogs.SshPasswordDialog
|
||||
@ -134,17 +142,82 @@ fun AppTab(
|
||||
.padding(bottom = 48.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
for (notification in notifications)
|
||||
Text(
|
||||
text = notification,
|
||||
modifier = Modifier
|
||||
.padding(bottom = 12.dp)
|
||||
.clip(RoundedCornerShape(8.dp))
|
||||
.background(MaterialTheme.colors.primary)
|
||||
.padding(8.dp),
|
||||
color = MaterialTheme.colors.onPrimary,
|
||||
style = MaterialTheme.typography.body1,
|
||||
)
|
||||
for (notification in notifications) {
|
||||
Notification(notification)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun NotificationSuccessPreview() {
|
||||
AppTheme(customTheme = null) {
|
||||
Notification(NotificationType.Positive, "Hello world!")
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Notification(notification: Notification) {
|
||||
val notificationShape = RoundedCornerShape(8.dp)
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
.border(2.dp, MaterialTheme.colors.onBackground.copy(0.2f), notificationShape)
|
||||
.clip(notificationShape)
|
||||
.background(MaterialTheme.colors.background)
|
||||
.height(IntrinsicSize.Max)
|
||||
.padding(2.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
val backgroundColor = when (notification.type) {
|
||||
NotificationType.Positive -> MaterialTheme.colors.primary
|
||||
NotificationType.Warning -> MaterialTheme.colors.secondary
|
||||
NotificationType.Error -> MaterialTheme.colors.error
|
||||
}
|
||||
|
||||
val contentColor = when (notification.type) {
|
||||
NotificationType.Positive -> MaterialTheme.colors.onPrimary
|
||||
NotificationType.Warning -> MaterialTheme.colors.onSecondary
|
||||
NotificationType.Error -> MaterialTheme.colors.onError
|
||||
}
|
||||
|
||||
val icon = when (notification.type) {
|
||||
NotificationType.Positive -> AppIcons.INFO
|
||||
NotificationType.Warning -> AppIcons.WARNING
|
||||
NotificationType.Error -> AppIcons.ERROR
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(topStart = 6.dp, bottomStart = 6.dp))
|
||||
.background(backgroundColor)
|
||||
.fillMaxHeight()
|
||||
// .padding(start = 2.dp, top = 2.dp, bottom = 2.dp)
|
||||
) {
|
||||
Icon(
|
||||
painterResource(icon),
|
||||
contentDescription = null,
|
||||
tint = contentColor,
|
||||
modifier = Modifier
|
||||
.padding(4.dp)
|
||||
)
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(end = 8.dp)
|
||||
.fillMaxHeight(),
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
) {
|
||||
Text(
|
||||
text = notification.text,
|
||||
modifier = Modifier,
|
||||
color = MaterialTheme.colors.onBackground,
|
||||
style = MaterialTheme.typography.body1,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,7 +80,6 @@ class HistoryViewModel @Inject constructor(
|
||||
title = "History",
|
||||
subtitle = "Loading file history",
|
||||
taskType = TaskType.HISTORY_FILE,
|
||||
positiveFeedbackText = null,
|
||||
) { git ->
|
||||
this@HistoryViewModel.filePath = filePath
|
||||
_historyState.value = HistoryState.Loading(filePath)
|
||||
@ -91,6 +90,8 @@ class HistoryViewModel @Inject constructor(
|
||||
.toList()
|
||||
|
||||
_historyState.value = HistoryState.Loaded(filePath, log)
|
||||
|
||||
null
|
||||
}
|
||||
|
||||
fun selectCommit(commit: RevCommit) = tabState.runOperation(
|
||||
|
@ -18,6 +18,7 @@ import com.jetpackduba.gitnuro.git.tags.CreateTagOnCommitUseCase
|
||||
import com.jetpackduba.gitnuro.git.workspace.CheckHasUncommittedChangesUseCase
|
||||
import com.jetpackduba.gitnuro.git.workspace.GetStatusSummaryUseCase
|
||||
import com.jetpackduba.gitnuro.git.workspace.StatusSummary
|
||||
import com.jetpackduba.gitnuro.models.positiveNotification
|
||||
import com.jetpackduba.gitnuro.repositories.AppSettingsRepository
|
||||
import com.jetpackduba.gitnuro.ui.SelectedItem
|
||||
import com.jetpackduba.gitnuro.ui.log.LogDialog
|
||||
@ -163,9 +164,10 @@ class LogViewModel @Inject constructor(
|
||||
title = "Commit checkout",
|
||||
subtitle = "Checking out commit ${revCommit.name}",
|
||||
taskType = TaskType.CHECKOUT_COMMIT,
|
||||
positiveFeedbackText = "Commit checked out",
|
||||
) { git ->
|
||||
checkoutCommitUseCase(git, revCommit)
|
||||
|
||||
positiveNotification("Commit checked out")
|
||||
}
|
||||
|
||||
fun revertCommit(revCommit: RevCommit) = tabState.safeProcessing(
|
||||
@ -174,9 +176,10 @@ class LogViewModel @Inject constructor(
|
||||
subtitle = "Reverting commit ${revCommit.name}",
|
||||
refreshEvenIfCrashes = true,
|
||||
taskType = TaskType.REVERT_COMMIT,
|
||||
positiveFeedbackText = "Commit reverted",
|
||||
) { git ->
|
||||
revertCommitUseCase(git, revCommit)
|
||||
|
||||
positiveNotification("Commit reverted")
|
||||
}
|
||||
|
||||
fun resetToCommit(revCommit: RevCommit, resetType: ResetType) = tabState.safeProcessing(
|
||||
@ -184,9 +187,10 @@ class LogViewModel @Inject constructor(
|
||||
title = "Branch reset",
|
||||
subtitle = "Resetting branch to commit ${revCommit.shortName}",
|
||||
taskType = TaskType.RESET_TO_COMMIT,
|
||||
positiveFeedbackText = "Reset completed",
|
||||
) { git ->
|
||||
resetToCommitUseCase(git, revCommit, resetType = resetType)
|
||||
|
||||
positiveNotification("Reset completed")
|
||||
}
|
||||
|
||||
fun cherryPickCommit(revCommit: RevCommit) = tabState.safeProcessing(
|
||||
@ -195,9 +199,10 @@ class LogViewModel @Inject constructor(
|
||||
subtitle = "Cherry-picking commit ${revCommit.shortName}",
|
||||
taskType = TaskType.CHERRY_PICK_COMMIT,
|
||||
refreshEvenIfCrashes = true,
|
||||
positiveFeedbackText = "Commit cherry-picked"
|
||||
) { git ->
|
||||
cherryPickCommitUseCase(git, revCommit)
|
||||
|
||||
positiveNotification("Commit cherry-picked")
|
||||
}
|
||||
|
||||
fun createBranchOnCommit(branch: String, revCommit: RevCommit) = tabState.safeProcessing(
|
||||
@ -206,9 +211,10 @@ class LogViewModel @Inject constructor(
|
||||
subtitle = "Creating new branch \"$branch\" on commit ${revCommit.shortName}",
|
||||
refreshEvenIfCrashesInteractive = { it is CheckoutConflictException },
|
||||
taskType = TaskType.CREATE_BRANCH,
|
||||
positiveFeedbackText = "Branch \"$branch\" created",
|
||||
) { git ->
|
||||
createBranchOnCommitUseCase(git, branch, revCommit)
|
||||
|
||||
positiveNotification("Branch \"$branch\" created")
|
||||
}
|
||||
|
||||
fun createTagOnCommit(tag: String, revCommit: RevCommit) = tabState.safeProcessing(
|
||||
@ -216,9 +222,10 @@ class LogViewModel @Inject constructor(
|
||||
title = "New tag",
|
||||
subtitle = "Creating new tag \"$tag\" on commit ${revCommit.shortName}",
|
||||
taskType = TaskType.CREATE_TAG,
|
||||
positiveFeedbackText = "Tag created",
|
||||
) { git ->
|
||||
createTagOnCommitUseCase(git, tag, revCommit)
|
||||
|
||||
positiveNotification("Tag created")
|
||||
}
|
||||
|
||||
private suspend fun uncommittedChangesLoadLog(git: Git) {
|
||||
@ -375,9 +382,10 @@ class LogViewModel @Inject constructor(
|
||||
fun rebaseInteractive(revCommit: RevCommit) = tabState.safeProcessing(
|
||||
refreshType = RefreshType.REBASE_INTERACTIVE_STATE,
|
||||
taskType = TaskType.REBASE_INTERACTIVE,
|
||||
positiveFeedbackText = null,
|
||||
) { git ->
|
||||
startRebaseInteractiveUseCase(git, revCommit)
|
||||
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,9 @@ import com.jetpackduba.gitnuro.git.stash.PopLastStashUseCase
|
||||
import com.jetpackduba.gitnuro.git.stash.StashChangesUseCase
|
||||
import com.jetpackduba.gitnuro.git.workspace.StageUntrackedFileUseCase
|
||||
import com.jetpackduba.gitnuro.managers.AppStateManager
|
||||
import com.jetpackduba.gitnuro.models.errorNotification
|
||||
import com.jetpackduba.gitnuro.models.positiveNotification
|
||||
import com.jetpackduba.gitnuro.models.warningNotification
|
||||
import com.jetpackduba.gitnuro.repositories.AppSettingsRepository
|
||||
import com.jetpackduba.gitnuro.terminal.OpenRepositoryInTerminalUseCase
|
||||
import javax.inject.Inject
|
||||
@ -22,10 +25,9 @@ class MenuViewModel @Inject constructor(
|
||||
private val fetchAllRemotesUseCase: FetchAllRemotesUseCase,
|
||||
private val popLastStashUseCase: PopLastStashUseCase,
|
||||
private val stashChangesUseCase: StashChangesUseCase,
|
||||
private val stageUntrackedFileUseCase: StageUntrackedFileUseCase,
|
||||
private val openRepositoryInTerminalUseCase: OpenRepositoryInTerminalUseCase,
|
||||
private val settings: AppSettingsRepository,
|
||||
private val appStateManager: AppStateManager,
|
||||
settings: AppSettingsRepository,
|
||||
appStateManager: AppStateManager,
|
||||
) {
|
||||
val isPullWithRebaseDefault = settings.pullRebaseFlow
|
||||
val lastLoadedTabs = appStateManager.latestOpenedRepositoriesPaths
|
||||
@ -34,11 +36,12 @@ class MenuViewModel @Inject constructor(
|
||||
refreshType = RefreshType.ALL_DATA,
|
||||
title = "Pulling",
|
||||
subtitle = "Pulling changes from the remote branch to the current branch",
|
||||
positiveFeedbackText = "Pull completed",
|
||||
refreshEvenIfCrashes = true,
|
||||
taskType = TaskType.PULL,
|
||||
) { git ->
|
||||
pullBranchUseCase(git, pullType)
|
||||
|
||||
positiveNotification("Pull completed")
|
||||
}
|
||||
|
||||
fun fetchAll() = tabState.safeProcessing(
|
||||
@ -48,9 +51,10 @@ class MenuViewModel @Inject constructor(
|
||||
isCancellable = false,
|
||||
refreshEvenIfCrashes = true,
|
||||
taskType = TaskType.FETCH,
|
||||
positiveFeedbackText = "Fetch all completed",
|
||||
) { git ->
|
||||
fetchAllRemotesUseCase(git)
|
||||
|
||||
positiveNotification("Fetch all completed")
|
||||
}
|
||||
|
||||
fun push(force: Boolean = false, pushTags: Boolean = false) = tabState.safeProcessing(
|
||||
@ -60,26 +64,31 @@ class MenuViewModel @Inject constructor(
|
||||
isCancellable = false,
|
||||
refreshEvenIfCrashes = true,
|
||||
taskType = TaskType.PUSH,
|
||||
positiveFeedbackText = "Push completed",
|
||||
) { git ->
|
||||
pushBranchUseCase(git, force, pushTags)
|
||||
|
||||
positiveNotification("Push completed")
|
||||
}
|
||||
|
||||
fun stash() = tabState.safeProcessing(
|
||||
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
||||
taskType = TaskType.STASH,
|
||||
positiveFeedbackText = "Changes stashed",
|
||||
) { git ->
|
||||
stashChangesUseCase(git, null)
|
||||
if (stashChangesUseCase(git, null)) {
|
||||
positiveNotification("Changes stashed")
|
||||
} else {
|
||||
errorNotification("There are no changes to stash")
|
||||
}
|
||||
}
|
||||
|
||||
fun popStash() = tabState.safeProcessing(
|
||||
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
||||
refreshEvenIfCrashes = true,
|
||||
taskType = TaskType.POP_STASH,
|
||||
positiveFeedbackText = "Stash popped",
|
||||
) { git ->
|
||||
popLastStashUseCase(git)
|
||||
|
||||
positiveNotification("Stash popped")
|
||||
}
|
||||
|
||||
fun openTerminal() = tabState.runOperation(
|
||||
|
@ -67,13 +67,12 @@ 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
|
||||
positiveFeedbackText = null,
|
||||
) { git ->
|
||||
val state = getRepositoryStateUseCase(git)
|
||||
|
||||
if (!state.isRebasing) {
|
||||
_rebaseState.value = RebaseInteractiveViewState.Loading
|
||||
return@safeProcessing
|
||||
return@safeProcessing null
|
||||
}
|
||||
|
||||
try {
|
||||
@ -107,6 +106,8 @@ class RebaseInteractiveViewModel @Inject constructor(
|
||||
throw ex
|
||||
}
|
||||
}
|
||||
|
||||
null
|
||||
}
|
||||
|
||||
private fun isSameRebase(rebaseLines: List<RebaseLine>, state: RebaseInteractiveViewState): Boolean {
|
||||
@ -126,10 +127,11 @@ 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
|
||||
positiveFeedbackText = null,
|
||||
) { git ->
|
||||
resumeRebaseInteractiveUseCase(git, interactiveHandlerContinue)
|
||||
_rebaseState.value = RebaseInteractiveViewState.Loading
|
||||
|
||||
null
|
||||
}
|
||||
|
||||
fun onCommitMessageChanged(commit: AbbreviatedObjectId, message: String) {
|
||||
@ -181,10 +183,11 @@ class RebaseInteractiveViewModel @Inject constructor(
|
||||
fun selectLine(line: RebaseLine) = tabState.safeProcessing(
|
||||
refreshType = RefreshType.NONE,
|
||||
taskType = TaskType.ABORT_REBASE, // TODO Perhaps be more precise with the task type
|
||||
positiveFeedbackText = null,
|
||||
) { git ->
|
||||
val fullCommit = getCommitFromRebaseLineUseCase(git, line.commit, line.shortMessage)
|
||||
tabState.newSelectedCommit(fullCommit)
|
||||
|
||||
null
|
||||
}
|
||||
|
||||
fun moveCommit(from: Int, to: Int) {
|
||||
|
@ -8,6 +8,8 @@ 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.models.positiveNotification
|
||||
import com.jetpackduba.gitnuro.models.warningNotification
|
||||
import com.jetpackduba.gitnuro.repositories.AppSettingsRepository
|
||||
import kotlinx.coroutines.Job
|
||||
import org.eclipse.jgit.lib.Ref
|
||||
@ -34,9 +36,13 @@ class SharedBranchesViewModel @Inject constructor(
|
||||
title = "Branch merge",
|
||||
subtitle = "Merging branch ${ref.simpleName}",
|
||||
taskType = TaskType.MERGE_BRANCH,
|
||||
positiveFeedbackText = "Merged from \"${ref.simpleName}\"",
|
||||
refreshEvenIfCrashes = true,
|
||||
) { git ->
|
||||
mergeBranchUseCase(git, ref, appSettingsRepository.ffMerge)
|
||||
if (mergeBranchUseCase(git, ref, appSettingsRepository.ffMerge)) {
|
||||
warningNotification("Merge produced conflicts, please fix them to continue.")
|
||||
} else {
|
||||
positiveNotification("Merged from \"${ref.simpleName}\"")
|
||||
}
|
||||
}
|
||||
|
||||
override fun deleteBranch(branch: Ref) = tabState.safeProcessing(
|
||||
@ -44,9 +50,10 @@ class SharedBranchesViewModel @Inject constructor(
|
||||
title = "Branch delete",
|
||||
subtitle = "Deleting branch ${branch.simpleName}",
|
||||
taskType = TaskType.DELETE_BRANCH,
|
||||
positiveFeedbackText = "\"${branch.simpleName}\" deleted",
|
||||
) { git ->
|
||||
deleteBranchUseCase(git, branch)
|
||||
|
||||
positiveNotification("\"${branch.simpleName}\" deleted")
|
||||
}
|
||||
|
||||
override fun checkoutRef(ref: Ref) = tabState.safeProcessing(
|
||||
@ -54,9 +61,10 @@ class SharedBranchesViewModel @Inject constructor(
|
||||
title = "Branch checkout",
|
||||
subtitle = "Checking out branch ${ref.simpleName}",
|
||||
taskType = TaskType.CHECKOUT_BRANCH,
|
||||
positiveFeedbackText = "\"${ref.simpleName}\" checked out",
|
||||
) { git ->
|
||||
checkoutRefUseCase(git, ref)
|
||||
|
||||
positiveNotification("\"${ref.simpleName}\" checked out")
|
||||
}
|
||||
|
||||
override fun rebaseBranch(ref: Ref) = tabState.safeProcessing(
|
||||
@ -64,8 +72,10 @@ class SharedBranchesViewModel @Inject constructor(
|
||||
title = "Branch rebase",
|
||||
subtitle = "Rebasing branch ${ref.simpleName}",
|
||||
taskType = TaskType.REBASE_BRANCH,
|
||||
positiveFeedbackText = "\"${ref.simpleName}\" rebased",
|
||||
refreshEvenIfCrashes = true,
|
||||
) { git ->
|
||||
rebaseBranchUseCase(git, ref)
|
||||
|
||||
positiveNotification("\"${ref.simpleName}\" rebased")
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ 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 com.jetpackduba.gitnuro.models.positiveNotification
|
||||
import kotlinx.coroutines.Job
|
||||
import org.eclipse.jgit.lib.Ref
|
||||
import javax.inject.Inject
|
||||
@ -31,17 +32,19 @@ class SharedRemotesViewModel @Inject constructor(
|
||||
title = "Deleting remote branch",
|
||||
subtitle = "Remote branch ${ref.simpleName} will be deleted from the remote",
|
||||
taskType = TaskType.DELETE_REMOTE_BRANCH,
|
||||
positiveFeedbackText = "Remote branch \"${ref.simpleName}\" deleted",
|
||||
) { git ->
|
||||
deleteRemoteBranchUseCase(git, ref)
|
||||
|
||||
positiveNotification("Remote branch \"${ref.simpleName}\" deleted",)
|
||||
}
|
||||
|
||||
override fun checkoutRemoteBranch(remoteBranch: Ref) = tabState.safeProcessing(
|
||||
refreshType = RefreshType.ALL_DATA,
|
||||
taskType = TaskType.CHECKOUT_REMOTE_BRANCH,
|
||||
positiveFeedbackText = "\"${remoteBranch.simpleName}\" checked out",
|
||||
) { git ->
|
||||
checkoutRefUseCase(git, remoteBranch)
|
||||
|
||||
positiveNotification("\"${remoteBranch.simpleName}\" checked out")
|
||||
}
|
||||
|
||||
override fun pushToRemoteBranch(branch: Ref) = tabState.safeProcessing(
|
||||
@ -49,7 +52,6 @@ class SharedRemotesViewModel @Inject constructor(
|
||||
title = "Push",
|
||||
subtitle = "Pushing current branch to ${branch.simpleName}",
|
||||
taskType = TaskType.PUSH_TO_BRANCH,
|
||||
positiveFeedbackText = "Pushed to \"${branch.simpleName}\"",
|
||||
) { git ->
|
||||
pushToSpecificBranchUseCase(
|
||||
git = git,
|
||||
@ -57,6 +59,8 @@ class SharedRemotesViewModel @Inject constructor(
|
||||
pushTags = false,
|
||||
remoteBranch = branch,
|
||||
)
|
||||
|
||||
positiveNotification("Pushed to \"${branch.simpleName}\"")
|
||||
}
|
||||
|
||||
override fun pullFromRemoteBranch(branch: Ref) = tabState.safeProcessing(
|
||||
@ -64,12 +68,13 @@ class SharedRemotesViewModel @Inject constructor(
|
||||
title = "Pull",
|
||||
subtitle = "Pulling changes from ${branch.simpleName} to the current branch",
|
||||
taskType = TaskType.PULL_FROM_BRANCH,
|
||||
positiveFeedbackText = "Pulled from \"${branch.simpleName}\"",
|
||||
) { git ->
|
||||
pullFromSpecificBranchUseCase(
|
||||
git = git,
|
||||
rebase = false,
|
||||
remoteBranch = branch,
|
||||
)
|
||||
|
||||
positiveNotification("Pulled from \"${branch.simpleName}\"")
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import com.jetpackduba.gitnuro.git.TabState
|
||||
import com.jetpackduba.gitnuro.git.stash.ApplyStashUseCase
|
||||
import com.jetpackduba.gitnuro.git.stash.DeleteStashUseCase
|
||||
import com.jetpackduba.gitnuro.git.stash.PopStashUseCase
|
||||
import com.jetpackduba.gitnuro.models.positiveNotification
|
||||
import com.jetpackduba.gitnuro.ui.SelectedItem
|
||||
import kotlinx.coroutines.Job
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
@ -29,30 +30,33 @@ class SharedStashViewModel @Inject constructor(
|
||||
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
||||
refreshEvenIfCrashes = true,
|
||||
taskType = TaskType.APPLY_STASH,
|
||||
positiveFeedbackText = "Stash applied",
|
||||
) { git ->
|
||||
applyStashUseCase(git, stashInfo)
|
||||
|
||||
positiveNotification("Stash applied")
|
||||
}
|
||||
|
||||
override fun popStash(stash: RevCommit) = tabState.safeProcessing(
|
||||
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
||||
refreshEvenIfCrashes = true,
|
||||
taskType = TaskType.POP_STASH,
|
||||
positiveFeedbackText = "Stash popped",
|
||||
) { git ->
|
||||
popStashUseCase(git, stash)
|
||||
|
||||
stashDropped(stash)
|
||||
|
||||
positiveNotification("Stash popped")
|
||||
}
|
||||
|
||||
override fun deleteStash(stash: RevCommit) = tabState.safeProcessing(
|
||||
refreshType = RefreshType.STASHES,
|
||||
taskType = TaskType.DELETE_STASH,
|
||||
positiveFeedbackText = "Stash deleted",
|
||||
) { git ->
|
||||
deleteStashUseCase(git, stash)
|
||||
|
||||
stashDropped(stash)
|
||||
|
||||
positiveNotification("Stash deleted")
|
||||
}
|
||||
|
||||
override fun selectStash(stash: RevCommit) = tabState.runOperation(
|
||||
|
@ -5,6 +5,7 @@ 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.models.positiveNotification
|
||||
import kotlinx.coroutines.Job
|
||||
import org.eclipse.jgit.lib.Ref
|
||||
import javax.inject.Inject
|
||||
@ -22,8 +23,9 @@ class SharedTagsViewModel @Inject constructor(
|
||||
title = "Tag delete",
|
||||
subtitle = "Deleting tag ${tag.simpleName}",
|
||||
taskType = TaskType.DELETE_TAG,
|
||||
positiveFeedbackText = "Tag \"${tag.simpleName}\" deleted",
|
||||
) { git ->
|
||||
deleteTagUseCase(git, tag)
|
||||
|
||||
positiveNotification("Tag \"${tag.simpleName}\" deleted")
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import com.jetpackduba.gitnuro.git.rebase.SkipRebaseUseCase
|
||||
import com.jetpackduba.gitnuro.git.repository.ResetRepositoryStateUseCase
|
||||
import com.jetpackduba.gitnuro.git.workspace.*
|
||||
import com.jetpackduba.gitnuro.models.AuthorInfo
|
||||
import com.jetpackduba.gitnuro.models.positiveNotification
|
||||
import com.jetpackduba.gitnuro.repositories.AppSettingsRepository
|
||||
import com.jetpackduba.gitnuro.ui.tree_files.TreeItem
|
||||
import com.jetpackduba.gitnuro.ui.tree_files.entriesToTreeEntry
|
||||
@ -216,17 +217,19 @@ class StatusViewModel @Inject constructor(
|
||||
fun unstageAll() = tabState.safeProcessing(
|
||||
refreshType = RefreshType.UNCOMMITTED_CHANGES,
|
||||
taskType = TaskType.UNSTAGE_ALL_FILES,
|
||||
positiveFeedbackText = null,
|
||||
) { git ->
|
||||
unstageAllUseCase(git)
|
||||
|
||||
null
|
||||
}
|
||||
|
||||
fun stageAll() = tabState.safeProcessing(
|
||||
refreshType = RefreshType.UNCOMMITTED_CHANGES,
|
||||
taskType = TaskType.STAGE_ALL_FILES,
|
||||
positiveFeedbackText = null,
|
||||
) { git ->
|
||||
stageAllUseCase(git)
|
||||
|
||||
null
|
||||
}
|
||||
|
||||
fun resetStaged(statusEntry: StatusEntry) = tabState.runOperation(
|
||||
@ -349,7 +352,6 @@ class StatusViewModel @Inject constructor(
|
||||
fun commit(message: String) = tabState.safeProcessing(
|
||||
refreshType = RefreshType.ALL_DATA,
|
||||
taskType = TaskType.DO_COMMIT,
|
||||
positiveFeedbackText = if (isAmend.value) "Commit amended" else "New commit created",
|
||||
) { git ->
|
||||
val amend = isAmend.value
|
||||
|
||||
@ -364,6 +366,8 @@ class StatusViewModel @Inject constructor(
|
||||
doCommitUseCase(git, commitMessage, amend, personIdent)
|
||||
updateCommitMessage("")
|
||||
_isAmend.value = false
|
||||
|
||||
positiveNotification(if (isAmend.value) "Commit amended" else "New commit created")
|
||||
}
|
||||
|
||||
private suspend fun getPersonIdent(git: Git): PersonIdent? {
|
||||
@ -404,7 +408,6 @@ class StatusViewModel @Inject constructor(
|
||||
fun continueRebase(message: String) = tabState.safeProcessing(
|
||||
refreshType = RefreshType.ALL_DATA,
|
||||
taskType = TaskType.CONTINUE_REBASE,
|
||||
positiveFeedbackText = null,
|
||||
) { git ->
|
||||
val repositoryState = sharedRepositoryStateManager.repositoryState.value
|
||||
val rebaseInteractiveState = sharedRepositoryStateManager.rebaseInteractiveState.value
|
||||
@ -423,30 +426,35 @@ class StatusViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
continueRebaseUseCase(git)
|
||||
|
||||
null
|
||||
}
|
||||
|
||||
fun abortRebase() = tabState.safeProcessing(
|
||||
refreshType = RefreshType.ALL_DATA,
|
||||
taskType = TaskType.ABORT_REBASE,
|
||||
positiveFeedbackText = "Rebase aborted",
|
||||
) { git ->
|
||||
abortRebaseUseCase(git)
|
||||
|
||||
positiveNotification("Rebase aborted")
|
||||
}
|
||||
|
||||
fun skipRebase() = tabState.safeProcessing(
|
||||
refreshType = RefreshType.ALL_DATA,
|
||||
taskType = TaskType.SKIP_REBASE,
|
||||
positiveFeedbackText = null,
|
||||
) { git ->
|
||||
skipRebaseUseCase(git)
|
||||
|
||||
null
|
||||
}
|
||||
|
||||
fun resetRepoState() = tabState.safeProcessing(
|
||||
refreshType = RefreshType.ALL_DATA,
|
||||
taskType = TaskType.RESET_REPO_STATE,
|
||||
positiveFeedbackText = "Repository state has been reset",
|
||||
) { git ->
|
||||
resetRepositoryStateUseCase(git)
|
||||
|
||||
positiveNotification("Repository state has been reset")
|
||||
}
|
||||
|
||||
fun deleteFile(statusEntry: StatusEntry) = tabState.runOperation(
|
||||
|
@ -20,6 +20,9 @@ import com.jetpackduba.gitnuro.managers.AppStateManager
|
||||
import com.jetpackduba.gitnuro.managers.ErrorsManager
|
||||
import com.jetpackduba.gitnuro.managers.newErrorNow
|
||||
import com.jetpackduba.gitnuro.models.AuthorInfoSimple
|
||||
import com.jetpackduba.gitnuro.models.errorNotification
|
||||
import com.jetpackduba.gitnuro.models.positiveNotification
|
||||
import com.jetpackduba.gitnuro.models.warningNotification
|
||||
import com.jetpackduba.gitnuro.system.OpenFilePickerUseCase
|
||||
import com.jetpackduba.gitnuro.system.OpenUrlInBrowserUseCase
|
||||
import com.jetpackduba.gitnuro.system.PickerType
|
||||
@ -353,7 +356,6 @@ class TabViewModel @Inject constructor(
|
||||
fun blameFile(filePath: String) = tabState.safeProcessing(
|
||||
refreshType = RefreshType.NONE,
|
||||
taskType = TaskType.BLAME_FILE,
|
||||
positiveFeedbackText = null,
|
||||
) { git ->
|
||||
_blameState.value = BlameState.Loading(filePath)
|
||||
try {
|
||||
@ -368,6 +370,8 @@ class TabViewModel @Inject constructor(
|
||||
|
||||
throw ex
|
||||
}
|
||||
|
||||
null
|
||||
}
|
||||
|
||||
fun resetBlameState() {
|
||||
@ -418,18 +422,23 @@ class TabViewModel @Inject constructor(
|
||||
refreshType = RefreshType.ALL_DATA,
|
||||
refreshEvenIfCrashesInteractive = { it is CheckoutConflictException },
|
||||
taskType = TaskType.CREATE_BRANCH,
|
||||
positiveFeedbackText = "Branch \"${branchName}\" created",
|
||||
) { git ->
|
||||
createBranchUseCase(git, branchName)
|
||||
|
||||
positiveNotification("Branch \"${branchName}\" created")
|
||||
}
|
||||
|
||||
fun stashWithMessage(message: String) = tabState.safeProcessing(
|
||||
refreshType = RefreshType.UNCOMMITTED_CHANGES_AND_LOG,
|
||||
taskType = TaskType.STASH,
|
||||
positiveFeedbackText = "Changes stashed",
|
||||
) { git ->
|
||||
stageUntrackedFileUseCase(git)
|
||||
stashChangesUseCase(git, message)
|
||||
|
||||
if (stashChangesUseCase(git, message)) {
|
||||
positiveNotification("Changes stashed")
|
||||
} else {
|
||||
errorNotification("There are no changes to stash")
|
||||
}
|
||||
}
|
||||
|
||||
fun openFolderInFileExplorer() = tabState.runOperation(
|
||||
|
@ -11,6 +11,7 @@ import com.jetpackduba.gitnuro.git.branches.GetCurrentBranchUseCase
|
||||
import com.jetpackduba.gitnuro.git.branches.GetRemoteBranchesUseCase
|
||||
import com.jetpackduba.gitnuro.git.remotes.*
|
||||
import com.jetpackduba.gitnuro.models.RemoteWrapper
|
||||
import com.jetpackduba.gitnuro.models.positiveNotification
|
||||
import com.jetpackduba.gitnuro.viewmodels.ISharedRemotesViewModel
|
||||
import com.jetpackduba.gitnuro.viewmodels.SharedRemotesViewModel
|
||||
import dagger.assisted.Assisted
|
||||
@ -117,7 +118,6 @@ class RemotesViewModel @AssistedInject constructor(
|
||||
fun deleteRemote(remoteName: String) = tabState.safeProcessing(
|
||||
refreshType = RefreshType.ALL_DATA,
|
||||
taskType = TaskType.DELETE_REMOTE,
|
||||
positiveFeedbackText = "Remote $remoteName deleted",
|
||||
) { git ->
|
||||
deleteRemoteUseCase(git, remoteName)
|
||||
|
||||
@ -129,6 +129,8 @@ class RemotesViewModel @AssistedInject constructor(
|
||||
}
|
||||
|
||||
deleteLocallyRemoteBranchesUseCase(git, remoteToDeleteBranchesNames)
|
||||
|
||||
positiveNotification("Remote $remoteName deleted")
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,6 +5,7 @@ import com.jetpackduba.gitnuro.extensions.lowercaseContains
|
||||
import com.jetpackduba.gitnuro.git.RefreshType
|
||||
import com.jetpackduba.gitnuro.git.TabState
|
||||
import com.jetpackduba.gitnuro.git.submodules.*
|
||||
import com.jetpackduba.gitnuro.models.positiveNotification
|
||||
import com.jetpackduba.gitnuro.ui.TabsManager
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
@ -61,10 +62,11 @@ class SubmodulesViewModel @AssistedInject constructor(
|
||||
fun initializeSubmodule(path: String) = tabState.safeProcessing(
|
||||
refreshType = RefreshType.SUBMODULES,
|
||||
taskType = TaskType.INIT_SUBMODULE,
|
||||
positiveFeedbackText = null,
|
||||
) { git ->
|
||||
initializeSubmoduleUseCase(git, path)
|
||||
updateSubmoduleUseCase(git, path)
|
||||
|
||||
null
|
||||
}
|
||||
|
||||
suspend fun refresh(git: Git) {
|
||||
@ -79,9 +81,10 @@ class SubmodulesViewModel @AssistedInject constructor(
|
||||
refreshType = RefreshType.SUBMODULES,
|
||||
title = "Deinitializing submodule $path",
|
||||
taskType = TaskType.DEINIT_SUBMODULE,
|
||||
positiveFeedbackText = null,
|
||||
) { git ->
|
||||
deInitializeSubmoduleUseCase(git, path)
|
||||
|
||||
null
|
||||
}
|
||||
|
||||
fun onSyncSubmodule(path: String) = tabState.safeProcessing(
|
||||
@ -89,9 +92,10 @@ class SubmodulesViewModel @AssistedInject constructor(
|
||||
title = "Syncing submodule $path",
|
||||
subtitle = "Please wait until synchronization has finished",
|
||||
taskType = TaskType.SYNC_SUBMODULE,
|
||||
positiveFeedbackText = "Submodule synced",
|
||||
) { git ->
|
||||
syncSubmoduleUseCase(git, path)
|
||||
|
||||
positiveNotification("Submodule synced")
|
||||
}
|
||||
|
||||
fun onUpdateSubmodule(path: String) = tabState.safeProcessing(
|
||||
@ -99,15 +103,15 @@ class SubmodulesViewModel @AssistedInject constructor(
|
||||
title = "Updating submodule $path",
|
||||
subtitle = "Please wait until update has finished",
|
||||
taskType = TaskType.UPDATE_SUBMODULE,
|
||||
positiveFeedbackText = "Submodule updated",
|
||||
) { git ->
|
||||
updateSubmoduleUseCase(git, path)
|
||||
|
||||
positiveNotification("Submodule updated")
|
||||
}
|
||||
|
||||
fun onCreateSubmodule(repository: String, directory: String) = tabState.safeProcessing(
|
||||
refreshType = RefreshType.ALL_DATA,
|
||||
taskType = TaskType.ADD_SUBMODULE,
|
||||
positiveFeedbackText = "Submodule created",
|
||||
) { git ->
|
||||
addSubmoduleUseCase(
|
||||
git = git,
|
||||
@ -115,14 +119,17 @@ class SubmodulesViewModel @AssistedInject constructor(
|
||||
path = directory,
|
||||
uri = repository,
|
||||
)
|
||||
|
||||
positiveNotification("Submodule created")
|
||||
}
|
||||
|
||||
fun onDeleteSubmodule(path: String) = tabState.safeProcessing(
|
||||
refreshType = RefreshType.ALL_DATA,
|
||||
taskType = TaskType.DELETE_SUBMODULE,
|
||||
positiveFeedbackText = "Submodule deleted",
|
||||
) { git ->
|
||||
deleteSubmoduleUseCase(git, path)
|
||||
|
||||
positiveNotification("Submodule deleted")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import com.jetpackduba.gitnuro.git.TabState
|
||||
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.models.positiveNotification
|
||||
import com.jetpackduba.gitnuro.viewmodels.ISharedTagsViewModel
|
||||
import com.jetpackduba.gitnuro.viewmodels.SharedTagsViewModel
|
||||
import dagger.assisted.Assisted
|
||||
@ -60,9 +61,10 @@ class TagsViewModel @AssistedInject constructor(
|
||||
fun checkoutTagCommit(ref: Ref) = tabState.safeProcessing(
|
||||
refreshType = RefreshType.ALL_DATA,
|
||||
taskType = TaskType.INIT_SUBMODULE,
|
||||
positiveFeedbackText = "Commit checked out",
|
||||
) { git ->
|
||||
checkoutCommitUseCase(git, ref.objectId.name)
|
||||
|
||||
positiveNotification("Commit checked out")
|
||||
}
|
||||
|
||||
fun selectTag(tag: Ref) {
|
||||
|
Loading…
Reference in New Issue
Block a user