mirror of
https://github.com/mihonapp/mihon.git
synced 2024-11-21 20:47:03 -05:00
Extract source api from app module (#8014)
* Extract source api from app module * Extract source online api from app module
This commit is contained in:
parent
30ac94181b
commit
86fe850794
53 changed files with 219 additions and 106 deletions
|
@ -150,6 +150,8 @@ android {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":i18n"))
|
implementation(project(":i18n"))
|
||||||
|
implementation(project(":core"))
|
||||||
|
implementation(project(":source-api"))
|
||||||
|
|
||||||
// Compose
|
// Compose
|
||||||
implementation(compose.activity)
|
implementation(compose.activity)
|
||||||
|
|
|
@ -33,6 +33,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
|
import eu.kanade.tachiyomi.source.model.copyFrom
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
import eu.kanade.tachiyomi.util.system.toLong
|
import eu.kanade.tachiyomi.util.system.toLong
|
||||||
import kotlinx.serialization.protobuf.ProtoBuf
|
import kotlinx.serialization.protobuf.ProtoBuf
|
||||||
|
|
|
@ -19,6 +19,7 @@ import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
|
||||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
import eu.kanade.tachiyomi.util.system.isDevFlavor
|
import eu.kanade.tachiyomi.util.system.isDevFlavor
|
||||||
|
import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package eu.kanade.tachiyomi.source
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import eu.kanade.domain.source.model.SourceData
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
|
fun Source.icon(): Drawable? = Injekt.get<ExtensionManager>().getAppIconForSource(this)
|
||||||
|
|
||||||
|
fun Source.getPreferenceKey(): String = "source_$id"
|
||||||
|
|
||||||
|
fun Source.toSourceData(): SourceData = SourceData(id = id, lang = lang, name = name)
|
||||||
|
|
||||||
|
fun Source.getNameForMangaInfo(): String {
|
||||||
|
val preferences = Injekt.get<PreferencesHelper>()
|
||||||
|
val enabledLanguages = preferences.enabledLanguages().get()
|
||||||
|
.filterNot { it in listOf("all", "other") }
|
||||||
|
val hasOneActiveLanguages = enabledLanguages.size == 1
|
||||||
|
val isInEnabledLanguages = lang in enabledLanguages
|
||||||
|
return when {
|
||||||
|
// For edge cases where user disables a source they got manga of in their library.
|
||||||
|
hasOneActiveLanguages && !isInEnabledLanguages -> toString()
|
||||||
|
// Hide the language tag when only one language is used.
|
||||||
|
hasOneActiveLanguages && isInEnabledLanguages -> name
|
||||||
|
else -> toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Source.isLocalOrStub(): Boolean = id == LocalSource.ID || this is SourceManager.StubSource
|
|
@ -0,0 +1,11 @@
|
||||||
|
package eu.kanade.tachiyomi.source.model
|
||||||
|
|
||||||
|
import data.Chapters
|
||||||
|
|
||||||
|
fun SChapter.copyFrom(other: Chapters) {
|
||||||
|
name = other.name
|
||||||
|
url = other.url
|
||||||
|
date_upload = other.date_upload
|
||||||
|
chapter_number = other.chapter_number
|
||||||
|
scanlator = other.scanlator
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package eu.kanade.tachiyomi.source.model
|
||||||
|
|
||||||
|
import data.Mangas
|
||||||
|
|
||||||
|
fun SManga.copyFrom(other: Mangas) {
|
||||||
|
if (other.author != null) {
|
||||||
|
author = other.author
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other.artist != null) {
|
||||||
|
artist = other.artist
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other.description != null) {
|
||||||
|
description = other.description
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other.genre != null) {
|
||||||
|
genre = other.genre.joinToString(separator = ", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other.thumbnail_url != null) {
|
||||||
|
thumbnail_url = other.thumbnail_url
|
||||||
|
}
|
||||||
|
|
||||||
|
status = other.status.toInt()
|
||||||
|
|
||||||
|
if (!initialized) {
|
||||||
|
initialized = other.initialized
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ import eu.kanade.tachiyomi.util.preference.preferenceCategory
|
||||||
import eu.kanade.tachiyomi.util.preference.switchPreference
|
import eu.kanade.tachiyomi.util.preference.switchPreference
|
||||||
import eu.kanade.tachiyomi.util.preference.titleRes
|
import eu.kanade.tachiyomi.util.preference.titleRes
|
||||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
||||||
|
import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable
|
||||||
import eu.kanade.tachiyomi.util.system.isTablet
|
import eu.kanade.tachiyomi.util.system.isTablet
|
||||||
import eu.kanade.tachiyomi.widget.preference.ThemesPreference
|
import eu.kanade.tachiyomi.widget.preference.ThemesPreference
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
|
@ -24,10 +24,8 @@ import android.util.TypedValue
|
||||||
import android.view.Display
|
import android.view.Display
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.annotation.AttrRes
|
import androidx.annotation.AttrRes
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import androidx.appcompat.view.ContextThemeWrapper
|
import androidx.appcompat.view.ContextThemeWrapper
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
@ -52,29 +50,6 @@ import kotlin.math.roundToInt
|
||||||
|
|
||||||
private const val TABLET_UI_MIN_SCREEN_WIDTH_DP = 720
|
private const val TABLET_UI_MIN_SCREEN_WIDTH_DP = 720
|
||||||
|
|
||||||
/**
|
|
||||||
* Display a toast in this context.
|
|
||||||
*
|
|
||||||
* @param resource the text resource.
|
|
||||||
* @param duration the duration of the toast. Defaults to short.
|
|
||||||
*/
|
|
||||||
fun Context.toast(@StringRes resource: Int, duration: Int = Toast.LENGTH_SHORT, block: (Toast) -> Unit = {}): Toast {
|
|
||||||
return toast(getString(resource), duration, block)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display a toast in this context.
|
|
||||||
*
|
|
||||||
* @param text the text to display.
|
|
||||||
* @param duration the duration of the toast. Defaults to short.
|
|
||||||
*/
|
|
||||||
fun Context.toast(text: String?, duration: Int = Toast.LENGTH_SHORT, block: (Toast) -> Unit = {}): Toast {
|
|
||||||
return Toast.makeText(applicationContext, text.orEmpty(), duration).also {
|
|
||||||
block(it)
|
|
||||||
it.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies a string to clipboard
|
* Copies a string to clipboard
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package eu.kanade.tachiyomi.util.system
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import com.google.android.material.color.DynamicColors
|
||||||
|
|
||||||
|
val DeviceUtil.isDynamicColorAvailable by lazy {
|
||||||
|
DynamicColors.isDynamicColorAvailable() || (DeviceUtil.isSamsung && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
|
||||||
|
}
|
1
core/.gitignore
vendored
Normal file
1
core/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/build
|
46
core/build.gradle.kts
Normal file
46
core/build.gradle.kts
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
plugins {
|
||||||
|
id("com.android.library")
|
||||||
|
kotlin("android")
|
||||||
|
kotlin("plugin.serialization")
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "eu.kanade.tachiyomi.core"
|
||||||
|
compileSdk = AndroidConfig.compileSdk
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdk = AndroidConfig.minSdk
|
||||||
|
targetSdk = AndroidConfig.targetSdk
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(project(":i18n"))
|
||||||
|
|
||||||
|
api(libs.logcat)
|
||||||
|
|
||||||
|
api(libs.rxjava)
|
||||||
|
|
||||||
|
api(libs.okhttp.core)
|
||||||
|
api(libs.okhttp.logging)
|
||||||
|
api(libs.okhttp.dnsoverhttps)
|
||||||
|
api(libs.okio)
|
||||||
|
|
||||||
|
api(kotlinx.coroutines.core)
|
||||||
|
api(kotlinx.serialization.json)
|
||||||
|
|
||||||
|
api(libs.injekt.core)
|
||||||
|
|
||||||
|
api(libs.preferencektx)
|
||||||
|
|
||||||
|
implementation(androidx.corektx)
|
||||||
|
}
|
2
core/src/main/AndroidManifest.xml
Normal file
2
core/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest />
|
|
@ -1,20 +1,20 @@
|
||||||
package eu.kanade.tachiyomi.network
|
package eu.kanade.tachiyomi.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import androidx.preference.PreferenceManager
|
||||||
import eu.kanade.tachiyomi.network.interceptor.CloudflareInterceptor
|
import eu.kanade.tachiyomi.network.interceptor.CloudflareInterceptor
|
||||||
import eu.kanade.tachiyomi.network.interceptor.Http103Interceptor
|
import eu.kanade.tachiyomi.network.interceptor.Http103Interceptor
|
||||||
import eu.kanade.tachiyomi.network.interceptor.UserAgentInterceptor
|
import eu.kanade.tachiyomi.network.interceptor.UserAgentInterceptor
|
||||||
import okhttp3.Cache
|
import okhttp3.Cache
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.logging.HttpLoggingInterceptor
|
import okhttp3.logging.HttpLoggingInterceptor
|
||||||
import uy.kohesive.injekt.injectLazy
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class NetworkHelper(context: Context) {
|
class NetworkHelper(context: Context) {
|
||||||
|
|
||||||
private val preferences: PreferencesHelper by injectLazy()
|
// TODO: Abstract preferences similar to 1.x
|
||||||
|
private val preferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
|
|
||||||
private val cacheDir = File(context.cacheDir, "network_cache")
|
private val cacheDir = File(context.cacheDir, "network_cache")
|
||||||
private val cacheSize = 5L * 1024 * 1024 // 5 MiB
|
private val cacheSize = 5L * 1024 * 1024 // 5 MiB
|
||||||
|
@ -36,14 +36,14 @@ class NetworkHelper(context: Context) {
|
||||||
.addInterceptor(userAgentInterceptor)
|
.addInterceptor(userAgentInterceptor)
|
||||||
.addNetworkInterceptor(http103Interceptor)
|
.addNetworkInterceptor(http103Interceptor)
|
||||||
|
|
||||||
if (preferences.verboseLogging()) {
|
if (preferences.getBoolean("verbose_logging", false)) {
|
||||||
val httpLoggingInterceptor = HttpLoggingInterceptor().apply {
|
val httpLoggingInterceptor = HttpLoggingInterceptor().apply {
|
||||||
level = HttpLoggingInterceptor.Level.HEADERS
|
level = HttpLoggingInterceptor.Level.HEADERS
|
||||||
}
|
}
|
||||||
builder.addNetworkInterceptor(httpLoggingInterceptor)
|
builder.addNetworkInterceptor(httpLoggingInterceptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
when (preferences.dohProvider()) {
|
when (preferences.getInt("doh_provider", -1)) {
|
||||||
PREF_DOH_CLOUDFLARE -> builder.dohCloudflare()
|
PREF_DOH_CLOUDFLARE -> builder.dohCloudflare()
|
||||||
PREF_DOH_GOOGLE -> builder.dohGoogle()
|
PREF_DOH_GOOGLE -> builder.dohGoogle()
|
||||||
PREF_DOH_ADGUARD -> builder.dohAdGuard()
|
PREF_DOH_ADGUARD -> builder.dohAdGuard()
|
||||||
|
@ -70,6 +70,6 @@ class NetworkHelper(context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
val defaultUserAgent by lazy {
|
val defaultUserAgent by lazy {
|
||||||
preferences.defaultUserAgent().get()
|
preferences.getString("default_user_agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0")!!
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,7 +10,7 @@ import java.util.concurrent.TimeUnit.MINUTES
|
||||||
private val DEFAULT_CACHE_CONTROL = CacheControl.Builder().maxAge(10, MINUTES).build()
|
private val DEFAULT_CACHE_CONTROL = CacheControl.Builder().maxAge(10, MINUTES).build()
|
||||||
private val DEFAULT_HEADERS = Headers.Builder().build()
|
private val DEFAULT_HEADERS = Headers.Builder().build()
|
||||||
private val DEFAULT_BODY: RequestBody = FormBody.Builder().build()
|
private val DEFAULT_BODY: RequestBody = FormBody.Builder().build()
|
||||||
internal val CACHE_CONTROL_NO_STORE = CacheControl.Builder().noStore().build()
|
val CACHE_CONTROL_NO_STORE = CacheControl.Builder().noStore().build()
|
||||||
|
|
||||||
fun GET(
|
fun GET(
|
||||||
url: String,
|
url: String,
|
|
@ -5,7 +5,7 @@ import android.content.Context
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.core.R
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.util.system.WebViewClientCompat
|
import eu.kanade.tachiyomi.util.system.WebViewClientCompat
|
||||||
import eu.kanade.tachiyomi.util.system.isOutdated
|
import eu.kanade.tachiyomi.util.system.isOutdated
|
|
@ -5,7 +5,7 @@ import android.os.Build
|
||||||
import android.webkit.WebSettings
|
import android.webkit.WebSettings
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.core.R
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
|
@ -5,6 +5,7 @@ import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.CoroutineStart
|
import kotlinx.coroutines.CoroutineStart
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.InternalCoroutinesApi
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import rx.Emitter
|
import rx.Emitter
|
||||||
|
@ -20,6 +21,7 @@ import kotlin.coroutines.resumeWithException
|
||||||
|
|
||||||
suspend fun <T> Observable<T>.awaitSingle(): T = single().awaitOne()
|
suspend fun <T> Observable<T>.awaitSingle(): T = single().awaitOne()
|
||||||
|
|
||||||
|
@OptIn(InternalCoroutinesApi::class)
|
||||||
private suspend fun <T> Observable<T>.awaitOne(): T = suspendCancellableCoroutine { cont ->
|
private suspend fun <T> Observable<T>.awaitOne(): T = suspendCancellableCoroutine { cont ->
|
||||||
cont.unsubscribeOnCancellation(
|
cont.unsubscribeOnCancellation(
|
||||||
subscribe(
|
subscribe(
|
|
@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.util.system
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import com.google.android.material.color.DynamicColors
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
|
||||||
object DeviceUtil {
|
object DeviceUtil {
|
||||||
|
@ -31,10 +30,6 @@ object DeviceUtil {
|
||||||
Build.MANUFACTURER.equals("samsung", ignoreCase = true)
|
Build.MANUFACTURER.equals("samsung", ignoreCase = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
val isDynamicColorAvailable by lazy {
|
|
||||||
DynamicColors.isDynamicColorAvailable() || (isSamsung && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
|
|
||||||
}
|
|
||||||
|
|
||||||
val invalidDefaultBrowsers = listOf("android", "com.huawei.android.internal.app")
|
val invalidDefaultBrowsers = listOf("android", "com.huawei.android.internal.app")
|
||||||
|
|
||||||
@SuppressLint("PrivateApi")
|
@SuppressLint("PrivateApi")
|
|
@ -0,0 +1,28 @@
|
||||||
|
package eu.kanade.tachiyomi.util.system
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a toast in this context.
|
||||||
|
*
|
||||||
|
* @param resource the text resource.
|
||||||
|
* @param duration the duration of the toast. Defaults to short.
|
||||||
|
*/
|
||||||
|
fun Context.toast(@StringRes resource: Int, duration: Int = Toast.LENGTH_SHORT, block: (Toast) -> Unit = {}): Toast {
|
||||||
|
return toast(getString(resource), duration, block)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a toast in this context.
|
||||||
|
*
|
||||||
|
* @param text the text to display.
|
||||||
|
* @param duration the duration of the toast. Defaults to short.
|
||||||
|
*/
|
||||||
|
fun Context.toast(text: String?, duration: Int = Toast.LENGTH_SHORT, block: (Toast) -> Unit = {}): Toast {
|
||||||
|
return Toast.makeText(applicationContext, text.orEmpty(), duration).also {
|
||||||
|
block(it)
|
||||||
|
it.show()
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,3 +37,5 @@ dependencyResolutionManagement {
|
||||||
rootProject.name = "Tachiyomi"
|
rootProject.name = "Tachiyomi"
|
||||||
include(":app")
|
include(":app")
|
||||||
include(":i18n")
|
include(":i18n")
|
||||||
|
include(":source-api")
|
||||||
|
include(":core")
|
||||||
|
|
1
source-api/.gitignore
vendored
Normal file
1
source-api/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/build
|
39
source-api/build.gradle.kts
Normal file
39
source-api/build.gradle.kts
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
plugins {
|
||||||
|
id("com.android.library")
|
||||||
|
kotlin("android")
|
||||||
|
kotlin("plugin.serialization")
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "eu.kanade.tachiyomi.source"
|
||||||
|
compileSdk = AndroidConfig.compileSdk
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdk = AndroidConfig.minSdk
|
||||||
|
targetSdk = AndroidConfig.targetSdk
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
implementation(project(":core"))
|
||||||
|
|
||||||
|
api(kotlinx.serialization.json)
|
||||||
|
|
||||||
|
api(libs.rxjava)
|
||||||
|
|
||||||
|
api(libs.preferencektx)
|
||||||
|
|
||||||
|
api(libs.jsoup)
|
||||||
|
|
||||||
|
implementation(androidx.corektx)
|
||||||
|
}
|
2
source-api/src/main/AndroidManifest.xml
Normal file
2
source-api/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest />
|
|
@ -1,16 +1,10 @@
|
||||||
package eu.kanade.tachiyomi.source
|
package eu.kanade.tachiyomi.source
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import eu.kanade.domain.source.model.SourceData
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
||||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.util.lang.awaitSingle
|
import eu.kanade.tachiyomi.util.lang.awaitSingle
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import uy.kohesive.injekt.Injekt
|
|
||||||
import uy.kohesive.injekt.api.get
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A basic interface for creating a source. It could be an online source, a local source, etc...
|
* A basic interface for creating a source. It could be an online source, a local source, etc...
|
||||||
|
@ -88,26 +82,3 @@ interface Source {
|
||||||
return fetchPageList(chapter).awaitSingle()
|
return fetchPageList(chapter).awaitSingle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Source.icon(): Drawable? = Injekt.get<ExtensionManager>().getAppIconForSource(this)
|
|
||||||
|
|
||||||
fun Source.getPreferenceKey(): String = "source_$id"
|
|
||||||
|
|
||||||
fun Source.toSourceData(): SourceData = SourceData(id = id, lang = lang, name = name)
|
|
||||||
|
|
||||||
fun Source.getNameForMangaInfo(): String {
|
|
||||||
val preferences = Injekt.get<PreferencesHelper>()
|
|
||||||
val enabledLanguages = preferences.enabledLanguages().get()
|
|
||||||
.filterNot { it in listOf("all", "other") }
|
|
||||||
val hasOneActiveLanguages = enabledLanguages.size == 1
|
|
||||||
val isInEnabledLanguages = lang in enabledLanguages
|
|
||||||
return when {
|
|
||||||
// For edge cases where user disables a source they got manga of in their library.
|
|
||||||
hasOneActiveLanguages && !isInEnabledLanguages -> toString()
|
|
||||||
// Hide the language tag when only one language is used.
|
|
||||||
hasOneActiveLanguages && isInEnabledLanguages -> name
|
|
||||||
else -> toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Source.isLocalOrStub(): Boolean = id == LocalSource.ID || this is SourceManager.StubSource
|
|
|
@ -1,6 +1,5 @@
|
||||||
package eu.kanade.tachiyomi.source.model
|
package eu.kanade.tachiyomi.source.model
|
||||||
|
|
||||||
import data.Chapters
|
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
interface SChapter : Serializable {
|
interface SChapter : Serializable {
|
||||||
|
@ -23,14 +22,6 @@ interface SChapter : Serializable {
|
||||||
scanlator = other.scanlator
|
scanlator = other.scanlator
|
||||||
}
|
}
|
||||||
|
|
||||||
fun copyFrom(other: Chapters) {
|
|
||||||
name = other.name
|
|
||||||
url = other.url
|
|
||||||
date_upload = other.date_upload
|
|
||||||
chapter_number = other.chapter_number
|
|
||||||
scanlator = other.scanlator
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun create(): SChapter {
|
fun create(): SChapter {
|
||||||
return SChapterImpl()
|
return SChapterImpl()
|
|
@ -1,6 +1,5 @@
|
||||||
package eu.kanade.tachiyomi.source.model
|
package eu.kanade.tachiyomi.source.model
|
||||||
|
|
||||||
import data.Mangas
|
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
interface SManga : Serializable {
|
interface SManga : Serializable {
|
||||||
|
@ -56,34 +55,6 @@ interface SManga : Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun copyFrom(other: Mangas) {
|
|
||||||
if (other.author != null) {
|
|
||||||
author = other.author
|
|
||||||
}
|
|
||||||
|
|
||||||
if (other.artist != null) {
|
|
||||||
artist = other.artist
|
|
||||||
}
|
|
||||||
|
|
||||||
if (other.description != null) {
|
|
||||||
description = other.description
|
|
||||||
}
|
|
||||||
|
|
||||||
if (other.genre != null) {
|
|
||||||
genre = other.genre.joinToString(separator = ", ")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (other.thumbnail_url != null) {
|
|
||||||
thumbnail_url = other.thumbnail_url
|
|
||||||
}
|
|
||||||
|
|
||||||
status = other.status.toInt()
|
|
||||||
|
|
||||||
if (!initialized) {
|
|
||||||
initialized = other.initialized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun copy() = create().also {
|
fun copy() = create().also {
|
||||||
it.url = url
|
it.url = url
|
||||||
it.title = title
|
it.title = title
|
|
@ -12,6 +12,7 @@ import org.jsoup.nodes.Element
|
||||||
/**
|
/**
|
||||||
* A simple implementation for sources from a website using Jsoup, an HTML parser.
|
* A simple implementation for sources from a website using Jsoup, an HTML parser.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("unused")
|
||||||
abstract class ParsedHttpSource : HttpSource() {
|
abstract class ParsedHttpSource : HttpSource() {
|
||||||
|
|
||||||
/**
|
/**
|
Loading…
Reference in a new issue