Refactor SourceManager/StubSource to domain module

This commit is contained in:
arkon 2023-03-05 12:38:31 -05:00
parent f96f0c5889
commit ad4912803b
41 changed files with 140 additions and 113 deletions

View File

@ -2,7 +2,6 @@ package eu.kanade.data.source
import eu.kanade.domain.source.repository.SourceRepository
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.online.HttpSource
import kotlinx.coroutines.flow.Flow
@ -15,7 +14,8 @@ import tachiyomi.data.source.SourceSearchPagingSource
import tachiyomi.data.source.sourceMapper
import tachiyomi.domain.source.model.Source
import tachiyomi.domain.source.model.SourceWithCount
import tachiyomi.source.local.LocalSource
import tachiyomi.domain.source.model.StubSource
import tachiyomi.domain.source.service.SourceManager
class SourceRepositoryImpl(
private val sourceManager: SourceManager,
@ -44,11 +44,10 @@ class SourceRepositoryImpl(
val sourceIdWithFavoriteCount = handler.subscribeToList { mangasQueries.getSourceIdWithFavoriteCount() }
return sourceIdWithFavoriteCount.map { sourceIdsWithCount ->
sourceIdsWithCount
.filterNot { it.source == LocalSource.ID }
.map { (sourceId, count) ->
val source = sourceManager.getOrStub(sourceId)
val domainSource = sourceMapper(source).copy(
isStub = source is SourceManager.StubSource,
isStub = source is StubSource,
)
domainSource to count
}
@ -61,7 +60,7 @@ class SourceRepositoryImpl(
sourceId.map { (sourceId, count) ->
val source = sourceManager.getOrStub(sourceId)
val domainSource = sourceMapper(source).copy(
isStub = source is SourceManager.StubSource,
isStub = source is StubSource,
)
SourceWithCount(domainSource, count)
}

View File

@ -1,10 +1,10 @@
package eu.kanade.domain.download.interactor
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.source.SourceManager
import tachiyomi.core.util.lang.withNonCancellableContext
import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.service.SourceManager
class DeleteDownload(
private val sourceManager: SourceManager,

View File

@ -5,6 +5,7 @@ import eu.kanade.domain.source.service.SourcePreferences
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import tachiyomi.domain.source.model.Source
import tachiyomi.source.local.LocalSource
import java.text.Collator
import java.util.Collections
import java.util.Locale
@ -20,7 +21,9 @@ class GetSourcesWithFavoriteCount(
preferences.migrationSortingMode().changes(),
repository.getSourcesWithFavoriteCount(),
) { direction, mode, list ->
list.sortedWith(sortFn(direction, mode))
list
.filterNot { it.first.id == LocalSource.ID }
.sortedWith(sortFn(direction, mode))
}
}

View File

@ -14,6 +14,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.paging.LoadState
import androidx.paging.compose.LazyPagingItems
import eu.kanade.presentation.browse.components.BrowseSourceComfortableGrid
@ -22,11 +23,11 @@ import eu.kanade.presentation.browse.components.BrowseSourceList
import eu.kanade.presentation.components.AppBar
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import kotlinx.coroutines.flow.StateFlow
import tachiyomi.data.source.NoResultsException
import tachiyomi.domain.library.model.LibraryDisplayMode
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.model.StubSource
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.screens.EmptyScreenAction
@ -147,7 +148,7 @@ fun BrowseSourceContent(
@Composable
fun MissingSourceScreen(
source: SourceManager.StubSource,
source: StubSource,
navigateUp: () -> Unit,
) {
Scaffold(
@ -160,7 +161,7 @@ fun MissingSourceScreen(
},
) { paddingValues ->
EmptyScreen(
message = source.getSourceNotInstalledException().message!!,
message = stringResource(R.string.source_not_installed, source.toString()),
modifier = Modifier.padding(paddingValues),
)
}

View File

@ -58,7 +58,6 @@ import eu.kanade.presentation.manga.components.MangaInfoBox
import eu.kanade.presentation.manga.components.MangaToolbar
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.getNameForMangaInfo
import eu.kanade.tachiyomi.ui.manga.ChapterItem
import eu.kanade.tachiyomi.ui.manga.MangaScreenState
@ -67,6 +66,7 @@ import eu.kanade.tachiyomi.util.lang.toRelativeString
import eu.kanade.tachiyomi.util.system.copyToClipboard
import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.model.StubSource
import tachiyomi.presentation.core.components.LazyColumn
import tachiyomi.presentation.core.components.TwoPanelBox
import tachiyomi.presentation.core.components.VerticalFastScroller
@ -350,7 +350,7 @@ private fun MangaScreenSmallImpl(
author = state.manga.author,
artist = state.manga.artist,
sourceName = remember { state.source.getNameForMangaInfo() },
isStubSource = remember { state.source is SourceManager.StubSource },
isStubSource = remember { state.source is StubSource },
coverDataProvider = { state.manga },
status = state.manga.status,
onCoverClick = onCoverClicked,
@ -560,7 +560,7 @@ fun MangaScreenLargeImpl(
author = state.manga.author,
artist = state.manga.artist,
sourceName = remember { state.source.getNameForMangaInfo() },
isStubSource = remember { state.source is SourceManager.StubSource },
isStubSource = remember { state.source is StubSource },
coverDataProvider = { state.manga },
status = state.manga.status,
onCoverClick = onCoverClicked,

View File

@ -50,7 +50,7 @@ import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.copyToClipboard
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.launch
import tachiyomi.domain.service.BackupPreferences
import tachiyomi.domain.backup.service.BackupPreferences
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.Divider
import tachiyomi.presentation.core.util.isScrolledToEnd

View File

@ -51,11 +51,11 @@ import eu.kanade.tachiyomi.data.track.anilist.AnilistApi
import eu.kanade.tachiyomi.data.track.bangumi.BangumiApi
import eu.kanade.tachiyomi.data.track.myanimelist.MyAnimeListApi
import eu.kanade.tachiyomi.data.track.shikimori.ShikimoriApi
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.util.system.openInBrowser
import eu.kanade.tachiyomi.util.system.toast
import tachiyomi.core.util.lang.launchIO
import tachiyomi.core.util.lang.withUIContext
import tachiyomi.domain.source.service.SourceManager
import tachiyomi.presentation.core.components.material.padding
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View File

@ -25,7 +25,7 @@ import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.network.JavaScriptEngine
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.NetworkPreferences
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.AndroidSourceManager
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import eu.kanade.tachiyomi.util.system.isDevFlavor
import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory
@ -46,8 +46,9 @@ import tachiyomi.data.Mangas
import tachiyomi.data.dateAdapter
import tachiyomi.data.listOfStringsAdapter
import tachiyomi.data.updateStrategyAdapter
import tachiyomi.domain.backup.service.BackupPreferences
import tachiyomi.domain.download.service.DownloadPreferences
import tachiyomi.domain.service.BackupPreferences
import tachiyomi.domain.source.service.SourceManager
import tachiyomi.source.local.image.LocalCoverManager
import tachiyomi.source.local.io.LocalSourceFileSystem
import uy.kohesive.injekt.api.InjektModule
@ -123,7 +124,7 @@ class AppModule(val app: Application) : InjektModule {
addSingletonFactory { NetworkHelper(app, get()) }
addSingletonFactory { JavaScriptEngine(app) }
addSingletonFactory { SourceManager(app, get(), get()) }
addSingletonFactory<SourceManager> { AndroidSourceManager(app, get(), get()) }
addSingletonFactory { ExtensionManager(app) }
addSingletonFactory { DownloadProvider(app) }

View File

@ -24,8 +24,8 @@ import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.toast
import tachiyomi.core.preference.PreferenceStore
import tachiyomi.core.preference.getEnum
import tachiyomi.domain.backup.service.BackupPreferences
import tachiyomi.domain.manga.model.TriStateFilter
import tachiyomi.domain.service.BackupPreferences
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.File

View File

@ -18,7 +18,7 @@ import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.util.system.notificationManager
import logcat.LogPriority
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.service.BackupPreferences
import tachiyomi.domain.backup.service.BackupPreferences
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.concurrent.TimeUnit

View File

@ -4,8 +4,8 @@ import android.content.Context
import android.net.Uri
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.util.BackupUtil
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View File

@ -26,7 +26,6 @@ import eu.kanade.tachiyomi.data.backup.models.backupTrackMapper
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.copyFrom
import eu.kanade.tachiyomi.util.system.hasPermission
import kotlinx.serialization.protobuf.ProtoBuf
@ -40,11 +39,12 @@ import tachiyomi.data.DatabaseHandler
import tachiyomi.data.Manga_sync
import tachiyomi.data.Mangas
import tachiyomi.data.updateStrategyAdapter
import tachiyomi.domain.backup.service.BackupPreferences
import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.category.model.Category
import tachiyomi.domain.history.model.HistoryUpdate
import tachiyomi.domain.manga.interactor.GetFavorites
import tachiyomi.domain.service.BackupPreferences
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.FileOutputStream

View File

@ -14,7 +14,6 @@ import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher.Companion.USE_CUSTOM_COVER
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.HttpSource
import logcat.LogPriority
import okhttp3.CacheControl
@ -28,6 +27,7 @@ import okio.buffer
import okio.sink
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.manga.model.MangaCover
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.injectLazy
import java.io.File
import tachiyomi.domain.manga.model.Manga as DomainManga

View File

@ -6,7 +6,6 @@ import com.hippo.unifile.UniFile
import eu.kanade.core.util.mapNotNullKeys
import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -32,6 +31,7 @@ import tachiyomi.core.util.system.logcat
import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.download.service.DownloadPreferences
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.concurrent.ConcurrentHashMap

View File

@ -4,7 +4,6 @@ import android.content.Context
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.Page
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
@ -22,6 +21,7 @@ import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.download.service.DownloadPreferences
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View File

@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.data.download
import android.content.Context
import androidx.core.content.edit
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.HttpSource
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.Serializable
@ -13,6 +12,7 @@ import kotlinx.serialization.json.Json
import tachiyomi.domain.chapter.interactor.GetChapter
import tachiyomi.domain.manga.interactor.GetManga
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View File

@ -12,7 +12,6 @@ import eu.kanade.tachiyomi.data.cache.ChapterCache
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.library.LibraryUpdateNotifier
import eu.kanade.tachiyomi.data.notification.NotificationHandler
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.UnmeteredSource
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.online.HttpSource
@ -50,6 +49,7 @@ import tachiyomi.core.util.system.logcat
import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.download.service.DownloadPreferences
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.BufferedOutputStream

View File

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.data.download.model
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.online.HttpSource
import kotlinx.coroutines.delay
@ -15,6 +14,7 @@ import tachiyomi.domain.chapter.interactor.GetChapter
import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.manga.interactor.GetManga
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View File

@ -37,7 +37,6 @@ import eu.kanade.tachiyomi.data.preference.MANGA_NON_READ
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.UnmeteredSource
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.UpdateStrategy
@ -72,6 +71,8 @@ import tachiyomi.domain.manga.interactor.GetLibraryManga
import tachiyomi.domain.manga.interactor.GetManga
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.toMangaUpdate
import tachiyomi.domain.source.model.SourceNotInstalledException
import tachiyomi.domain.source.service.SourceManager
import tachiyomi.domain.track.interactor.GetTracks
import tachiyomi.domain.track.interactor.InsertTrack
import uy.kohesive.injekt.Injekt
@ -284,7 +285,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
val errorMessage = when (e) {
is NoChaptersException -> context.getString(R.string.no_chapters_error)
// failedUpdates will already have the source, don't need to copy it into the message
is SourceManager.SourceNotInstalledException -> context.getString(R.string.loader_not_implemented_error)
is SourceNotInstalledException -> context.getString(R.string.loader_not_implemented_error)
else -> e.message
}
failedUpdates.add(manga to errorMessage)

View File

@ -13,7 +13,6 @@ import eu.kanade.tachiyomi.data.backup.BackupRestoreService
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
import eu.kanade.tachiyomi.data.updater.AppUpdateService
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.storage.DiskUtil
@ -32,6 +31,7 @@ import tachiyomi.domain.chapter.model.toChapterUpdate
import tachiyomi.domain.download.service.DownloadPreferences
import tachiyomi.domain.manga.interactor.GetManga
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy

View File

@ -1,12 +1,8 @@
package eu.kanade.tachiyomi.source
import android.content.Context
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -17,20 +13,21 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import rx.Observable
import tachiyomi.domain.source.model.SourceData
import tachiyomi.domain.source.model.StubSource
import tachiyomi.domain.source.repository.SourceDataRepository
import tachiyomi.domain.source.service.SourceManager
import tachiyomi.source.local.LocalSource
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import java.util.concurrent.ConcurrentHashMap
class SourceManager(
class AndroidSourceManager(
private val context: Context,
private val extensionManager: ExtensionManager,
private val sourceRepository: SourceDataRepository,
) {
) : SourceManager {
private val downloadManager: DownloadManager by injectLazy()
private val scope = CoroutineScope(Job() + Dispatchers.IO)
@ -39,7 +36,7 @@ class SourceManager(
private val stubSourcesMap = ConcurrentHashMap<Long, StubSource>()
val catalogueSources: Flow<List<CatalogueSource>> = sourcesMapFlow.map { it.values.filterIsInstance<CatalogueSource>() }
override val catalogueSources: Flow<List<CatalogueSource>> = sourcesMapFlow.map { it.values.filterIsInstance<CatalogueSource>() }
init {
scope.launch {
@ -75,21 +72,21 @@ class SourceManager(
}
}
fun get(sourceKey: Long): Source? {
override fun get(sourceKey: Long): Source? {
return sourcesMapFlow.value[sourceKey]
}
fun getOrStub(sourceKey: Long): Source {
override fun getOrStub(sourceKey: Long): Source {
return sourcesMapFlow.value[sourceKey] ?: stubSourcesMap.getOrPut(sourceKey) {
runBlocking { createStubSource(sourceKey) }
}
}
fun getOnlineSources() = sourcesMapFlow.value.values.filterIsInstance<HttpSource>()
override fun getOnlineSources() = sourcesMapFlow.value.values.filterIsInstance<HttpSource>()
fun getCatalogueSources() = sourcesMapFlow.value.values.filterIsInstance<CatalogueSource>()
override fun getCatalogueSources() = sourcesMapFlow.value.values.filterIsInstance<CatalogueSource>()
fun getStubSources(): List<StubSource> {
override fun getStubSources(): List<StubSource> {
val onlineSourceIds = getOnlineSources().map { it.id }
return stubSourcesMap.values.filterNot { it.id in onlineSourceIds }
}
@ -116,52 +113,4 @@ class SourceManager(
}
return StubSource(SourceData(id, "", ""))
}
@Suppress("OverridingDeprecatedMember")
inner class StubSource(private val sourceData: SourceData) : Source {
override val id: Long = sourceData.id
override val name: String = sourceData.name.ifBlank { id.toString() }
override val lang: String = sourceData.lang
override suspend fun getMangaDetails(manga: SManga): SManga {
throw getSourceNotInstalledException()
}
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getMangaDetails"))
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
return Observable.error(getSourceNotInstalledException())
}
override suspend fun getChapterList(manga: SManga): List<SChapter> {
throw getSourceNotInstalledException()
}
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getChapterList"))
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
return Observable.error(getSourceNotInstalledException())
}
override suspend fun getPageList(chapter: SChapter): List<Page> {
throw getSourceNotInstalledException()
}
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getPageList"))
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
return Observable.error(getSourceNotInstalledException())
}
override fun toString(): String {
return if (sourceData.isMissingInfo.not()) "$name (${lang.uppercase()})" else id.toString()
}
fun getSourceNotInstalledException(): SourceNotInstalledException {
return SourceNotInstalledException(toString())
}
}
inner class SourceNotInstalledException(sourceString: String) :
Exception(context.getString(R.string.source_not_installed, sourceString))
}

View File

@ -4,6 +4,7 @@ import android.graphics.drawable.Drawable
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.tachiyomi.extension.ExtensionManager
import tachiyomi.domain.source.model.SourceData
import tachiyomi.domain.source.model.StubSource
import tachiyomi.source.local.LocalSource
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -31,4 +32,4 @@ fun Source.getNameForMangaInfo(): String {
fun Source.isLocal(): Boolean = id == LocalSource.ID
fun Source.isLocalOrStub(): Boolean = isLocal() || this is SourceManager.StubSource
fun Source.isLocalOrStub(): Boolean = isLocal() || this is StubSource

View File

@ -41,9 +41,9 @@ import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore
import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.getPreferenceKey
import eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText.Companion.setIncognito
import tachiyomi.domain.source.service.SourceManager
import tachiyomi.presentation.core.components.material.Scaffold
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View File

@ -4,7 +4,6 @@ import androidx.compose.runtime.Immutable
import cafe.adriel.voyager.core.model.StateScreenModel
import cafe.adriel.voyager.core.model.coroutineScope
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
@ -17,6 +16,7 @@ import logcat.LogPriority
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.manga.interactor.GetFavorites
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View File

@ -34,7 +34,6 @@ import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags
import kotlinx.coroutines.flow.update
@ -49,6 +48,7 @@ import tachiyomi.domain.chapter.interactor.UpdateChapter
import tachiyomi.domain.chapter.model.toChapterUpdate
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.MangaUpdate
import tachiyomi.domain.source.service.SourceManager
import tachiyomi.domain.track.interactor.GetTracks
import tachiyomi.domain.track.interactor.InsertTrack
import tachiyomi.presentation.core.screens.LoadingScreen

View File

@ -5,13 +5,13 @@ import cafe.adriel.voyager.core.model.coroutineScope
import eu.kanade.domain.base.BasePreferences
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchItemResult
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchScreenModel
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import tachiyomi.domain.manga.interactor.GetManga
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View File

@ -45,7 +45,6 @@ import eu.kanade.presentation.util.AssistContentScreen
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.browse.extension.details.SourcePreferencesScreen
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel.Listing
@ -57,6 +56,7 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.receiveAsFlow
import tachiyomi.core.Constants
import tachiyomi.core.util.lang.launchIO
import tachiyomi.domain.source.model.StubSource
import tachiyomi.presentation.core.components.material.Divider
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.padding
@ -84,7 +84,7 @@ data class BrowseSourceScreen(
}
}
if (screenModel.source is SourceManager.StubSource) {
if (screenModel.source is StubSource) {
MissingSourceScreen(
source = screenModel.source,
navigateUp = navigateUp,

View File

@ -29,7 +29,6 @@ import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.util.removeCovers
import kotlinx.coroutines.flow.SharingStarted
@ -58,6 +57,7 @@ import tachiyomi.domain.manga.interactor.GetManga
import tachiyomi.domain.manga.interactor.NetworkToLocalManga
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.toMangaUpdate
import tachiyomi.domain.source.service.SourceManager
import tachiyomi.domain.track.interactor.InsertTrack
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View File

@ -4,8 +4,8 @@ import androidx.compose.runtime.Immutable
import eu.kanade.domain.base.BasePreferences
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.SourceManager
import kotlinx.coroutines.flow.update
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View File

@ -1,8 +1,8 @@
package eu.kanade.tachiyomi.ui.library
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.getNameForMangaInfo
import tachiyomi.domain.library.model.LibraryManga
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View File

@ -27,7 +27,6 @@ import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.download.DownloadCache
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.chapter.getNextUnread
@ -60,6 +59,7 @@ import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.MangaUpdate
import tachiyomi.domain.manga.model.TriStateFilter
import tachiyomi.domain.manga.model.applyFilter
import tachiyomi.domain.source.service.SourceManager
import tachiyomi.domain.track.interactor.GetTracksPerManga
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View File

@ -31,7 +31,6 @@ import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.network.HttpException
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import eu.kanade.tachiyomi.util.chapter.getNextUnread
@ -71,6 +70,7 @@ import tachiyomi.domain.manga.interactor.SetMangaChapterFlags
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.TriStateFilter
import tachiyomi.domain.manga.model.applyFilter
import tachiyomi.domain.source.service.SourceManager
import tachiyomi.domain.track.interactor.GetTracks
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View File

@ -52,7 +52,6 @@ import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.util.system.openInBrowser
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.flow.catch
@ -68,6 +67,7 @@ import tachiyomi.core.util.lang.withUIContext
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.manga.interactor.GetManga
import tachiyomi.domain.manga.interactor.GetMangaWithChapters
import tachiyomi.domain.source.service.SourceManager
import tachiyomi.domain.track.interactor.DeleteTrack
import tachiyomi.domain.track.interactor.GetTracks
import tachiyomi.domain.track.interactor.InsertTrack

View File

@ -25,7 +25,6 @@ import eu.kanade.tachiyomi.data.saver.Image
import eu.kanade.tachiyomi.data.saver.ImageSaver
import eu.kanade.tachiyomi.data.saver.Location
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.reader.loader.ChapterLoader
@ -76,6 +75,7 @@ import tachiyomi.domain.history.interactor.UpsertHistory
import tachiyomi.domain.history.model.HistoryUpdate
import tachiyomi.domain.manga.interactor.GetManga
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.service.SourceManager
import tachiyomi.domain.track.interactor.GetTracks
import tachiyomi.domain.track.interactor.InsertTrack
import uy.kohesive.injekt.Injekt

View File

@ -6,12 +6,12 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadProvider
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import tachiyomi.core.util.lang.withIOContext
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.model.StubSource
import tachiyomi.source.local.LocalSource
import tachiyomi.source.local.io.Format
@ -91,7 +91,7 @@ class ChapterLoader(
is Format.Epub -> EpubPageLoader(format.file)
}
}
source is SourceManager.StubSource -> throw source.getSourceNotInstalledException()
source is StubSource -> error(context.getString(R.string.source_not_installed, source.toString()))
else -> error(context.getString(R.string.loader_not_implemented_error))
}
}

View File

@ -20,7 +20,6 @@ import eu.kanade.tachiyomi.data.download.DownloadCache
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.util.lang.toDateKey
import eu.kanade.tachiyomi.util.lang.toRelativeString
import kotlinx.coroutines.channels.Channel
@ -41,6 +40,7 @@ import tachiyomi.domain.chapter.interactor.GetChapter
import tachiyomi.domain.chapter.interactor.UpdateChapter
import tachiyomi.domain.chapter.model.ChapterUpdate
import tachiyomi.domain.manga.interactor.GetManga
import tachiyomi.domain.source.service.SourceManager
import tachiyomi.domain.updates.interactor.GetUpdates
import tachiyomi.domain.updates.model.UpdatesWithRelations
import uy.kohesive.injekt.Injekt

View File

@ -9,7 +9,6 @@ import androidx.core.net.toUri
import eu.kanade.presentation.webview.WebViewScreenContent
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
import eu.kanade.tachiyomi.util.system.WebViewUtil
@ -20,6 +19,7 @@ import eu.kanade.tachiyomi.util.view.setComposeContent
import logcat.LogPriority
import okhttp3.HttpUrl.Companion.toHttpUrl
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.injectLazy
class WebViewActivity : BaseActivity() {

View File

@ -5,7 +5,6 @@ import androidx.core.net.toUri
import cafe.adriel.voyager.core.model.StateScreenModel
import eu.kanade.presentation.more.stats.StatsScreenState
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.system.openInBrowser
import eu.kanade.tachiyomi.util.system.toShareIntent
@ -13,6 +12,7 @@ import eu.kanade.tachiyomi.util.system.toast
import logcat.LogPriority
import okhttp3.HttpUrl.Companion.toHttpUrl
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

View File

@ -1,4 +1,4 @@
package tachiyomi.domain.service
package tachiyomi.domain.backup.service
import tachiyomi.core.preference.PreferenceStore
import tachiyomi.core.provider.FolderProvider

View File

@ -0,0 +1,50 @@
package tachiyomi.domain.source.model
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import rx.Observable
@Suppress("OverridingDeprecatedMember")
class StubSource(private val sourceData: SourceData) : Source {
override val id: Long = sourceData.id
override val name: String = sourceData.name.ifBlank { id.toString() }
override val lang: String = sourceData.lang
override suspend fun getMangaDetails(manga: SManga): SManga {
throw SourceNotInstalledException()
}
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getMangaDetails"))
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
return Observable.error(SourceNotInstalledException())
}
override suspend fun getChapterList(manga: SManga): List<SChapter> {
throw SourceNotInstalledException()
}
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getChapterList"))
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
return Observable.error(SourceNotInstalledException())
}
override suspend fun getPageList(chapter: SChapter): List<Page> {
throw SourceNotInstalledException()
}
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getPageList"))
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
return Observable.error(SourceNotInstalledException())
}
override fun toString(): String {
return if (sourceData.isMissingInfo.not()) "$name (${lang.uppercase()})" else id.toString()
}
}
class SourceNotInstalledException : Exception()

View File

@ -0,0 +1,22 @@
package tachiyomi.domain.source.service
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.online.HttpSource
import kotlinx.coroutines.flow.Flow
import tachiyomi.domain.source.model.StubSource
interface SourceManager {
val catalogueSources: Flow<List<CatalogueSource>>
fun get(sourceKey: Long): Source?
fun getOrStub(sourceKey: Long): Source
fun getOnlineSources(): List<HttpSource>
fun getCatalogueSources(): List<CatalogueSource>
fun getStubSources(): List<StubSource>
}