breaking changes!!!

-moved a bunch of classes to the package called animesource
-implemented a downloader that (barely) works
This commit is contained in:
jmir1 2021-05-27 22:13:27 +02:00
parent 58c954e1c3
commit 6461ea42dc
101 changed files with 583 additions and 471 deletions

View file

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi
import android.app.Application import android.app.Application
import android.os.Handler import android.os.Handler
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
import eu.kanade.tachiyomi.data.cache.AnimeCoverCache import eu.kanade.tachiyomi.data.cache.AnimeCoverCache
import eu.kanade.tachiyomi.data.cache.ChapterCache import eu.kanade.tachiyomi.data.cache.ChapterCache
import eu.kanade.tachiyomi.data.cache.CoverCache 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.AnimeExtensionManager
import eu.kanade.tachiyomi.extension.ExtensionManager import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.source.AnimeSourceManager
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import uy.kohesive.injekt.api.InjektModule import uy.kohesive.injekt.api.InjektModule

View file

@ -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.animesource.model.AnimesPage
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.animesource.model.FilterList
import rx.Observable import rx.Observable
interface AnimeCatalogueSource : AnimeSource { interface AnimeCatalogueSource : AnimeSource {

View file

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

View file

@ -1,24 +1,24 @@
package eu.kanade.tachiyomi.source package eu.kanade.tachiyomi.animesource
import android.graphics.drawable.Drawable 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.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 eu.kanade.tachiyomi.util.lang.awaitSingle
import rx.Observable import rx.Observable
import tachiyomi.source.model.AnimeInfo import tachiyomi.animesource.model.AnimeInfo
import tachiyomi.source.model.EpisodeInfo import tachiyomi.animesource.model.EpisodeInfo
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
/** /**
* A basic interface for creating a source. It could be an online source, a local source, etc... * 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. * Id for the source. Must be unique.

View file

@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.source package eu.kanade.tachiyomi.animesource
/** /**
* A factory for creating sources at runtime. * A factory for creating sources at runtime.

View file

@ -1,10 +1,10 @@
package eu.kanade.tachiyomi.source package eu.kanade.tachiyomi.animesource
import android.content.Context import android.content.Context
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SAnime import eu.kanade.tachiyomi.animesource.model.SAnime
import eu.kanade.tachiyomi.source.model.SEpisode import eu.kanade.tachiyomi.animesource.model.SEpisode
import eu.kanade.tachiyomi.source.online.AnimeHttpSource import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
import rx.Observable import rx.Observable
open class AnimeSourceManager(private val context: Context) { open class AnimeSourceManager(private val context: Context) {

View file

@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.source package eu.kanade.tachiyomi.animesource
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen

View file

@ -1,14 +1,14 @@
package eu.kanade.tachiyomi.source package eu.kanade.tachiyomi.animesource
import android.content.Context import android.content.Context
import com.github.junrar.Archive import com.github.junrar.Archive
import com.google.gson.JsonParser import com.google.gson.JsonParser
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.AnimesPage import eu.kanade.tachiyomi.animesource.model.AnimesPage
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.animesource.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.animesource.model.FilterList
import eu.kanade.tachiyomi.source.model.SAnime import eu.kanade.tachiyomi.animesource.model.SAnime
import eu.kanade.tachiyomi.source.model.SEpisode import eu.kanade.tachiyomi.animesource.model.SEpisode
import eu.kanade.tachiyomi.util.episode.EpisodeRecognition import eu.kanade.tachiyomi.util.episode.EpisodeRecognition
import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder
import eu.kanade.tachiyomi.util.storage.AnimeFile import eu.kanade.tachiyomi.util.storage.AnimeFile

View file

@ -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) data class AnimesPage(val animes: List<SAnime>, val hasNextPage: Boolean)

View file

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

View file

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

View file

@ -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 import java.io.Serializable
interface SAnime : Serializable { interface SAnime : Serializable {

View file

@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.source.model package eu.kanade.tachiyomi.animesource.model
class SAnimeImpl : SAnime { class SAnimeImpl : SAnime {

View file

@ -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 import java.io.Serializable
interface SEpisode : Serializable { interface SEpisode : Serializable {

View file

@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.source.model package eu.kanade.tachiyomi.animesource.model
class SEpisodeImpl : SEpisode { class SEpisodeImpl : SEpisode {

View file

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

View file

@ -1,20 +1,19 @@
package eu.kanade.tachiyomi.source.online package eu.kanade.tachiyomi.animesource.online
import eu.kanade.tachiyomi.network.GET import android.net.Uri
import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.animesource.model.AnimesPage
import eu.kanade.tachiyomi.network.newCallWithProgress import eu.kanade.tachiyomi.animesource.model.FilterList
import eu.kanade.tachiyomi.source.AnimeCatalogueSource import eu.kanade.tachiyomi.animesource.model.SAnime
import eu.kanade.tachiyomi.source.model.AnimesPage import eu.kanade.tachiyomi.animesource.model.SEpisode
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.network.*
import eu.kanade.tachiyomi.source.model.SAnime
import eu.kanade.tachiyomi.source.model.SEpisode
import okhttp3.Headers import okhttp3.Headers
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import rx.Observable import rx.Observable
import timber.log.Timber
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.net.URI import java.net.URI
import java.net.URISyntaxException 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 * 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. * 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 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 * 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. * database and the urls could still work after a domain change.

View file

@ -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.animesource.model.AnimesPage
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.animesource.model.SAnime
import eu.kanade.tachiyomi.source.model.SAnime import eu.kanade.tachiyomi.animesource.model.SEpisode
import eu.kanade.tachiyomi.source.model.SEpisode
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
@ -187,36 +186,4 @@ abstract class ParsedAnimeHttpSource : AnimeHttpSource() {
* @param element an element obtained from [episodeListSelector]. * @param element an element obtained from [episodeListSelector].
*/ */
protected abstract fun linkFromElement(element: Element): String 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
} }

View file

@ -7,6 +7,10 @@ import android.os.IBinder
import android.os.PowerManager import android.os.PowerManager
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import eu.kanade.tachiyomi.R 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.AnimelibUpdateRanker.rankingScheme
import eu.kanade.tachiyomi.data.animelib.AnimelibUpdateService.Companion.start import eu.kanade.tachiyomi.data.animelib.AnimelibUpdateService.Companion.start
import eu.kanade.tachiyomi.data.cache.AnimeCoverCache 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.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.UnattendedTrackService 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.NoEpisodesException
import eu.kanade.tachiyomi.util.episode.syncEpisodesWithSource import eu.kanade.tachiyomi.util.episode.syncEpisodesWithSource
import eu.kanade.tachiyomi.util.episode.syncEpisodesWithTrackServiceTwoWay import eu.kanade.tachiyomi.util.episode.syncEpisodesWithTrackServiceTwoWay

View file

@ -2,6 +2,8 @@ package eu.kanade.tachiyomi.data.backup
import android.content.Context import android.content.Context
import android.net.Uri 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.AnimeDatabaseHelper
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Anime 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.database.models.toMangaInfo
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.AnimeSource
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.toSChapter 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.chapter.syncChaptersWithSource
import eu.kanade.tachiyomi.util.episode.syncEpisodesWithSource import eu.kanade.tachiyomi.util.episode.syncEpisodesWithSource
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy

View file

@ -8,6 +8,8 @@ import com.github.salomonbrys.kotson.registerTypeHierarchyAdapter
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
import com.google.gson.JsonArray 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.AbstractBackupManager
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.CURRENT_VERSION import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.CURRENT_VERSION
import eu.kanade.tachiyomi.data.backup.legacy.models.DHistory 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.TrackImpl
import eu.kanade.tachiyomi.data.database.models.toAnimeInfo import eu.kanade.tachiyomi.data.database.models.toAnimeInfo
import eu.kanade.tachiyomi.data.database.models.toMangaInfo 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.Source
import eu.kanade.tachiyomi.source.model.toSAnime
import eu.kanade.tachiyomi.source.model.toSManga import eu.kanade.tachiyomi.source.model.toSManga
import kotlin.math.max import kotlin.math.max

View file

