mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-25 06:11:04 +03:00
breaking changes!!!
-moved a bunch of classes to the package called animesource -implemented a downloader that (barely) works
This commit is contained in:
parent
58c954e1c3
commit
6461ea42dc
101 changed files with 583 additions and 471 deletions
|
@ -2,6 +2,7 @@ package eu.kanade.tachiyomi
|
|||
|
||||
import android.app.Application
|
||||
import android.os.Handler
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.data.cache.AnimeCoverCache
|
||||
import eu.kanade.tachiyomi.data.cache.ChapterCache
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
|
@ -15,7 +16,6 @@ import eu.kanade.tachiyomi.data.track.TrackManager
|
|||
import eu.kanade.tachiyomi.extension.AnimeExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import kotlinx.serialization.json.Json
|
||||
import uy.kohesive.injekt.api.InjektModule
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package eu.kanade.tachiyomi.source
|
||||
package eu.kanade.tachiyomi.animesource
|
||||
|
||||
import eu.kanade.tachiyomi.source.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.animesource.model.FilterList
|
||||
import rx.Observable
|
||||
|
||||
interface AnimeCatalogueSource : AnimeSource {
|
|
@ -0,0 +1,30 @@
|
|||
package eu.kanade.tachiyomi.animesource
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||
import rx.Observable
|
||||
import timber.log.Timber
|
||||
|
||||
fun AnimeHttpSource.getImageUrl(video: Video): Observable<Video> {
|
||||
Timber.w("getImageUrl")
|
||||
video.status = Video.LOAD_VIDEO
|
||||
return fetchVideoLink(video)
|
||||
.doOnError { video.status = Video.ERROR }
|
||||
.onErrorReturn { null }
|
||||
.doOnNext { video.videoUrl = it }
|
||||
.map { video }
|
||||
}
|
||||
|
||||
fun AnimeHttpSource.fetchUrlFromVideo(video: Video): Observable<Video> {
|
||||
Timber.w("fetchUrlFromVideo")
|
||||
return Observable.just(video)
|
||||
.filter { !it.url.isEmpty() }
|
||||
.mergeWith(fetchRemainingImageUrlsFromPageList(video))
|
||||
}
|
||||
|
||||
fun AnimeHttpSource.fetchRemainingImageUrlsFromPageList(video: Video): Observable<Video> {
|
||||
Timber.w("fetchRemainingImageUrlsFromPageList")
|
||||
return Observable.just(video)
|
||||
.filter { it.url.isEmpty() }
|
||||
.concatMap { getImageUrl(it) }
|
||||
}
|
|
@ -1,24 +1,24 @@
|
|||
package eu.kanade.tachiyomi.source
|
||||
package eu.kanade.tachiyomi.animesource
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.toAnimeInfo
|
||||
import eu.kanade.tachiyomi.animesource.model.toEpisodeInfo
|
||||
import eu.kanade.tachiyomi.animesource.model.toSAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.toSEpisode
|
||||
import eu.kanade.tachiyomi.extension.AnimeExtensionManager
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import eu.kanade.tachiyomi.source.model.SEpisode
|
||||
import eu.kanade.tachiyomi.source.model.toAnimeInfo
|
||||
import eu.kanade.tachiyomi.source.model.toEpisodeInfo
|
||||
import eu.kanade.tachiyomi.source.model.toSAnime
|
||||
import eu.kanade.tachiyomi.source.model.toSEpisode
|
||||
import eu.kanade.tachiyomi.util.lang.awaitSingle
|
||||
import rx.Observable
|
||||
import tachiyomi.source.model.AnimeInfo
|
||||
import tachiyomi.source.model.EpisodeInfo
|
||||
import tachiyomi.animesource.model.AnimeInfo
|
||||
import tachiyomi.animesource.model.EpisodeInfo
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
/**
|
||||
* A basic interface for creating a source. It could be an online source, a local source, etc...
|
||||
*/
|
||||
interface AnimeSource : tachiyomi.source.AnimeSource {
|
||||
interface AnimeSource : tachiyomi.animesource.AnimeSource {
|
||||
|
||||
/**
|
||||
* Id for the source. Must be unique.
|
|
@ -1,4 +1,4 @@
|
|||
package eu.kanade.tachiyomi.source
|
||||
package eu.kanade.tachiyomi.animesource
|
||||
|
||||
/**
|
||||
* A factory for creating sources at runtime.
|
|
@ -1,10 +1,10 @@
|
|||
package eu.kanade.tachiyomi.source
|
||||
package eu.kanade.tachiyomi.animesource
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import eu.kanade.tachiyomi.source.model.SEpisode
|
||||
import eu.kanade.tachiyomi.source.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||
import rx.Observable
|
||||
|
||||
open class AnimeSourceManager(private val context: Context) {
|
|
@ -1,4 +1,4 @@
|
|||
package eu.kanade.tachiyomi.source
|
||||
package eu.kanade.tachiyomi.animesource
|
||||
|
||||
import androidx.preference.PreferenceScreen
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
package eu.kanade.tachiyomi.source
|
||||
package eu.kanade.tachiyomi.animesource
|
||||
|
||||
import android.content.Context
|
||||
import com.github.junrar.Archive
|
||||
import com.google.gson.JsonParser
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import eu.kanade.tachiyomi.source.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.animesource.model.Filter
|
||||
import eu.kanade.tachiyomi.animesource.model.FilterList
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.util.episode.EpisodeRecognition
|
||||
import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder
|
||||
import eu.kanade.tachiyomi.util.storage.AnimeFile
|
|
@ -1,3 +1,3 @@
|
|||
package eu.kanade.tachiyomi.source.model
|
||||
package eu.kanade.tachiyomi.animesource.model
|
||||
|
||||
data class AnimesPage(val animes: List<SAnime>, val hasNextPage: Boolean)
|
|
@ -0,0 +1,40 @@
|
|||
package eu.kanade.tachiyomi.animesource.model
|
||||
|
||||
sealed class Filter<T>(val name: String, var state: T) {
|
||||
open class Header(name: String) : Filter<Any>(name, 0)
|
||||
open class Separator(name: String = "") : Filter<Any>(name, 0)
|
||||
abstract class Select<V>(name: String, val values: Array<V>, state: Int = 0) : Filter<Int>(name, state)
|
||||
abstract class Text(name: String, state: String = "") : Filter<String>(name, state)
|
||||
abstract class CheckBox(name: String, state: Boolean = false) : Filter<Boolean>(name, state)
|
||||
abstract class TriState(name: String, state: Int = STATE_IGNORE) : Filter<Int>(name, state) {
|
||||
fun isIgnored() = state == STATE_IGNORE
|
||||
fun isIncluded() = state == STATE_INCLUDE
|
||||
fun isExcluded() = state == STATE_EXCLUDE
|
||||
|
||||
companion object {
|
||||
const val STATE_IGNORE = 0
|
||||
const val STATE_INCLUDE = 1
|
||||
const val STATE_EXCLUDE = 2
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Group<V>(name: String, state: List<V>) : Filter<List<V>>(name, state)
|
||||
|
||||
abstract class Sort(name: String, val values: Array<String>, state: Selection? = null) :
|
||||
Filter<Sort.Selection?>(name, state) {
|
||||
data class Selection(val index: Int, val ascending: Boolean)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is Filter<*>) return false
|
||||
|
||||
return name == other.name && state == other.state
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = name.hashCode()
|
||||
result = 31 * result + (state?.hashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package eu.kanade.tachiyomi.animesource.model
|
||||
|
||||
data class FilterList(val list: List<Filter<*>>) : List<Filter<*>> by list {
|
||||
|
||||
constructor(vararg fs: Filter<*>) : this(if (fs.isNotEmpty()) fs.asList() else emptyList())
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package eu.kanade.tachiyomi.source.model
|
||||
package eu.kanade.tachiyomi.animesource.model
|
||||
|
||||
import tachiyomi.source.model.AnimeInfo
|
||||
import tachiyomi.animesource.model.AnimeInfo
|
||||
import java.io.Serializable
|
||||
|
||||
interface SAnime : Serializable {
|
|
@ -1,4 +1,4 @@
|
|||
package eu.kanade.tachiyomi.source.model
|
||||
package eu.kanade.tachiyomi.animesource.model
|
||||
|
||||
class SAnimeImpl : SAnime {
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package eu.kanade.tachiyomi.source.model
|
||||
package eu.kanade.tachiyomi.animesource.model
|
||||
|
||||
import tachiyomi.source.model.EpisodeInfo
|
||||
import tachiyomi.animesource.model.EpisodeInfo
|
||||
import java.io.Serializable
|
||||
|
||||
interface SEpisode : Serializable {
|
|
@ -1,4 +1,4 @@
|
|||
package eu.kanade.tachiyomi.source.model
|
||||
package eu.kanade.tachiyomi.animesource.model
|
||||
|
||||
class SEpisodeImpl : SEpisode {
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package eu.kanade.tachiyomi.animesource.model
|
||||
|
||||
import android.net.Uri
|
||||
import eu.kanade.tachiyomi.network.ProgressListener
|
||||
import rx.subjects.Subject
|
||||
import tachiyomi.animesource.model.VideoUrl
|
||||
|
||||
open class Video(
|
||||
val url: String = "",
|
||||
var videoUrl: String? = null,
|
||||
@Transient var uri: Uri? = null // Deprecated but can't be deleted due to extensions
|
||||
) : ProgressListener {
|
||||
|
||||
@Transient
|
||||
@Volatile
|
||||
var status: Int = 0
|
||||
set(value) {
|
||||
field = value
|
||||
statusSubject?.onNext(value)
|
||||
statusCallback?.invoke(this)
|
||||
}
|
||||
|
||||
@Transient
|
||||
@Volatile
|
||||
var progress: Int = 0
|
||||
set(value) {
|
||||
field = value
|
||||
statusCallback?.invoke(this)
|
||||
}
|
||||
|
||||
@Transient
|
||||
private var statusSubject: Subject<Int, Int>? = null
|
||||
|
||||
@Transient
|
||||
private var statusCallback: ((Video) -> Unit)? = null
|
||||
|
||||
override fun update(bytesRead: Long, contentLength: Long, done: Boolean) {
|
||||
progress = if (contentLength > 0) {
|
||||
(100 * bytesRead / contentLength).toInt()
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
||||
fun setStatusSubject(subject: Subject<Int, Int>?) {
|
||||
this.statusSubject = subject
|
||||
}
|
||||
|
||||
fun setStatusCallback(f: ((Video) -> Unit)?) {
|
||||
statusCallback = f
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val QUEUE = 0
|
||||
const val LOAD_VIDEO = 1
|
||||
const val DOWNLOAD_IMAGE = 2
|
||||
const val READY = 3
|
||||
const val ERROR = 4
|
||||
}
|
||||
}
|
||||
|
||||
fun Video.toVideoUrl(): VideoUrl {
|
||||
return VideoUrl(
|
||||
url = this.videoUrl ?: this.url
|
||||
)
|
||||
}
|
||||
|
||||
fun VideoUrl.toVideo(index: Int): Video {
|
||||
return Video(
|
||||
videoUrl = this.url
|
||||
)
|
||||
}
|
|
@ -1,20 +1,19 @@
|
|||
package eu.kanade.tachiyomi.source.online
|
||||
package eu.kanade.tachiyomi.animesource.online
|
||||
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||
import eu.kanade.tachiyomi.network.newCallWithProgress
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.source.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import eu.kanade.tachiyomi.source.model.SEpisode
|
||||
import android.net.Uri
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.animesource.model.FilterList
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.*
|
||||
import okhttp3.Headers
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import rx.Observable
|
||||
import timber.log.Timber
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.net.URI
|
||||
import java.net.URISyntaxException
|
||||
|
@ -226,6 +225,67 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an observable with the page containing the source url of the image. If there's any
|
||||
* error, it will return null instead of throwing an exception.
|
||||
*
|
||||
* @param page the page whose source image has to be fetched.
|
||||
*/
|
||||
open fun fetchVideoLink(video: Video): Observable<String> {
|
||||
Timber.w("fetchVideoLink")
|
||||
return client.newCall(videoUrlRequest(video))
|
||||
.asObservableSuccess()
|
||||
.map { videoUrlParse(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request for getting the url to the source image. Override only if it's needed to
|
||||
* override the url, send different headers or request method like POST.
|
||||
*
|
||||
* @param video the episode whose page list has to be fetched
|
||||
*/
|
||||
protected open fun videoUrlRequest(video: Video): Request {
|
||||
return GET(video.url, headers)
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the response from the site and returns the absolute url to the source image.
|
||||
*
|
||||
* @param response the response from the site.
|
||||
*/
|
||||
protected abstract fun videoUrlParse(response: Response): String
|
||||
|
||||
/**
|
||||
* Returns an observable with the response of the source image.
|
||||
*
|
||||
* @param page the page whose source image has to be downloaded.
|
||||
*/
|
||||
fun fetchVideo(page: Video): Observable<Response> {
|
||||
return client.newCallWithProgress(videoRequest(page), page)
|
||||
.asObservableSuccess()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request for getting the source image. Override only if it's needed to override
|
||||
* the url, send different headers or request method like POST.
|
||||
*
|
||||
* @param video the episode whose page list has to be fetched
|
||||
*/
|
||||
protected open fun videoRequest(video: Video): Request {
|
||||
return GET(video.videoUrl!!, headers)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an observable with the page list for a chapter.
|
||||
*
|
||||
* @param chapter the chapter whose page list has to be fetched.
|
||||
*/
|
||||
fun fetchVideoList(episode: SEpisode): Observable<Video> {
|
||||
return client.newCall(episodeLinkRequest(episode))
|
||||
.asObservableSuccess()
|
||||
.map { response -> val link = episodeLinkParse(response); Video(link, link, Uri.parse(link)) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request for updating the episode list. Override only if it's needed to override
|
||||
* the url, send different headers or request method like POST.
|
||||
|
@ -260,72 +320,6 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
*/
|
||||
protected abstract fun episodeLinkParse(response: Response): String
|
||||
|
||||
/**
|
||||
* Returns the request for getting the page list. Override only if it's needed to override the
|
||||
* url, send different headers or request method like POST.
|
||||
*
|
||||
* @param episode the episode whose page list has to be fetched.
|
||||
*/
|
||||
protected open fun pageListRequest(episode: SEpisode): Request {
|
||||
return GET(baseUrl + episode.url, headers)
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the response from the site and returns a list of pages.
|
||||
*
|
||||
* @param response the response from the site.
|
||||
*/
|
||||
protected abstract fun pageListParse(response: Response): List<Page>
|
||||
|
||||
/**
|
||||
* Returns an observable with the page containing the source url of the image. If there's any
|
||||
* error, it will return null instead of throwing an exception.
|
||||
*
|
||||
* @param page the page whose source image has to be fetched.
|
||||
*/
|
||||
open fun fetchImageUrl(page: Page): Observable<String> {
|
||||
return client.newCall(imageUrlRequest(page))
|
||||
.asObservableSuccess()
|
||||
.map { imageUrlParse(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request for getting the url to the source image. Override only if it's needed to
|
||||
* override the url, send different headers or request method like POST.
|
||||
*
|
||||
* @param page the episode whose page list has to be fetched
|
||||
*/
|
||||
protected open fun imageUrlRequest(page: Page): Request {
|
||||
return GET(page.url, headers)
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the response from the site and returns the absolute url to the source image.
|
||||
*
|
||||
* @param response the response from the site.
|
||||
*/
|
||||
protected abstract fun imageUrlParse(response: Response): String
|
||||
|
||||
/**
|
||||
* Returns an observable with the response of the source image.
|
||||
*
|
||||
* @param page the page whose source image has to be downloaded.
|
||||
*/
|
||||
fun fetchImage(page: Page): Observable<Response> {
|
||||
return client.newCallWithProgress(imageRequest(page), page)
|
||||
.asObservableSuccess()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request for getting the source image. Override only if it's needed to override
|
||||
* the url, send different headers or request method like POST.
|
||||
*
|
||||
* @param page the episode whose page list has to be fetched
|
||||
*/
|
||||
protected open fun imageRequest(page: Page): Request {
|
||||
return GET(page.imageUrl!!, headers)
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the url of the episode without the scheme and domain. It saves some redundancy from
|
||||
* database and the urls could still work after a domain change.
|
|
@ -1,9 +1,8 @@
|
|||
package eu.kanade.tachiyomi.source.online
|
||||
package eu.kanade.tachiyomi.animesource.online
|
||||
|
||||
import eu.kanade.tachiyomi.source.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import eu.kanade.tachiyomi.source.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
|
@ -187,36 +186,4 @@ abstract class ParsedAnimeHttpSource : AnimeHttpSource() {
|
|||
* @param element an element obtained from [episodeListSelector].
|
||||
*/
|
||||
protected abstract fun linkFromElement(element: Element): String
|
||||
|
||||
/**
|
||||
* Parses the response from the site and returns the page list.
|
||||
*
|
||||
* @param response the response from the site.
|
||||
*/
|
||||
override fun pageListParse(response: Response): List<Page> {
|
||||
return pageListParse(response.asJsoup())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a page list from the given document.
|
||||
*
|
||||
* @param document the parsed document.
|
||||
*/
|
||||
protected abstract fun pageListParse(document: Document): List<Page>
|
||||
|
||||
/**
|
||||
* Parse the response from the site and returns the absolute url to the source image.
|
||||
*
|
||||
* @param response the response from the site.
|
||||
*/
|
||||
override fun imageUrlParse(response: Response): String {
|
||||
return imageUrlParse(response.asJsoup())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute url to the source image from the document.
|
||||
*
|
||||
* @param document the parsed document.
|
||||
*/
|
||||
protected abstract fun imageUrlParse(document: Document): String
|
||||
}
|
|
@ -7,6 +7,10 @@ import android.os.IBinder
|
|||
import android.os.PowerManager
|
||||
import androidx.core.content.ContextCompat
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.toSAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.toSEpisode
|
||||
import eu.kanade.tachiyomi.data.animelib.AnimelibUpdateRanker.rankingScheme
|
||||
import eu.kanade.tachiyomi.data.animelib.AnimelibUpdateService.Companion.start
|
||||
import eu.kanade.tachiyomi.data.cache.AnimeCoverCache
|
||||
|
@ -23,10 +27,6 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.data.track.TrackService
|
||||
import eu.kanade.tachiyomi.data.track.UnattendedTrackService
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import eu.kanade.tachiyomi.source.model.toSAnime
|
||||
import eu.kanade.tachiyomi.source.model.toSEpisode
|
||||
import eu.kanade.tachiyomi.util.episode.NoEpisodesException
|
||||
import eu.kanade.tachiyomi.util.episode.syncEpisodesWithSource
|
||||
import eu.kanade.tachiyomi.util.episode.syncEpisodesWithTrackServiceTwoWay
|
||||
|
|
|
@ -2,6 +2,8 @@ package eu.kanade.tachiyomi.data.backup
|
|||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.toSEpisode
|
||||
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
|
@ -12,11 +14,9 @@ import eu.kanade.tachiyomi.data.database.models.toAnimeInfo
|
|||
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.model.toSChapter
|
||||
import eu.kanade.tachiyomi.source.model.toSEpisode
|
||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||
import eu.kanade.tachiyomi.util.episode.syncEpisodesWithSource
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
|
|
@ -8,6 +8,8 @@ import com.github.salomonbrys.kotson.registerTypeHierarchyAdapter
|
|||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.JsonArray
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.toSAnime
|
||||
import eu.kanade.tachiyomi.data.backup.AbstractBackupManager
|
||||
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.CURRENT_VERSION
|
||||
import eu.kanade.tachiyomi.data.backup.legacy.models.DHistory
|
||||
|
@ -28,9 +30,7 @@ import eu.kanade.tachiyomi.data.database.models.Track
|
|||
import eu.kanade.tachiyomi.data.database.models.TrackImpl
|
||||
import eu.kanade.tachiyomi.data.database.models.toAnimeInfo
|
||||
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.model.toSAnime
|
||||
import eu.kanade.tachiyomi.source.model.toSManga
|
||||
import kotlin.math.max
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@ import android.content.Context
|
|||
import android.text.format.Formatter
|
||||
import com.google.gson.Gson
|
||||
import com.jakewharton.disklrucache.DiskLruCache
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.data.database.models.Episode
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||
import eu.kanade.tachiyomi.util.storage.saveTo
|
||||
import okhttp3.Response
|
||||
|
@ -97,9 +97,9 @@ class EpisodeCache(private val context: Context) {
|
|||
* @param episode the episode.
|
||||
* @param pages list of pages.
|
||||
*/
|
||||
fun putPageListToCache(episode: Episode, pages: List<Page>) {
|
||||
fun putPageListToCache(episode: Episode, video: Video) {
|
||||
// Convert list of pages to json string.
|
||||
val cachedValue = gson.toJson(pages)
|
||||
val cachedValue = gson.toJson(video)
|
||||
|
||||
// Initialize the editor (edits the values for an entry).
|
||||
var editor: DiskLruCache.Editor? = null
|
||||
|
@ -145,7 +145,7 @@ class EpisodeCache(private val context: Context) {
|
|||
* @param imageUrl url of image.
|
||||
* @return path of image.
|
||||
*/
|
||||
fun getImageFile(imageUrl: String): File {
|
||||
fun getVideoFile(imageUrl: String): File {
|
||||
// Get file from md5 key.
|
||||
val imageName = DiskUtil.hashKeyForDisk(imageUrl) + ".0"
|
||||
return File(diskCache.directory, imageName)
|
||||
|
|
|
@ -9,12 +9,12 @@ import coil.fetch.SourceResult
|
|||
import coil.network.HttpException
|
||||
import coil.request.get
|
||||
import coil.size.Size
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.data.cache.AnimeCoverCache
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import eu.kanade.tachiyomi.network.await
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.online.AnimeHttpSource
|
||||
import okhttp3.CacheControl
|
||||
import okhttp3.Call
|
||||
import okhttp3.Request
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package eu.kanade.tachiyomi.data.database.models
|
||||
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import tachiyomi.source.model.AnimeInfo
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import tachiyomi.animesource.model.AnimeInfo
|
||||
|
||||
interface Anime : SAnime {
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package eu.kanade.tachiyomi.data.database.models
|
||||
|
||||
import eu.kanade.tachiyomi.source.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import java.io.Serializable
|
||||
|
||||
interface Episode : SEpisode, Serializable {
|
||||
|
|
|
@ -3,10 +3,10 @@ package eu.kanade.tachiyomi.data.download
|
|||
import android.content.Context
|
||||
import androidx.core.net.toUri
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.Episode
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
|
|
@ -4,14 +4,14 @@ import android.content.Context
|
|||
import com.hippo.unifile.UniFile
|
||||
import com.jakewharton.rxrelay.BehaviorRelay
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.Episode
|
||||
import eu.kanade.tachiyomi.data.download.model.AnimeDownload
|
||||
import eu.kanade.tachiyomi.data.download.model.AnimeDownloadQueue
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import rx.Observable
|
||||
import timber.log.Timber
|
||||
|
@ -137,8 +137,8 @@ class AnimeDownloadManager(private val context: Context) {
|
|||
* @param episode the downloaded episode.
|
||||
* @return an observable containing the list of pages from the episode.
|
||||
*/
|
||||
fun buildPageList(source: AnimeSource, anime: Anime, episode: Episode): Observable<List<Page>> {
|
||||
return buildPageList(provider.findEpisodeDir(episode, anime, source))
|
||||
fun buildVideo(source: AnimeSource, anime: Anime, episode: Episode): Observable<Video> {
|
||||
return buildVideo(provider.findEpisodeDir(episode, anime, source))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,19 +147,17 @@ class AnimeDownloadManager(private val context: Context) {
|
|||
* @param episodeDir the file where the episode is downloaded.
|
||||
* @return an observable containing the list of pages from the episode.
|
||||
*/
|
||||
private fun buildPageList(episodeDir: UniFile?): Observable<List<Page>> {
|
||||
private fun buildVideo(episodeDir: UniFile?): Observable<Video> {
|
||||
return Observable.fromCallable {
|
||||
val files = episodeDir?.listFiles().orEmpty()
|
||||
.filter { "image" in it.type.orEmpty() }
|
||||
.filter { "video" in it.type.orEmpty() }
|
||||
|
||||
if (files.isEmpty()) {
|
||||
throw Exception(context.getString(R.string.page_list_empty_error))
|
||||
}
|
||||
|
||||
files.sortedBy { it.name }
|
||||
.mapIndexed { i, file ->
|
||||
Page(i, uri = file.uri).apply { status = Page.READY }
|
||||
}
|
||||
val file = files[0]
|
||||
Video(uri = file.uri).apply { status = Video.READY }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ internal class AnimeDownloadNotifier(private val context: Context) {
|
|||
val downloadingProgressText = context.getString(
|
||||
R.string.chapter_downloading_progress,
|
||||
download.downloadedImages,
|
||||
download.pages!!.size
|
||||
1
|
||||
)
|
||||
|
||||
if (preferences.hideNotificationContent()) {
|
||||
|
@ -113,7 +113,7 @@ internal class AnimeDownloadNotifier(private val context: Context) {
|
|||
setContentText(downloadingProgressText)
|
||||
}
|
||||
|
||||
setProgress(download.pages!!.size, download.downloadedImages, false)
|
||||
setProgress(1, download.downloadedImages, false)
|
||||
setOngoing(true)
|
||||
|
||||
show(Notifications.ID_DOWNLOAD_CHAPTER_PROGRESS)
|
||||
|
|
|
@ -4,10 +4,10 @@ import android.content.Context
|
|||
import androidx.core.net.toUri
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.Episode
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
|
|
|
@ -2,11 +2,11 @@ package eu.kanade.tachiyomi.data.download
|
|||
|
||||
import android.content.Context
|
||||
import androidx.core.content.edit
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.download.model.AnimeDownload
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.online.AnimeHttpSource
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.encodeToString
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
package eu.kanade.tachiyomi.data.download
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import android.webkit.MimeTypeMap
|
||||
import com.hippo.unifile.UniFile
|
||||
import com.jakewharton.rxrelay.BehaviorRelay
|
||||
import com.jakewharton.rxrelay.PublishRelay
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.animesource.fetchUrlFromVideo
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.data.cache.EpisodeCache
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.Episode
|
||||
import eu.kanade.tachiyomi.data.download.model.AnimeDownload
|
||||
import eu.kanade.tachiyomi.data.download.model.AnimeDownloadQueue
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.source.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.source.online.fetchAllImageUrlsFromPageList
|
||||
import eu.kanade.tachiyomi.util.lang.RetryWithDelay
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.launchNow
|
||||
|
@ -257,7 +258,8 @@ class AnimeDownloader(
|
|||
|
||||
// Start downloader if needed
|
||||
if (autoStart && wasEmpty) {
|
||||
DownloadService.start(this@AnimeDownloader.context)
|
||||
Log.w("start", "started")
|
||||
AnimeDownloadService.start(this@AnimeDownloader.context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -280,17 +282,25 @@ class AnimeDownloader(
|
|||
val episodeDirname = provider.getEpisodeDirName(download.episode)
|
||||
val tmpDir = animeDir.createDirectory(episodeDirname + TMP_DIR_SUFFIX)
|
||||
|
||||
val pageListObservable = if (download.pages == null) {
|
||||
// Pull page list from network and add them to download object
|
||||
Observable.just(emptyList())
|
||||
val videoObservable = if (download.video == null) {
|
||||
// Pull video from network and add them to download object
|
||||
download.source.fetchVideoList(download.episode)
|
||||
.doOnNext { video ->
|
||||
if (video == null) {
|
||||
Timber.w("mah m9")
|
||||
throw Exception(context.getString(R.string.page_list_empty_error))
|
||||
}
|
||||
download.video = video
|
||||
}
|
||||
} else {
|
||||
// Or if the page list already exists, start from the file
|
||||
Observable.just(download.pages!!)
|
||||
// Or if the video already exists, start from the file
|
||||
Observable.just(download.video!!)
|
||||
}
|
||||
|
||||
pageListObservable
|
||||
videoObservable
|
||||
.doOnNext { _ ->
|
||||
// Delete all temporary (unfinished) files
|
||||
Timber.w("delfiles")
|
||||
tmpDir.listFiles()
|
||||
?.filter { it.name!!.endsWith(".tmp") }
|
||||
?.forEach { it.delete() }
|
||||
|
@ -299,10 +309,10 @@ class AnimeDownloader(
|
|||
download.status = AnimeDownload.State.DOWNLOADING
|
||||
}
|
||||
// Get all the URLs to the source images, fetch pages if necessary
|
||||
.flatMap { download.source.fetchAllImageUrlsFromPageList(it) }
|
||||
.flatMap { download.source.fetchUrlFromVideo(it) }
|
||||
// Start downloading images, consider we can have downloaded images already
|
||||
// Concurrently do 5 pages at a time
|
||||
.flatMap({ page -> getOrAnimeDownloadImage(page, download, tmpDir) }, 5)
|
||||
.flatMap({ video -> getOrAnimeDownloadImage(video, download, tmpDir) }, 5)
|
||||
.onBackpressureLatest()
|
||||
// Do when page is downloaded.
|
||||
.doOnNext { notifier.onProgressChange(download) }
|
||||
|
@ -322,61 +332,63 @@ class AnimeDownloader(
|
|||
* Returns the observable which gets the image from the filesystem if it exists or downloads it
|
||||
* otherwise.
|
||||
*
|
||||
* @param page the page to download.
|
||||
* @param video the page to download.
|
||||
* @param download the download of the page.
|
||||
* @param tmpDir the temporary directory of the download.
|
||||
*/
|
||||
private fun getOrAnimeDownloadImage(page: Page, download: AnimeDownload, tmpDir: UniFile): Observable<Page> {
|
||||
private fun getOrAnimeDownloadImage(video: Video, download: AnimeDownload, tmpDir: UniFile): Observable<Video> {
|
||||
// If the image URL is empty, do nothing
|
||||
if (page.imageUrl == null) {
|
||||
return Observable.just(page)
|
||||
if (video.videoUrl == null) {
|
||||
Timber.w("nourl")
|
||||
return Observable.just(video)
|
||||
}
|
||||
|
||||
val filename = String.format("%03d", page.number)
|
||||
val filename = download.episode.name
|
||||
Timber.w(filename)
|
||||
val tmpFile = tmpDir.findFile("$filename.tmp")
|
||||
|
||||
// Delete temp file if it exists.
|
||||
tmpFile?.delete()
|
||||
|
||||
// Try to find the image file.
|
||||
val imageFile = tmpDir.listFiles()!!.find { it.name!!.startsWith("$filename.") }
|
||||
val videoFile = tmpDir.listFiles()!!.find { it.name!!.startsWith("$filename.") }
|
||||
|
||||
// If the image is already downloaded, do nothing. Otherwise download from network
|
||||
// If the video is already downloaded, do nothing. Otherwise download from network
|
||||
val pageObservable = when {
|
||||
imageFile != null -> Observable.just(imageFile)
|
||||
episodeCache.isImageInCache(page.imageUrl!!) -> copyImageFromCache(episodeCache.getImageFile(page.imageUrl!!), tmpDir, filename)
|
||||
else -> downloadImage(page, download.source, tmpDir, filename)
|
||||
videoFile != null -> Observable.just(videoFile)
|
||||
episodeCache.isImageInCache(video.videoUrl!!) -> copyVideoFromCache(episodeCache.getVideoFile(video.videoUrl!!), tmpDir, filename)
|
||||
else -> downloadVideo(video, download.source, tmpDir, filename)
|
||||
}
|
||||
|
||||
return pageObservable
|
||||
// When the image is ready, set image path, progress (just in case) and status
|
||||
.doOnNext { file ->
|
||||
page.uri = file.uri
|
||||
page.progress = 100
|
||||
video.uri = file.uri
|
||||
video.progress = 100
|
||||
download.downloadedImages++
|
||||
page.status = Page.READY
|
||||
video.status = Video.READY
|
||||
}
|
||||
.map { page }
|
||||
.map { video }
|
||||
// Mark this page as error and allow to download the remaining
|
||||
.onErrorReturn {
|
||||
page.progress = 0
|
||||
page.status = Page.ERROR
|
||||
page
|
||||
video.progress = 0
|
||||
video.status = Video.ERROR
|
||||
video
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the observable which downloads the image from network.
|
||||
*
|
||||
* @param page the page to download.
|
||||
* @param video the page to download.
|
||||
* @param source the source of the page.
|
||||
* @param tmpDir the temporary directory of the download.
|
||||
* @param filename the filename of the image.
|
||||
*/
|
||||
private fun downloadImage(page: Page, source: AnimeHttpSource, tmpDir: UniFile, filename: String): Observable<UniFile> {
|
||||
page.status = Page.DOWNLOAD_IMAGE
|
||||
page.progress = 0
|
||||
return source.fetchImage(page)
|
||||
private fun downloadVideo(video: Video, source: AnimeHttpSource, tmpDir: UniFile, filename: String): Observable<UniFile> {
|
||||
video.status = Video.DOWNLOAD_IMAGE
|
||||
video.progress = 0
|
||||
return source.fetchVideo(video)
|
||||
.map { response ->
|
||||
val file = tmpDir.createFile("$filename.tmp")
|
||||
try {
|
||||
|
@ -401,7 +413,7 @@ class AnimeDownloader(
|
|||
* @param tmpDir the temporary directory of the download.
|
||||
* @param filename the filename of the image.
|
||||
*/
|
||||
private fun copyImageFromCache(cacheFile: File, tmpDir: UniFile, filename: String): Observable<UniFile> {
|
||||
private fun copyVideoFromCache(cacheFile: File, tmpDir: UniFile, filename: String): Observable<UniFile> {
|
||||
return Observable.just(cacheFile).map {
|
||||
val tmpFile = tmpDir.createFile("$filename.tmp")
|
||||
cacheFile.inputStream().use { input ->
|
||||
|
@ -451,7 +463,7 @@ class AnimeDownloader(
|
|||
// Ensure that the episode folder has all the images.
|
||||
val downloadedImages = tmpDir.listFiles().orEmpty().filterNot { it.name!!.endsWith(".tmp") }
|
||||
|
||||
download.status = if (downloadedImages.size == download.pages!!.size) {
|
||||
download.status = if (downloadedImages.size == 1) {
|
||||
AnimeDownload.State.DOWNLOADED
|
||||
} else {
|
||||
AnimeDownload.State.ERROR
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
package eu.kanade.tachiyomi.data.download.model
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.Episode
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.source.online.AnimeHttpSource
|
||||
import rx.subjects.PublishSubject
|
||||
|
||||
class AnimeDownload(val source: AnimeHttpSource, val anime: Anime, val episode: Episode) {
|
||||
|
||||
var pages: List<Page>? = null
|
||||
var video: Video? = null
|
||||
|
||||
@Volatile
|
||||
@Transient
|
||||
|
@ -35,8 +35,8 @@ class AnimeDownload(val source: AnimeHttpSource, val anime: Anime, val episode:
|
|||
|
||||
val progress: Int
|
||||
get() {
|
||||
val pages = pages ?: return 0
|
||||
return pages.map(Page::progress).average().toInt()
|
||||
val video = video ?: return 0
|
||||
return video.progress
|
||||
}
|
||||
|
||||
fun setStatusSubject(subject: PublishSubject<AnimeDownload>?) {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package eu.kanade.tachiyomi.data.download.model
|
||||
|
||||
import com.jakewharton.rxrelay.PublishRelay
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.Episode
|
||||
import eu.kanade.tachiyomi.data.download.AnimeDownloadStore
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import rx.Observable
|
||||
import rx.subjects.PublishSubject
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
|
@ -80,7 +80,7 @@ class AnimeDownloadQueue(
|
|||
|
||||
private fun setPagesFor(download: AnimeDownload) {
|
||||
if (download.status == AnimeDownload.State.DOWNLOADED || download.status == AnimeDownload.State.ERROR) {
|
||||
setPagesSubject(download.pages, null)
|
||||
setPagesSubject(download.video, null)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,20 +90,20 @@ class AnimeDownloadQueue(
|
|||
.flatMap { download ->
|
||||
if (download.status == AnimeDownload.State.DOWNLOADING) {
|
||||
val pageStatusSubject = PublishSubject.create<Int>()
|
||||
setPagesSubject(download.pages, pageStatusSubject)
|
||||
setPagesSubject(download.video, pageStatusSubject)
|
||||
return@flatMap pageStatusSubject
|
||||
.onBackpressureBuffer()
|
||||
.filter { it == Page.READY }
|
||||
.filter { it == Video.READY }
|
||||
.map { download }
|
||||
} else if (download.status == AnimeDownload.State.DOWNLOADED || download.status == AnimeDownload.State.ERROR) {
|
||||
setPagesSubject(download.pages, null)
|
||||
setPagesSubject(download.video, null)
|
||||
}
|
||||
Observable.just(download)
|
||||
}
|
||||
.filter { it.status == AnimeDownload.State.DOWNLOADING }
|
||||
}
|
||||
|
||||
private fun setPagesSubject(pages: List<Page>?, subject: PublishSubject<Int>?) {
|
||||
pages?.forEach { it.setStatusSubject(subject) }
|
||||
private fun setPagesSubject(video: Video?, subject: PublishSubject<Int>?) {
|
||||
video?.setStatusSubject(subject)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import android.net.Uri
|
|||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.data.animelib.AnimelibUpdateService
|
||||
import eu.kanade.tachiyomi.data.backup.BackupRestoreService
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
|
@ -20,29 +21,24 @@ import eu.kanade.tachiyomi.data.download.DownloadManager
|
|||
import eu.kanade.tachiyomi.data.download.DownloadService
|
||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.model.toEpisodeInfo
|
||||
import eu.kanade.tachiyomi.ui.anime.AnimeController
|
||||
import eu.kanade.tachiyomi.ui.anime.episode.EpisodeItem
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||
import eu.kanade.tachiyomi.ui.watcher.EpisodeLoader
|
||||
import eu.kanade.tachiyomi.ui.watcher.WatcherActivity
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.io.File
|
||||
import java.util.Collections.emptyList
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import eu.kanade.tachiyomi.BuildConfig.APPLICATION_ID as ID
|
||||
|
||||
/**
|
||||
|
@ -441,19 +437,7 @@ class NotificationReceiver : BroadcastReceiver() {
|
|||
*/
|
||||
internal fun openEpisodePendingActivity(context: Context, anime: Anime, episode: Episode): PendingIntent {
|
||||
val source = Injekt.get<AnimeSourceManager>().getOrStub(anime.source)
|
||||
val link = runBlocking {
|
||||
return@runBlocking suspendCoroutine<String> { continuation ->
|
||||
var link: String
|
||||
launchIO {
|
||||
try {
|
||||
link = source.getEpisodeLink(episode.toEpisodeInfo())
|
||||
continuation.resume(link)
|
||||
} catch (e: Throwable) {
|
||||
withUIContext { throw e }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val link = EpisodeLoader.getUri(episode, anime, source)
|
||||
val episodeList: List<EpisodeItem> = emptyList()
|
||||
val newIntent = WatcherActivity.newIntent(context, anime, episode, episodeList, link)
|
||||
return PendingIntent.getActivity(context, AnimeController.REQUEST_INTERNAL, newIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package eu.kanade.tachiyomi.data.track
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch
|
||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||
import android.graphics.Color
|
||||
import androidx.annotation.StringRes
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.AnimeTrack
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
|
@ -13,7 +14,6 @@ import eu.kanade.tachiyomi.data.track.TrackService
|
|||
import eu.kanade.tachiyomi.data.track.UnattendedTrackService
|
||||
import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch
|
||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import okhttp3.Dns
|
||||
import okhttp3.OkHttpClient
|
||||
|
|
|
@ -3,6 +3,8 @@ package eu.kanade.tachiyomi.extension
|
|||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import com.jakewharton.rxrelay.BehaviorRelay
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.plusAssign
|
||||
import eu.kanade.tachiyomi.extension.api.AnimeExtensionGithubApi
|
||||
|
@ -12,8 +14,6 @@ import eu.kanade.tachiyomi.extension.model.InstallStep
|
|||
import eu.kanade.tachiyomi.extension.util.AnimeExtensionInstallReceiver
|
||||
import eu.kanade.tachiyomi.extension.util.AnimeExtensionInstaller
|
||||
import eu.kanade.tachiyomi.extension.util.AnimeExtensionLoader
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.util.lang.launchNow
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.coroutines.async
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package eu.kanade.tachiyomi.extension.model
|
||||
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
|
||||
sealed class AnimeExtension {
|
||||
|
||||
|
|
|
@ -5,13 +5,13 @@ import android.content.Context
|
|||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import dalvik.system.PathClassLoader
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceFactory
|
||||
import eu.kanade.tachiyomi.annotations.Nsfw
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.extension.model.AnimeExtension
|
||||
import eu.kanade.tachiyomi.extension.model.AnimeLoadResult
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceFactory
|
||||
import eu.kanade.tachiyomi.util.lang.Hash
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
package eu.kanade.tachiyomi.source.online
|
||||
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import rx.Observable
|
||||
|
||||
fun AnimeHttpSource.getImageUrl(page: Page): Observable<Page> {
|
||||
page.status = Page.LOAD_PAGE
|
||||
return fetchImageUrl(page)
|
||||
.doOnError { page.status = Page.ERROR }
|
||||
.onErrorReturn { null }
|
||||
.doOnNext { page.imageUrl = it }
|
||||
.map { page }
|
||||
}
|
||||
|
||||
fun AnimeHttpSource.fetchAllImageUrlsFromPageList(pages: List<Page>): Observable<Page> {
|
||||
return Observable.from(pages)
|
||||
.filter { !it.imageUrl.isNullOrEmpty() }
|
||||
.mergeWith(fetchRemainingImageUrlsFromPageList(pages))
|
||||
}
|
||||
|
||||
fun AnimeHttpSource.fetchRemainingImageUrlsFromPageList(pages: List<Page>): Observable<Page> {
|
||||
return Observable.from(pages)
|
||||
.filter { it.imageUrl.isNullOrEmpty() }
|
||||
.concatMap { getImageUrl(it) }
|
||||
}
|
|
@ -26,6 +26,10 @@ import dev.chrisbanes.insetter.applyInsetter
|
|||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.data.cache.AnimeCoverCache
|
||||
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
|
@ -41,10 +45,6 @@ import eu.kanade.tachiyomi.data.track.TrackService
|
|||
import eu.kanade.tachiyomi.data.track.UnattendedTrackService
|
||||
import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch
|
||||
import eu.kanade.tachiyomi.databinding.AnimeControllerBinding
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.LocalSource
|
||||
import eu.kanade.tachiyomi.source.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.ui.anime.episode.*
|
||||
import eu.kanade.tachiyomi.ui.anime.episode.base.BaseEpisodesAdapter
|
||||
import eu.kanade.tachiyomi.ui.anime.info.AnimeInfoHeaderAdapter
|
||||
|
@ -65,6 +65,7 @@ import eu.kanade.tachiyomi.ui.browse.migration.search.AnimeSearchController
|
|||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.recent.history.HistoryController
|
||||
import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController
|
||||
import eu.kanade.tachiyomi.ui.watcher.EpisodeLoader
|
||||
import eu.kanade.tachiyomi.ui.watcher.WatcherActivity
|
||||
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
||||
import eu.kanade.tachiyomi.util.episode.NoEpisodesException
|
||||
|
@ -80,8 +81,6 @@ import kotlinx.coroutines.async
|
|||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import reactivecircus.flowbinding.recyclerview.scrollEvents
|
||||
import reactivecircus.flowbinding.swiperefreshlayout.refreshes
|
||||
import rx.schedulers.Schedulers
|
||||
|
@ -163,7 +162,7 @@ class AnimeController :
|
|||
*/
|
||||
private val selectedEpisodes = mutableSetOf<EpisodeItem>()
|
||||
|
||||
private val isLocalSource by lazy { presenter.source.id == LocalSource.ID }
|
||||
private val isLocalSource by lazy { presenter.source.id == LocalAnimeSource.ID }
|
||||
|
||||
private var lastClickPositionStack = ArrayDeque(listOf(-1))
|
||||
|
||||
|
@ -337,7 +336,7 @@ class AnimeController :
|
|||
// Create animation listener
|
||||
val revealAnimationListener: Animator.AnimatorListener = object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationStart(animation: Animator?) {
|
||||
openEpisode(item.episode, true)
|
||||
openEpisode(item.episode)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -348,7 +347,7 @@ class AnimeController :
|
|||
coordinates.y,
|
||||
object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationStart(animation: Animator?) {
|
||||
openEpisode(item.episode, true)
|
||||
openEpisode(item.episode)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -901,28 +900,22 @@ class AnimeController :
|
|||
}
|
||||
}
|
||||
|
||||
fun openEpisode(episode: Episode, hasAnimation: Boolean = false) {
|
||||
fun openEpisode(episode: Episode) {
|
||||
val activity = activity ?: return
|
||||
runBlocking {
|
||||
launch {
|
||||
val url = fetchEpisodeLinksFromSource(false, episode)
|
||||
val episodeList = presenter.filteredAndSortedEpisodes
|
||||
val intent = WatcherActivity.newIntent(activity, presenter.anime, episode, episodeList, url)
|
||||
if (hasAnimation) {
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
|
||||
}
|
||||
if (!preferences.alwaysUseExternalPlayer()) {
|
||||
startActivityForResult(intent, REQUEST_INTERNAL)
|
||||
} else {
|
||||
currentExtEpisode = episode
|
||||
val uri = Uri.parse(url)
|
||||
val extIntent = Intent(Intent.ACTION_VIEW)
|
||||
extIntent.setDataAndTypeAndNormalize(uri, "video/*")
|
||||
extIntent.putExtra("title", episode.name)
|
||||
extIntent.putExtra("position", episode.last_second_seen.toInt())
|
||||
extIntent.putExtra("return_result", true)
|
||||
startActivityForResult(extIntent, REQUEST_EXTERNAL)
|
||||
}
|
||||
launchIO {
|
||||
val url = EpisodeLoader.getUri(episode, anime!!, source!!)
|
||||
val episodeList = presenter.filteredAndSortedEpisodes
|
||||
val intent = WatcherActivity.newIntent(activity, presenter.anime, episode, episodeList, url)
|
||||
if (!preferences.alwaysUseExternalPlayer()) {
|
||||
startActivityForResult(intent, REQUEST_INTERNAL)
|
||||
} else {
|
||||
currentExtEpisode = episode
|
||||
val extIntent = Intent(Intent.ACTION_VIEW)
|
||||
extIntent.setDataAndTypeAndNormalize(Uri.parse(url), "video/*")
|
||||
extIntent.putExtra("title", episode.name)
|
||||
extIntent.putExtra("position", episode.last_second_seen.toInt())
|
||||
extIntent.putExtra("return_result", true)
|
||||
startActivityForResult(extIntent, REQUEST_EXTERNAL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,11 @@ import android.content.Context
|
|||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import com.jakewharton.rxrelay.PublishRelay
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.toEpisodeInfo
|
||||
import eu.kanade.tachiyomi.animesource.model.toSAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.toSEpisode
|
||||
import eu.kanade.tachiyomi.data.cache.AnimeCoverCache
|
||||
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
|
@ -18,11 +23,6 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.data.track.TrackService
|
||||
import eu.kanade.tachiyomi.data.track.UnattendedTrackService
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.source.model.toEpisodeInfo
|
||||
import eu.kanade.tachiyomi.source.model.toSAnime
|
||||
import eu.kanade.tachiyomi.source.model.toSEpisode
|
||||
import eu.kanade.tachiyomi.ui.anime.episode.EpisodeItem
|
||||
import eu.kanade.tachiyomi.ui.anime.track.TrackItem
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
|
|
|
@ -6,9 +6,9 @@ import androidx.core.text.buildSpannedString
|
|||
import androidx.core.text.color
|
||||
import androidx.core.view.isVisible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.databinding.EpisodesItemBinding
|
||||
import eu.kanade.tachiyomi.source.LocalSource
|
||||
import eu.kanade.tachiyomi.ui.anime.episode.base.BaseEpisodeHolder
|
||||
import java.util.Date
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
@ -93,7 +93,7 @@ class EpisodeHolder(
|
|||
binding.episodeDescription.text = ""
|
||||
}
|
||||
|
||||
binding.animedownload.isVisible = item.anime.source != LocalSource.ID
|
||||
binding.animedownload.isVisible = item.anime.source != LocalAnimeSource.ID
|
||||
binding.animedownload.setState(item.status, item.progress)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
|||
import eu.davidea.flexibleadapter.items.AbstractSectionableItem
|
||||
import eu.kanade.tachiyomi.data.database.models.Episode
|
||||
import eu.kanade.tachiyomi.data.download.model.AnimeDownload
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
|
||||
abstract class BaseEpisodeItem<T : BaseEpisodeHolder, H : AbstractHeaderItem<*>>(
|
||||
val episode: Episode,
|
||||
|
@ -23,8 +22,8 @@ abstract class BaseEpisodeItem<T : BaseEpisodeHolder, H : AbstractHeaderItem<*>>
|
|||
|
||||
val progress: Int
|
||||
get() {
|
||||
val pages = download?.pages ?: return 0
|
||||
return pages.map(Page::progress).average().toInt()
|
||||
val video = download?.video ?: return 0
|
||||
return video.progress
|
||||
}
|
||||
|
||||
@Transient
|
||||
|
|
|
@ -7,13 +7,13 @@ import androidx.core.view.isVisible
|
|||
import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.loadAny
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.databinding.AnimeInfoHeaderBinding
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.ui.anime.AnimeController
|
||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import eu.kanade.tachiyomi.util.view.setChips
|
||||
|
@ -114,7 +114,7 @@ class AnimeInfoHeaderAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
if (controller.presenter.source is HttpSource) {
|
||||
if (controller.presenter.source is AnimeHttpSource) {
|
||||
binding.btnWebview.isVisible = true
|
||||
binding.btnWebview.clicks()
|
||||
.onEach { controller.openAnimeInWebView() }
|
||||
|
|
|
@ -6,10 +6,10 @@ import android.view.View
|
|||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import eu.kanade.tachiyomi.R.string
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.track.UnattendedTrackService
|
||||
import eu.kanade.tachiyomi.databinding.TrackControllerBinding
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.ui.anime.AnimeController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.openInBrowser
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
|
|
|
@ -19,13 +19,13 @@ import com.jakewharton.rxrelay.PublishRelay
|
|||
import com.tfcporciuncula.flow.Preference
|
||||
import dev.chrisbanes.insetter.applyInsetter
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.data.animelib.AnimelibUpdateService
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
||||
import eu.kanade.tachiyomi.databinding.AnimelibControllerBinding
|
||||
import eu.kanade.tachiyomi.source.LocalSource
|
||||
import eu.kanade.tachiyomi.ui.anime.AnimeController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.RootController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.SearchableNucleusController
|
||||
|
@ -447,7 +447,7 @@ class AnimelibController(
|
|||
} else {
|
||||
mode.title = count.toString()
|
||||
|
||||
binding.actionToolbar.findItem(R.id.action_download_unread)?.isVisible = selectedAnimes.any { it.source != LocalSource.ID }
|
||||
binding.actionToolbar.findItem(R.id.action_download_unread)?.isVisible = selectedAnimes.any { it.source != LocalAnimeSource.ID }
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -12,11 +12,11 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
|||
import eu.davidea.flexibleadapter.items.IFilterable
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.data.database.models.AnimelibAnime
|
||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
|
||||
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
|
||||
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
@ -24,7 +24,7 @@ import uy.kohesive.injekt.api.get
|
|||
class AnimelibItem(val anime: AnimelibAnime, private val animelibDisplayMode: Preference<DisplayMode>) :
|
||||
AbstractFlexibleItem<AnimelibHolder<*>>(), IFilterable<String> {
|
||||
|
||||
private val sourceManager: SourceManager = Injekt.get()
|
||||
private val sourceManager: AnimeSourceManager = Injekt.get()
|
||||
|
||||
var downloadCount = -1
|
||||
var unreadCount = -1
|
||||
|
|
|
@ -2,6 +2,9 @@ package eu.kanade.tachiyomi.ui.animelib
|
|||
|
||||
import android.os.Bundle
|
||||
import com.jakewharton.rxrelay.BehaviorRelay
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.data.cache.AnimeCoverCache
|
||||
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
|
@ -11,9 +14,6 @@ import eu.kanade.tachiyomi.data.database.models.Episode
|
|||
import eu.kanade.tachiyomi.data.download.AnimeDownloadManager
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import eu.kanade.tachiyomi.source.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import eu.kanade.tachiyomi.util.isLocal
|
||||
import eu.kanade.tachiyomi.util.lang.combineLatest
|
||||
|
|
|
@ -6,9 +6,9 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
|
|||
import eu.davidea.flexibleadapter.items.AbstractSectionableItem
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.extension.model.AnimeExtension
|
||||
import eu.kanade.tachiyomi.extension.model.InstallStep
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
|
||||
/**
|
||||
* Item that contains source information.
|
||||
|
|
|
@ -23,16 +23,16 @@ import androidx.recyclerview.widget.ConcatAdapter
|
|||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import dev.chrisbanes.insetter.applyInsetter
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.getPreferenceKey
|
||||
import eu.kanade.tachiyomi.data.preference.EmptyPreferenceDataStore
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.minusAssign
|
||||
import eu.kanade.tachiyomi.data.preference.plusAssign
|
||||
import eu.kanade.tachiyomi.databinding.AnimeExtensionDetailControllerBinding
|
||||
import eu.kanade.tachiyomi.extension.model.AnimeExtension
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.ConfigurableAnimeSource
|
||||
import eu.kanade.tachiyomi.source.getPreferenceKey
|
||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.ToolbarLiftOnScrollController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.openInBrowser
|
||||
|
|
|
@ -21,12 +21,12 @@ import androidx.preference.PreferenceManager
|
|||
import androidx.preference.PreferenceScreen
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.getPreferenceKey
|
||||
import eu.kanade.tachiyomi.data.preference.EmptyPreferenceDataStore
|
||||
import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore
|
||||
import eu.kanade.tachiyomi.databinding.AnimeSourcePreferencesControllerBinding
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.ConfigurableAnimeSource
|
||||
import eu.kanade.tachiyomi.source.getPreferenceKey
|
||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||
import timber.log.Timber
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package eu.kanade.tachiyomi.ui.browse.animeextension.details
|
||||
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
|
|
@ -17,13 +17,13 @@ import dev.chrisbanes.insetter.applyInsetter
|
|||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.minusAssign
|
||||
import eu.kanade.tachiyomi.data.preference.plusAssign
|
||||
import eu.kanade.tachiyomi.databinding.AnimeSourceMainControllerBinding
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.SearchableNucleusController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.requestPermissionsSafe
|
||||
|
|
|
@ -5,12 +5,12 @@ import androidx.preference.CheckBoxPreference
|
|||
import androidx.preference.PreferenceGroup
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.animesource.getPreferenceKey
|
||||
import eu.kanade.tachiyomi.animesource.icon
|
||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.data.preference.minusAssign
|
||||
import eu.kanade.tachiyomi.data.preference.plusAssign
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.getPreferenceKey
|
||||
import eu.kanade.tachiyomi.source.icon
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.ui.setting.SettingsController
|
||||
import eu.kanade.tachiyomi.util.preference.onChange
|
||||
import eu.kanade.tachiyomi.util.preference.switchPreferenceCategory
|
||||
|
@ -22,7 +22,7 @@ import java.util.TreeMap
|
|||
|
||||
class AnimeSourceFilterController : SettingsController() {
|
||||
|
||||
private val onlineSources by lazy { Injekt.get<SourceManager>().getOnlineSources() }
|
||||
private val onlineSources by lazy { Injekt.get<AnimeSourceManager>().getOnlineSources() }
|
||||
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
|
||||
titleRes = R.string.label_sources
|
||||
|
@ -78,7 +78,7 @@ class AnimeSourceFilterController : SettingsController() {
|
|||
*
|
||||
* @param group the language category.
|
||||
*/
|
||||
private fun addLanguageSources(group: PreferenceGroup, sources: List<HttpSource>) {
|
||||
private fun addLanguageSources(group: PreferenceGroup, sources: List<AnimeHttpSource>) {
|
||||
val disabledSourceIds = preferences.disabledAnimeSources().get()
|
||||
|
||||
sources
|
||||
|
|
|
@ -4,10 +4,9 @@ import android.view.View
|
|||
import androidx.core.view.isVisible
|
||||
import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.icon
|
||||
import eu.kanade.tachiyomi.databinding.SourceMainControllerCardItemBinding
|
||||
import eu.kanade.tachiyomi.source.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.source.LocalSource
|
||||
import eu.kanade.tachiyomi.source.icon
|
||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||
import eu.kanade.tachiyomi.util.view.setVectorCompat
|
||||
|
||||
|
@ -38,7 +37,7 @@ class AnimeSourceHolder(private val view: View, val adapter: AnimeSourceAdapter)
|
|||
val icon = source.icon()
|
||||
when {
|
||||
icon != null -> binding.image.setImageDrawable(icon)
|
||||
item.source.id == LocalSource.ID -> binding.image.setImageResource(R.mipmap.ic_local_source)
|
||||
item.source.id == LocalAnimeSource.ID -> binding.image.setImageResource(R.mipmap.ic_local_source)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
|
|||
import eu.davidea.flexibleadapter.items.AbstractSectionableItem
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
|
||||
/**
|
||||
* Item that contains source information.
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package eu.kanade.tachiyomi.ui.browse.animesource
|
||||
|
||||
import android.os.Bundle
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package eu.kanade.tachiyomi.ui.browse.animesource.browse
|
||||
|
||||
import com.jakewharton.rxrelay.PublishRelay
|
||||
import eu.kanade.tachiyomi.source.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import rx.Observable
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package eu.kanade.tachiyomi.ui.browse.animesource.browse
|
||||
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.source.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.animesource.model.FilterList
|
||||
import rx.Observable
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import rx.schedulers.Schedulers
|
||||
|
|
|
@ -22,16 +22,16 @@ import dev.chrisbanes.insetter.applyInsetter
|
|||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.FilterList
|
||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
||||
import eu.kanade.tachiyomi.databinding.AnimeSourceControllerBinding
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.source.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.ui.anime.AnimeController
|
||||
import eu.kanade.tachiyomi.ui.animelib.ChangeAnimeCategoriesDialog
|
||||
import eu.kanade.tachiyomi.ui.base.controller.FabController
|
||||
|
|
|
@ -2,6 +2,12 @@ package eu.kanade.tachiyomi.ui.browse.animesource.browse
|
|||
|
||||
import android.os.Bundle
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.animesource.model.Filter
|
||||
import eu.kanade.tachiyomi.animesource.model.FilterList
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.toSAnime
|
||||
import eu.kanade.tachiyomi.data.cache.AnimeCoverCache
|
||||
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
|
@ -12,12 +18,6 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.data.track.TrackService
|
||||
import eu.kanade.tachiyomi.data.track.UnattendedTrackService
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import eu.kanade.tachiyomi.source.model.toSAnime
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import eu.kanade.tachiyomi.ui.browse.animesource.filter.CheckboxItem
|
||||
import eu.kanade.tachiyomi.ui.browse.animesource.filter.CheckboxSectionItem
|
||||
|
|
|
@ -8,7 +8,7 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
|||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.animesource.model.Filter
|
||||
|
||||
open class CheckboxItem(val filter: Filter.CheckBox) : AbstractFlexibleItem<CheckboxItem.Holder>() {
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import eu.davidea.flexibleadapter.items.IFlexible
|
|||
import eu.davidea.flexibleadapter.items.ISectionable
|
||||
import eu.davidea.viewholders.ExpandableViewHolder
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.animesource.model.Filter
|
||||
import eu.kanade.tachiyomi.util.view.setVectorCompat
|
||||
|
||||
class GroupItem(val filter: Filter.Group<*>) : AbstractExpandableHeaderItem<GroupItem.Holder, ISectionable<*, *>>() {
|
||||
|
|
|
@ -9,7 +9,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
|
|||
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.animesource.model.Filter
|
||||
|
||||
class HeaderItem(val filter: Filter.Header) : AbstractHeaderItem<HeaderItem.Holder>() {
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package eu.kanade.tachiyomi.ui.browse.animesource.filter
|
||||
|
||||
import eu.davidea.flexibleadapter.items.ISectionable
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.animesource.model.Filter
|
||||
|
||||
class TriStateSectionItem(filter: Filter.TriState) : TriStateItem(filter), ISectionable<TriStateItem.Holder, GroupItem> {
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
|||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.animesource.model.Filter
|
||||
import eu.kanade.tachiyomi.widget.listener.IgnoreFirstSpinnerListener
|
||||
|
||||
open class SelectItem(val filter: Filter.Select<*>) : AbstractFlexibleItem<SelectItem.Holder>() {
|
||||
|
|
|
@ -8,7 +8,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
|
|||
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.animesource.model.Filter
|
||||
|
||||
class SeparatorItem(val filter: Filter.Separator) : AbstractHeaderItem<SeparatorItem.Holder>() {
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import eu.davidea.flexibleadapter.items.AbstractExpandableHeaderItem
|
|||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.davidea.flexibleadapter.items.ISectionable
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.animesource.model.Filter
|
||||
import eu.kanade.tachiyomi.util.view.setVectorCompat
|
||||
|
||||
class SortGroup(val filter: Filter.Sort) : AbstractExpandableHeaderItem<SortGroup.Holder, ISectionable<*, *>>() {
|
||||
|
|
|
@ -9,7 +9,7 @@ import eu.davidea.flexibleadapter.items.AbstractSectionableItem
|
|||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.animesource.model.Filter
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
|
||||
class SortItem(val name: String, val group: SortGroup) : AbstractSectionableItem<SortItem.Holder, SortGroup>(group) {
|
||||
|
|
|
@ -10,7 +10,7 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
|||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.animesource.model.Filter
|
||||
|
||||
open class TextItem(val filter: Filter.Text) : AbstractFlexibleItem<TextItem.Holder>() {
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
|
|||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.animesource.model.Filter
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.R as TR
|
||||
|
|
|
@ -5,7 +5,7 @@ import android.os.Parcelable
|
|||
import android.util.SparseArray
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
|
||||
/**
|
||||
* Adapter that holds the search cards.
|
||||
|
|
|
@ -10,10 +10,10 @@ import androidx.appcompat.widget.SearchView
|
|||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.databinding.GlobalAnimeSearchControllerBinding
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.ui.anime.AnimeController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.SearchableNucleusController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
|
|
|
@ -4,9 +4,9 @@ import android.view.View
|
|||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.databinding.GlobalSearchControllerCardBinding
|
||||
import eu.kanade.tachiyomi.source.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,7 +6,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
|
|||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
|
||||
/**
|
||||
* Item that contains search result information.
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
package eu.kanade.tachiyomi.ui.browse.animesource.globalsearch
|
||||
|
||||
import android.os.Bundle
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.animesource.model.FilterList
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.toSAnime
|
||||
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.toAnimeInfo
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.extension.AnimeExtensionManager
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import eu.kanade.tachiyomi.source.model.toSAnime
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import eu.kanade.tachiyomi.ui.browse.animesource.browse.BrowseAnimeSourcePresenter
|
||||
import eu.kanade.tachiyomi.util.lang.runAsObservable
|
||||
|
|
|
@ -4,7 +4,7 @@ import android.os.Bundle
|
|||
import android.view.Menu
|
||||
import androidx.core.os.bundleOf
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.ui.browse.animesource.browse.BrowseAnimeSourceController
|
||||
import eu.kanade.tachiyomi.ui.browse.animesource.browse.BrowseAnimeSourcePresenter
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package eu.kanade.tachiyomi.ui.browse.animesource.latest
|
||||
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.source.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.ui.browse.animesource.browse.AnimePager
|
||||
import rx.Observable
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package eu.kanade.tachiyomi.ui.browse.animesource.latest
|
||||
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.animesource.model.FilterList
|
||||
import eu.kanade.tachiyomi.ui.browse.animesource.browse.AnimePager
|
||||
import eu.kanade.tachiyomi.ui.browse.animesource.browse.BrowseAnimeSourcePresenter
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ import com.afollestad.materialdialogs.MaterialDialog
|
|||
import com.afollestad.materialdialogs.list.listItemsMultiChoice
|
||||
import com.bluelinelabs.conductor.Controller
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.browse.animesource.globalsearch.GlobalAnimeSearchController
|
||||
|
|
|
@ -2,14 +2,14 @@ package eu.kanade.tachiyomi.ui.browse.migration.search
|
|||
|
||||
import android.os.Bundle
|
||||
import com.jakewharton.rxrelay.BehaviorRelay
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.toSEpisode
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.AnimeCategory
|
||||
import eu.kanade.tachiyomi.data.database.models.toAnimeInfo
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import eu.kanade.tachiyomi.source.model.SEpisode
|
||||
import eu.kanade.tachiyomi.source.model.toSEpisode
|
||||
import eu.kanade.tachiyomi.ui.browse.animesource.globalsearch.GlobalAnimeSearchCardItem
|
||||
import eu.kanade.tachiyomi.ui.browse.animesource.globalsearch.GlobalAnimeSearchItem
|
||||
import eu.kanade.tachiyomi.ui.browse.animesource.globalsearch.GlobalAnimeSearchPresenter
|
||||
|
|
|
@ -2,8 +2,8 @@ package eu.kanade.tachiyomi.ui.browse.migration.search
|
|||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.ui.browse.animesource.browse.AnimeSourceItem
|
||||
import eu.kanade.tachiyomi.ui.browse.animesource.browse.BrowseAnimeSourceController
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
|
|||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
|
||||
/**
|
||||
* Item that contains source information.
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
package eu.kanade.tachiyomi.ui.browse.migration.sources
|
||||
|
||||
import android.os.Bundle
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.source.*
|
||||
import eu.kanade.tachiyomi.source.LocalSource
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import uy.kohesive.injekt.Injekt
|
||||
|
@ -49,7 +52,7 @@ class MigrationSourcesPresenter(
|
|||
private fun findSourcesWithAnime(library: List<Anime>): List<AnimeSourceItem> {
|
||||
return library
|
||||
.groupBy { it.source }
|
||||
.filterKeys { it != LocalSource.ID }
|
||||
.filterKeys { it != LocalAnimeSource.ID }
|
||||
.map {
|
||||
val source = animesourceManager.getOrStub(it.key)
|
||||
AnimeSourceItem(source, it.value.size)
|
||||
|
|
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.browse.migration.sources
|
|||
import android.view.View
|
||||
import androidx.core.view.isVisible
|
||||
import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import eu.kanade.tachiyomi.animesource.icon
|
||||
import eu.kanade.tachiyomi.databinding.SourceMainControllerCardItemBinding
|
||||
import eu.kanade.tachiyomi.source.icon
|
||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.recent.animehistory
|
|||
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.text.DecimalFormat
|
||||
import java.text.DecimalFormatSymbols
|
||||
|
|
|
@ -13,13 +13,12 @@ import com.afollestad.materialdialogs.MaterialDialog
|
|||
import dev.chrisbanes.insetter.applyInsetter
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.data.backup.BackupRestoreService
|
||||
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.AnimeHistory
|
||||
import eu.kanade.tachiyomi.databinding.AnimeHistoryControllerBinding
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.model.toEpisodeInfo
|
||||
import eu.kanade.tachiyomi.ui.anime.AnimeController
|
||||
import eu.kanade.tachiyomi.ui.anime.episode.EpisodeItem
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
|
@ -27,21 +26,17 @@ import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
|||
import eu.kanade.tachiyomi.ui.base.controller.RootController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.browse.source.browse.ProgressItem
|
||||
import eu.kanade.tachiyomi.ui.watcher.EpisodeLoader
|
||||
import eu.kanade.tachiyomi.ui.watcher.WatcherActivity
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import reactivecircus.flowbinding.appcompat.queryTextChanges
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.util.Collections
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
/**
|
||||
* Fragment that shows recently read anime.
|
||||
|
@ -166,19 +161,7 @@ class AnimeHistoryController :
|
|||
val nextEpisode = presenter.getNextEpisode(chapter, anime)
|
||||
if (nextEpisode != null) {
|
||||
val source = Injekt.get<AnimeSourceManager>().getOrStub(anime.source)
|
||||
val link = runBlocking {
|
||||
return@runBlocking suspendCoroutine<String> { continuation ->
|
||||
var link: String
|
||||
launchIO {
|
||||
try {
|
||||
link = source.getEpisodeLink(nextEpisode.toEpisodeInfo())
|
||||
continuation.resume(link)
|
||||
} catch (e: Throwable) {
|
||||
withUIContext { throw e }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val link = EpisodeLoader.getUri(nextEpisode, anime, source)
|
||||
val episodeList: List<EpisodeItem> = Collections.emptyList()
|
||||
val newIntent = WatcherActivity.newIntent(activity, anime, nextEpisode, episodeList, link)
|
||||
startActivity(newIntent)
|
||||
|
|
|
@ -13,13 +13,12 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
|
|||
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.data.animelib.AnimelibUpdateService
|
||||
import eu.kanade.tachiyomi.data.download.AnimeDownloadService
|
||||
import eu.kanade.tachiyomi.data.download.model.AnimeDownload
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.databinding.AnimeUpdatesControllerBinding
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.model.toEpisodeInfo
|
||||
import eu.kanade.tachiyomi.ui.anime.AnimeController
|
||||
import eu.kanade.tachiyomi.ui.anime.episode.EpisodeItem
|
||||
import eu.kanade.tachiyomi.ui.anime.episode.base.BaseEpisodesAdapter
|
||||
|
@ -27,22 +26,18 @@ import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
|||
import eu.kanade.tachiyomi.ui.base.controller.RootController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.watcher.EpisodeLoader
|
||||
import eu.kanade.tachiyomi.ui.watcher.WatcherActivity
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import reactivecircus.flowbinding.recyclerview.scrollStateChanges
|
||||
import reactivecircus.flowbinding.swiperefreshlayout.refreshes
|
||||
import timber.log.Timber
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.util.*
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
/**
|
||||
* Fragment that shows recent episodes.
|
||||
|
@ -216,19 +211,7 @@ class AnimeUpdatesController :
|
|||
private fun openEpisode(item: AnimeUpdatesItem) {
|
||||
val activity = activity ?: return
|
||||
val source = Injekt.get<AnimeSourceManager>().getOrStub(item.anime.source)
|
||||
val link = runBlocking {
|
||||
return@runBlocking suspendCoroutine<String> { continuation ->
|
||||
var link: String
|
||||
launchIO {
|
||||
try {
|
||||
link = source.getEpisodeLink(item.episode.toEpisodeInfo())
|
||||
continuation.resume(link)
|
||||
} catch (e: Throwable) {
|
||||
withUIContext { throw e }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val link = EpisodeLoader.getUri(item.episode, item.anime, source)
|
||||
val episodeList: List<EpisodeItem> = Collections.emptyList()
|
||||
val intent = WatcherActivity.newIntent(activity, item.anime, item.episode, episodeList, link)
|
||||
startActivity(intent)
|
||||
|
|
|
@ -6,8 +6,8 @@ import coil.clear
|
|||
import coil.loadAny
|
||||
import coil.transform.RoundedCornersTransformation
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.databinding.AnimeUpdatesItemBinding
|
||||
import eu.kanade.tachiyomi.source.LocalSource
|
||||
import eu.kanade.tachiyomi.ui.anime.episode.base.BaseEpisodeHolder
|
||||
|
||||
/**
|
||||
|
@ -51,7 +51,7 @@ class AnimeUpdatesHolder(private val view: View, private val adapter: AnimeUpdat
|
|||
}
|
||||
|
||||
// Set episode status
|
||||
binding.download.isVisible = item.anime.source != LocalSource.ID
|
||||
binding.download.isVisible = item.anime.source != LocalAnimeSource.ID
|
||||
binding.download.setState(item.status, item.progress)
|
||||
|
||||
// Set cover
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package eu.kanade.tachiyomi.ui.recent.animeupdates
|
||||
|
||||
import android.os.Bundle
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.AnimeEpisode
|
||||
import eu.kanade.tachiyomi.data.download.AnimeDownloadManager
|
||||
import eu.kanade.tachiyomi.data.download.model.AnimeDownload
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import eu.kanade.tachiyomi.ui.recent.DateSectionItem
|
||||
import eu.kanade.tachiyomi.util.lang.toDateKey
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package eu.kanade.tachiyomi.ui.watcher
|
||||
|
||||
import android.net.Uri
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.toEpisodeInfo
|
||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.Episode
|
||||
import eu.kanade.tachiyomi.data.download.AnimeDownloadManager
|
||||
import eu.kanade.tachiyomi.util.lang.awaitSingle
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
class EpisodeLoader {
|
||||
companion object {
|
||||
fun getUri(episode: Episode, anime: Anime, source: AnimeSource): String {
|
||||
val downloadManager: AnimeDownloadManager = Injekt.get()
|
||||
val isDownloaded = downloadManager.isEpisodeDownloaded(episode, anime, true)
|
||||
return when {
|
||||
isDownloaded -> downloaded(episode, anime, source, downloadManager).toString()
|
||||
source is AnimeHttpSource -> notDownloaded(episode, anime, source)
|
||||
source is LocalAnimeSource -> "path"
|
||||
else -> error("no worky")
|
||||
}
|
||||
}
|
||||
|
||||
fun notDownloaded(episode: Episode, anime: Anime, source: AnimeSource): String {
|
||||
val link = runBlocking {
|
||||
return@runBlocking suspendCoroutine<String> { continuation ->
|
||||
var link: String
|
||||
launchIO {
|
||||
try {
|
||||
link = source.getEpisodeLink(episode.toEpisodeInfo())
|
||||
continuation.resume(link)
|
||||
} catch (e: Throwable) {
|
||||
withUIContext { throw e }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return link
|
||||
}
|
||||
|
||||
fun downloaded(
|
||||
episode: Episode,
|
||||
anime: Anime,
|
||||
source: AnimeSource,
|
||||
downloadManager: AnimeDownloadManager
|
||||
): Uri {
|
||||
val path = runBlocking {
|
||||
return@runBlocking suspendCoroutine<Uri> { continuation ->
|
||||
launchIO {
|
||||
val link =
|
||||
downloadManager.buildVideo(source, anime, episode).awaitSingle().uri!!
|
||||
continuation.resume(link)
|
||||
}
|
||||
}
|
||||
}
|
||||
return path
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,6 +21,8 @@ import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
|
|||
import com.google.android.exoplayer2.util.MimeTypes
|
||||
import com.google.android.exoplayer2.util.Util
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.AnimeHistory
|
||||
|
@ -29,8 +31,6 @@ import eu.kanade.tachiyomi.data.download.AnimeDownloadManager
|
|||
import eu.kanade.tachiyomi.data.download.model.AnimeDownload
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.ui.anime.episode.EpisodeItem
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.view.hideBar
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package eu.kanade.tachiyomi.util
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.data.cache.AnimeCoverCache
|
||||
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.source.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import java.util.Date
|
||||
|
||||
fun Anime.isLocal() = source == LocalAnimeSource.ID
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package eu.kanade.tachiyomi.util.episode
|
||||
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import eu.kanade.tachiyomi.source.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
|
||||
/**
|
||||
* -R> = regex conversion.
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package eu.kanade.tachiyomi.util.episode
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Anime
|
||||
import eu.kanade.tachiyomi.data.database.models.Episode
|
||||
import eu.kanade.tachiyomi.data.download.AnimeDownloadManager
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.model.SEpisode
|
||||
import eu.kanade.tachiyomi.source.online.AnimeHttpSource
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.util.Date
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package eu.kanade.tachiyomi.util.storage
|
||||
|
||||
import eu.kanade.tachiyomi.source.model.SAnime
|
||||
import eu.kanade.tachiyomi.source.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Document
|
||||
import java.io.Closeable
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package tachiyomi.source
|
||||
package tachiyomi.animesource
|
||||
|
||||
import tachiyomi.source.model.AnimeInfo
|
||||
import tachiyomi.source.model.EpisodeInfo
|
||||
import tachiyomi.animesource.model.AnimeInfo
|
||||
import tachiyomi.animesource.model.EpisodeInfo
|
||||
|
||||
/**
|
||||
* A basic interface for creating a source. It could be an online source, a local source, etc...
|
|
@ -1,4 +1,4 @@
|
|||
package tachiyomi.source.model
|
||||
package tachiyomi.animesource.model
|
||||
|
||||
/**
|
||||
* Model for a anime given by a source
|
|
@ -1,4 +1,4 @@
|
|||
package tachiyomi.source.model
|
||||
package tachiyomi.animesource.model
|
||||
|
||||
data class EpisodeInfo(
|
||||
var key: String,
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue