mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-07-02 10:16:03 +02:00
113 lines
3.3 KiB
Kotlin
113 lines
3.3 KiB
Kotlin
![]() |
package eu.kanade.presentation.category.repos
|
||
|
|
||
|
import androidx.compose.runtime.Immutable
|
||
|
import cafe.adriel.voyager.core.model.StateScreenModel
|
||
|
import cafe.adriel.voyager.core.model.screenModelScope
|
||
|
import dev.icerock.moko.resources.StringResource
|
||
|
import eu.kanade.domain.source.interactor.CreateSourceRepo
|
||
|
import eu.kanade.domain.source.interactor.DeleteSourceRepos
|
||
|
import eu.kanade.domain.source.interactor.GetSourceRepos
|
||
|
import kotlinx.collections.immutable.ImmutableList
|
||
|
import kotlinx.collections.immutable.toImmutableList
|
||
|
import kotlinx.coroutines.channels.Channel
|
||
|
import kotlinx.coroutines.flow.collectLatest
|
||
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||
|
import kotlinx.coroutines.flow.update
|
||
|
import tachiyomi.core.util.lang.launchIO
|
||
|
import tachiyomi.i18n.MR
|
||
|
import uy.kohesive.injekt.Injekt
|
||
|
import uy.kohesive.injekt.api.get
|
||
|
|
||
|
class RepoScreenModel(
|
||
|
private val getSourceRepos: GetSourceRepos = Injekt.get(),
|
||
|
private val createSourceRepo: CreateSourceRepo = Injekt.get(),
|
||
|
private val deleteSourceRepos: DeleteSourceRepos = Injekt.get(),
|
||
|
) : StateScreenModel<RepoScreenState>(RepoScreenState.Loading) {
|
||
|
|
||
|
private val _events: Channel<RepoEvent> = Channel(Int.MAX_VALUE)
|
||
|
val events = _events.receiveAsFlow()
|
||
|
|
||
|
init {
|
||
|
screenModelScope.launchIO {
|
||
|
getSourceRepos.subscribe()
|
||
|
.collectLatest { repos ->
|
||
|
mutableState.update {
|
||
|
RepoScreenState.Success(
|
||
|
repos = repos.toImmutableList(),
|
||
|
)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Creates and adds a new repo to the database.
|
||
|
*
|
||
|
* @param name The name of the repo to create.
|
||
|
*/
|
||
|
fun createRepo(name: String) {
|
||
|
screenModelScope.launchIO {
|
||
|
when (createSourceRepo.await(name)) {
|
||
|
is CreateSourceRepo.Result.InvalidName -> _events.send(RepoEvent.InvalidName)
|
||
|
else -> {}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Deletes the given repos from the database.
|
||
|
*
|
||
|
* @param repos The list of repos to delete.
|
||
|
*/
|
||
|
fun deleteRepos(repos: List<String>) {
|
||
|
screenModelScope.launchIO {
|
||
|
deleteSourceRepos.await(repos)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fun showDialog(dialog: RepoDialog) {
|
||
|
mutableState.update {
|
||
|
when (it) {
|
||
|
RepoScreenState.Loading -> it
|
||
|
is RepoScreenState.Success -> it.copy(dialog = dialog)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fun dismissDialog() {
|
||
|
mutableState.update {
|
||
|
when (it) {
|
||
|
RepoScreenState.Loading -> it
|
||
|
is RepoScreenState.Success -> it.copy(dialog = null)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
sealed class RepoEvent {
|
||
|
sealed class LocalizedMessage(val stringRes: StringResource) : RepoEvent()
|
||
|
data object InvalidName : LocalizedMessage(MR.strings.invalid_repo_name)
|
||
|
data object InternalError : LocalizedMessage(MR.strings.internal_error)
|
||
|
}
|
||
|
|
||
|
sealed class RepoDialog {
|
||
|
data object Create : RepoDialog()
|
||
|
data class Delete(val repo: String) : RepoDialog()
|
||
|
}
|
||
|
|
||
|
sealed class RepoScreenState {
|
||
|
|
||
|
@Immutable
|
||
|
data object Loading : RepoScreenState()
|
||
|
|
||
|
@Immutable
|
||
|
data class Success(
|
||
|
val repos: ImmutableList<String>,
|
||
|
val dialog: RepoDialog? = null,
|
||
|
) : RepoScreenState() {
|
||
|
|
||
|
val isEmpty: Boolean
|
||
|
get() = repos.isEmpty()
|
||
|
}
|
||
|
}
|