@ -4,8 +4,8 @@ import android.content.Context
import android.text.format.Formatter import android.text.format.Formatter
import com.google.gson.Gson import com.google.gson.Gson
import com.jakewharton.disklrucache.DiskLruCache import com.jakewharton.disklrucache.DiskLruCache
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.data.database.models.Episode 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.DiskUtil
import eu.kanade.tachiyomi.util.storage.saveTo import eu.kanade.tachiyomi.util.storage.saveTo
import okhttp3.Response import okhttp3.Response
@ -97,9 +97,9 @@ class EpisodeCache(private val context: Context) {
* @param episode the episode. * @param episode the episode.
* @param pages list of pages. * @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. // 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). // Initialize the editor (edits the values for an entry).
var editor: DiskLruCache.Editor? = null var editor: DiskLruCache.Editor? = null
@ -145,7 +145,7 @@ class EpisodeCache(private val context: Context) {
* @param imageUrl url of image. * @param imageUrl url of image.
* @return path of image. * @return path of image.
*/ */
fun getImageFile(imageUrl: String): File { fun getVideoFile(imageUrl: String): File {
// Get file from md5 key. // Get file from md5 key.
val imageName = DiskUtil.hashKeyForDisk(imageUrl) + ".0" val imageName = DiskUtil.hashKeyForDisk(imageUrl) + ".0"
return File(diskCache.directory, imageName) return File(diskCache.directory, imageName)

View file

@ -9,12 +9,12 @@ import coil.fetch.SourceResult
import coil.network.HttpException import coil.network.HttpException
import coil.request.get import coil.request.get
import coil.size.Size 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.cache.AnimeCoverCache
import eu.kanade.tachiyomi.data.database.models.Anime import eu.kanade.tachiyomi.data.database.models.Anime
import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.source.AnimeSourceManager
import eu.kanade.tachiyomi.source.online.AnimeHttpSource
import okhttp3.CacheControl import okhttp3.CacheControl
import okhttp3.Call import okhttp3.Call
import okhttp3.Request import okhttp3.Request

View file

@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.data.database.models package eu.kanade.tachiyomi.data.database.models
import eu.kanade.tachiyomi.source.model.SAnime import eu.kanade.tachiyomi.animesource.model.SAnime
import tachiyomi.source.model.AnimeInfo import tachiyomi.animesource.model.AnimeInfo
interface Anime : SAnime { interface Anime : SAnime {

View file

@ -1,6 +1,6 @@
package eu.kanade.tachiyomi.data.database.models 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 import java.io.Serializable
interface Episode : SEpisode, Serializable { interface Episode : SEpisode, Serializable {

View file

@ -3,10 +3,10 @@ package eu.kanade.tachiyomi.data.download
import android.content.Context import android.content.Context
import androidx.core.net.toUri import androidx.core.net.toUri
import com.hippo.unifile.UniFile 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.Anime
import eu.kanade.tachiyomi.data.database.models.Episode import eu.kanade.tachiyomi.data.database.models.Episode
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.AnimeSourceManager
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get

View file

@ -4,14 +4,14 @@ import android.content.Context
import com.hippo.unifile.UniFile import com.hippo.unifile.UniFile
import com.jakewharton.rxrelay.BehaviorRelay import com.jakewharton.rxrelay.BehaviorRelay
import eu.kanade.tachiyomi.R 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.Anime
import eu.kanade.tachiyomi.data.database.models.Episode import eu.kanade.tachiyomi.data.database.models.Episode
import eu.kanade.tachiyomi.data.download.model.AnimeDownload import eu.kanade.tachiyomi.data.download.model.AnimeDownload
import eu.kanade.tachiyomi.data.download.model.AnimeDownloadQueue import eu.kanade.tachiyomi.data.download.model.AnimeDownloadQueue
import eu.kanade.tachiyomi.data.preference.PreferencesHelper 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 eu.kanade.tachiyomi.util.lang.launchIO
import rx.Observable import rx.Observable
import timber.log.Timber import timber.log.Timber
@ -137,8 +137,8 @@ class AnimeDownloadManager(private val context: Context) {
* @param episode the downloaded episode. * @param episode the downloaded episode.
* @return an observable containing the list of pages from the episode. * @return an observable containing the list of pages from the episode.
*/ */
fun buildPageList(source: AnimeSource, anime: Anime, episode: Episode): Observable<List<Page>> { fun buildVideo(source: AnimeSource, anime: Anime, episode: Episode): Observable<Video> {
return buildPageList(provider.findEpisodeDir(episode, anime, source)) 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. * @param episodeDir the file where the episode is downloaded.
* @return an observable containing the list of pages from the episode. * @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 { return Observable.fromCallable {
val files = episodeDir?.listFiles().orEmpty() val files = episodeDir?.listFiles().orEmpty()
.filter { "image" in it.type.orEmpty() } .filter { "video" in it.type.orEmpty() }
if (files.isEmpty()) { if (files.isEmpty()) {
throw Exception(context.getString(R.string.page_list_empty_error)) throw Exception(context.getString(R.string.page_list_empty_error))
} }
files.sortedBy { it.name } val file = files[0]
.mapIndexed { i, file -> Video(uri = file.uri).apply { status = Video.READY }
Page(i, uri = file.uri).apply { status = Page.READY }
}
} }
} }

View file

@ -100,7 +100,7 @@ internal class AnimeDownloadNotifier(private val context: Context) {
val downloadingProgressText = context.getString( val downloadingProgressText = context.getString(
R.string.chapter_downloading_progress, R.string.chapter_downloading_progress,
download.downloadedImages, download.downloadedImages,
download.pages!!.size 1
) )
if (preferences.hideNotificationContent()) { if (preferences.hideNotificationContent()) {
@ -113,7 +113,7 @@ internal class AnimeDownloadNotifier(private val context: Context) {
setContentText(downloadingProgressText) setContentText(downloadingProgressText)
} }
setProgress(download.pages!!.size, download.downloadedImages, false) setProgress(1, download.downloadedImages, false)
setOngoing(true) setOngoing(true)
show(Notifications.ID_DOWNLOAD_CHAPTER_PROGRESS) show(Notifications.ID_DOWNLOAD_CHAPTER_PROGRESS)

View file

@ -4,10 +4,10 @@ import android.content.Context
import androidx.core.net.toUri import androidx.core.net.toUri
import com.hippo.unifile.UniFile import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.R 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.Anime
import eu.kanade.tachiyomi.data.database.models.Episode import eu.kanade.tachiyomi.data.database.models.Episode
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.AnimeSource
import eu.kanade.tachiyomi.util.storage.DiskUtil import eu.kanade.tachiyomi.util.storage.DiskUtil
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn

View file

@ -2,11 +2,11 @@ package eu.kanade.tachiyomi.data.download
import android.content.Context import android.content.Context
import androidx.core.content.edit 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.AnimeDatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Anime import eu.kanade.tachiyomi.data.database.models.Anime
import eu.kanade.tachiyomi.data.download.model.AnimeDownload 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.Serializable
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString

View file

@ -1,20 +1,21 @@
package eu.kanade.tachiyomi.data.download package eu.kanade.tachiyomi.data.download
import android.content.Context import android.content.Context
import android.util.Log
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import com.hippo.unifile.UniFile import com.hippo.unifile.UniFile
import com.jakewharton.rxrelay.BehaviorRelay import com.jakewharton.rxrelay.BehaviorRelay
import com.jakewharton.rxrelay.PublishRelay import com.jakewharton.rxrelay.PublishRelay
import eu.kanade.tachiyomi.R 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.cache.EpisodeCache
import eu.kanade.tachiyomi.data.database.models.Anime import eu.kanade.tachiyomi.data.database.models.Anime
import eu.kanade.tachiyomi.data.database.models.Episode import eu.kanade.tachiyomi.data.database.models.Episode
import eu.kanade.tachiyomi.data.download.model.AnimeDownload import eu.kanade.tachiyomi.data.download.model.AnimeDownload
import eu.kanade.tachiyomi.data.download.model.AnimeDownloadQueue 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.RetryWithDelay
import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.launchNow import eu.kanade.tachiyomi.util.lang.launchNow
@ -257,7 +258,8 @@ class AnimeDownloader(
// Start downloader if needed // Start downloader if needed
if (autoStart && wasEmpty) { 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 episodeDirname = provider.getEpisodeDirName(download.episode)
val tmpDir = animeDir.createDirectory(episodeDirname + TMP_DIR_SUFFIX) val tmpDir = animeDir.createDirectory(episodeDirname + TMP_DIR_SUFFIX)
val pageListObservable = if (download.pages == null) { val videoObservable = if (download.video == null) {
// Pull page list from network and add them to download object // Pull video from network and add them to download object
Observable.just(emptyList()) 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 { } else {
// Or if the page list already exists, start from the file // Or if the video already exists, start from the file
Observable.just(download.pages!!) Observable.just(download.video!!)
} }
pageListObservable videoObservable
.doOnNext { _ -> .doOnNext { _ ->
// Delete all temporary (unfinished) files // Delete all temporary (unfinished) files
Timber.w("delfiles")
tmpDir.listFiles() tmpDir.listFiles()
?.filter { it.name!!.endsWith(".tmp") } ?.filter { it.name!!.endsWith(".tmp") }
?.forEach { it.delete() } ?.forEach { it.delete() }
@ -299,10 +309,10 @@ class AnimeDownloader(
download.status = AnimeDownload.State.DOWNLOADING download.status = AnimeDownload.State.DOWNLOADING
} }
// Get all the URLs to the source images, fetch pages if necessary // 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 // Start downloading images, consider we can have downloaded images already
// Concurrently do 5 pages at a time // Concurrently do 5 pages at a time
.flatMap({ page -> getOrAnimeDownloadImage(page, download, tmpDir) }, 5) .flatMap({ video -> getOrAnimeDownloadImage(video, download, tmpDir) }, 5)
.onBackpressureLatest() .onBackpressureLatest()
// Do when page is downloaded. // Do when page is downloaded.
.doOnNext { notifier.onProgressChange(download) } .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 * Returns the observable which gets the image from the filesystem if it exists or downloads it
* otherwise. * otherwise.
* *
* @param page the page to download. * @param video the page to download.
* @param download the download of the page. * @param download the download of the page.
* @param tmpDir the temporary directory of the download. * @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 the image URL is empty, do nothing
if (page.imageUrl == null) { if (video.videoUrl == null) {
return Observable.just(page) 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") val tmpFile = tmpDir.findFile("$filename.tmp")
// Delete temp file if it exists. // Delete temp file if it exists.
tmpFile?.delete() tmpFile?.delete()
// Try to find the image file. // 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 { val pageObservable = when {
imageFile != null -> Observable.just(imageFile) videoFile != null -> Observable.just(videoFile)
episodeCache.isImageInCache(page.imageUrl!!) -> copyImageFromCache(episodeCache.getImageFile(page.imageUrl!!), tmpDir, filename) episodeCache.isImageInCache(video.videoUrl!!) -> copyVideoFromCache(episodeCache.getVideoFile(video.videoUrl!!), tmpDir, filename)
else -> downloadImage(page, download.source, tmpDir, filename) else -> downloadVideo(video, download.source, tmpDir, filename)
} }
return pageObservable return pageObservable
// When the image is ready, set image path, progress (just in case) and status // When the image is ready, set image path, progress (just in case) and status
.doOnNext { file -> .doOnNext { file ->
page.uri = file.uri video.uri = file.uri
page.progress = 100 video.progress = 100
download.downloadedImages++ 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 // Mark this page as error and allow to download the remaining
.onErrorReturn { .onErrorReturn {
page.progress = 0 video.progress = 0
page.status = Page.ERROR video.status = Video.ERROR
page video
} }
} }
/** /**
* Returns the observable which downloads the image from network. * 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 source the source of the page.
* @param tmpDir the temporary directory of the download. * @param tmpDir the temporary directory of the download.
* @param filename the filename of the image. * @param filename the filename of the image.
*/ */
private fun downloadImage(page: Page, source: AnimeHttpSource, tmpDir: UniFile, filename: String): Observable<UniFile> { private fun downloadVideo(video: Video, source: AnimeHttpSource, tmpDir: UniFile, filename: String): Observable<UniFile> {
page.status = Page.DOWNLOAD_IMAGE video.status = Video.DOWNLOAD_IMAGE
page.progress = 0 video.progress = 0
return source.fetchImage(page) return source.fetchVideo(video)
.map { response -> .map { response ->
val file = tmpDir.createFile("$filename.tmp") val file = tmpDir.createFile("$filename.tmp")
try { try {
@ -401,7 +413,7 @@ class AnimeDownloader(
* @param tmpDir the temporary directory of the download. * @param tmpDir the temporary directory of the download.
* @param filename the filename of the image. * @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 { return Observable.just(cacheFile).map {
val tmpFile = tmpDir.createFile("$filename.tmp") val tmpFile = tmpDir.createFile("$filename.tmp")
cacheFile.inputStream().use { input -> cacheFile.inputStream().use { input ->
@ -451,7 +463,7 @@ class AnimeDownloader(
// Ensure that the episode folder has all the images. // Ensure that the episode folder has all the images.
val downloadedImages = tmpDir.listFiles().orEmpty().filterNot { it.name!!.endsWith(".tmp") } 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 AnimeDownload.State.DOWNLOADED
} else { } else {
AnimeDownload.State.ERROR AnimeDownload.State.ERROR

View file

@ -1,14 +1,14 @@
package eu.kanade.tachiyomi.data.download.model 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.Anime
import eu.kanade.tachiyomi.data.database.models.Episode 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 import rx.subjects.PublishSubject
class AnimeDownload(val source: AnimeHttpSource, val anime: Anime, val episode: Episode) { class AnimeDownload(val source: AnimeHttpSource, val anime: Anime, val episode: Episode) {
var pages: List<Page>? = null var video: Video? = null
@Volatile @Volatile
@Transient @Transient
@ -35,8 +35,8 @@ class AnimeDownload(val source: AnimeHttpSource, val anime: Anime, val episode:
val progress: Int val progress: Int
get() { get() {
val pages = pages ?: return 0 val video = video ?: return 0
return pages.map(Page::progress).average().toInt() return video.progress
} }
fun setStatusSubject(subject: PublishSubject<AnimeDownload>?) { fun setStatusSubject(subject: PublishSubject<AnimeDownload>?) {

View file

@ -1,10 +1,10 @@
package eu.kanade.tachiyomi.data.download.model package eu.kanade.tachiyomi.data.download.model
import com.jakewharton.rxrelay.PublishRelay 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.Anime
import eu.kanade.tachiyomi.data.database.models.Episode import eu.kanade.tachiyomi.data.database.models.Episode
import eu.kanade.tachiyomi.data.download.AnimeDownloadStore import eu.kanade.tachiyomi.data.download.AnimeDownloadStore
import eu.kanade.tachiyomi.source.model.Page
import rx.Observable import rx.Observable
import rx.subjects.PublishSubject import rx.subjects.PublishSubject
import java.util.concurrent.CopyOnWriteArrayList import java.util.concurrent.CopyOnWriteArrayList
@ -80,7 +80,7 @@ class AnimeDownloadQueue(
private fun setPagesFor(download: AnimeDownload) { private fun setPagesFor(download: AnimeDownload) {
if (download.status == AnimeDownload.State.DOWNLOADED || download.status == AnimeDownload.State.ERROR) { 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 -> .flatMap { download ->
if (download.status == AnimeDownload.State.DOWNLOADING) { if (download.status == AnimeDownload.State.DOWNLOADING) {
val pageStatusSubject = PublishSubject.create<Int>() val pageStatusSubject = PublishSubject.create<Int>()
setPagesSubject(download.pages, pageStatusSubject) setPagesSubject(download.video, pageStatusSubject)
return@flatMap pageStatusSubject return@flatMap pageStatusSubject
.onBackpressureBuffer() .onBackpressureBuffer()
.filter { it == Page.READY } .filter { it == Video.READY }
.map { download } .map { download }
} else if (download.status == AnimeDownload.State.DOWNLOADED || download.status == AnimeDownload.State.ERROR) { } else if (download.status == AnimeDownload.State.DOWNLOADED || download.status == AnimeDownload.State.ERROR) {
setPagesSubject(download.pages, null) setPagesSubject(download.video, null)
} }
Observable.just(download) Observable.just(download)
} }
.filter { it.status == AnimeDownload.State.DOWNLOADING } .filter { it.status == AnimeDownload.State.DOWNLOADING }
} }
private fun setPagesSubject(pages: List<Page>?, subject: PublishSubject<Int>?) { private fun setPagesSubject(video: Video?, subject: PublishSubject<Int>?) {
pages?.forEach { it.setStatusSubject(subject) } video?.setStatusSubject(subject)
} }
} }

View file

@ -9,6 +9,7 @@ import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Handler import android.os.Handler
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
import eu.kanade.tachiyomi.data.animelib.AnimelibUpdateService import eu.kanade.tachiyomi.data.animelib.AnimelibUpdateService
import eu.kanade.tachiyomi.data.backup.BackupRestoreService import eu.kanade.tachiyomi.data.backup.BackupRestoreService
import eu.kanade.tachiyomi.data.database.DatabaseHelper 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.download.DownloadService
import eu.kanade.tachiyomi.data.library.LibraryUpdateService import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.AnimeSourceManager
import eu.kanade.tachiyomi.source.SourceManager 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.AnimeController
import eu.kanade.tachiyomi.ui.anime.episode.EpisodeItem import eu.kanade.tachiyomi.ui.anime.episode.EpisodeItem
import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.reader.ReaderActivity 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.ui.watcher.WatcherActivity
import eu.kanade.tachiyomi.util.lang.launchIO 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.DiskUtil
import eu.kanade.tachiyomi.util.storage.getUriCompat import eu.kanade.tachiyomi.util.storage.getUriCompat
import eu.kanade.tachiyomi.util.system.notificationManager import eu.kanade.tachiyomi.util.system.notificationManager
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.runBlocking
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.File import java.io.File
import java.util.Collections.emptyList import java.util.Collections.emptyList
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import eu.kanade.tachiyomi.BuildConfig.APPLICATION_ID as ID 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 { internal fun openEpisodePendingActivity(context: Context, anime: Anime, episode: Episode): PendingIntent {
val source = Injekt.get<AnimeSourceManager>().getOrStub(anime.source) val source = Injekt.get<AnimeSourceManager>().getOrStub(anime.source)
val link = runBlocking { val link = EpisodeLoader.getUri(episode, anime, source)
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 episodeList: List<EpisodeItem> = emptyList() val episodeList: List<EpisodeItem> = emptyList()
val newIntent = WatcherActivity.newIntent(context, anime, episode, episodeList, link) val newIntent = WatcherActivity.newIntent(context, anime, episode, episodeList, link)
return PendingIntent.getActivity(context, AnimeController.REQUEST_INTERNAL, newIntent, PendingIntent.FLAG_UPDATE_CURRENT) return PendingIntent.getActivity(context, AnimeController.REQUEST_INTERNAL, newIntent, PendingIntent.FLAG_UPDATE_CURRENT)

View file

@ -1,10 +1,10 @@
package eu.kanade.tachiyomi.data.track 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.Anime
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.source.AnimeSource
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
/** /**

View file

@ -4,6 +4,7 @@ import android.content.Context
import android.graphics.Color import android.graphics.Color
import androidx.annotation.StringRes import androidx.annotation.StringRes
import eu.kanade.tachiyomi.R 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.Anime
import eu.kanade.tachiyomi.data.database.models.AnimeTrack import eu.kanade.tachiyomi.data.database.models.AnimeTrack
import eu.kanade.tachiyomi.data.database.models.Manga 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.UnattendedTrackService
import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.source.AnimeSource
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import okhttp3.Dns import okhttp3.Dns
import okhttp3.OkHttpClient import okhttp3.OkHttpClient

View file

@ -3,6 +3,8 @@ package eu.kanade.tachiyomi.extension
import android.content.Context import android.content.Context
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import com.jakewharton.rxrelay.BehaviorRelay 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.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.plusAssign import eu.kanade.tachiyomi.data.preference.plusAssign
import eu.kanade.tachiyomi.extension.api.AnimeExtensionGithubApi 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.AnimeExtensionInstallReceiver
import eu.kanade.tachiyomi.extension.util.AnimeExtensionInstaller import eu.kanade.tachiyomi.extension.util.AnimeExtensionInstaller
import eu.kanade.tachiyomi.extension.util.AnimeExtensionLoader 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.lang.launchNow
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.async import kotlinx.coroutines.async

View file

@ -1,6 +1,6 @@
package eu.kanade.tachiyomi.extension.model package eu.kanade.tachiyomi.extension.model
import eu.kanade.tachiyomi.source.AnimeSource import eu.kanade.tachiyomi.animesource.AnimeSource
sealed class AnimeExtension { sealed class AnimeExtension {

View file

@ -5,13 +5,13 @@ import android.content.Context
import android.content.pm.PackageInfo import android.content.pm.PackageInfo
import android.content.pm.PackageManager import android.content.pm.PackageManager
import dalvik.system.PathClassLoader 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.annotations.Nsfw
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.extension.model.AnimeExtension import eu.kanade.tachiyomi.extension.model.AnimeExtension
import eu.kanade.tachiyomi.extension.model.AnimeLoadResult 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 eu.kanade.tachiyomi.util.lang.Hash
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking

View file

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

View file

@ -26,6 +26,10 @@ import dev.chrisbanes.insetter.applyInsetter
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.SelectableAdapter import eu.davidea.flexibleadapter.SelectableAdapter
import eu.kanade.tachiyomi.R 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.cache.AnimeCoverCache
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Anime 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.UnattendedTrackService
import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch import eu.kanade.tachiyomi.data.track.model.AnimeTrackSearch
import eu.kanade.tachiyomi.databinding.AnimeControllerBinding 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.*
import eu.kanade.tachiyomi.ui.anime.episode.base.BaseEpisodesAdapter import eu.kanade.tachiyomi.ui.anime.episode.base.BaseEpisodesAdapter
import eu.kanade.tachiyomi.ui.anime.info.AnimeInfoHeaderAdapter 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.main.MainActivity
import eu.kanade.tachiyomi.ui.recent.history.HistoryController import eu.kanade.tachiyomi.ui.recent.history.HistoryController
import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController 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.watcher.WatcherActivity
import eu.kanade.tachiyomi.ui.webview.WebViewActivity import eu.kanade.tachiyomi.ui.webview.WebViewActivity
import eu.kanade.tachiyomi.util.episode.NoEpisodesException import eu.kanade.tachiyomi.util.episode.NoEpisodesException
@ -80,8 +81,6 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import reactivecircus.flowbinding.recyclerview.scrollEvents import reactivecircus.flowbinding.recyclerview.scrollEvents
import reactivecircus.flowbinding.swiperefreshlayout.refreshes import reactivecircus.flowbinding.swiperefreshlayout.refreshes
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
@ -163,7 +162,7 @@ class AnimeController :
*/ */
private val selectedEpisodes = mutableSetOf<EpisodeItem>() 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)) private var lastClickPositionStack = ArrayDeque(listOf(-1))
@ -337,7 +336,7 @@ class AnimeController :
// Create animation listener // Create animation listener
val revealAnimationListener: Animator.AnimatorListener = object : AnimatorListenerAdapter() { val revealAnimationListener: Animator.AnimatorListener = object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator?) { override fun onAnimationStart(animation: Animator?) {
openEpisode(item.episode, true) openEpisode(item.episode)
} }
} }
@ -348,7 +347,7 @@ class AnimeController :
coordinates.y, coordinates.y,
object : AnimatorListenerAdapter() { object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator?) { 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 val activity = activity ?: return
runBlocking { launchIO {
launch { val url = EpisodeLoader.getUri(episode, anime!!, source!!)
val url = fetchEpisodeLinksFromSource(false, episode) val episodeList = presenter.filteredAndSortedEpisodes
val episodeList = presenter.filteredAndSortedEpisodes val intent = WatcherActivity.newIntent(activity, presenter.anime, episode, episodeList, url)
val intent = WatcherActivity.newIntent(activity, presenter.anime, episode, episodeList, url) if (!preferences.alwaysUseExternalPlayer()) {
if (hasAnimation) { startActivityForResult(intent, REQUEST_INTERNAL)
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION) } else {
} currentExtEpisode = episode
if (!preferences.alwaysUseExternalPlayer()) { val extIntent = Intent(Intent.ACTION_VIEW)
startActivityForResult(intent, REQUEST_INTERNAL) extIntent.setDataAndTypeAndNormalize(Uri.parse(url), "video/*")
} else { extIntent.putExtra("title", episode.name)
currentExtEpisode = episode extIntent.putExtra("position", episode.last_second_seen.toInt())
val uri = Uri.parse(url) extIntent.putExtra("return_result", true)
val extIntent = Intent(Intent.ACTION_VIEW) startActivityForResult(extIntent, REQUEST_EXTERNAL)
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)
}
} }
} }
} }

View file

@ -4,6 +4,11 @@ import android.content.Context
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import com.jakewharton.rxrelay.PublishRelay 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.cache.AnimeCoverCache
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Anime 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.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.UnattendedTrackService 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.episode.EpisodeItem
import eu.kanade.tachiyomi.ui.anime.track.TrackItem import eu.kanade.tachiyomi.ui.anime.track.TrackItem
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter

View file

@ -6,9 +6,9 @@ import androidx.core.text.buildSpannedString
import androidx.core.text.color import androidx.core.text.color
import androidx.core.view.isVisible import androidx.core.view.isVisible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
import eu.kanade.tachiyomi.data.database.models.Anime import eu.kanade.tachiyomi.data.database.models.Anime
import eu.kanade.tachiyomi.databinding.EpisodesItemBinding import eu.kanade.tachiyomi.databinding.EpisodesItemBinding
import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.ui.anime.episode.base.BaseEpisodeHolder import eu.kanade.tachiyomi.ui.anime.episode.base.BaseEpisodeHolder
import java.util.Date import java.util.Date
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -93,7 +93,7 @@ class EpisodeHolder(
binding.episodeDescription.text = "" 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) binding.animedownload.setState(item.status, item.progress)
} }
} }

View file

@ -4,7 +4,6 @@ import eu.davidea.flexibleadapter.items.AbstractHeaderItem
import eu.davidea.flexibleadapter.items.AbstractSectionableItem import eu.davidea.flexibleadapter.items.AbstractSectionableItem
import eu.kanade.tachiyomi.data.database.models.Episode import eu.kanade.tachiyomi.data.database.models.Episode
import eu.kanade.tachiyomi.data.download.model.AnimeDownload import eu.kanade.tachiyomi.data.download.model.AnimeDownload
import eu.kanade.tachiyomi.source.model.Page
abstract class BaseEpisodeItem<T : BaseEpisodeHolder, H : AbstractHeaderItem<*>>( abstract class BaseEpisodeItem<T : BaseEpisodeHolder, H : AbstractHeaderItem<*>>(
val episode: Episode, val episode: Episode,
@ -23,8 +22,8 @@ abstract class BaseEpisodeItem<T : BaseEpisodeHolder, H : AbstractHeaderItem<*>>
val progress: Int val progress: Int
get() { get() {
val pages = download?.pages ?: return 0 val video = download?.video ?: return 0
return pages.map(Page::progress).average().toInt() return video.progress
} }
@Transient @Transient

View file

@ -7,13 +7,13 @@ import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import coil.loadAny import coil.loadAny
import eu.kanade.tachiyomi.R 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.database.models.Anime
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.databinding.AnimeInfoHeaderBinding 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.ui.anime.AnimeController
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import eu.kanade.tachiyomi.util.view.setChips 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.isVisible = true
binding.btnWebview.clicks() binding.btnWebview.clicks()
.onEach { controller.openAnimeInWebView() } .onEach { controller.openAnimeInWebView() }

View file

@ -6,10 +6,10 @@ import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import eu.kanade.tachiyomi.R.string 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.database.models.Anime
import eu.kanade.tachiyomi.data.track.UnattendedTrackService import eu.kanade.tachiyomi.data.track.UnattendedTrackService
import eu.kanade.tachiyomi.databinding.TrackControllerBinding import eu.kanade.tachiyomi.databinding.TrackControllerBinding
import eu.kanade.tachiyomi.source.AnimeSourceManager
import eu.kanade.tachiyomi.ui.anime.AnimeController import eu.kanade.tachiyomi.ui.anime.AnimeController
import eu.kanade.tachiyomi.ui.base.controller.openInBrowser import eu.kanade.tachiyomi.ui.base.controller.openInBrowser
import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchIO

View file

@ -19,13 +19,13 @@ import com.jakewharton.rxrelay.PublishRelay
import com.tfcporciuncula.flow.Preference import com.tfcporciuncula.flow.Preference
import dev.chrisbanes.insetter.applyInsetter import dev.chrisbanes.insetter.applyInsetter
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
import eu.kanade.tachiyomi.data.animelib.AnimelibUpdateService import eu.kanade.tachiyomi.data.animelib.AnimelibUpdateService
import eu.kanade.tachiyomi.data.database.models.Anime import eu.kanade.tachiyomi.data.database.models.Anime
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.asImmediateFlow import eu.kanade.tachiyomi.data.preference.asImmediateFlow
import eu.kanade.tachiyomi.databinding.AnimelibControllerBinding import eu.kanade.tachiyomi.databinding.AnimelibControllerBinding
import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.ui.anime.AnimeController import eu.kanade.tachiyomi.ui.anime.AnimeController
import eu.kanade.tachiyomi.ui.base.controller.RootController import eu.kanade.tachiyomi.ui.base.controller.RootController
import eu.kanade.tachiyomi.ui.base.controller.SearchableNucleusController import eu.kanade.tachiyomi.ui.base.controller.SearchableNucleusController
@ -447,7 +447,7 @@ class AnimelibController(
} else { } else {
mode.title = count.toString() 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 return false
} }

View file

@ -12,11 +12,11 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import eu.davidea.flexibleadapter.items.IFilterable import eu.davidea.flexibleadapter.items.IFilterable
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
import eu.kanade.tachiyomi.data.database.models.AnimelibAnime import eu.kanade.tachiyomi.data.database.models.AnimelibAnime
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.widget.AutofitRecyclerView import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get 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>) : class AnimelibItem(val anime: AnimelibAnime, private val animelibDisplayMode: Preference<DisplayMode>) :
AbstractFlexibleItem<AnimelibHolder<*>>(), IFilterable<String> { AbstractFlexibleItem<AnimelibHolder<*>>(), IFilterable<String> {
private val sourceManager: SourceManager = Injekt.get() private val sourceManager: AnimeSourceManager = Injekt.get()
var downloadCount = -1 var downloadCount = -1
var unreadCount = -1 var unreadCount = -1

View file

@ -2,6 +2,9 @@ package eu.kanade.tachiyomi.ui.animelib
import android.os.Bundle import android.os.Bundle
import com.jakewharton.rxrelay.BehaviorRelay 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.cache.AnimeCoverCache
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Anime 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.download.AnimeDownloadManager
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager 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.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.util.isLocal import eu.kanade.tachiyomi.util.isLocal
import eu.kanade.tachiyomi.util.lang.combineLatest import eu.kanade.tachiyomi.util.lang.combineLatest

View file

@ -6,9 +6,9 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractSectionableItem import eu.davidea.flexibleadapter.items.AbstractSectionableItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
import eu.kanade.tachiyomi.extension.model.AnimeExtension import eu.kanade.tachiyomi.extension.model.AnimeExtension
import eu.kanade.tachiyomi.extension.model.InstallStep import eu.kanade.tachiyomi.extension.model.InstallStep
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
/** /**
* Item that contains source information. * Item that contains source information.

View file

@ -23,16 +23,16 @@ import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import dev.chrisbanes.insetter.applyInsetter import dev.chrisbanes.insetter.applyInsetter
import eu.kanade.tachiyomi.R 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.EmptyPreferenceDataStore
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.minusAssign import eu.kanade.tachiyomi.data.preference.minusAssign
import eu.kanade.tachiyomi.data.preference.plusAssign import eu.kanade.tachiyomi.data.preference.plusAssign
import eu.kanade.tachiyomi.databinding.AnimeExtensionDetailControllerBinding import eu.kanade.tachiyomi.databinding.AnimeExtensionDetailControllerBinding
import eu.kanade.tachiyomi.extension.model.AnimeExtension 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.NucleusController
import eu.kanade.tachiyomi.ui.base.controller.ToolbarLiftOnScrollController import eu.kanade.tachiyomi.ui.base.controller.ToolbarLiftOnScrollController
import eu.kanade.tachiyomi.ui.base.controller.openInBrowser import eu.kanade.tachiyomi.ui.base.controller.openInBrowser

View file

@ -21,12 +21,12 @@ import androidx.preference.PreferenceManager
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import eu.kanade.tachiyomi.R 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.EmptyPreferenceDataStore
import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore
import eu.kanade.tachiyomi.databinding.AnimeSourcePreferencesControllerBinding 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 eu.kanade.tachiyomi.ui.base.controller.NucleusController
import timber.log.Timber import timber.log.Timber

View file

@ -1,6 +1,6 @@
package eu.kanade.tachiyomi.ui.browse.animeextension.details 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 eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get

View file

@ -17,13 +17,13 @@ import dev.chrisbanes.insetter.applyInsetter
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R 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.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.minusAssign import eu.kanade.tachiyomi.data.preference.minusAssign
import eu.kanade.tachiyomi.data.preference.plusAssign import eu.kanade.tachiyomi.data.preference.plusAssign
import eu.kanade.tachiyomi.databinding.AnimeSourceMainControllerBinding 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.DialogController
import eu.kanade.tachiyomi.ui.base.controller.SearchableNucleusController import eu.kanade.tachiyomi.ui.base.controller.SearchableNucleusController
import eu.kanade.tachiyomi.ui.base.controller.requestPermissionsSafe import eu.kanade.tachiyomi.ui.base.controller.requestPermissionsSafe

View file

@ -5,12 +5,12 @@ import androidx.preference.CheckBoxPreference
import androidx.preference.PreferenceGroup import androidx.preference.PreferenceGroup
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.R 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.minusAssign
import eu.kanade.tachiyomi.data.preference.plusAssign 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.ui.setting.SettingsController
import eu.kanade.tachiyomi.util.preference.onChange import eu.kanade.tachiyomi.util.preference.onChange
import eu.kanade.tachiyomi.util.preference.switchPreferenceCategory import eu.kanade.tachiyomi.util.preference.switchPreferenceCategory
@ -22,7 +22,7 @@ import java.util.TreeMap
class AnimeSourceFilterController : SettingsController() { 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 { override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
titleRes = R.string.label_sources titleRes = R.string.label_sources
@ -78,7 +78,7 @@ class AnimeSourceFilterController : SettingsController() {
* *
* @param group the language category. * @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() val disabledSourceIds = preferences.disabledAnimeSources().get()
sources sources

View file

@ -4,10 +4,9 @@ import android.view.View
import androidx.core.view.isVisible import androidx.core.view.isVisible
import eu.davidea.viewholders.FlexibleViewHolder import eu.davidea.viewholders.FlexibleViewHolder
import eu.kanade.tachiyomi.R 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.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.system.LocaleHelper
import eu.kanade.tachiyomi.util.view.setVectorCompat import eu.kanade.tachiyomi.util.view.setVectorCompat
@ -38,7 +37,7 @@ class AnimeSourceHolder(private val view: View, val adapter: AnimeSourceAdapter)
val icon = source.icon() val icon = source.icon()
when { when {
icon != null -> binding.image.setImageDrawable(icon) 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)
} }
} }

View file

@ -6,7 +6,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractSectionableItem import eu.davidea.flexibleadapter.items.AbstractSectionableItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.AnimeCatalogueSource import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
/** /**
* Item that contains source information. * Item that contains source information.

View file

@ -1,10 +1,10 @@
package eu.kanade.tachiyomi.ui.browse.animesource package eu.kanade.tachiyomi.ui.browse.animesource
import android.os.Bundle 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.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 eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged

View file

@ -1,8 +1,8 @@
package eu.kanade.tachiyomi.ui.browse.animesource.browse package eu.kanade.tachiyomi.ui.browse.animesource.browse
import com.jakewharton.rxrelay.PublishRelay import com.jakewharton.rxrelay.PublishRelay
import eu.kanade.tachiyomi.source.model.AnimesPage import eu.kanade.tachiyomi.animesource.model.AnimesPage
import eu.kanade.tachiyomi.source.model.SAnime import eu.kanade.tachiyomi.animesource.model.SAnime
import rx.Observable import rx.Observable
/** /**

View file

@ -1,8 +1,8 @@
package eu.kanade.tachiyomi.ui.browse.animesource.browse package eu.kanade.tachiyomi.ui.browse.animesource.browse
import eu.kanade.tachiyomi.source.AnimeCatalogueSource import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
import eu.kanade.tachiyomi.source.model.AnimesPage import eu.kanade.tachiyomi.animesource.model.AnimesPage
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.animesource.model.FilterList
import rx.Observable import rx.Observable
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers import rx.schedulers.Schedulers

View file

@ -22,16 +22,16 @@ import dev.chrisbanes.insetter.applyInsetter
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R 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.Anime
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.asImmediateFlow import eu.kanade.tachiyomi.data.preference.asImmediateFlow
import eu.kanade.tachiyomi.databinding.AnimeSourceControllerBinding 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.anime.AnimeController
import eu.kanade.tachiyomi.ui.animelib.ChangeAnimeCategoriesDialog import eu.kanade.tachiyomi.ui.animelib.ChangeAnimeCategoriesDialog
import eu.kanade.tachiyomi.ui.base.controller.FabController import eu.kanade.tachiyomi.ui.base.controller.FabController

View file

@ -2,6 +2,12 @@ package eu.kanade.tachiyomi.ui.browse.animesource.browse
import android.os.Bundle import android.os.Bundle
import eu.davidea.flexibleadapter.items.IFlexible 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.cache.AnimeCoverCache
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Anime 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.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.UnattendedTrackService 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.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.browse.animesource.filter.CheckboxItem import eu.kanade.tachiyomi.ui.browse.animesource.filter.CheckboxItem
import eu.kanade.tachiyomi.ui.browse.animesource.filter.CheckboxSectionItem import eu.kanade.tachiyomi.ui.browse.animesource.filter.CheckboxSectionItem

View file

@ -8,7 +8,7 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.davidea.viewholders.FlexibleViewHolder import eu.davidea.viewholders.FlexibleViewHolder
import eu.kanade.tachiyomi.R 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>() { open class CheckboxItem(val filter: Filter.CheckBox) : AbstractFlexibleItem<CheckboxItem.Holder>() {

View file

@ -10,7 +10,7 @@ import eu.davidea.flexibleadapter.items.IFlexible
import eu.davidea.flexibleadapter.items.ISectionable import eu.davidea.flexibleadapter.items.ISectionable
import eu.davidea.viewholders.ExpandableViewHolder import eu.davidea.viewholders.ExpandableViewHolder
import eu.kanade.tachiyomi.R 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 import eu.kanade.tachiyomi.util.view.setVectorCompat
class GroupItem(val filter: Filter.Group<*>) : AbstractExpandableHeaderItem<GroupItem.Holder, ISectionable<*, *>>() { class GroupItem(val filter: Filter.Group<*>) : AbstractExpandableHeaderItem<GroupItem.Holder, ISectionable<*, *>>() {

View file

@ -9,7 +9,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractHeaderItem import eu.davidea.flexibleadapter.items.AbstractHeaderItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.davidea.viewholders.FlexibleViewHolder 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>() { class HeaderItem(val filter: Filter.Header) : AbstractHeaderItem<HeaderItem.Holder>() {

View file

@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.ui.browse.animesource.filter package eu.kanade.tachiyomi.ui.browse.animesource.filter
import eu.davidea.flexibleadapter.items.ISectionable 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> { class TriStateSectionItem(filter: Filter.TriState) : TriStateItem(filter), ISectionable<TriStateItem.Holder, GroupItem> {

View file

@ -10,7 +10,7 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.davidea.viewholders.FlexibleViewHolder import eu.davidea.viewholders.FlexibleViewHolder
import eu.kanade.tachiyomi.R 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 import eu.kanade.tachiyomi.widget.listener.IgnoreFirstSpinnerListener
open class SelectItem(val filter: Filter.Select<*>) : AbstractFlexibleItem<SelectItem.Holder>() { open class SelectItem(val filter: Filter.Select<*>) : AbstractFlexibleItem<SelectItem.Holder>() {

View file

@ -8,7 +8,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractHeaderItem import eu.davidea.flexibleadapter.items.AbstractHeaderItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.davidea.viewholders.FlexibleViewHolder 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>() { class SeparatorItem(val filter: Filter.Separator) : AbstractHeaderItem<SeparatorItem.Holder>() {

View file

@ -7,7 +7,7 @@ import eu.davidea.flexibleadapter.items.AbstractExpandableHeaderItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.davidea.flexibleadapter.items.ISectionable import eu.davidea.flexibleadapter.items.ISectionable
import eu.kanade.tachiyomi.R 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 import eu.kanade.tachiyomi.util.view.setVectorCompat
class SortGroup(val filter: Filter.Sort) : AbstractExpandableHeaderItem<SortGroup.Holder, ISectionable<*, *>>() { class SortGroup(val filter: Filter.Sort) : AbstractExpandableHeaderItem<SortGroup.Holder, ISectionable<*, *>>() {

View file

@ -9,7 +9,7 @@ import eu.davidea.flexibleadapter.items.AbstractSectionableItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.davidea.viewholders.FlexibleViewHolder import eu.davidea.viewholders.FlexibleViewHolder
import eu.kanade.tachiyomi.R 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 import eu.kanade.tachiyomi.util.system.getResourceColor
class SortItem(val name: String, val group: SortGroup) : AbstractSectionableItem<SortItem.Holder, SortGroup>(group) { class SortItem(val name: String, val group: SortGroup) : AbstractSectionableItem<SortItem.Holder, SortGroup>(group) {

View file

@ -10,7 +10,7 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.davidea.viewholders.FlexibleViewHolder import eu.davidea.viewholders.FlexibleViewHolder
import eu.kanade.tachiyomi.R 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>() { open class TextItem(val filter: Filter.Text) : AbstractFlexibleItem<TextItem.Holder>() {

View file

@ -9,7 +9,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.davidea.viewholders.FlexibleViewHolder 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.dpToPx
import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.R as TR import eu.kanade.tachiyomi.R as TR

View file

@ -5,7 +5,7 @@ import android.os.Parcelable
import android.util.SparseArray import android.util.SparseArray
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.tachiyomi.source.AnimeCatalogueSource import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
/** /**
* Adapter that holds the search cards. * Adapter that holds the search cards.

View file

@ -10,10 +10,10 @@ import androidx.appcompat.widget.SearchView
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
import eu.kanade.tachiyomi.data.database.models.Anime import eu.kanade.tachiyomi.data.database.models.Anime
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.GlobalAnimeSearchControllerBinding import eu.kanade.tachiyomi.databinding.GlobalAnimeSearchControllerBinding
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
import eu.kanade.tachiyomi.ui.anime.AnimeController import eu.kanade.tachiyomi.ui.anime.AnimeController
import eu.kanade.tachiyomi.ui.base.controller.SearchableNucleusController import eu.kanade.tachiyomi.ui.base.controller.SearchableNucleusController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction

View file

@ -4,9 +4,9 @@ import android.view.View
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import eu.davidea.viewholders.FlexibleViewHolder import eu.davidea.viewholders.FlexibleViewHolder
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
import eu.kanade.tachiyomi.data.database.models.Anime import eu.kanade.tachiyomi.data.database.models.Anime
import eu.kanade.tachiyomi.databinding.GlobalSearchControllerCardBinding import eu.kanade.tachiyomi.databinding.GlobalSearchControllerCardBinding
import eu.kanade.tachiyomi.source.LocalAnimeSource
import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.system.LocaleHelper
/** /**

View file

@ -6,7 +6,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.AnimeCatalogueSource import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
/** /**
* Item that contains search result information. * Item that contains search result information.

View file

@ -1,18 +1,18 @@
package eu.kanade.tachiyomi.ui.browse.animesource.globalsearch package eu.kanade.tachiyomi.ui.browse.animesource.globalsearch
import android.os.Bundle 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.AnimeDatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Anime import eu.kanade.tachiyomi.data.database.models.Anime
import eu.kanade.tachiyomi.data.database.models.toAnimeInfo import eu.kanade.tachiyomi.data.database.models.toAnimeInfo
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.extension.AnimeExtensionManager 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.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.browse.animesource.browse.BrowseAnimeSourcePresenter import eu.kanade.tachiyomi.ui.browse.animesource.browse.BrowseAnimeSourcePresenter
import eu.kanade.tachiyomi.util.lang.runAsObservable import eu.kanade.tachiyomi.util.lang.runAsObservable

View file

@ -4,7 +4,7 @@ import android.os.Bundle
import android.view.Menu import android.view.Menu
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import eu.kanade.tachiyomi.R 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.BrowseAnimeSourceController
import eu.kanade.tachiyomi.ui.browse.animesource.browse.BrowseAnimeSourcePresenter import eu.kanade.tachiyomi.ui.browse.animesource.browse.BrowseAnimeSourcePresenter

View file

@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.ui.browse.animesource.latest package eu.kanade.tachiyomi.ui.browse.animesource.latest
import eu.kanade.tachiyomi.source.AnimeCatalogueSource import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
import eu.kanade.tachiyomi.source.model.AnimesPage import eu.kanade.tachiyomi.animesource.model.AnimesPage
import eu.kanade.tachiyomi.ui.browse.animesource.browse.AnimePager import eu.kanade.tachiyomi.ui.browse.animesource.browse.AnimePager
import rx.Observable import rx.Observable
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers

View file

@ -1,6 +1,6 @@
package eu.kanade.tachiyomi.ui.browse.animesource.latest 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.AnimePager
import eu.kanade.tachiyomi.ui.browse.animesource.browse.BrowseAnimeSourcePresenter import eu.kanade.tachiyomi.ui.browse.animesource.browse.BrowseAnimeSourcePresenter

View file

@ -7,9 +7,9 @@ import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.list.listItemsMultiChoice import com.afollestad.materialdialogs.list.listItemsMultiChoice
import com.bluelinelabs.conductor.Controller import com.bluelinelabs.conductor.Controller
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
import eu.kanade.tachiyomi.data.database.models.Anime import eu.kanade.tachiyomi.data.database.models.Anime
import eu.kanade.tachiyomi.data.preference.PreferencesHelper 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.DialogController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.browse.animesource.globalsearch.GlobalAnimeSearchController import eu.kanade.tachiyomi.ui.browse.animesource.globalsearch.GlobalAnimeSearchController

View file

@ -2,14 +2,14 @@ package eu.kanade.tachiyomi.ui.browse.migration.search
import android.os.Bundle import android.os.Bundle
import com.jakewharton.rxrelay.BehaviorRelay 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.Anime
import eu.kanade.tachiyomi.data.database.models.AnimeCategory import eu.kanade.tachiyomi.data.database.models.AnimeCategory
import eu.kanade.tachiyomi.data.database.models.toAnimeInfo 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.GlobalAnimeSearchCardItem
import eu.kanade.tachiyomi.ui.browse.animesource.globalsearch.GlobalAnimeSearchItem import eu.kanade.tachiyomi.ui.browse.animesource.globalsearch.GlobalAnimeSearchItem
import eu.kanade.tachiyomi.ui.browse.animesource.globalsearch.GlobalAnimeSearchPresenter import eu.kanade.tachiyomi.ui.browse.animesource.globalsearch.GlobalAnimeSearchPresenter

View file

@ -2,8 +2,8 @@ package eu.kanade.tachiyomi.ui.browse.migration.search
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
import eu.kanade.tachiyomi.data.database.models.Anime 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.AnimeSourceItem
import eu.kanade.tachiyomi.ui.browse.animesource.browse.BrowseAnimeSourceController import eu.kanade.tachiyomi.ui.browse.animesource.browse.BrowseAnimeSourceController

View file

@ -6,7 +6,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.AnimeSource import eu.kanade.tachiyomi.animesource.AnimeSource
/** /**
* Item that contains source information. * Item that contains source information.

View file

@ -1,11 +1,14 @@
package eu.kanade.tachiyomi.ui.browse.migration.sources package eu.kanade.tachiyomi.ui.browse.migration.sources
import android.os.Bundle 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.AnimeDatabaseHelper
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Anime import eu.kanade.tachiyomi.data.database.models.Anime
import eu.kanade.tachiyomi.data.database.models.Manga 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 eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
@ -49,7 +52,7 @@ class MigrationSourcesPresenter(
private fun findSourcesWithAnime(library: List<Anime>): List<AnimeSourceItem> { private fun findSourcesWithAnime(library: List<Anime>): List<AnimeSourceItem> {
return library return library
.groupBy { it.source } .groupBy { it.source }
.filterKeys { it != LocalSource.ID } .filterKeys { it != LocalAnimeSource.ID }
.map { .map {
val source = animesourceManager.getOrStub(it.key) val source = animesourceManager.getOrStub(it.key)
AnimeSourceItem(source, it.value.size) AnimeSourceItem(source, it.value.size)

View file

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.browse.migration.sources
import android.view.View import android.view.View
import androidx.core.view.isVisible import androidx.core.view.isVisible
import eu.davidea.viewholders.FlexibleViewHolder import eu.davidea.viewholders.FlexibleViewHolder
import eu.kanade.tachiyomi.animesource.icon
import eu.kanade.tachiyomi.databinding.SourceMainControllerCardItemBinding import eu.kanade.tachiyomi.databinding.SourceMainControllerCardItemBinding
import eu.kanade.tachiyomi.source.icon import eu.kanade.tachiyomi.source.icon
import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.system.LocaleHelper

View file

@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.recent.animehistory
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.source.AnimeSourceManager import eu.kanade.tachiyomi.animesource.AnimeSourceManager
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.text.DecimalFormat import java.text.DecimalFormat
import java.text.DecimalFormatSymbols import java.text.DecimalFormatSymbols

View file

@ -13,13 +13,12 @@ import com.afollestad.materialdialogs.MaterialDialog
import dev.chrisbanes.insetter.applyInsetter import dev.chrisbanes.insetter.applyInsetter
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
import eu.kanade.tachiyomi.data.backup.BackupRestoreService import eu.kanade.tachiyomi.data.backup.BackupRestoreService
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Anime import eu.kanade.tachiyomi.data.database.models.Anime
import eu.kanade.tachiyomi.data.database.models.AnimeHistory import eu.kanade.tachiyomi.data.database.models.AnimeHistory
import eu.kanade.tachiyomi.databinding.AnimeHistoryControllerBinding 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.AnimeController
import eu.kanade.tachiyomi.ui.anime.episode.EpisodeItem import eu.kanade.tachiyomi.ui.anime.episode.EpisodeItem
import eu.kanade.tachiyomi.ui.base.controller.DialogController 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.RootController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.browse.source.browse.ProgressItem 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.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 eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.runBlocking
import reactivecircus.flowbinding.appcompat.queryTextChanges import reactivecircus.flowbinding.appcompat.queryTextChanges
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.util.Collections import java.util.Collections
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
/** /**
* Fragment that shows recently read anime. * Fragment that shows recently read anime.
@ -166,19 +161,7 @@ class AnimeHistoryController :
val nextEpisode = presenter.getNextEpisode(chapter, anime) val nextEpisode = presenter.getNextEpisode(chapter, anime)
if (nextEpisode != null) { if (nextEpisode != null) {
val source = Injekt.get<AnimeSourceManager>().getOrStub(anime.source) val source = Injekt.get<AnimeSourceManager>().getOrStub(anime.source)
val link = runBlocking { val link = EpisodeLoader.getUri(nextEpisode, anime, source)
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 episodeList: List<EpisodeItem> = Collections.emptyList() val episodeList: List<EpisodeItem> = Collections.emptyList()
val newIntent = WatcherActivity.newIntent(activity, anime, nextEpisode, episodeList, link) val newIntent = WatcherActivity.newIntent(activity, anime, nextEpisode, episodeList, link)
startActivity(newIntent) startActivity(newIntent)

View file

@ -13,13 +13,12 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.SelectableAdapter import eu.davidea.flexibleadapter.SelectableAdapter
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
import eu.kanade.tachiyomi.data.animelib.AnimelibUpdateService import eu.kanade.tachiyomi.data.animelib.AnimelibUpdateService
import eu.kanade.tachiyomi.data.download.AnimeDownloadService import eu.kanade.tachiyomi.data.download.AnimeDownloadService
import eu.kanade.tachiyomi.data.download.model.AnimeDownload import eu.kanade.tachiyomi.data.download.model.AnimeDownload
import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.databinding.AnimeUpdatesControllerBinding 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.AnimeController
import eu.kanade.tachiyomi.ui.anime.episode.EpisodeItem import eu.kanade.tachiyomi.ui.anime.episode.EpisodeItem
import eu.kanade.tachiyomi.ui.anime.episode.base.BaseEpisodesAdapter 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.RootController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.main.MainActivity 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.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.notificationManager
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.runBlocking
import reactivecircus.flowbinding.recyclerview.scrollStateChanges import reactivecircus.flowbinding.recyclerview.scrollStateChanges
import reactivecircus.flowbinding.swiperefreshlayout.refreshes import reactivecircus.flowbinding.swiperefreshlayout.refreshes
import timber.log.Timber import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.util.* import java.util.*
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
/** /**
* Fragment that shows recent episodes. * Fragment that shows recent episodes.
@ -216,19 +211,7 @@ class AnimeUpdatesController :
private fun openEpisode(item: AnimeUpdatesItem) { private fun openEpisode(item: AnimeUpdatesItem) {
val activity = activity ?: return val activity = activity ?: return
val source = Injekt.get<AnimeSourceManager>().getOrStub(item.anime.source) val source = Injekt.get<AnimeSourceManager>().getOrStub(item.anime.source)
val link = runBlocking { val link = EpisodeLoader.getUri(item.episode, item.anime, source)
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 episodeList: List<EpisodeItem> = Collections.emptyList() val episodeList: List<EpisodeItem> = Collections.emptyList()
val intent = WatcherActivity.newIntent(activity, item.anime, item.episode, episodeList, link) val intent = WatcherActivity.newIntent(activity, item.anime, item.episode, episodeList, link)
startActivity(intent) startActivity(intent)

View file

@ -6,8 +6,8 @@ import coil.clear
import coil.loadAny import coil.loadAny
import coil.transform.RoundedCornersTransformation import coil.transform.RoundedCornersTransformation
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.animesource.LocalAnimeSource
import eu.kanade.tachiyomi.databinding.AnimeUpdatesItemBinding import eu.kanade.tachiyomi.databinding.AnimeUpdatesItemBinding
import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.ui.anime.episode.base.BaseEpisodeHolder 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 // 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) binding.download.setState(item.status, item.progress)
// Set cover // Set cover

View file

@ -1,12 +1,12 @@
package eu.kanade.tachiyomi.ui.recent.animeupdates package eu.kanade.tachiyomi.ui.recent.animeupdates
import android.os.Bundle import android.os.Bundle
import eu.kanade.tachiyomi.animesource.AnimeSourceManager
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
import eu.kanade.tachiyomi.data.database.models.AnimeEpisode import eu.kanade.tachiyomi.data.database.models.AnimeEpisode
import eu.kanade.tachiyomi.data.download.AnimeDownloadManager import eu.kanade.tachiyomi.data.download.AnimeDownloadManager
import eu.kanade.tachiyomi.data.download.model.AnimeDownload import eu.kanade.tachiyomi.data.download.model.AnimeDownload
import eu.kanade.tachiyomi.data.preference.PreferencesHelper 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.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.recent.DateSectionItem import eu.kanade.tachiyomi.ui.recent.DateSectionItem
import eu.kanade.tachiyomi.util.lang.toDateKey import eu.kanade.tachiyomi.util.lang.toDateKey

View file

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

View file

@ -21,6 +21,8 @@ import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
import com.google.android.exoplayer2.util.MimeTypes import com.google.android.exoplayer2.util.MimeTypes
import com.google.android.exoplayer2.util.Util import com.google.android.exoplayer2.util.Util
import eu.kanade.tachiyomi.R 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.AnimeDatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Anime import eu.kanade.tachiyomi.data.database.models.Anime
import eu.kanade.tachiyomi.data.database.models.AnimeHistory 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.download.model.AnimeDownload
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager 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.ui.anime.episode.EpisodeItem
import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.view.hideBar import eu.kanade.tachiyomi.util.view.hideBar

View file

@ -1,11 +1,11 @@
package eu.kanade.tachiyomi.util 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.cache.AnimeCoverCache
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Anime import eu.kanade.tachiyomi.data.database.models.Anime
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.LocalAnimeSource
import eu.kanade.tachiyomi.source.model.SAnime
import java.util.Date import java.util.Date
fun Anime.isLocal() = source == LocalAnimeSource.ID fun Anime.isLocal() = source == LocalAnimeSource.ID

View file

@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.util.episode package eu.kanade.tachiyomi.util.episode
import eu.kanade.tachiyomi.source.model.SAnime import eu.kanade.tachiyomi.animesource.model.SAnime
import eu.kanade.tachiyomi.source.model.SEpisode import eu.kanade.tachiyomi.animesource.model.SEpisode
/** /**
* -R> = regex conversion. * -R> = regex conversion.

View file

@ -1,12 +1,12 @@
package eu.kanade.tachiyomi.util.episode 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.AnimeDatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Anime import eu.kanade.tachiyomi.data.database.models.Anime
import eu.kanade.tachiyomi.data.database.models.Episode import eu.kanade.tachiyomi.data.database.models.Episode
import eu.kanade.tachiyomi.data.download.AnimeDownloadManager 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.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.util.Date import java.util.Date

View file

@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.util.storage package eu.kanade.tachiyomi.util.storage
import eu.kanade.tachiyomi.source.model.SAnime import eu.kanade.tachiyomi.animesource.model.SAnime
import eu.kanade.tachiyomi.source.model.SEpisode import eu.kanade.tachiyomi.animesource.model.SEpisode
import org.jsoup.Jsoup import org.jsoup.Jsoup
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import java.io.Closeable import java.io.Closeable

View file

@ -1,7 +1,7 @@
package tachiyomi.source package tachiyomi.animesource
import tachiyomi.source.model.AnimeInfo import tachiyomi.animesource.model.AnimeInfo
import tachiyomi.source.model.EpisodeInfo import tachiyomi.animesource.model.EpisodeInfo
/** /**
* A basic interface for creating a source. It could be an online source, a local source, etc... * A basic interface for creating a source. It could be an online source, a local source, etc...

View file

@ -1,4 +1,4 @@
package tachiyomi.source.model package tachiyomi.animesource.model
/** /**
* Model for a anime given by a source * Model for a anime given by a source

View file

@ -1,4 +1,4 @@
package tachiyomi.source.model package tachiyomi.animesource.model
data class EpisodeInfo( data class EpisodeInfo(
var key: String, var key: String,

Some files were not shown because too many files have changed in this diff Show more