Skip to content

Commit

Permalink
Extract source api from app module (#8014)
Browse files Browse the repository at this point in the history
* Extract source api from app module

* Extract source online api from app module
  • Loading branch information
ghostbear authored Sep 15, 2022
1 parent 30ac941 commit 86fe850
Show file tree
Hide file tree
Showing 53 changed files with 219 additions and 106 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ android {

dependencies {
implementation(project(":i18n"))
implementation(project(":core"))
implementation(project(":source-api"))

// Compose
implementation(compose.activity)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.preference.PreferencesHelper
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.toLong
import kotlinx.serialization.protobuf.ProtoBuf
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.LocaleHelper
import eu.kanade.tachiyomi.util.system.isDevFlavor
import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
import java.io.File
import java.text.DateFormat
Expand Down
31 changes: 31 additions & 0 deletions app/src/main/java/eu/kanade/tachiyomi/source/SourceExtensions.kt
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import eu.kanade.tachiyomi.util.preference.preferenceCategory
import eu.kanade.tachiyomi.util.preference.switchPreference
import eu.kanade.tachiyomi.util.preference.titleRes
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.widget.preference.ThemesPreference
import java.util.Date
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ import android.util.TypedValue
import android.view.Display
import android.view.View
import android.view.WindowManager
import android.widget.Toast
import androidx.annotation.AttrRes
import androidx.annotation.ColorInt
import androidx.annotation.StringRes
import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
Expand All @@ -52,29 +50,6 @@ import kotlin.math.roundToInt

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
*
Expand Down
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions core/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
46 changes: 46 additions & 0 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -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 changes: 2 additions & 0 deletions core/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest />
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package eu.kanade.tachiyomi.network

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.Http103Interceptor
import eu.kanade.tachiyomi.network.interceptor.UserAgentInterceptor
import okhttp3.Cache
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import uy.kohesive.injekt.injectLazy
import java.io.File
import java.util.concurrent.TimeUnit

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 cacheSize = 5L * 1024 * 1024 // 5 MiB
Expand All @@ -36,14 +36,14 @@ class NetworkHelper(context: Context) {
.addInterceptor(userAgentInterceptor)
.addNetworkInterceptor(http103Interceptor)

if (preferences.verboseLogging()) {
if (preferences.getBoolean("verbose_logging", false)) {
val httpLoggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.HEADERS
}
builder.addNetworkInterceptor(httpLoggingInterceptor)
}

when (preferences.dohProvider()) {
when (preferences.getInt("doh_provider", -1)) {
PREF_DOH_CLOUDFLARE -> builder.dohCloudflare()
PREF_DOH_GOOGLE -> builder.dohGoogle()
PREF_DOH_ADGUARD -> builder.dohAdGuard()
Expand All @@ -70,6 +70,6 @@ class NetworkHelper(context: Context) {
}

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")!!
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import java.util.concurrent.TimeUnit.MINUTES
private val DEFAULT_CACHE_CONTROL = CacheControl.Builder().maxAge(10, MINUTES).build()
private val DEFAULT_HEADERS = Headers.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(
url: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import android.content.Context
import android.webkit.WebView
import android.widget.Toast
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.util.system.WebViewClientCompat
import eu.kanade.tachiyomi.util.system.isOutdated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import android.os.Build
import android.webkit.WebSettings
import android.webkit.WebView
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.util.lang.launchUI
import eu.kanade.tachiyomi.util.system.DeviceUtil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import rx.Emitter
Expand All @@ -20,6 +21,7 @@ import kotlin.coroutines.resumeWithException

suspend fun <T> Observable<T>.awaitSingle(): T = single().awaitOne()

@OptIn(InternalCoroutinesApi::class)
private suspend fun <T> Observable<T>.awaitOne(): T = suspendCancellableCoroutine { cont ->
cont.unsubscribeOnCancellation(
subscribe(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.util.system

import android.annotation.SuppressLint
import android.os.Build
import com.google.android.material.color.DynamicColors
import logcat.LogPriority

object DeviceUtil {
Expand Down Expand Up @@ -31,10 +30,6 @@ object DeviceUtil {
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")

@SuppressLint("PrivateApi")
Expand Down
Original file line number Diff line number Diff line change
@@ -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()
}
}
2 changes: 2 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ dependencyResolutionManagement {
rootProject.name = "Tachiyomi"
include(":app")
include(":i18n")
include(":source-api")
include(":core")
1 change: 1 addition & 0 deletions source-api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
Loading

0 comments on commit 86fe850

Please sign in to comment.