mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-23 02:21:47 +01:00
Show manga with no installed source. Based on PR #1345
This commit is contained in:
parent
fd825b1049
commit
3d1afe7cf2
@ -33,7 +33,8 @@ import timber.log.Timber
|
|||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
import java.util.concurrent.ExecutorService
|
import java.util.concurrent.ExecutorService
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
@ -295,7 +296,7 @@ class BackupRestoreService : Service() {
|
|||||||
categories: List<String>, history: List<DHistory>,
|
categories: List<String>, history: List<DHistory>,
|
||||||
tracks: List<Track>): Observable<Manga>? {
|
tracks: List<Track>): Observable<Manga>? {
|
||||||
// Get source
|
// Get source
|
||||||
val source = backupManager.sourceManager.get(manga.source) ?: return null
|
val source = backupManager.sourceManager.getOrStub(manga.source)
|
||||||
val dbManga = backupManager.getMangaFromDatabase(manga)
|
val dbManga = backupManager.getMangaFromDatabase(manga)
|
||||||
|
|
||||||
return if (dbManga == null) {
|
return if (dbManga == null) {
|
||||||
|
@ -1,17 +1,24 @@
|
|||||||
package eu.kanade.tachiyomi.source
|
package eu.kanade.tachiyomi.source
|
||||||
|
|
||||||
import android.content.Context
|
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.HttpSource
|
||||||
import eu.kanade.tachiyomi.source.online.english.*
|
import eu.kanade.tachiyomi.source.online.english.*
|
||||||
import eu.kanade.tachiyomi.source.online.german.WieManga
|
import eu.kanade.tachiyomi.source.online.german.WieManga
|
||||||
import eu.kanade.tachiyomi.source.online.russian.Mangachan
|
import eu.kanade.tachiyomi.source.online.russian.Mangachan
|
||||||
import eu.kanade.tachiyomi.source.online.russian.Mintmanga
|
import eu.kanade.tachiyomi.source.online.russian.Mintmanga
|
||||||
import eu.kanade.tachiyomi.source.online.russian.Readmanga
|
import eu.kanade.tachiyomi.source.online.russian.Readmanga
|
||||||
|
import rx.Observable
|
||||||
|
|
||||||
open class SourceManager(private val context: Context) {
|
open class SourceManager(private val context: Context) {
|
||||||
|
|
||||||
private val sourcesMap = mutableMapOf<Long, Source>()
|
private val sourcesMap = mutableMapOf<Long, Source>()
|
||||||
|
|
||||||
|
private val stubSourcesMap = mutableMapOf<Long, StubSource>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
createInternalSources().forEach { registerSource(it) }
|
createInternalSources().forEach { registerSource(it) }
|
||||||
}
|
}
|
||||||
@ -20,13 +27,19 @@ open class SourceManager(private val context: Context) {
|
|||||||
return sourcesMap[sourceKey]
|
return sourcesMap[sourceKey]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getOrStub(sourceKey: Long): Source {
|
||||||
|
return sourcesMap[sourceKey] ?: stubSourcesMap.getOrPut(sourceKey) {
|
||||||
|
StubSource(sourceKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getOnlineSources() = sourcesMap.values.filterIsInstance<HttpSource>()
|
fun getOnlineSources() = sourcesMap.values.filterIsInstance<HttpSource>()
|
||||||
|
|
||||||
fun getCatalogueSources() = sourcesMap.values.filterIsInstance<CatalogueSource>()
|
fun getCatalogueSources() = sourcesMap.values.filterIsInstance<CatalogueSource>()
|
||||||
|
|
||||||
internal fun registerSource(source: Source, overwrite: Boolean = false) {
|
internal fun registerSource(source: Source, overwrite: Boolean = false) {
|
||||||
if (overwrite || !sourcesMap.containsKey(source.id)) {
|
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(),
|
Mangasee(),
|
||||||
WieManga()
|
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 uy.kohesive.injekt.api.get
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.util.*
|
import java.util.ArrayList
|
||||||
|
import java.util.Collections
|
||||||
|
import java.util.Comparator
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class containing library information.
|
* Class containing library information.
|
||||||
@ -113,9 +115,6 @@ class LibraryPresenter(
|
|||||||
val filterCompleted = preferences.filterCompleted().getOrDefault()
|
val filterCompleted = preferences.filterCompleted().getOrDefault()
|
||||||
|
|
||||||
val filterFn: (LibraryItem) -> Boolean = f@ { item ->
|
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.
|
// Filter when there isn't unread chapters.
|
||||||
if (filterUnread && item.manga.unread == 0) {
|
if (filterUnread && item.manga.unread == 0) {
|
||||||
return@f false
|
return@f false
|
||||||
@ -197,8 +196,8 @@ class LibraryPresenter(
|
|||||||
manga1TotalChapter.compareTo(mange2TotalChapter)
|
manga1TotalChapter.compareTo(mange2TotalChapter)
|
||||||
}
|
}
|
||||||
LibrarySort.SOURCE -> {
|
LibrarySort.SOURCE -> {
|
||||||
val source1Name = sourceManager.get(i1.manga.source)?.name ?: ""
|
val source1Name = sourceManager.getOrStub(i1.manga.source).name
|
||||||
val source2Name = sourceManager.get(i2.manga.source)?.name ?: ""
|
val source2Name = sourceManager.getOrStub(i2.manga.source).name
|
||||||
source1Name.compareTo(source2Name)
|
source1Name.compareTo(source2Name)
|
||||||
}
|
}
|
||||||
else -> throw Exception("Unknown sorting mode")
|
else -> throw Exception("Unknown sorting mode")
|
||||||
|
@ -34,7 +34,7 @@ import kotlinx.android.synthetic.main.manga_controller.*
|
|||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.*
|
import java.util.Date
|
||||||
|
|
||||||
class MangaController : RxController, TabbedController {
|
class MangaController : RxController, TabbedController {
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ class MangaController : RxController, TabbedController {
|
|||||||
}) {
|
}) {
|
||||||
this.manga = manga
|
this.manga = manga
|
||||||
if (manga != null) {
|
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> {
|
private fun findSourcesWithManga(library: List<Manga>): List<SourceItem> {
|
||||||
val header = SelectionHeader()
|
val header = SelectionHeader()
|
||||||
return library.map { it.source }.toSet()
|
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) }
|
.map { SourceItem(it, header) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,8 @@ import uy.kohesive.injekt.Injekt
|
|||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URLConnection
|
import java.net.URLConnection
|
||||||
import java.util.*
|
import java.util.Comparator
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Presenter of [ReaderActivity].
|
* Presenter of [ReaderActivity].
|
||||||
@ -74,7 +75,7 @@ class ReaderPresenter(
|
|||||||
/**
|
/**
|
||||||
* Source of the manga.
|
* 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
|
* 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 timber.log.Timber
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.*
|
import java.util.Calendar
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.TreeMap
|
||||||
|
|
||||||
class RecentChaptersPresenter(
|
class RecentChaptersPresenter(
|
||||||
val preferences: PreferencesHelper = Injekt.get(),
|
val preferences: PreferencesHelper = Injekt.get(),
|
||||||
@ -57,7 +59,6 @@ class RecentChaptersPresenter(
|
|||||||
.map { mangaChapters ->
|
.map { mangaChapters ->
|
||||||
val map = TreeMap<Date, MutableList<MangaChapter>> { d1, d2 -> d2.compareTo(d1) }
|
val map = TreeMap<Date, MutableList<MangaChapter>> { d1, d2 -> d2.compareTo(d1) }
|
||||||
val byDay = mangaChapters
|
val byDay = mangaChapters
|
||||||
.filter { sourceManager.get(it.manga.source) != null }
|
|
||||||
.groupByTo(map, { getMapKey(it.chapter.date_fetch) })
|
.groupByTo(map, { getMapKey(it.chapter.date_fetch) })
|
||||||
byDay.flatMap {
|
byDay.flatMap {
|
||||||
val dateItem = DateItem(it.key)
|
val dateItem = DateItem(it.key)
|
||||||
|
@ -7,7 +7,7 @@ import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
|
|||||||
import eu.kanade.tachiyomi.data.glide.GlideApp
|
import eu.kanade.tachiyomi.data.glide.GlideApp
|
||||||
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
||||||
import kotlinx.android.synthetic.main.recently_read_item.*
|
import kotlinx.android.synthetic.main.recently_read_item.*
|
||||||
import java.util.*
|
import java.util.Date
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holder that contains recent manga item
|
* Holder that contains recent manga item
|
||||||
@ -52,7 +52,7 @@ class RecentlyReadHolder(
|
|||||||
// Set source + chapter title
|
// Set source + chapter title
|
||||||
val formattedNumber = adapter.decimalFormat.format(chapter.chapter_number.toDouble())
|
val formattedNumber = adapter.decimalFormat.format(chapter.chapter_number.toDouble())
|
||||||
manga_source.text = itemView.context.getString(R.string.recent_manga_source)
|
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
|
// Set last read timestamp title
|
||||||
last_read.text = adapter.dateFormat.format(Date(history.last_read))
|
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.Chapter
|
||||||
import eu.kanade.tachiyomi.data.database.models.History
|
import eu.kanade.tachiyomi.data.database.models.History
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
import rx.android.schedulers.AndroidSchedulers
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.util.*
|
import java.util.Calendar
|
||||||
|
import java.util.Comparator
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Presenter of RecentlyReadFragment.
|
* Presenter of RecentlyReadFragment.
|
||||||
@ -24,8 +25,6 @@ class RecentlyReadPresenter : BasePresenter<RecentlyReadController>() {
|
|||||||
*/
|
*/
|
||||||
val db: DatabaseHelper by injectLazy()
|
val db: DatabaseHelper by injectLazy()
|
||||||
|
|
||||||
private val sourceManager: SourceManager by injectLazy()
|
|
||||||
|
|
||||||
override fun onCreate(savedState: Bundle?) {
|
override fun onCreate(savedState: Bundle?) {
|
||||||
super.onCreate(savedState)
|
super.onCreate(savedState)
|
||||||
|
|
||||||
@ -45,10 +44,7 @@ class RecentlyReadPresenter : BasePresenter<RecentlyReadController>() {
|
|||||||
cal.add(Calendar.MONTH, -1)
|
cal.add(Calendar.MONTH, -1)
|
||||||
|
|
||||||
return db.getRecentManga(cal.time).asRxObservable()
|
return db.getRecentManga(cal.time).asRxObservable()
|
||||||
.map { recents ->
|
.map { recents -> recents.map(::RecentlyReadItem) }
|
||||||
recents.filter { sourceManager.get(it.manga.source) != null }
|
|
||||||
.map(::RecentlyReadItem)
|
|
||||||
}
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,6 +349,7 @@
|
|||||||
<string name="icon_creation_fail">Failed to create shortcut!</string>
|
<string name="icon_creation_fail">Failed to create shortcut!</string>
|
||||||
<string name="delete_downloads_for_manga">Delete downloaded chapters?</string>
|
<string name="delete_downloads_for_manga">Delete downloaded chapters?</string>
|
||||||
<string name="copied_to_clipboard">%1$s copied to clipboard</string>
|
<string name="copied_to_clipboard">%1$s copied to clipboard</string>
|
||||||
|
<string name="source_not_installed">Source not installed: %1$s</string>
|
||||||
|
|
||||||
<!-- Manga chapters fragment -->
|
<!-- Manga chapters fragment -->
|
||||||
<string name="manga_chapters_tab">Chapters</string>
|
<string name="manga_chapters_tab">Chapters</string>
|
||||||
|
@ -7,7 +7,7 @@ buildscript {
|
|||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.1.2'
|
classpath 'com.android.tools.build:gradle:3.1.3'
|
||||||
classpath 'com.github.ben-manes:gradle-versions-plugin:0.17.0'
|
classpath 'com.github.ben-manes:gradle-versions-plugin:0.17.0'
|
||||||
classpath 'com.github.zellius:android-shortcut-gradle-plugin:0.1.2'
|
classpath 'com.github.zellius:android-shortcut-gradle-plugin:0.1.2'
|
||||||
classpath 'com.google.gms:google-services:3.2.0'
|
classpath 'com.google.gms:google-services:3.2.0'
|
||||||
|
Loading…
Reference in New Issue
Block a user