mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-23 13:23:28 +03:00
Fix multiple issues regarding sources loading too late
Co-authored-by: jobobby04 <17078382+jobobby04@users.noreply.github.com> Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
This commit is contained in:
parent
94730b153e
commit
fd5d568a10
23 changed files with 141 additions and 29 deletions
13
app/src/main/java/eu/kanade/core/util/AnimeSourceUtil.kt
Normal file
13
app/src/main/java/eu/kanade/core/util/AnimeSourceUtil.kt
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package eu.kanade.core.util
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import tachiyomi.domain.source.anime.service.AnimeSourceManager
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ifAnimeSourcesLoaded(): Boolean {
|
||||||
|
return remember { Injekt.get<AnimeSourceManager>().isInitialized }.collectAsState().value
|
||||||
|
}
|
13
app/src/main/java/eu/kanade/core/util/MangaSourceUtil.kt
Normal file
13
app/src/main/java/eu/kanade/core/util/MangaSourceUtil.kt
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package eu.kanade.core.util
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import tachiyomi.domain.source.manga.service.MangaSourceManager
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ifMangaSourcesLoaded(): Boolean {
|
||||||
|
return remember { Injekt.get<MangaSourceManager>().isInitialized }.collectAsState().value
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ import kotlinx.coroutines.delay
|
||||||
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
|
||||||
|
@ -318,19 +319,13 @@ class AnimeDownloadCache(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to wait until extensions and sources have loaded
|
// Try to wait until extensions and sources have loaded
|
||||||
var sources = getSources()
|
var sources = emptyList<AnimeSource>()
|
||||||
if (sources.isEmpty()) {
|
|
||||||
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()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val sourceMap = sources.associate {
|
val sourceMap = sources.associate {
|
||||||
provider.getSourceDirName(it).lowercase() to it.id
|
provider.getSourceDirName(it).lowercase() to it.id
|
||||||
|
|
|
@ -19,6 +19,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
|
||||||
|
@ -342,19 +343,13 @@ class MangaDownloadCache(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to wait until extensions and sources have loaded
|
// Try to wait until extensions and sources have loaded
|
||||||
var sources = getSources()
|
var sources = emptyList<MangaSource>()
|
||||||
if (sources.isEmpty()) {
|
|
||||||
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()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val sourceMap = sources.associate { provider.getSourceDirName(it).lowercase() to it.id }
|
val sourceMap = sources.associate { provider.getSourceDirName(it).lowercase() to it.id }
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import eu.kanade.tachiyomi.util.system.toast
|
||||||
import kotlinx.coroutines.async
|
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.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.emptyFlow
|
import kotlinx.coroutines.flow.emptyFlow
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
@ -44,8 +45,8 @@ class AnimeExtensionManager(
|
||||||
private val trustExtension: TrustAnimeExtension = Injekt.get(),
|
private val trustExtension: TrustAnimeExtension = Injekt.get(),
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var isInitialized = false
|
private val _isInitialized = MutableStateFlow(false)
|
||||||
private set
|
val isInitialized: StateFlow<Boolean> = _isInitialized.asStateFlow()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API where all the available anime extensions can be found.
|
* API where all the available anime extensions can be found.
|
||||||
|
@ -119,7 +120,7 @@ class AnimeExtensionManager(
|
||||||
.filterIsInstance<AnimeLoadResult.Untrusted>()
|
.filterIsInstance<AnimeLoadResult.Untrusted>()
|
||||||
.map { it.extension }
|
.map { it.extension }
|
||||||
|
|
||||||
isInitialized = true
|
_isInitialized.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,10 +16,10 @@ import eu.kanade.tachiyomi.util.system.toast
|
||||||
import kotlinx.coroutines.async
|
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.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.emptyFlow
|
import kotlinx.coroutines.flow.emptyFlow
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
import tachiyomi.core.common.preference.plusAssign
|
|
||||||
import tachiyomi.core.common.util.lang.launchNow
|
import tachiyomi.core.common.util.lang.launchNow
|
||||||
import tachiyomi.core.common.util.lang.withUIContext
|
import tachiyomi.core.common.util.lang.withUIContext
|
||||||
import tachiyomi.core.common.util.system.logcat
|
import tachiyomi.core.common.util.system.logcat
|
||||||
|
@ -42,8 +42,8 @@ class MangaExtensionManager(
|
||||||
private val trustExtension: TrustMangaExtension = Injekt.get(),
|
private val trustExtension: TrustMangaExtension = Injekt.get(),
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var isInitialized = false
|
private val _isInitialized = MutableStateFlow(false)
|
||||||
private set
|
val isInitialized: StateFlow<Boolean> = _isInitialized.asStateFlow()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API where all the available extensions can be found.
|
* API where all the available extensions can be found.
|
||||||
|
@ -109,7 +109,7 @@ class MangaExtensionManager(
|
||||||
.filterIsInstance<MangaLoadResult.Untrusted>()
|
.filterIsInstance<MangaLoadResult.Untrusted>()
|
||||||
.map { it.extension }
|
.map { it.extension }
|
||||||
|
|
||||||
isInitialized = true
|
_isInitialized.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -11,6 +11,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.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -29,6 +31,10 @@ class AndroidAnimeSourceManager(
|
||||||
private val extensionManager: AnimeExtensionManager,
|
private val extensionManager: AnimeExtensionManager,
|
||||||
private val sourceRepository: AnimeStubSourceRepository,
|
private val sourceRepository: AnimeStubSourceRepository,
|
||||||
) : AnimeSourceManager {
|
) : AnimeSourceManager {
|
||||||
|
|
||||||
|
private val _isInitialized = MutableStateFlow(false)
|
||||||
|
override val isInitialized: StateFlow<Boolean> = _isInitialized.asStateFlow()
|
||||||
|
|
||||||
private val downloadManager: AnimeDownloadManager by injectLazy()
|
private val downloadManager: AnimeDownloadManager by injectLazy()
|
||||||
|
|
||||||
private val scope = CoroutineScope(Job() + Dispatchers.IO)
|
private val scope = CoroutineScope(Job() + Dispatchers.IO)
|
||||||
|
@ -61,6 +67,7 @@ class AndroidAnimeSourceManager(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sourcesMapFlow.value = mutableMap
|
sourcesMapFlow.value = mutableMap
|
||||||
|
_isInitialized.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,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.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -29,6 +31,10 @@ class AndroidMangaSourceManager(
|
||||||
private val extensionManager: MangaExtensionManager,
|
private val extensionManager: MangaExtensionManager,
|
||||||
private val sourceRepository: MangaStubSourceRepository,
|
private val sourceRepository: MangaStubSourceRepository,
|
||||||
) : MangaSourceManager {
|
) : MangaSourceManager {
|
||||||
|
|
||||||
|
private val _isInitialized = MutableStateFlow(false)
|
||||||
|
override val isInitialized: StateFlow<Boolean> = _isInitialized.asStateFlow()
|
||||||
|
|
||||||
private val downloadManager: MangaDownloadManager by injectLazy()
|
private val downloadManager: MangaDownloadManager by injectLazy()
|
||||||
|
|
||||||
private val scope = CoroutineScope(Job() + Dispatchers.IO)
|
private val scope = CoroutineScope(Job() + Dispatchers.IO)
|
||||||
|
@ -61,6 +67,7 @@ class AndroidMangaSourceManager(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sourcesMapFlow.value = mutableMap
|
sourcesMapFlow.value = mutableMap
|
||||||
|
_isInitialized.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ import androidx.preference.forEach
|
||||||
import androidx.preference.getOnBindEditTextListener
|
import androidx.preference.getOnBindEditTextListener
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
|
import eu.kanade.core.util.ifAnimeSourcesLoaded
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
import eu.kanade.presentation.util.Screen
|
import eu.kanade.presentation.util.Screen
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
@ -40,6 +41,7 @@ import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore
|
||||||
import eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText.Companion.setIncognito
|
import eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText.Companion.setIncognito
|
||||||
import tachiyomi.domain.source.anime.service.AnimeSourceManager
|
import tachiyomi.domain.source.anime.service.AnimeSourceManager
|
||||||
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
|
||||||
|
|
||||||
|
@ -47,6 +49,11 @@ class AnimeSourcePreferencesScreen(val sourceId: Long) : Screen() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifAnimeSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import androidx.paging.compose.collectAsLazyPagingItems
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
|
import eu.kanade.core.util.ifAnimeSourcesLoaded
|
||||||
import eu.kanade.presentation.browse.anime.BrowseAnimeSourceContent
|
import eu.kanade.presentation.browse.anime.BrowseAnimeSourceContent
|
||||||
import eu.kanade.presentation.components.SearchToolbar
|
import eu.kanade.presentation.components.SearchToolbar
|
||||||
import eu.kanade.presentation.util.Screen
|
import eu.kanade.presentation.util.Screen
|
||||||
|
@ -34,6 +35,7 @@ import tachiyomi.i18n.MR
|
||||||
import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton
|
import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton
|
||||||
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
|
||||||
import tachiyomi.source.local.entries.anime.LocalAnimeSource
|
import tachiyomi.source.local.entries.anime.LocalAnimeSource
|
||||||
|
|
||||||
data class AnimeSourceSearchScreen(
|
data class AnimeSourceSearchScreen(
|
||||||
|
@ -44,6 +46,11 @@ data class AnimeSourceSearchScreen(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifAnimeSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val uriHandler = LocalUriHandler.current
|
val uriHandler = LocalUriHandler.current
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
|
@ -35,6 +35,7 @@ import androidx.paging.compose.collectAsLazyPagingItems
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
|
import eu.kanade.core.util.ifAnimeSourcesLoaded
|
||||||
import eu.kanade.presentation.browse.anime.BrowseAnimeSourceContent
|
import eu.kanade.presentation.browse.anime.BrowseAnimeSourceContent
|
||||||
import eu.kanade.presentation.browse.anime.MissingSourceScreen
|
import eu.kanade.presentation.browse.anime.MissingSourceScreen
|
||||||
import eu.kanade.presentation.browse.anime.components.BrowseAnimeSourceToolbar
|
import eu.kanade.presentation.browse.anime.components.BrowseAnimeSourceToolbar
|
||||||
|
@ -60,6 +61,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.entries.anime.LocalAnimeSource
|
import tachiyomi.source.local.entries.anime.LocalAnimeSource
|
||||||
|
|
||||||
data class BrowseAnimeSourceScreen(
|
data class BrowseAnimeSourceScreen(
|
||||||
|
@ -73,6 +75,11 @@ data class BrowseAnimeSourceScreen(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifAnimeSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val screenModel = rememberScreenModel { BrowseAnimeSourceScreenModel(sourceId, listingQuery) }
|
val screenModel = rememberScreenModel { BrowseAnimeSourceScreenModel(sourceId, listingQuery) }
|
||||||
val state by screenModel.state.collectAsState()
|
val state by screenModel.state.collectAsState()
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import androidx.compose.runtime.setValue
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
|
import eu.kanade.core.util.ifAnimeSourcesLoaded
|
||||||
import eu.kanade.presentation.browse.anime.GlobalAnimeSearchScreen
|
import eu.kanade.presentation.browse.anime.GlobalAnimeSearchScreen
|
||||||
import eu.kanade.presentation.util.Screen
|
import eu.kanade.presentation.util.Screen
|
||||||
import eu.kanade.tachiyomi.ui.browse.anime.source.browse.BrowseAnimeSourceScreen
|
import eu.kanade.tachiyomi.ui.browse.anime.source.browse.BrowseAnimeSourceScreen
|
||||||
|
@ -23,6 +24,11 @@ class GlobalAnimeSearchScreen(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifAnimeSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
|
|
||||||
val screenModel = rememberScreenModel {
|
val screenModel = rememberScreenModel {
|
||||||
|
|
|
@ -31,6 +31,7 @@ import androidx.preference.forEach
|
||||||
import androidx.preference.getOnBindEditTextListener
|
import androidx.preference.getOnBindEditTextListener
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
|
import eu.kanade.core.util.ifMangaSourcesLoaded
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
import eu.kanade.presentation.util.Screen
|
import eu.kanade.presentation.util.Screen
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
@ -40,6 +41,7 @@ import eu.kanade.tachiyomi.source.sourcePreferences
|
||||||
import eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText.Companion.setIncognito
|
import eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText.Companion.setIncognito
|
||||||
import tachiyomi.domain.source.manga.service.MangaSourceManager
|
import tachiyomi.domain.source.manga.service.MangaSourceManager
|
||||||
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
|
||||||
|
|
||||||
|
@ -47,6 +49,11 @@ class MangaSourcePreferencesScreen(val sourceId: Long) : Screen() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifMangaSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import androidx.paging.compose.collectAsLazyPagingItems
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
|
import eu.kanade.core.util.ifMangaSourcesLoaded
|
||||||
import eu.kanade.presentation.browse.manga.BrowseSourceContent
|
import eu.kanade.presentation.browse.manga.BrowseSourceContent
|
||||||
import eu.kanade.presentation.components.SearchToolbar
|
import eu.kanade.presentation.components.SearchToolbar
|
||||||
import eu.kanade.presentation.util.Screen
|
import eu.kanade.presentation.util.Screen
|
||||||
|
@ -34,6 +35,7 @@ import tachiyomi.i18n.MR
|
||||||
import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton
|
import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton
|
||||||
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
|
||||||
import tachiyomi.source.local.entries.manga.LocalMangaSource
|
import tachiyomi.source.local.entries.manga.LocalMangaSource
|
||||||
|
|
||||||
data class MangaSourceSearchScreen(
|
data class MangaSourceSearchScreen(
|
||||||
|
@ -44,6 +46,11 @@ data class MangaSourceSearchScreen(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifMangaSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val uriHandler = LocalUriHandler.current
|
val uriHandler = LocalUriHandler.current
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
|
@ -35,6 +35,7 @@ import androidx.paging.compose.collectAsLazyPagingItems
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
|
import eu.kanade.core.util.ifMangaSourcesLoaded
|
||||||
import eu.kanade.presentation.browse.anime.components.RemoveEntryDialog
|
import eu.kanade.presentation.browse.anime.components.RemoveEntryDialog
|
||||||
import eu.kanade.presentation.browse.manga.BrowseSourceContent
|
import eu.kanade.presentation.browse.manga.BrowseSourceContent
|
||||||
import eu.kanade.presentation.browse.manga.MissingSourceScreen
|
import eu.kanade.presentation.browse.manga.MissingSourceScreen
|
||||||
|
@ -60,6 +61,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.entries.manga.LocalMangaSource
|
import tachiyomi.source.local.entries.manga.LocalMangaSource
|
||||||
|
|
||||||
data class BrowseMangaSourceScreen(
|
data class BrowseMangaSourceScreen(
|
||||||
|
@ -73,6 +75,11 @@ data class BrowseMangaSourceScreen(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifMangaSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val screenModel = rememberScreenModel { BrowseMangaSourceScreenModel(sourceId, listingQuery) }
|
val screenModel = rememberScreenModel { BrowseMangaSourceScreenModel(sourceId, listingQuery) }
|
||||||
val state by screenModel.state.collectAsState()
|
val state by screenModel.state.collectAsState()
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import androidx.compose.runtime.setValue
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
|
import eu.kanade.core.util.ifMangaSourcesLoaded
|
||||||
import eu.kanade.presentation.browse.manga.GlobalMangaSearchScreen
|
import eu.kanade.presentation.browse.manga.GlobalMangaSearchScreen
|
||||||
import eu.kanade.presentation.util.Screen
|
import eu.kanade.presentation.util.Screen
|
||||||
import eu.kanade.tachiyomi.ui.browse.manga.source.browse.BrowseMangaSourceScreen
|
import eu.kanade.tachiyomi.ui.browse.manga.source.browse.BrowseMangaSourceScreen
|
||||||
|
@ -23,6 +24,11 @@ class GlobalMangaSearchScreen(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifMangaSourcesLoaded()) {
|
||||||
|
LoadingScreen()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
|
|
||||||
val screenModel = rememberScreenModel {
|
val screenModel = rememberScreenModel {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.Navigator
|
import cafe.adriel.voyager.navigator.Navigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
|
import eu.kanade.core.util.ifAnimeSourcesLoaded
|
||||||
import eu.kanade.domain.entries.anime.model.hasCustomCover
|
import eu.kanade.domain.entries.anime.model.hasCustomCover
|
||||||
import eu.kanade.domain.entries.anime.model.toSAnime
|
import eu.kanade.domain.entries.anime.model.toSAnime
|
||||||
import eu.kanade.presentation.category.components.ChangeCategoryDialog
|
import eu.kanade.presentation.category.components.ChangeCategoryDialog
|
||||||
|
@ -76,6 +77,11 @@ class AnimeScreen(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifAnimeSourcesLoaded()) {
|
||||||
|
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
|
||||||
|
|
|
@ -22,6 +22,7 @@ import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.Navigator
|
import cafe.adriel.voyager.navigator.Navigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
|
import eu.kanade.core.util.ifMangaSourcesLoaded
|
||||||
import eu.kanade.domain.entries.manga.model.hasCustomCover
|
import eu.kanade.domain.entries.manga.model.hasCustomCover
|
||||||
import eu.kanade.domain.entries.manga.model.toSManga
|
import eu.kanade.domain.entries.manga.model.toSManga
|
||||||
import eu.kanade.presentation.category.components.ChangeCategoryDialog
|
import eu.kanade.presentation.category.components.ChangeCategoryDialog
|
||||||
|
@ -74,6 +75,11 @@ class MangaScreen(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
if (!ifMangaSourcesLoaded()) {
|
||||||
|
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
|
||||||
|
|
|
@ -44,6 +44,7 @@ import `is`.xyz.mpv.Utils
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.receiveAsFlow
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
@ -245,6 +246,7 @@ class PlayerViewModel @JvmOverloads constructor(
|
||||||
return try {
|
return try {
|
||||||
val anime = getAnime.await(animeId)
|
val anime = getAnime.await(animeId)
|
||||||
if (anime != null) {
|
if (anime != null) {
|
||||||
|
sourceManager.isInitialized.first { it }
|
||||||
if (episodeId == -1L) episodeId = initialEpisodeId
|
if (episodeId == -1L) episodeId = initialEpisodeId
|
||||||
|
|
||||||
checkTrackers(anime)
|
checkTrackers(anime)
|
||||||
|
|
|
@ -40,6 +40,7 @@ import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||||
import com.google.android.material.elevation.SurfaceColors
|
import com.google.android.material.elevation.SurfaceColors
|
||||||
import com.google.android.material.transition.platform.MaterialContainerTransform
|
import com.google.android.material.transition.platform.MaterialContainerTransform
|
||||||
import dev.chrisbanes.insetter.applyInsetter
|
import dev.chrisbanes.insetter.applyInsetter
|
||||||
|
import eu.kanade.core.util.ifMangaSourcesLoaded
|
||||||
import eu.kanade.domain.base.BasePreferences
|
import eu.kanade.domain.base.BasePreferences
|
||||||
import eu.kanade.presentation.reader.DisplayRefreshHost
|
import eu.kanade.presentation.reader.DisplayRefreshHost
|
||||||
import eu.kanade.presentation.reader.OrientationSelectDialog
|
import eu.kanade.presentation.reader.OrientationSelectDialog
|
||||||
|
@ -350,6 +351,10 @@ class ReaderActivity : BaseActivity() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ifMangaSourcesLoaded()) {
|
||||||
|
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()
|
||||||
|
|
|
@ -47,6 +47,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
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.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
@ -270,6 +271,7 @@ class ReaderViewModel @JvmOverloads constructor(
|
||||||
try {
|
try {
|
||||||
val manga = getManga.await(mangaId)
|
val manga = getManga.await(mangaId)
|
||||||
if (manga != null) {
|
if (manga != null) {
|
||||||
|
sourceManager.isInitialized.first { it }
|
||||||
mutableState.update { it.copy(manga = manga) }
|
mutableState.update { it.copy(manga = manga) }
|
||||||
if (chapterId == -1L) chapterId = initialChapterId
|
if (chapterId == -1L) chapterId = initialChapterId
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,13 @@ import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import tachiyomi.domain.source.anime.model.StubAnimeSource
|
import tachiyomi.domain.source.anime.model.StubAnimeSource
|
||||||
|
|
||||||
interface AnimeSourceManager {
|
interface AnimeSourceManager {
|
||||||
|
|
||||||
|
val isInitialized: StateFlow<Boolean>
|
||||||
|
|
||||||
val catalogueSources: Flow<List<AnimeCatalogueSource>>
|
val catalogueSources: Flow<List<AnimeCatalogueSource>>
|
||||||
|
|
||||||
fun get(sourceKey: Long): AnimeSource?
|
fun get(sourceKey: Long): AnimeSource?
|
||||||
|
|
|
@ -4,10 +4,13 @@ import eu.kanade.tachiyomi.source.CatalogueSource
|
||||||
import eu.kanade.tachiyomi.source.MangaSource
|
import eu.kanade.tachiyomi.source.MangaSource
|
||||||
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.manga.model.StubMangaSource
|
import tachiyomi.domain.source.manga.model.StubMangaSource
|
||||||
|
|
||||||
interface MangaSourceManager {
|
interface MangaSourceManager {
|
||||||
|
|
||||||
|
val isInitialized: StateFlow<Boolean>
|
||||||
|
|
||||||
val catalogueSources: Flow<List<CatalogueSource>>
|
val catalogueSources: Flow<List<CatalogueSource>>
|
||||||
|
|
||||||
fun get(sourceKey: Long): MangaSource?
|
fun get(sourceKey: Long): MangaSource?
|
||||||
|
|
Loading…
Reference in a new issue