Parcourir la source

Refactor SourceManager/StubSource to domain module

arkon il y a 2 ans
Parent
commit
ad4912803b
41 fichiers modifiés avec 140 ajouts et 113 suppressions
  1. 4 5
      app/src/main/java/eu/kanade/data/source/SourceRepositoryImpl.kt
  2. 1 1
      app/src/main/java/eu/kanade/domain/download/interactor/DeleteDownload.kt
  3. 4 1
      app/src/main/java/eu/kanade/domain/source/interactor/GetSourcesWithFavoriteCount.kt
  4. 4 3
      app/src/main/java/eu/kanade/presentation/browse/BrowseSourceScreen.kt
  5. 3 3
      app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt
  6. 1 1
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt
  7. 1 1
      app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsTrackingScreen.kt
  8. 4 3
      app/src/main/java/eu/kanade/tachiyomi/AppModule.kt
  9. 1 1
      app/src/main/java/eu/kanade/tachiyomi/Migrations.kt
  10. 1 1
      app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreatorJob.kt
  11. 1 1
      app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupFileValidator.kt
  12. 2 2
      app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt
  13. 1 1
      app/src/main/java/eu/kanade/tachiyomi/data/coil/MangaCoverFetcher.kt
  14. 1 1
      app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt
  15. 1 1
      app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt
  16. 1 1
      app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadStore.kt
  17. 1 1
      app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
  18. 1 1
      app/src/main/java/eu/kanade/tachiyomi/data/download/model/Download.kt
  19. 3 2
      app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt
  20. 1 1
      app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt
  21. 10 61
      app/src/main/java/eu/kanade/tachiyomi/source/AndroidSourceManager.kt
  22. 2 1
      app/src/main/java/eu/kanade/tachiyomi/source/SourceExtensions.kt
  23. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/details/SourcePreferencesScreen.kt
  24. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaScreenModel.kt
  25. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateDialog.kt
  26. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateSearchScreenModel.kt
  27. 2 2
      app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreen.kt
  28. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt
  29. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchScreenModel.kt
  30. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt
  31. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt
  32. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
  33. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackInfoDialog.kt
  34. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
  35. 2 2
      app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt
  36. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt
  37. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewActivity.kt
  38. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewScreenModel.kt
  39. 1 1
      domain/src/main/java/tachiyomi/domain/backup/service/BackupPreferences.kt
  40. 50 0
      domain/src/main/java/tachiyomi/domain/source/model/StubSource.kt
  41. 22 0
      domain/src/main/java/tachiyomi/domain/source/service/SourceManager.kt

+ 4 - 5
app/src/main/java/eu/kanade/data/source/SourceRepositoryImpl.kt

@@ -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)
             }

+ 1 - 1
app/src/main/java/eu/kanade/domain/download/interactor/DeleteDownload.kt

@@ -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,

+ 4 - 1
app/src/main/java/eu/kanade/domain/source/interactor/GetSourcesWithFavoriteCount.kt

@@ -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))
         }
     }
 

+ 4 - 3
app/src/main/java/eu/kanade/presentation/browse/BrowseSourceScreen.kt

@@ -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),
         )
     }

+ 3 - 3
app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt

@@ -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,

+ 1 - 1
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt

@@ -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

+ 1 - 1
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsTrackingScreen.kt

@@ -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

+ 4 - 3
app/src/main/java/eu/kanade/tachiyomi/AppModule.kt

@@ -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) }

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/Migrations.kt

@@ -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

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreatorJob.kt

@@ -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

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupFileValidator.kt

@@ -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
 

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt

@@ -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

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/coil/MangaCoverFetcher.kt

@@ -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

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt

@@ -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

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt

@@ -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
 

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadStore.kt

@@ -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
 

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt

@@ -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

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/download/model/Download.kt

@@ -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
 

+ 3 - 2
app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt

@@ -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)

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt

@@ -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

+ 10 - 61
app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt → app/src/main/java/eu/kanade/tachiyomi/source/AndroidSourceManager.kt

@@ -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))
 }

+ 2 - 1
app/src/main/java/eu/kanade/tachiyomi/source/SourceExtensions.kt

@@ -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

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/details/SourcePreferencesScreen.kt

@@ -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

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaScreenModel.kt

@@ -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
 

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateDialog.kt

@@ -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

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateSearchScreenModel.kt

@@ -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
 

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreen.kt

@@ -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,

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt

@@ -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

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchScreenModel.kt

@@ -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
 

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt

@@ -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
 

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt

@@ -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

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt

@@ -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

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackInfoDialog.kt

@@ -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

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt

@@ -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

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt

@@ -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))
         }
     }

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt

@@ -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

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewActivity.kt

@@ -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() {

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewScreenModel.kt

@@ -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
 

+ 1 - 1
domain/src/main/java/tachiyomi/domain/service/BackupPreferences.kt → domain/src/main/java/tachiyomi/domain/backup/service/BackupPreferences.kt

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

+ 50 - 0
domain/src/main/java/tachiyomi/domain/source/model/StubSource.kt

@@ -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()

+ 22 - 0
domain/src/main/java/tachiyomi/domain/source/service/SourceManager.kt

@@ -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>
+}