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