Fix multiple issues regarding sources loading too late
This commit is contained in:
parent
202900edf0
commit
31e5ba4caf
@ -18,6 +18,7 @@ import kotlinx.coroutines.ensureActive
|
|||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.debounce
|
import kotlinx.coroutines.flow.debounce
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.onStart
|
import kotlinx.coroutines.flow.onStart
|
||||||
@ -336,19 +337,15 @@ class DownloadCache(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to wait until extensions and sources have loaded
|
// Try to wait until extensions and sources have loaded
|
||||||
var sources = getSources()
|
// SY -->
|
||||||
if (sources.isEmpty()) {
|
var sources = emptyList<Source>()
|
||||||
withTimeoutOrNull(30.seconds) {
|
withTimeoutOrNull(30.seconds) {
|
||||||
while (!extensionManager.isInitialized) {
|
extensionManager.isInitialized.first { it }
|
||||||
delay(2.seconds)
|
sourceManager.isInitialized.first { it }
|
||||||
}
|
|
||||||
|
|
||||||
while (extensionManager.availableExtensionsFlow.value.isNotEmpty() && sources.isEmpty()) {
|
|
||||||
delay(2.seconds)
|
|
||||||
sources = getSources()
|
sources = getSources()
|
||||||
}
|
}
|
||||||
}
|
// SY <--
|
||||||
}
|
|
||||||
|
|
||||||
val sourceMap = sources.associate { provider.getSourceDirName(it).lowercase() to it.id }
|
val sourceMap = sources.associate { provider.getSourceDirName(it).lowercase() to it.id }
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ import kotlinx.coroutines.async
|
|||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.emptyFlow
|
import kotlinx.coroutines.flow.emptyFlow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
@ -53,8 +54,10 @@ class ExtensionManager(
|
|||||||
private val trustExtension: TrustExtension = Injekt.get(),
|
private val trustExtension: TrustExtension = Injekt.get(),
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var isInitialized = false
|
// SY -->
|
||||||
private set
|
private val _isInitialized = MutableStateFlow(false)
|
||||||
|
val isInitialized: StateFlow<Boolean> = _isInitialized.asStateFlow()
|
||||||
|
// SY <--
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API where all the available extensions can be found.
|
* API where all the available extensions can be found.
|
||||||
@ -135,9 +138,9 @@ class ExtensionManager(
|
|||||||
.map { it.extension }
|
.map { it.extension }
|
||||||
// SY -->
|
// SY -->
|
||||||
.filterNotBlacklisted()
|
.filterNotBlacklisted()
|
||||||
// SY <--
|
|
||||||
|
|
||||||
isInitialized = true
|
_isInitialized.value = true
|
||||||
|
// SY <--
|
||||||
}
|
}
|
||||||
|
|
||||||
// EXH -->
|
// EXH -->
|
||||||
|
@ -29,6 +29,8 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
@ -103,6 +105,7 @@ class AndroidSourceManager(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sourcesMapFlow.value = mutableMap
|
sourcesMapFlow.value = mutableMap
|
||||||
|
_isInitialized.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +189,9 @@ class AndroidSourceManager(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SY -->
|
// SY -->
|
||||||
|
private val _isInitialized = MutableStateFlow(false)
|
||||||
|
override val isInitialized: StateFlow<Boolean> = _isInitialized.asStateFlow()
|
||||||
|
|
||||||
override fun getVisibleOnlineSources() = sourcesMapFlow.value.values
|
override fun getVisibleOnlineSources() = sourcesMapFlow.value.values
|
||||||
.filterIsInstance<HttpSource>()
|
.filterIsInstance<HttpSource>()
|
||||||
.filter {
|
.filter {
|
||||||
|
@ -39,8 +39,10 @@ import eu.kanade.tachiyomi.source.ConfigurableSource
|
|||||||
import eu.kanade.tachiyomi.source.sourcePreferences
|
import eu.kanade.tachiyomi.source.sourcePreferences
|
||||||
import eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText.Companion.setIncognito
|
import eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText.Companion.setIncognito
|
||||||
import exh.source.EnhancedHttpSource
|
import exh.source.EnhancedHttpSource
|
||||||
|
import exh.ui.ifSourcesLoaded
|
||||||
import tachiyomi.domain.source.service.SourceManager
|
import tachiyomi.domain.source.service.SourceManager
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
@ -48,6 +50,11 @@ class SourcePreferencesScreen(val sourceId: Long) : Screen() {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
|
|
||||||
@ -130,7 +137,7 @@ class SourcePreferencesFragment : PreferenceFragmentCompat() {
|
|||||||
// SY -->
|
// SY -->
|
||||||
val source = Injekt.get<SourceManager>()
|
val source = Injekt.get<SourceManager>()
|
||||||
.getOrStub(sourceId)
|
.getOrStub(sourceId)
|
||||||
?.let { source ->
|
.let { source ->
|
||||||
if (source is EnhancedHttpSource) {
|
if (source is EnhancedHttpSource) {
|
||||||
if (source.enhancedSource is ConfigurableSource) {
|
if (source.enhancedSource is ConfigurableSource) {
|
||||||
source.source()
|
source.source()
|
||||||
@ -141,7 +148,6 @@ class SourcePreferencesFragment : PreferenceFragmentCompat() {
|
|||||||
source
|
source
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?: throw NullPointerException("source = null, SOURCE_ID = $SOURCE_ID")
|
|
||||||
// SY <--
|
// SY <--
|
||||||
val sourceScreen = preferenceManager.createPreferenceScreen(requireContext())
|
val sourceScreen = preferenceManager.createPreferenceScreen(requireContext())
|
||||||
|
|
||||||
|
@ -22,10 +22,12 @@ import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel
|
|||||||
import eu.kanade.tachiyomi.ui.browse.source.browse.SourceFilterDialog
|
import eu.kanade.tachiyomi.ui.browse.source.browse.SourceFilterDialog
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
||||||
import eu.kanade.tachiyomi.ui.webview.WebViewScreen
|
import eu.kanade.tachiyomi.ui.webview.WebViewScreen
|
||||||
|
import exh.ui.ifSourcesLoaded
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import tachiyomi.core.common.Constants
|
import tachiyomi.core.common.Constants
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
import tachiyomi.source.local.LocalSource
|
import tachiyomi.source.local.LocalSource
|
||||||
|
|
||||||
data class SourceSearchScreen(
|
data class SourceSearchScreen(
|
||||||
@ -36,6 +38,11 @@ data class SourceSearchScreen(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val uriHandler = LocalUriHandler.current
|
val uriHandler = LocalUriHandler.current
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
|||||||
import eu.kanade.tachiyomi.ui.webview.WebViewScreen
|
import eu.kanade.tachiyomi.ui.webview.WebViewScreen
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import exh.md.follows.MangaDexFollowsScreen
|
import exh.md.follows.MangaDexFollowsScreen
|
||||||
|
import exh.ui.ifSourcesLoaded
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.receiveAsFlow
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
@ -66,6 +67,7 @@ import tachiyomi.i18n.MR
|
|||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
import tachiyomi.presentation.core.components.material.padding
|
import tachiyomi.presentation.core.components.material.padding
|
||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
import tachiyomi.source.local.LocalSource
|
import tachiyomi.source.local.LocalSource
|
||||||
|
|
||||||
data class BrowseSourceScreen(
|
data class BrowseSourceScreen(
|
||||||
@ -84,6 +86,11 @@ data class BrowseSourceScreen(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val screenModel = rememberScreenModel {
|
val screenModel = rememberScreenModel {
|
||||||
BrowseSourceScreenModel(
|
BrowseSourceScreenModel(
|
||||||
sourceId = sourceId,
|
sourceId = sourceId,
|
||||||
|
@ -19,15 +19,22 @@ import eu.kanade.tachiyomi.ui.browse.source.browse.SourceFilterDialog
|
|||||||
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import exh.md.follows.MangaDexFollowsScreen
|
import exh.md.follows.MangaDexFollowsScreen
|
||||||
|
import exh.ui.ifSourcesLoaded
|
||||||
import exh.util.nullIfBlank
|
import exh.util.nullIfBlank
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.domain.source.interactor.GetRemoteManga
|
import tachiyomi.domain.source.interactor.GetRemoteManga
|
||||||
import tachiyomi.domain.source.model.SavedSearch
|
import tachiyomi.domain.source.model.SavedSearch
|
||||||
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
|
|
||||||
class SourceFeedScreen(val sourceId: Long) : Screen() {
|
class SourceFeedScreen(val sourceId: Long) : Screen() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val screenModel = rememberScreenModel { SourceFeedScreenModel(sourceId) }
|
val screenModel = rememberScreenModel { SourceFeedScreenModel(sourceId) }
|
||||||
val state by screenModel.state.collectAsState()
|
val state by screenModel.state.collectAsState()
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
|
@ -14,6 +14,7 @@ import eu.kanade.presentation.browse.GlobalSearchScreen
|
|||||||
import eu.kanade.presentation.util.Screen
|
import eu.kanade.presentation.util.Screen
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreen
|
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreen
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
||||||
|
import exh.ui.ifSourcesLoaded
|
||||||
import tachiyomi.presentation.core.screens.LoadingScreen
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
|
|
||||||
class GlobalSearchScreen(
|
class GlobalSearchScreen(
|
||||||
@ -23,6 +24,11 @@ class GlobalSearchScreen(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
|
|
||||||
val screenModel = rememberScreenModel {
|
val screenModel = rememberScreenModel {
|
||||||
|
@ -64,6 +64,7 @@ import exh.recs.RecommendsScreen
|
|||||||
import exh.source.MERGED_SOURCE_ID
|
import exh.source.MERGED_SOURCE_ID
|
||||||
import exh.source.getMainSource
|
import exh.source.getMainSource
|
||||||
import exh.source.isMdBasedSource
|
import exh.source.isMdBasedSource
|
||||||
|
import exh.ui.ifSourcesLoaded
|
||||||
import exh.ui.metadata.MetadataViewScreen
|
import exh.ui.metadata.MetadataViewScreen
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
@ -98,6 +99,11 @@ class MangaScreen(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val haptic = LocalHapticFeedback.current
|
val haptic = LocalHapticFeedback.current
|
||||||
|
@ -91,6 +91,7 @@ import eu.kanade.tachiyomi.util.system.toShareIntent
|
|||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.util.view.setComposeContent
|
import eu.kanade.tachiyomi.util.view.setComposeContent
|
||||||
import exh.source.isEhBasedSource
|
import exh.source.isEhBasedSource
|
||||||
|
import exh.ui.ifSourcesLoaded
|
||||||
import exh.util.defaultReaderType
|
import exh.util.defaultReaderType
|
||||||
import exh.util.mangaType
|
import exh.util.mangaType
|
||||||
import kotlinx.collections.immutable.persistentSetOf
|
import kotlinx.collections.immutable.persistentSetOf
|
||||||
@ -391,6 +392,10 @@ class ReaderActivity : BaseActivity() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ifSourcesLoaded()) {
|
||||||
|
return@setComposeContent
|
||||||
|
}
|
||||||
|
|
||||||
val isHttpSource = viewModel.getSource() is HttpSource
|
val isHttpSource = viewModel.getSource() is HttpSource
|
||||||
val isFullscreen by readerPreferences.fullscreen().collectAsState()
|
val isFullscreen by readerPreferences.fullscreen().collectAsState()
|
||||||
val flashOnPageChange by readerPreferences.flashOnPageChange().collectAsState()
|
val flashOnPageChange by readerPreferences.flashOnPageChange().collectAsState()
|
||||||
|
@ -63,6 +63,7 @@ import kotlinx.coroutines.flow.asStateFlow
|
|||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.drop
|
import kotlinx.coroutines.flow.drop
|
||||||
import kotlinx.coroutines.flow.filterNotNull
|
import kotlinx.coroutines.flow.filterNotNull
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.mapLatest
|
import kotlinx.coroutines.flow.mapLatest
|
||||||
@ -336,6 +337,7 @@ class ReaderViewModel @JvmOverloads constructor(
|
|||||||
val manga = getManga.await(mangaId)
|
val manga = getManga.await(mangaId)
|
||||||
if (manga != null) {
|
if (manga != null) {
|
||||||
// SY -->
|
// SY -->
|
||||||
|
sourceManager.isInitialized.first { it }
|
||||||
val source = sourceManager.getOrStub(manga.source)
|
val source = sourceManager.getOrStub(manga.source)
|
||||||
val metadataSource = source.getMainSource<MetadataSource<*, *>>()
|
val metadataSource = source.getMainSource<MetadataSource<*, *>>()
|
||||||
val metadata = if (metadataSource != null) {
|
val metadata = if (metadataSource != null) {
|
||||||
|
@ -23,15 +23,22 @@ import eu.kanade.presentation.util.Screen
|
|||||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel
|
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel
|
||||||
import eu.kanade.tachiyomi.ui.category.CategoryScreen
|
import eu.kanade.tachiyomi.ui.category.CategoryScreen
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
||||||
|
import exh.ui.ifSourcesLoaded
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
import tachiyomi.core.common.util.lang.launchIO
|
||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
|
|
||||||
class MangaDexFollowsScreen(private val sourceId: Long) : Screen() {
|
class MangaDexFollowsScreen(private val sourceId: Long) : Screen() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val haptic = LocalHapticFeedback.current
|
val haptic = LocalHapticFeedback.current
|
||||||
|
@ -15,15 +15,22 @@ import eu.kanade.presentation.browse.BrowseSourceContent
|
|||||||
import eu.kanade.presentation.browse.components.BrowseSourceSimpleToolbar
|
import eu.kanade.presentation.browse.components.BrowseSourceSimpleToolbar
|
||||||
import eu.kanade.presentation.util.Screen
|
import eu.kanade.presentation.util.Screen
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
||||||
|
import exh.ui.ifSourcesLoaded
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
|
|
||||||
class MangaDexSimilarScreen(val mangaId: Long, val sourceId: Long) : Screen() {
|
class MangaDexSimilarScreen(val mangaId: Long, val sourceId: Long) : Screen() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val screenModel = rememberScreenModel { MangaDexSimilarScreenModel(mangaId, sourceId) }
|
val screenModel = rememberScreenModel { MangaDexSimilarScreenModel(mangaId, sourceId) }
|
||||||
val state by screenModel.state.collectAsState()
|
val state by screenModel.state.collectAsState()
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
|
@ -16,13 +16,20 @@ import eu.kanade.presentation.browse.BrowseSourceContent
|
|||||||
import eu.kanade.presentation.browse.components.BrowseSourceSimpleToolbar
|
import eu.kanade.presentation.browse.components.BrowseSourceSimpleToolbar
|
||||||
import eu.kanade.presentation.util.Screen
|
import eu.kanade.presentation.util.Screen
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen
|
import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen
|
||||||
|
import exh.ui.ifSourcesLoaded
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
|
|
||||||
class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() {
|
class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val screenModel = rememberScreenModel { RecommendsScreenModel(mangaId, sourceId) }
|
val screenModel = rememberScreenModel { RecommendsScreenModel(mangaId, sourceId) }
|
||||||
val state by screenModel.state.collectAsState()
|
val state by screenModel.state.collectAsState()
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
|
13
app/src/main/java/exh/ui/SourceUtil.kt
Normal file
13
app/src/main/java/exh/ui/SourceUtil.kt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package exh.ui
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import tachiyomi.domain.source.service.SourceManager
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ifSourcesLoaded(): Boolean {
|
||||||
|
return remember { Injekt.get<SourceManager>().isInitialized }.collectAsState().value
|
||||||
|
}
|
@ -28,19 +28,22 @@ import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
|||||||
import eu.kanade.tachiyomi.util.view.setComposeContent
|
import eu.kanade.tachiyomi.util.view.setComposeContent
|
||||||
import exh.GalleryAddEvent
|
import exh.GalleryAddEvent
|
||||||
import exh.GalleryAdder
|
import exh.GalleryAdder
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import tachiyomi.core.common.Constants
|
import tachiyomi.core.common.Constants
|
||||||
import tachiyomi.core.common.i18n.stringResource
|
import tachiyomi.core.common.i18n.stringResource
|
||||||
|
import tachiyomi.core.common.util.lang.launchIO
|
||||||
import tachiyomi.domain.chapter.model.Chapter
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.source.service.SourceManager
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
class InterceptActivity : BaseActivity() {
|
class InterceptActivity : BaseActivity() {
|
||||||
private var statusJob: Job? = null
|
private var statusJob: Job? = null
|
||||||
@ -108,9 +111,13 @@ class InterceptActivity : BaseActivity() {
|
|||||||
|
|
||||||
private fun processLink() {
|
private fun processLink() {
|
||||||
if (Intent.ACTION_VIEW == intent.action) {
|
if (Intent.ACTION_VIEW == intent.action) {
|
||||||
|
lifecycleScope.launchIO {
|
||||||
|
// wait for sources to load
|
||||||
|
Injekt.get<SourceManager>().isInitialized.first { it }
|
||||||
loadGallery(intent.dataString!!)
|
loadGallery(intent.dataString!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
@ -167,8 +174,7 @@ class InterceptActivity : BaseActivity() {
|
|||||||
|
|
||||||
private val galleryAdder = GalleryAdder()
|
private val galleryAdder = GalleryAdder()
|
||||||
|
|
||||||
@Synchronized
|
suspend fun loadGallery(gallery: String) {
|
||||||
fun loadGallery(gallery: String) {
|
|
||||||
// Do not load gallery if already loading
|
// Do not load gallery if already loading
|
||||||
if (status.value is InterceptResult.Idle) {
|
if (status.value is InterceptResult.Idle) {
|
||||||
status.value = InterceptResult.Loading
|
status.value = InterceptResult.Loading
|
||||||
@ -178,8 +184,11 @@ class InterceptActivity : BaseActivity() {
|
|||||||
.setTitle(MR.strings.label_sources.getString(this))
|
.setTitle(MR.strings.label_sources.getString(this))
|
||||||
.setSingleChoiceItems(sources.map { it.toString() }.toTypedArray(), 0) { dialog, index ->
|
.setSingleChoiceItems(sources.map { it.toString() }.toTypedArray(), 0) { dialog, index ->
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
|
lifecycleScope.launchIO {
|
||||||
loadGalleryEnd(gallery, sources[index])
|
loadGalleryEnd(gallery, sources[index])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
.show()
|
.show()
|
||||||
} else {
|
} else {
|
||||||
loadGalleryEnd(gallery)
|
loadGalleryEnd(gallery)
|
||||||
@ -187,9 +196,7 @@ class InterceptActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadGalleryEnd(gallery: String, source: UrlImportableSource? = null) {
|
private suspend fun loadGalleryEnd(gallery: String, source: UrlImportableSource? = null) {
|
||||||
// Load gallery async
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
|
||||||
val result = galleryAdder.addGallery(this@InterceptActivity, gallery, forceSource = source)
|
val result = galleryAdder.addGallery(this@InterceptActivity, gallery, forceSource = source)
|
||||||
|
|
||||||
status.value = when (result) {
|
status.value = when (result) {
|
||||||
@ -197,7 +204,6 @@ class InterceptActivity : BaseActivity() {
|
|||||||
is GalleryAddEvent.Fail -> InterceptResult.Failure(result.logMessage)
|
is GalleryAddEvent.Fail -> InterceptResult.Failure(result.logMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
registerSecureActivity(this)
|
registerSecureActivity(this)
|
||||||
|
@ -4,6 +4,7 @@ import eu.kanade.tachiyomi.source.CatalogueSource
|
|||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import tachiyomi.domain.source.model.StubSource
|
import tachiyomi.domain.source.model.StubSource
|
||||||
|
|
||||||
interface SourceManager {
|
interface SourceManager {
|
||||||
@ -19,6 +20,8 @@ interface SourceManager {
|
|||||||
fun getCatalogueSources(): List<CatalogueSource>
|
fun getCatalogueSources(): List<CatalogueSource>
|
||||||
|
|
||||||
// SY -->
|
// SY -->
|
||||||
|
val isInitialized: StateFlow<Boolean>
|
||||||
|
|
||||||
fun getVisibleOnlineSources(): List<HttpSource>
|
fun getVisibleOnlineSources(): List<HttpSource>
|
||||||
|
|
||||||
fun getVisibleCatalogueSources(): List<CatalogueSource>
|
fun getVisibleCatalogueSources(): List<CatalogueSource>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user