mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 16:18:55 +01:00 
			
		
		
		
	Show manga with no installed source. Based on PR #1345
This commit is contained in:
		@@ -33,7 +33,8 @@ import timber.log.Timber
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
import java.io.File
 | 
			
		||||
import java.text.SimpleDateFormat
 | 
			
		||||
import java.util.*
 | 
			
		||||
import java.util.Date
 | 
			
		||||
import java.util.Locale
 | 
			
		||||
import java.util.concurrent.ExecutorService
 | 
			
		||||
import java.util.concurrent.Executors
 | 
			
		||||
 | 
			
		||||
@@ -295,7 +296,7 @@ class BackupRestoreService : Service() {
 | 
			
		||||
                                          categories: List<String>, history: List<DHistory>,
 | 
			
		||||
                                          tracks: List<Track>): Observable<Manga>? {
 | 
			
		||||
        // Get source
 | 
			
		||||
        val source = backupManager.sourceManager.get(manga.source) ?: return null
 | 
			
		||||
        val source = backupManager.sourceManager.getOrStub(manga.source)
 | 
			
		||||
        val dbManga = backupManager.getMangaFromDatabase(manga)
 | 
			
		||||
 | 
			
		||||
        return if (dbManga == null) {
 | 
			
		||||
@@ -441,4 +442,4 @@ class BackupRestoreService : Service() {
 | 
			
		||||
        sendLocalBroadcast(intent)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,24 @@
 | 
			
		||||
package eu.kanade.tachiyomi.source
 | 
			
		||||
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
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 eu.kanade.tachiyomi.source.online.english.*
 | 
			
		||||
import eu.kanade.tachiyomi.source.online.german.WieManga
 | 
			
		||||
import eu.kanade.tachiyomi.source.online.russian.Mangachan
 | 
			
		||||
import eu.kanade.tachiyomi.source.online.russian.Mintmanga
 | 
			
		||||
import eu.kanade.tachiyomi.source.online.russian.Readmanga
 | 
			
		||||
import rx.Observable
 | 
			
		||||
 | 
			
		||||
open class SourceManager(private val context: Context) {
 | 
			
		||||
 | 
			
		||||
    private val sourcesMap = mutableMapOf<Long, Source>()
 | 
			
		||||
 | 
			
		||||
    private val stubSourcesMap = mutableMapOf<Long, StubSource>()
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        createInternalSources().forEach { registerSource(it) }
 | 
			
		||||
    }
 | 
			
		||||
@@ -20,13 +27,19 @@ open class SourceManager(private val context: Context) {
 | 
			
		||||
        return sourcesMap[sourceKey]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getOrStub(sourceKey: Long): Source {
 | 
			
		||||
        return sourcesMap[sourceKey] ?: stubSourcesMap.getOrPut(sourceKey) {
 | 
			
		||||
            StubSource(sourceKey)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getOnlineSources() = sourcesMap.values.filterIsInstance<HttpSource>()
 | 
			
		||||
 | 
			
		||||
    fun getCatalogueSources() = sourcesMap.values.filterIsInstance<CatalogueSource>()
 | 
			
		||||
 | 
			
		||||
    internal fun registerSource(source: Source, overwrite: Boolean = false) {
 | 
			
		||||
        if (overwrite || !sourcesMap.containsKey(source.id)) {
 | 
			
		||||
            sourcesMap.put(source.id, source)
 | 
			
		||||
            sourcesMap[source.id] = source
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -47,4 +60,30 @@ open class SourceManager(private val context: Context) {
 | 
			
		||||
            Mangasee(),
 | 
			
		||||
            WieManga()
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    private inner class StubSource(override val id: Long) : Source {
 | 
			
		||||
 | 
			
		||||
        override val name: String
 | 
			
		||||
            get() = id.toString()
 | 
			
		||||
 | 
			
		||||
        override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
 | 
			
		||||
            return Observable.error(getSourceNotInstalledException())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
 | 
			
		||||
            return Observable.error(getSourceNotInstalledException())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
 | 
			
		||||
            return Observable.error(getSourceNotInstalledException())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        override fun toString(): String {
 | 
			
		||||
            return name
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private fun getSourceNotInstalledException(): Exception {
 | 
			
		||||
            return Exception(context.getString(R.string.source_not_installed, id.toString()))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,9 @@ import uy.kohesive.injekt.Injekt
 | 
			
		||||
import uy.kohesive.injekt.api.get
 | 
			
		||||
import java.io.IOException
 | 
			
		||||
import java.io.InputStream
 | 
			
		||||
import java.util.*
 | 
			
		||||
import java.util.ArrayList
 | 
			
		||||
import java.util.Collections
 | 
			
		||||
import java.util.Comparator
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class containing library information.
 | 
			
		||||
@@ -113,9 +115,6 @@ class LibraryPresenter(
 | 
			
		||||
        val filterCompleted = preferences.filterCompleted().getOrDefault()
 | 
			
		||||
 | 
			
		||||
        val filterFn: (LibraryItem) -> Boolean = f@ { item ->
 | 
			
		||||
            // Filter out manga without source.
 | 
			
		||||
            sourceManager.get(item.manga.source) ?: return@f false
 | 
			
		||||
 | 
			
		||||
            // Filter when there isn't unread chapters.
 | 
			
		||||
            if (filterUnread && item.manga.unread == 0) {
 | 
			
		||||
                return@f false
 | 
			
		||||
@@ -197,8 +196,8 @@ class LibraryPresenter(
 | 
			
		||||
                    manga1TotalChapter.compareTo(mange2TotalChapter)
 | 
			
		||||
                }
 | 
			
		||||
                LibrarySort.SOURCE -> {
 | 
			
		||||
                    val source1Name = sourceManager.get(i1.manga.source)?.name ?: ""
 | 
			
		||||
                    val source2Name = sourceManager.get(i2.manga.source)?.name ?: ""
 | 
			
		||||
                    val source1Name = sourceManager.getOrStub(i1.manga.source).name
 | 
			
		||||
                    val source2Name = sourceManager.getOrStub(i2.manga.source).name
 | 
			
		||||
                    source1Name.compareTo(source2Name)
 | 
			
		||||
                }
 | 
			
		||||
                else -> throw Exception("Unknown sorting mode")
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@ import kotlinx.android.synthetic.main.manga_controller.*
 | 
			
		||||
import rx.Subscription
 | 
			
		||||
import uy.kohesive.injekt.Injekt
 | 
			
		||||
import uy.kohesive.injekt.api.get
 | 
			
		||||
import java.util.*
 | 
			
		||||
import java.util.Date
 | 
			
		||||
 | 
			
		||||
class MangaController : RxController, TabbedController {
 | 
			
		||||
 | 
			
		||||
@@ -44,7 +44,7 @@ class MangaController : RxController, TabbedController {
 | 
			
		||||
    }) {
 | 
			
		||||
        this.manga = manga
 | 
			
		||||
        if (manga != null) {
 | 
			
		||||
            source = Injekt.get<SourceManager>().get(manga.source)
 | 
			
		||||
            source = Injekt.get<SourceManager>().getOrStub(manga.source)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ class MigrationPresenter(
 | 
			
		||||
    private fun findSourcesWithManga(library: List<Manga>): List<SourceItem> {
 | 
			
		||||
        val header = SelectionHeader()
 | 
			
		||||
        return library.map { it.source }.toSet()
 | 
			
		||||
                .mapNotNull { if (it != LocalSource.ID) sourceManager.get(it) else null }
 | 
			
		||||
                .mapNotNull { if (it != LocalSource.ID) sourceManager.getOrStub(it) else null }
 | 
			
		||||
                .map { SourceItem(it, header) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,8 @@ import uy.kohesive.injekt.Injekt
 | 
			
		||||
import uy.kohesive.injekt.api.get
 | 
			
		||||
import java.io.File
 | 
			
		||||
import java.net.URLConnection
 | 
			
		||||
import java.util.*
 | 
			
		||||
import java.util.Comparator
 | 
			
		||||
import java.util.Date
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Presenter of [ReaderActivity].
 | 
			
		||||
@@ -74,7 +75,7 @@ class ReaderPresenter(
 | 
			
		||||
    /**
 | 
			
		||||
     * Source of the manga.
 | 
			
		||||
     */
 | 
			
		||||
    private val source by lazy { sourceManager.get(manga.source)!! }
 | 
			
		||||
    private val source by lazy { sourceManager.getOrStub(manga.source) }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Chapter list for the active manga. It's retrieved lazily and should be accessed for the first
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,9 @@ import rx.schedulers.Schedulers
 | 
			
		||||
import timber.log.Timber
 | 
			
		||||
import uy.kohesive.injekt.Injekt
 | 
			
		||||
import uy.kohesive.injekt.api.get
 | 
			
		||||
import java.util.*
 | 
			
		||||
import java.util.Calendar
 | 
			
		||||
import java.util.Date
 | 
			
		||||
import java.util.TreeMap
 | 
			
		||||
 | 
			
		||||
class RecentChaptersPresenter(
 | 
			
		||||
        val preferences: PreferencesHelper = Injekt.get(),
 | 
			
		||||
@@ -57,7 +59,6 @@ class RecentChaptersPresenter(
 | 
			
		||||
                .map { mangaChapters ->
 | 
			
		||||
                    val map = TreeMap<Date, MutableList<MangaChapter>> { d1, d2 -> d2.compareTo(d1) }
 | 
			
		||||
                    val byDay = mangaChapters
 | 
			
		||||
                            .filter { sourceManager.get(it.manga.source) != null }
 | 
			
		||||
                            .groupByTo(map, { getMapKey(it.chapter.date_fetch) })
 | 
			
		||||
                    byDay.flatMap {
 | 
			
		||||
                        val dateItem = DateItem(it.key)
 | 
			
		||||
@@ -195,4 +196,4 @@ class RecentChaptersPresenter(
 | 
			
		||||
        item.download = null
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
 | 
			
		||||
import eu.kanade.tachiyomi.data.glide.GlideApp
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
 | 
			
		||||
import kotlinx.android.synthetic.main.recently_read_item.*
 | 
			
		||||
import java.util.*
 | 
			
		||||
import java.util.Date
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Holder that contains recent manga item
 | 
			
		||||
@@ -52,7 +52,7 @@ class RecentlyReadHolder(
 | 
			
		||||
        // Set source + chapter title
 | 
			
		||||
        val formattedNumber = adapter.decimalFormat.format(chapter.chapter_number.toDouble())
 | 
			
		||||
        manga_source.text = itemView.context.getString(R.string.recent_manga_source)
 | 
			
		||||
                .format(adapter.sourceManager.get(manga.source)?.toString(), formattedNumber)
 | 
			
		||||
                .format(adapter.sourceManager.getOrStub(manga.source).toString(), formattedNumber)
 | 
			
		||||
 | 
			
		||||
        // Set last read timestamp title
 | 
			
		||||
        last_read.text = adapter.dateFormat.format(Date(history.last_read))
 | 
			
		||||
 
 | 
			
		||||
@@ -5,12 +5,13 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.models.Chapter
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.models.History
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.models.Manga
 | 
			
		||||
import eu.kanade.tachiyomi.source.SourceManager
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import rx.android.schedulers.AndroidSchedulers
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
import java.util.*
 | 
			
		||||
import java.util.Calendar
 | 
			
		||||
import java.util.Comparator
 | 
			
		||||
import java.util.Date
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Presenter of RecentlyReadFragment.
 | 
			
		||||
@@ -24,8 +25,6 @@ class RecentlyReadPresenter : BasePresenter<RecentlyReadController>() {
 | 
			
		||||
     */
 | 
			
		||||
    val db: DatabaseHelper by injectLazy()
 | 
			
		||||
 | 
			
		||||
    private val sourceManager: SourceManager by injectLazy()
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(savedState: Bundle?) {
 | 
			
		||||
        super.onCreate(savedState)
 | 
			
		||||
 | 
			
		||||
@@ -45,10 +44,7 @@ class RecentlyReadPresenter : BasePresenter<RecentlyReadController>() {
 | 
			
		||||
        cal.add(Calendar.MONTH, -1)
 | 
			
		||||
 | 
			
		||||
        return db.getRecentManga(cal.time).asRxObservable()
 | 
			
		||||
                .map { recents ->
 | 
			
		||||
                    recents.filter { sourceManager.get(it.manga.source) != null }
 | 
			
		||||
                            .map(::RecentlyReadItem)
 | 
			
		||||
                }
 | 
			
		||||
                .map { recents -> recents.map(::RecentlyReadItem) }
 | 
			
		||||
                .observeOn(AndroidSchedulers.mainThread())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user