Renamed CloneStatus to CloneState
This commit is contained in:
parent
50fff76b1f
commit
35d7b23913
@ -3,12 +3,12 @@ package com.jetpackduba.gitnuro.git
|
|||||||
import org.eclipse.jgit.transport.RemoteRefUpdate
|
import org.eclipse.jgit.transport.RemoteRefUpdate
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
sealed class CloneStatus {
|
sealed class CloneState {
|
||||||
object None : CloneStatus()
|
object None : CloneState()
|
||||||
data class Cloning(val taskName: String, val progress: Int, val total: Int) : CloneStatus()
|
data class Cloning(val taskName: String, val progress: Int, val total: Int) : CloneState()
|
||||||
object Cancelling : CloneStatus()
|
object Cancelling : CloneState()
|
||||||
data class Fail(val reason: String) : CloneStatus()
|
data class Fail(val reason: String) : CloneState()
|
||||||
data class Completed(val repoDir: File) : CloneStatus()
|
data class Completed(val repoDir: File) : CloneState()
|
||||||
}
|
}
|
||||||
|
|
||||||
val RemoteRefUpdate.Status.isRejected: Boolean
|
val RemoteRefUpdate.Status.isRejected: Boolean
|
@ -1,6 +1,6 @@
|
|||||||
package com.jetpackduba.gitnuro.git.remote_operations
|
package com.jetpackduba.gitnuro.git.remote_operations
|
||||||
|
|
||||||
import com.jetpackduba.gitnuro.git.CloneStatus
|
import com.jetpackduba.gitnuro.git.CloneState
|
||||||
import com.jetpackduba.gitnuro.logging.printDebug
|
import com.jetpackduba.gitnuro.logging.printDebug
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
@ -18,14 +18,14 @@ private const val TAG = "CloneRepositoryUseCase"
|
|||||||
class CloneRepositoryUseCase @Inject constructor(
|
class CloneRepositoryUseCase @Inject constructor(
|
||||||
private val handleTransportUseCase: HandleTransportUseCase,
|
private val handleTransportUseCase: HandleTransportUseCase,
|
||||||
) {
|
) {
|
||||||
operator fun invoke(directory: File, url: String, cloneSubmodules: Boolean): Flow<CloneStatus> = callbackFlow {
|
operator fun invoke(directory: File, url: String, cloneSubmodules: Boolean): Flow<CloneState> = callbackFlow {
|
||||||
var lastTitle: String = ""
|
var lastTitle: String = ""
|
||||||
var lastTotalWork = 0
|
var lastTotalWork = 0
|
||||||
var progress = 0
|
var progress = 0
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ensureActive()
|
ensureActive()
|
||||||
trySend(CloneStatus.Cloning("Starting...", progress, lastTotalWork))
|
trySend(CloneState.Cloning("Starting...", progress, lastTotalWork))
|
||||||
|
|
||||||
Git.cloneRepository()
|
Git.cloneRepository()
|
||||||
.setDirectory(directory)
|
.setDirectory(directory)
|
||||||
@ -41,7 +41,7 @@ class CloneRepositoryUseCase @Inject constructor(
|
|||||||
lastTitle = title.orEmpty()
|
lastTitle = title.orEmpty()
|
||||||
lastTotalWork = totalWork
|
lastTotalWork = totalWork
|
||||||
progress = 0
|
progress = 0
|
||||||
trySend(CloneStatus.Cloning(lastTitle, progress, lastTotalWork))
|
trySend(CloneState.Cloning(lastTitle, progress, lastTotalWork))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun update(completed: Int) {
|
override fun update(completed: Int) {
|
||||||
@ -49,7 +49,7 @@ class CloneRepositoryUseCase @Inject constructor(
|
|||||||
ensureActive()
|
ensureActive()
|
||||||
|
|
||||||
progress += completed
|
progress += completed
|
||||||
trySend(CloneStatus.Cloning(lastTitle, progress, lastTotalWork))
|
trySend(CloneState.Cloning(lastTitle, progress, lastTotalWork))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun endTask() {
|
override fun endTask() {
|
||||||
@ -68,13 +68,13 @@ class CloneRepositoryUseCase @Inject constructor(
|
|||||||
.call()
|
.call()
|
||||||
|
|
||||||
ensureActive()
|
ensureActive()
|
||||||
trySend(CloneStatus.Completed(directory))
|
trySend(CloneState.Completed(directory))
|
||||||
channel.close()
|
channel.close()
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
if (ex.cause?.cause is CancellationException) {
|
if (ex.cause?.cause is CancellationException) {
|
||||||
printDebug(TAG, "Clone cancelled")
|
printDebug(TAG, "Clone cancelled")
|
||||||
} else {
|
} else {
|
||||||
trySend(CloneStatus.Fail(ex.localizedMessage))
|
trySend(CloneState.Fail(ex.localizedMessage))
|
||||||
}
|
}
|
||||||
|
|
||||||
channel.close()
|
channel.close()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.jetpackduba.gitnuro.ui.dialogs
|
package com.jetpackduba.gitnuro.ui.dialogs
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.animateContentSize
|
import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
@ -20,7 +21,7 @@ import androidx.compose.ui.graphics.Color
|
|||||||
import androidx.compose.ui.graphics.Shape
|
import androidx.compose.ui.graphics.Shape
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
import com.jetpackduba.gitnuro.extensions.handMouseClickable
|
||||||
import com.jetpackduba.gitnuro.git.CloneStatus
|
import com.jetpackduba.gitnuro.git.CloneState
|
||||||
import com.jetpackduba.gitnuro.theme.outlinedTextFieldColors
|
import com.jetpackduba.gitnuro.theme.outlinedTextFieldColors
|
||||||
|
|
||||||
import com.jetpackduba.gitnuro.theme.textButtonColors
|
import com.jetpackduba.gitnuro.theme.textButtonColors
|
||||||
@ -36,7 +37,7 @@ fun CloneDialog(
|
|||||||
onClose: () -> Unit,
|
onClose: () -> Unit,
|
||||||
onOpenRepository: (File) -> Unit,
|
onOpenRepository: (File) -> Unit,
|
||||||
) {
|
) {
|
||||||
val cloneStatus = cloneViewModel.cloneStatus.collectAsState()
|
val cloneStatus = cloneViewModel.cloneState.collectAsState()
|
||||||
val cloneStatusValue = cloneStatus.value
|
val cloneStatusValue = cloneStatus.value
|
||||||
|
|
||||||
MaterialDialog(
|
MaterialDialog(
|
||||||
@ -46,30 +47,29 @@ fun CloneDialog(
|
|||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(720.dp)
|
.width(720.dp)
|
||||||
.height(280.dp)
|
|
||||||
.animateContentSize()
|
.animateContentSize()
|
||||||
) {
|
) {
|
||||||
when (cloneStatusValue) {
|
when (cloneStatusValue) {
|
||||||
is CloneStatus.Cloning -> {
|
is CloneState.Cloning -> {
|
||||||
Cloning(cloneViewModel, cloneStatusValue)
|
Cloning(cloneViewModel, cloneStatusValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
is CloneStatus.Cancelling -> {
|
is CloneState.Cancelling -> {
|
||||||
Cancelling()
|
Cancelling()
|
||||||
}
|
}
|
||||||
|
|
||||||
is CloneStatus.Completed -> {
|
is CloneState.Completed -> {
|
||||||
onOpenRepository(cloneStatusValue.repoDir)
|
onOpenRepository(cloneStatusValue.repoDir)
|
||||||
onClose()
|
onClose()
|
||||||
}
|
}
|
||||||
|
|
||||||
is CloneStatus.Fail -> CloneInput(
|
is CloneState.Fail -> CloneInput(
|
||||||
cloneViewModel = cloneViewModel,
|
cloneViewModel = cloneViewModel,
|
||||||
onClose = onClose,
|
onClose = onClose,
|
||||||
errorMessage = cloneStatusValue.reason
|
errorMessage = cloneStatusValue.reason
|
||||||
)
|
)
|
||||||
|
|
||||||
CloneStatus.None -> CloneInput(
|
CloneState.None -> CloneInput(
|
||||||
cloneViewModel = cloneViewModel,
|
cloneViewModel = cloneViewModel,
|
||||||
onClose = onClose,
|
onClose = onClose,
|
||||||
)
|
)
|
||||||
@ -94,10 +94,6 @@ private fun CloneInput(
|
|||||||
val cloneButtonFocusRequester = remember { FocusRequester() }
|
val cloneButtonFocusRequester = remember { FocusRequester() }
|
||||||
val cancelButtonFocusRequester = remember { FocusRequester() }
|
val cancelButtonFocusRequester = remember { FocusRequester() }
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
urlFocusRequester.requestFocus()
|
|
||||||
}
|
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
.padding(horizontal = 8.dp)
|
.padding(horizontal = 8.dp)
|
||||||
@ -133,7 +129,7 @@ private fun CloneInput(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
TextInput(
|
TextInput(
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.padding(top = 16.dp),
|
||||||
title = "Directory",
|
title = "Directory",
|
||||||
value = directory,
|
value = directory,
|
||||||
focusRequester = directoryFocusRequester,
|
focusRequester = directoryFocusRequester,
|
||||||
@ -204,7 +200,7 @@ private fun CloneInput(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorMessage != null) {
|
AnimatedVisibility (errorMessage != null) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@ -213,17 +209,15 @@ private fun CloneInput(
|
|||||||
.background(MaterialTheme.colors.error)
|
.background(MaterialTheme.colors.error)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
errorMessage,
|
errorMessage.orEmpty(),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(vertical = 4.dp, horizontal = 8.dp),
|
.padding(vertical = 4.dp, horizontal = 8.dp),
|
||||||
color = MaterialTheme.colors.onError,
|
color = MaterialTheme.colors.onError,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(Modifier.weight(1f))
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(top = 16.dp)
|
.padding(top = 16.dp)
|
||||||
@ -258,18 +252,18 @@ private fun CloneInput(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Cloning(cloneViewModel: CloneViewModel, cloneStatusValue: CloneStatus.Cloning) {
|
private fun Cloning(cloneViewModel: CloneViewModel, cloneStateValue: CloneState.Cloning) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize(),
|
.fillMaxWidth(),
|
||||||
) {
|
) {
|
||||||
val progress = remember(cloneStatusValue) {
|
val progress = remember(cloneStateValue) {
|
||||||
val total = cloneStatusValue.total
|
val total = cloneStateValue.total
|
||||||
|
|
||||||
if (total == 0) // Prevent division by 0
|
if (total == 0) // Prevent division by 0
|
||||||
-1f
|
-1f
|
||||||
else
|
else
|
||||||
cloneStatusValue.progress / total.toFloat()
|
cloneStateValue.progress / total.toFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
@ -278,7 +272,7 @@ private fun Cloning(cloneViewModel: CloneViewModel, cloneStatusValue: CloneStatu
|
|||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
Text(cloneStatusValue.taskName, color = MaterialTheme.colors.onBackground)
|
Text(cloneStateValue.taskName, color = MaterialTheme.colors.onBackground)
|
||||||
|
|
||||||
if (progress >= 0f)
|
if (progress >= 0f)
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
@ -318,7 +312,7 @@ private fun Cloning(cloneViewModel: CloneViewModel, cloneStatusValue: CloneStatu
|
|||||||
private fun Cancelling() {
|
private fun Cancelling() {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize(),
|
.fillMaxWidth(),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement.Center,
|
verticalArrangement = Arrangement.Center,
|
||||||
) {
|
) {
|
||||||
@ -346,23 +340,19 @@ private fun TextInput(
|
|||||||
onValueChange: (String) -> Unit,
|
onValueChange: (String) -> Unit,
|
||||||
textFieldShape: Shape = RoundedCornerShape(4.dp),
|
textFieldShape: Shape = RoundedCornerShape(4.dp),
|
||||||
) {
|
) {
|
||||||
Row(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier,
|
||||||
.padding(vertical = 8.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = title,
|
text = title,
|
||||||
style = MaterialTheme.typography.body1,
|
style = MaterialTheme.typography.body1,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(100.dp)
|
.padding(bottom = 8.dp),
|
||||||
.padding(end = 16.dp),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
AdjustableOutlinedTextField(
|
AdjustableOutlinedTextField(
|
||||||
value = value,
|
value = value,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
|
||||||
.focusRequester(focusRequester)
|
.focusRequester(focusRequester)
|
||||||
.focusProperties(focusProperties),
|
.focusProperties(focusProperties),
|
||||||
enabled = enabled,
|
enabled = enabled,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package com.jetpackduba.gitnuro.viewmodels
|
package com.jetpackduba.gitnuro.viewmodels
|
||||||
|
|
||||||
import com.jetpackduba.gitnuro.git.CloneStatus
|
import com.jetpackduba.gitnuro.git.CloneState
|
||||||
import com.jetpackduba.gitnuro.git.TabState
|
import com.jetpackduba.gitnuro.git.TabState
|
||||||
import com.jetpackduba.gitnuro.git.remote_operations.CloneRepositoryUseCase
|
import com.jetpackduba.gitnuro.git.remote_operations.CloneRepositoryUseCase
|
||||||
import com.jetpackduba.gitnuro.system.OpenFilePickerUseCase
|
import com.jetpackduba.gitnuro.system.OpenFilePickerUseCase
|
||||||
@ -20,9 +20,9 @@ class CloneViewModel @Inject constructor(
|
|||||||
private val openFilePickerUseCase: OpenFilePickerUseCase,
|
private val openFilePickerUseCase: OpenFilePickerUseCase,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val _cloneStatus = MutableStateFlow<CloneStatus>(CloneStatus.None)
|
private val _cloneState = MutableStateFlow<CloneState>(CloneState.None)
|
||||||
val cloneStatus: StateFlow<CloneStatus>
|
val cloneState: StateFlow<CloneState>
|
||||||
get() = _cloneStatus
|
get() = _cloneState
|
||||||
|
|
||||||
var url: String = ""
|
var url: String = ""
|
||||||
var directory: String = ""
|
var directory: String = ""
|
||||||
@ -32,12 +32,12 @@ class CloneViewModel @Inject constructor(
|
|||||||
fun clone(directoryPath: String, url: String, cloneSubmodules: Boolean) {
|
fun clone(directoryPath: String, url: String, cloneSubmodules: Boolean) {
|
||||||
cloneJob = tabState.safeProcessingWithoutGit {
|
cloneJob = tabState.safeProcessingWithoutGit {
|
||||||
if (directoryPath.isBlank()) {
|
if (directoryPath.isBlank()) {
|
||||||
_cloneStatus.value = CloneStatus.Fail("Invalid empty directory")
|
_cloneState.value = CloneState.Fail("Invalid empty directory")
|
||||||
return@safeProcessingWithoutGit
|
return@safeProcessingWithoutGit
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.isBlank()) {
|
if (url.isBlank()) {
|
||||||
_cloneStatus.value = CloneStatus.Fail("Invalid empty URL")
|
_cloneState.value = CloneState.Fail("Invalid empty URL")
|
||||||
return@safeProcessingWithoutGit
|
return@safeProcessingWithoutGit
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ class CloneViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (repoName.isNullOrBlank()) {
|
if (repoName.isNullOrBlank()) {
|
||||||
_cloneStatus.value = CloneStatus.Fail("Check your URL and try again")
|
_cloneState.value = CloneState.Fail("Check your URL and try again")
|
||||||
return@safeProcessingWithoutGit
|
return@safeProcessingWithoutGit
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,25 +75,25 @@ class CloneViewModel @Inject constructor(
|
|||||||
cloneRepositoryUseCase(repoDir, url, cloneSubmodules)
|
cloneRepositoryUseCase(repoDir, url, cloneSubmodules)
|
||||||
.flowOn(Dispatchers.IO)
|
.flowOn(Dispatchers.IO)
|
||||||
.collect { newCloneStatus ->
|
.collect { newCloneStatus ->
|
||||||
_cloneStatus.value = newCloneStatus
|
_cloneState.value = newCloneStatus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
_cloneStatus.value = CloneStatus.None
|
_cloneState.value = CloneState.None
|
||||||
url = ""
|
url = ""
|
||||||
directory = ""
|
directory = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
fun cancelClone() = tabState.safeProcessingWithoutGit {
|
fun cancelClone() = tabState.safeProcessingWithoutGit {
|
||||||
_cloneStatus.value = CloneStatus.Cancelling
|
_cloneState.value = CloneState.Cancelling
|
||||||
cloneJob?.cancelAndJoin()
|
cloneJob?.cancelAndJoin()
|
||||||
_cloneStatus.value = CloneStatus.None
|
_cloneState.value = CloneState.None
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resetStateIfError() {
|
fun resetStateIfError() {
|
||||||
_cloneStatus.value = CloneStatus.None
|
_cloneState.value = CloneState.None
|
||||||
}
|
}
|
||||||
|
|
||||||
fun openDirectoryPicker(): String? {
|
fun openDirectoryPicker(): String? {
|
||||||
|
Loading…
Reference in New Issue
Block a user