Gitnuro/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/CloneViewModel.kt
2023-04-17 17:03:06 +02:00

102 lines
3.3 KiB
Kotlin

package com.jetpackduba.gitnuro.viewmodels
import com.jetpackduba.gitnuro.git.CloneStatus
import com.jetpackduba.gitnuro.git.TabState
import com.jetpackduba.gitnuro.git.remote_operations.CloneRepositoryUseCase
import com.jetpackduba.gitnuro.system.OpenFilePickerUseCase
import com.jetpackduba.gitnuro.system.PickerType
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flowOn
import java.io.File
import javax.inject.Inject
class CloneViewModel @Inject constructor(
private val tabState: TabState,
private val cloneRepositoryUseCase: CloneRepositoryUseCase,
private val openFilePickerUseCase: OpenFilePickerUseCase,
) {
private val _cloneStatus = MutableStateFlow<CloneStatus>(CloneStatus.None)
val cloneStatus: StateFlow<CloneStatus>
get() = _cloneStatus
var url: String = ""
var directory: String = ""
private var cloneJob: Job? = null
fun clone(directoryPath: String, url: String, cloneSubmodules: Boolean) {
cloneJob = tabState.safeProcessingWithoutGit {
if (directoryPath.isBlank()) {
_cloneStatus.value = CloneStatus.Fail("Invalid empty directory")
return@safeProcessingWithoutGit
}
if (url.isBlank()) {
_cloneStatus.value = CloneStatus.Fail("Invalid empty URL")
return@safeProcessingWithoutGit
}
val urlSplit = url.split("/", "\\").toMutableList()
// Removes the last element for URLs that end with "/" or "\" instead of the repo name like https://github.com/JetpackDuba/Gitnuro/
if (urlSplit.isNotEmpty() && urlSplit.last().isBlank()) {
urlSplit.removeLast()
}
// Take the last element of the path/URL to generate obtain the repo name
var repoName = urlSplit.lastOrNull()
if (repoName?.endsWith(".git") == true) {
repoName = repoName.removeSuffix(".git")
}
if (repoName.isNullOrBlank()) {
_cloneStatus.value = CloneStatus.Fail("Check your URL and try again")
return@safeProcessingWithoutGit
}
val directory = File(directoryPath)
if (!directory.exists()) {
directory.mkdirs()
}
val repoDir = File(directory, repoName)
if (!repoDir.exists()) {
repoDir.mkdir()
}
cloneRepositoryUseCase(repoDir, url, cloneSubmodules)
.flowOn(Dispatchers.IO)
.collect { newCloneStatus ->
_cloneStatus.value = newCloneStatus
}
}
}
fun reset() {
_cloneStatus.value = CloneStatus.None
url = ""
directory = ""
}
fun cancelClone() = tabState.safeProcessingWithoutGit {
_cloneStatus.value = CloneStatus.Cancelling
cloneJob?.cancelAndJoin()
_cloneStatus.value = CloneStatus.None
}
fun resetStateIfError() {
_cloneStatus.value = CloneStatus.None
}
fun openDirectoryPicker(): String? {
return openFilePickerUseCase(PickerType.DIRECTORIES, null)
}
}