59a6fd7dca
(cherry picked from commit 012854dd1e13eedecd92419fd6a4d1d5cc900462) # Conflicts: # app/src/main/java/eu/kanade/presentation/browse/BrowseSourceScreen.kt # app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesScreenModel.kt # app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt # app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsScreenModel.kt # app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt # app/src/main/java/eu/kanade/tachiyomi/ui/stats/StatsScreenModel.kt
149 lines
4.7 KiB
Kotlin
149 lines
4.7 KiB
Kotlin
package exh.ui.batchadd
|
|
|
|
import android.content.Context
|
|
import cafe.adriel.voyager.core.model.StateScreenModel
|
|
import cafe.adriel.voyager.core.model.screenModelScope
|
|
import eu.kanade.tachiyomi.R
|
|
import exh.GalleryAddEvent
|
|
import exh.GalleryAdder
|
|
import exh.log.xLogE
|
|
import exh.util.trimOrNull
|
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.ensureActive
|
|
import kotlinx.coroutines.flow.update
|
|
import kotlinx.coroutines.launch
|
|
import tachiyomi.core.util.lang.withIOContext
|
|
import tachiyomi.domain.UnsortedPreferences
|
|
import uy.kohesive.injekt.Injekt
|
|
import uy.kohesive.injekt.api.get
|
|
|
|
class BatchAddScreenModel(
|
|
private val unsortedPreferences: UnsortedPreferences = Injekt.get(),
|
|
) : StateScreenModel<BatchAddState>(BatchAddState()) {
|
|
private val galleryAdder by lazy { GalleryAdder() }
|
|
|
|
fun addGalleries(context: Context) {
|
|
val galleries = state.value.galleries
|
|
// Check text box has content
|
|
if (galleries.isBlank()) {
|
|
mutableState.update { it.copy(dialog = Dialog.NoGalleriesSpecified) }
|
|
return
|
|
}
|
|
|
|
addGalleries(context, galleries)
|
|
}
|
|
|
|
private fun addGalleries(context: Context, galleries: String) {
|
|
val splitGalleries = if (ehVisitedRegex.containsMatchIn(galleries)) {
|
|
val url = if (unsortedPreferences.enableExhentai().get()) {
|
|
"https://exhentai.org/g/"
|
|
} else {
|
|
"https://e-hentai.org/g/"
|
|
}
|
|
ehVisitedRegex.findAll(galleries).map { galleryKeys ->
|
|
val linkParts = galleryKeys.value.split(".")
|
|
url + linkParts[0] + "/" + linkParts[1].replace(":", "")
|
|
}.toList()
|
|
} else {
|
|
galleries.split("\n")
|
|
.mapNotNull(String::trimOrNull)
|
|
}
|
|
|
|
mutableState.update { state ->
|
|
state.copy(
|
|
progress = 0,
|
|
progressTotal = splitGalleries.size,
|
|
state = State.PROGRESS,
|
|
)
|
|
}
|
|
|
|
val handler = CoroutineExceptionHandler { _, throwable ->
|
|
xLogE("Batch add error", throwable)
|
|
}
|
|
|
|
screenModelScope.launch(Dispatchers.IO + handler) {
|
|
val succeeded = mutableListOf<String>()
|
|
val failed = mutableListOf<String>()
|
|
|
|
splitGalleries.forEachIndexed { i, s ->
|
|
ensureActive()
|
|
val result = withIOContext {
|
|
galleryAdder.addGallery(
|
|
context = context,
|
|
url = s,
|
|
fav = true,
|
|
retry = 2,
|
|
)
|
|
}
|
|
if (result is GalleryAddEvent.Success) {
|
|
succeeded.add(s)
|
|
} else {
|
|
failed.add(s)
|
|
}
|
|
mutableState.update { state ->
|
|
state.copy(
|
|
progress = i + 1,
|
|
events = state.events.plus(
|
|
when (result) {
|
|
is GalleryAddEvent.Success -> context.getString(R.string.batch_add_ok)
|
|
is GalleryAddEvent.Fail -> context.getString(R.string.batch_add_error)
|
|
} + " " + result.logMessage,
|
|
),
|
|
)
|
|
}
|
|
}
|
|
|
|
// Show report
|
|
val summary = context.getString(R.string.batch_add_summary, succeeded.size, failed.size)
|
|
mutableState.update { state ->
|
|
state.copy(
|
|
events = state.events + summary,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
fun finish() {
|
|
mutableState.update { state ->
|
|
state.copy(
|
|
progressTotal = 0,
|
|
progress = 0,
|
|
galleries = "",
|
|
state = State.INPUT,
|
|
events = emptyList(),
|
|
)
|
|
}
|
|
}
|
|
|
|
fun updateGalleries(galleries: String) {
|
|
mutableState.update { it.copy(galleries = galleries) }
|
|
}
|
|
|
|
fun dismissDialog() {
|
|
mutableState.update { it.copy(dialog = null) }
|
|
}
|
|
|
|
enum class State {
|
|
INPUT,
|
|
PROGRESS,
|
|
}
|
|
|
|
sealed class Dialog {
|
|
object NoGalleriesSpecified : Dialog()
|
|
}
|
|
|
|
companion object {
|
|
val ehVisitedRegex = """[0-9]*?\.[a-z0-9]*?:""".toRegex()
|
|
}
|
|
}
|
|
|
|
data class BatchAddState(
|
|
val progressTotal: Int = 0,
|
|
val progress: Int = 0,
|
|
val galleries: String = "",
|
|
val state: BatchAddScreenModel.State = BatchAddScreenModel.State.INPUT,
|
|
val events: List<String> = emptyList(),
|
|
val dialog: BatchAddScreenModel.Dialog? = null,
|
|
)
|