148268571e
(cherry picked from commit e3cf8632305283468a5e8366a257d6d6880ca1a6) # Conflicts: # app/src/main/java/eu/kanade/presentation/browse/ExtensionsScreen.kt # app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsMainScreen.kt # app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/details/SourcePreferencesScreen.kt # app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SourceSearchScreen.kt # app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryTab.kt # app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
191 lines
7.2 KiB
Kotlin
Executable File
191 lines
7.2 KiB
Kotlin
Executable File
package exh.ui.intercept
|
|
|
|
import android.content.Intent
|
|
import android.os.Bundle
|
|
import androidx.compose.foundation.layout.Arrangement
|
|
import androidx.compose.foundation.layout.Column
|
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
import androidx.compose.foundation.layout.padding
|
|
import androidx.compose.foundation.layout.size
|
|
import androidx.compose.material3.CircularProgressIndicator
|
|
import androidx.compose.material3.MaterialTheme
|
|
import androidx.compose.material3.Text
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.collectAsState
|
|
import androidx.compose.ui.Alignment
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.res.stringResource
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.lifecycle.lifecycleScope
|
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
import eu.kanade.presentation.components.AppBar
|
|
import eu.kanade.tachiyomi.R
|
|
import eu.kanade.tachiyomi.source.online.UrlImportableSource
|
|
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
|
|
import eu.kanade.tachiyomi.ui.main.MainActivity
|
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
|
import eu.kanade.tachiyomi.util.view.setComposeContent
|
|
import exh.GalleryAddEvent
|
|
import exh.GalleryAdder
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.Job
|
|
import kotlinx.coroutines.flow.MutableStateFlow
|
|
import kotlinx.coroutines.flow.launchIn
|
|
import kotlinx.coroutines.flow.onEach
|
|
import kotlinx.coroutines.launch
|
|
import tachiyomi.core.Constants
|
|
import tachiyomi.domain.chapter.model.Chapter
|
|
import tachiyomi.domain.manga.model.Manga
|
|
import tachiyomi.presentation.core.components.material.Scaffold
|
|
|
|
class InterceptActivity : BaseActivity() {
|
|
private var statusJob: Job? = null
|
|
|
|
private val status: MutableStateFlow<InterceptResult> = MutableStateFlow(InterceptResult.Idle)
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
overridePendingTransition(R.anim.shared_axis_x_push_enter, R.anim.shared_axis_x_push_exit)
|
|
super.onCreate(savedInstanceState)
|
|
|
|
setComposeContent {
|
|
InterceptActivityContent(status.collectAsState().value)
|
|
}
|
|
|
|
processLink()
|
|
}
|
|
|
|
@Composable
|
|
private fun InterceptActivityContent(status: InterceptResult) {
|
|
Scaffold(
|
|
topBar = { scrollBehavior ->
|
|
AppBar(
|
|
title = stringResource(R.string.app_name),
|
|
navigateUp = ::onBackPressed,
|
|
scrollBehavior = scrollBehavior,
|
|
)
|
|
},
|
|
) {
|
|
Column(
|
|
modifier = Modifier
|
|
.fillMaxSize()
|
|
.padding(it),
|
|
horizontalAlignment = Alignment.CenterHorizontally,
|
|
verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically),
|
|
) {
|
|
when (status) {
|
|
InterceptResult.Idle, InterceptResult.Loading -> {
|
|
Text(
|
|
text = stringResource(R.string.loading_entry),
|
|
style = MaterialTheme.typography.titleLarge,
|
|
)
|
|
CircularProgressIndicator(modifier = Modifier.size(56.dp))
|
|
}
|
|
is InterceptResult.Success -> Text(
|
|
text = stringResource(R.string.launching_app),
|
|
style = MaterialTheme.typography.titleLarge,
|
|
)
|
|
is InterceptResult.Failure -> Text(
|
|
text = stringResource(R.string.error_with_reason, status.reason),
|
|
style = MaterialTheme.typography.titleLarge,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun processLink() {
|
|
if (Intent.ACTION_VIEW == intent.action) {
|
|
loadGallery(intent.dataString!!)
|
|
}
|
|
}
|
|
|
|
override fun onStart() {
|
|
super.onStart()
|
|
statusJob?.cancel()
|
|
statusJob = status
|
|
.onEach {
|
|
when (it) {
|
|
is InterceptResult.Success -> {
|
|
onBackPressed()
|
|
startActivity(
|
|
if (it.chapter != null) {
|
|
ReaderActivity.newIntent(this, it.manga.id, it.chapter.id)
|
|
} else {
|
|
Intent(this, MainActivity::class.java)
|
|
.setAction(Constants.SHORTCUT_MANGA)
|
|
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
|
.putExtra(Constants.MANGA_EXTRA, it.mangaId)
|
|
},
|
|
)
|
|
}
|
|
is InterceptResult.Failure -> {
|
|
MaterialAlertDialogBuilder(this)
|
|
.setTitle(R.string.chapter_error)
|
|
.setMessage(getString(R.string.could_not_open_entry, it.reason))
|
|
.setPositiveButton(android.R.string.ok, null)
|
|
.setOnCancelListener { onBackPressed() }
|
|
.setOnDismissListener { onBackPressed() }
|
|
.show()
|
|
}
|
|
else -> Unit
|
|
}
|
|
}
|
|
.launchIn(lifecycleScope)
|
|
}
|
|
|
|
override fun onStop() {
|
|
super.onStop()
|
|
statusJob?.cancel()
|
|
}
|
|
|
|
override fun finish() {
|
|
super.finish()
|
|
overridePendingTransition(R.anim.shared_axis_x_pop_enter, R.anim.shared_axis_x_pop_exit)
|
|
}
|
|
|
|
private val galleryAdder = GalleryAdder()
|
|
|
|
@Synchronized
|
|
fun loadGallery(gallery: String) {
|
|
// Do not load gallery if already loading
|
|
if (status.value is InterceptResult.Idle) {
|
|
status.value = InterceptResult.Loading
|
|
val sources = galleryAdder.pickSource(gallery)
|
|
if (sources.size > 1) {
|
|
MaterialAlertDialogBuilder(this)
|
|
.setTitle(R.string.label_sources)
|
|
.setSingleChoiceItems(sources.map { it.toString() }.toTypedArray(), 0) { dialog, index ->
|
|
dialog.dismiss()
|
|
loadGalleryEnd(gallery, sources[index])
|
|
}
|
|
.show()
|
|
} else {
|
|
loadGalleryEnd(gallery)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun loadGalleryEnd(gallery: String, source: UrlImportableSource? = null) {
|
|
// Load gallery async
|
|
lifecycleScope.launch(Dispatchers.IO) {
|
|
val result = galleryAdder.addGallery(this@InterceptActivity, gallery, forceSource = source)
|
|
|
|
status.value = when (result) {
|
|
is GalleryAddEvent.Success -> InterceptResult.Success(result.manga.id, result.manga, result.chapter)
|
|
is GalleryAddEvent.Fail -> InterceptResult.Failure(result.logMessage)
|
|
}
|
|
}
|
|
}
|
|
|
|
init {
|
|
registerSecureActivity(this)
|
|
}
|
|
}
|
|
|
|
sealed class InterceptResult {
|
|
object Idle : InterceptResult()
|
|
object Loading : InterceptResult()
|
|
data class Success(val mangaId: Long, val manga: Manga, val chapter: Chapter? = null) : InterceptResult()
|
|
data class Failure(val reason: String) : InterceptResult()
|
|
}
|