Browse Source

Convert source modules to Kotlin Multiplatform (#9172)

Use KMP in source modules 


Use KMP in source-api


Expect LocalSource
Andreas 2 years ago
parent
commit
1abf01c4a0
38 changed files with 91 additions and 49 deletions
  1. 2 4
      app/src/main/java/eu/kanade/tachiyomi/AppModule.kt
  2. 2 0
      gradle.properties
  3. 22 12
      source-api/build.gradle.kts
  4. 3 0
      source-api/src/androidMain/kotlin/eu/kanade/tachiyomi/source/PreferenceScreen.kt
  5. 6 0
      source-api/src/androidMain/kotlin/eu/kanade/tachiyomi/util/RxExtension.kt
  6. 0 0
      source-api/src/commonMain/AndroidManifest.xml
  7. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/CatalogueSource.kt
  8. 0 2
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt
  9. 3 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/PreferenceScreen.kt
  10. 1 1
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/Source.kt
  11. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/SourceFactory.kt
  12. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/UnmeteredSource.kt
  13. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/Filter.kt
  14. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/FilterList.kt
  15. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/MangasPage.kt
  16. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/Page.kt
  17. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/SChapter.kt
  18. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/SChapterImpl.kt
  19. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/SManga.kt
  20. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/SMangaImpl.kt
  21. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/UpdateStrategy.kt
  22. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt
  23. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt
  24. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/ParsedHttpSource.kt
  25. 0 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/util/JsoupExtensions.kt
  26. 5 0
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/util/RxExtension.kt
  27. 25 17
      source-local/build.gradle.kts
  28. 0 0
      source-local/src/androidMain/AndroidManifest.xml
  29. 1 1
      source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt
  30. 0 0
      source-local/src/androidMain/kotlin/tachiyomi/source/local/filter/OrderBy.kt
  31. 7 4
      source-local/src/androidMain/kotlin/tachiyomi/source/local/image/LocalCoverManager.kt
  32. 6 6
      source-local/src/androidMain/kotlin/tachiyomi/source/local/io/LocalSourceFileSystem.kt
  33. 0 0
      source-local/src/androidMain/kotlin/tachiyomi/source/local/metadata/EpubFile.kt
  34. 6 0
      source-local/src/commonMain/kotlin/tachiyomi/source/local/LocalSource.kt
  35. 1 1
      source-local/src/commonMain/kotlin/tachiyomi/source/local/image/LocalCoverManager.kt
  36. 0 0
      source-local/src/commonMain/kotlin/tachiyomi/source/local/io/Archive.kt
  37. 0 0
      source-local/src/commonMain/kotlin/tachiyomi/source/local/io/Format.kt
  38. 1 1
      source-local/src/commonMain/kotlin/tachiyomi/source/local/io/LocalSourceFileSystem.kt

+ 2 - 4
app/src/main/java/eu/kanade/tachiyomi/AppModule.kt

@@ -48,9 +48,7 @@ import tachiyomi.data.Mangas
 import tachiyomi.data.dateAdapter
 import tachiyomi.data.listOfStringsAdapter
 import tachiyomi.data.updateStrategyAdapter
-import tachiyomi.source.local.image.AndroidLocalCoverManager
 import tachiyomi.source.local.image.LocalCoverManager
-import tachiyomi.source.local.io.AndroidLocalSourceFileSystem
 import tachiyomi.source.local.io.LocalSourceFileSystem
 import uy.kohesive.injekt.api.InjektModule
 import uy.kohesive.injekt.api.InjektRegistrar
@@ -137,8 +135,8 @@ class AppModule(val app: Application) : InjektModule {
 
         addSingletonFactory { ImageSaver(app) }
 
-        addSingletonFactory<LocalSourceFileSystem> { AndroidLocalSourceFileSystem(app) }
-        addSingletonFactory<LocalCoverManager> { AndroidLocalCoverManager(app, get()) }
+        addSingletonFactory { LocalSourceFileSystem(app) }
+        addSingletonFactory { LocalCoverManager(app, get()) }
 
         // Asynchronously init expensive components for a faster cold start
         ContextCompat.getMainExecutor(app).execute {

+ 2 - 0
gradle.properties

@@ -22,3 +22,5 @@ org.gradle.caching=true
 
 # AndroidX support
 android.useAndroidX=true
+
+kotlin.mpp.androidSourceSetLayoutVersion=2

+ 22 - 12
source-api/build.gradle.kts

@@ -1,7 +1,27 @@
 plugins {
-    id("com.android.library")
-    kotlin("android")
+    kotlin("multiplatform")
     kotlin("plugin.serialization")
+    id("com.android.library")
+}
+
+kotlin {
+    android()
+    sourceSets {
+        val commonMain by getting {
+            dependencies {
+                api(kotlinx.serialization.json)
+                api(libs.injekt.core)
+                api(libs.rxjava)
+                api(libs.jsoup)
+            }
+        }
+        val androidMain by getting {
+            dependencies {
+                implementation(project(":core"))
+                api(libs.preferencektx)
+            }
+        }
+    }
 }
 
 android {
@@ -11,13 +31,3 @@ android {
         consumerProguardFile("consumer-proguard.pro")
     }
 }
-
-dependencies {
-    implementation(project(":core"))
-
-    api(kotlinx.serialization.json)
-    api(libs.injekt.core)
-    api(libs.rxjava)
-    api(libs.preferencektx)
-    api(libs.jsoup)
-}

+ 3 - 0
source-api/src/androidMain/kotlin/eu/kanade/tachiyomi/source/PreferenceScreen.kt

@@ -0,0 +1,3 @@
+package eu.kanade.tachiyomi.source
+
+actual typealias PreferenceScreen = androidx.preference.PreferenceScreen

+ 6 - 0
source-api/src/androidMain/kotlin/eu/kanade/tachiyomi/util/RxExtension.kt

@@ -0,0 +1,6 @@
+package eu.kanade.tachiyomi.util
+
+import rx.Observable
+import tachiyomi.core.util.lang.awaitSingle
+
+actual suspend fun <T> Observable<T>.awaitSingle(): T = awaitSingle()

+ 0 - 0
source-api/src/main/AndroidManifest.xml → source-api/src/commonMain/AndroidManifest.xml


+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/source/CatalogueSource.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/CatalogueSource.kt


+ 0 - 2
source-api/src/main/java/eu/kanade/tachiyomi/source/ConfigurableSource.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt

@@ -1,7 +1,5 @@
 package eu.kanade.tachiyomi.source
 
-import androidx.preference.PreferenceScreen
-
 interface ConfigurableSource : Source {
 
     fun setupPreferenceScreen(screen: PreferenceScreen)

+ 3 - 0
source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/PreferenceScreen.kt

@@ -0,0 +1,3 @@
+package eu.kanade.tachiyomi.source
+
+expect class PreferenceScreen

+ 1 - 1
source-api/src/main/java/eu/kanade/tachiyomi/source/Source.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/Source.kt

@@ -3,8 +3,8 @@ package eu.kanade.tachiyomi.source
 import eu.kanade.tachiyomi.source.model.Page
 import eu.kanade.tachiyomi.source.model.SChapter
 import eu.kanade.tachiyomi.source.model.SManga
+import eu.kanade.tachiyomi.util.awaitSingle
 import rx.Observable
-import tachiyomi.core.util.lang.awaitSingle
 
 /**
  * A basic interface for creating a source. It could be an online source, a local source, etc...

+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/source/SourceFactory.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/SourceFactory.kt


+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/source/UnmeteredSource.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/UnmeteredSource.kt


+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/source/model/Filter.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/Filter.kt


+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/source/model/FilterList.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/FilterList.kt


+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/source/model/MangasPage.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/MangasPage.kt


+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/Page.kt


+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/source/model/SChapter.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/SChapter.kt


+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/source/model/SChapterImpl.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/SChapterImpl.kt


+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/source/model/SManga.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/SManga.kt


+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/source/model/SMangaImpl.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/SMangaImpl.kt


+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/source/model/UpdateStrategy.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/UpdateStrategy.kt


+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/source/online/HttpSource.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt


+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt


+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/source/online/ParsedHttpSource.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/ParsedHttpSource.kt


+ 0 - 0
source-api/src/main/java/eu/kanade/tachiyomi/util/JsoupExtensions.kt → source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/util/JsoupExtensions.kt


+ 5 - 0
source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/util/RxExtension.kt

@@ -0,0 +1,5 @@
+package eu.kanade.tachiyomi.util
+
+import rx.Observable
+
+expect suspend fun <T> Observable<T>.awaitSingle(): T

+ 25 - 17
source-local/build.gradle.kts

@@ -1,29 +1,37 @@
 plugins {
+    kotlin("multiplatform")
     id("com.android.library")
-    kotlin("android")
+}
+
+kotlin {
+    android()
+    sourceSets {
+        val commonMain by getting {
+            dependencies {
+                implementation(project(":source-api"))
+                implementation(libs.unifile)
+                implementation(libs.junrar)
+            }
+        }
+        val androidMain by getting {
+            dependencies {
+                implementation(project(":core"))
+                implementation(project(":core-metadata"))
+
+                // Move ChapterRecognition to separate module?
+                implementation(project(":domain"))
+
+                implementation(kotlinx.bundles.serialization)
+            }
+        }
+    }
 }
 
 android {
     namespace = "tachiyomi.source.local"
 
     defaultConfig {
-
         testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
         consumerProguardFiles("consumer-rules.pro")
     }
 }
-
-dependencies {
-
-    implementation(project(":source-api"))
-    implementation(project(":core"))
-    implementation(project(":core-metadata"))
-
-    // Move ChapterRecognition to separate module?
-    implementation(project(":domain"))
-
-    implementation(kotlinx.bundles.serialization)
-
-    implementation(libs.unifile)
-    implementation(libs.junrar)
-}

+ 0 - 0
source-local/src/main/AndroidManifest.xml → source-local/src/androidMain/AndroidManifest.xml


+ 1 - 1
source-local/src/main/java/tachiyomi/source/local/LocalSource.kt → source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt

@@ -40,7 +40,7 @@ import java.util.concurrent.TimeUnit
 import java.util.zip.ZipFile
 import com.github.junrar.Archive as JunrarArchive
 
-class LocalSource(
+actual class LocalSource(
     private val context: Context,
     private val fileSystem: LocalSourceFileSystem,
     private val coverManager: LocalCoverManager,

+ 0 - 0
source-local/src/main/java/tachiyomi/source/local/filter/OrderBy.kt → source-local/src/androidMain/kotlin/tachiyomi/source/local/filter/OrderBy.kt


+ 7 - 4
source-local/src/main/java/tachiyomi/source/local/image/AndroidLocalCoverManager.kt → source-local/src/androidMain/kotlin/tachiyomi/source/local/image/LocalCoverManager.kt

@@ -11,12 +11,12 @@ import java.io.InputStream
 
 private const val DEFAULT_COVER_NAME = "cover.jpg"
 
-class AndroidLocalCoverManager(
+actual class LocalCoverManager(
     private val context: Context,
     private val fileSystem: LocalSourceFileSystem,
-) : LocalCoverManager {
+) {
 
-    override fun find(mangaUrl: String): File? {
+    actual fun find(mangaUrl: String): File? {
         return fileSystem.getFilesInMangaDirectory(mangaUrl)
             // Get all file whose names start with 'cover'
             .filter { it.isFile && it.nameWithoutExtension.equals("cover", ignoreCase = true) }
@@ -26,7 +26,10 @@ class AndroidLocalCoverManager(
             }
     }
 
-    override fun update(manga: SManga, inputStream: InputStream): File? {
+    actual fun update(
+        manga: SManga,
+        inputStream: InputStream,
+    ): File? {
         val directory = fileSystem.getMangaDirectory(manga.url)
         if (directory == null) {
             inputStream.close()

+ 6 - 6
source-local/src/main/java/tachiyomi/source/local/io/AndroidLocalSourceFileSystem.kt → source-local/src/androidMain/kotlin/tachiyomi/source/local/io/LocalSourceFileSystem.kt

@@ -5,31 +5,31 @@ import eu.kanade.tachiyomi.util.storage.DiskUtil
 import tachiyomi.source.local.R
 import java.io.File
 
-class AndroidLocalSourceFileSystem(
+actual class LocalSourceFileSystem(
     private val context: Context,
-) : LocalSourceFileSystem {
+) {
 
     private val baseFolderLocation = "${context.getString(R.string.app_name)}${File.separator}local"
 
-    override fun getBaseDirectories(): Sequence<File> {
+    actual fun getBaseDirectories(): Sequence<File> {
         return DiskUtil.getExternalStorages(context)
             .map { File(it.absolutePath, baseFolderLocation) }
             .asSequence()
     }
 
-    override fun getFilesInBaseDirectories(): Sequence<File> {
+    actual fun getFilesInBaseDirectories(): Sequence<File> {
         return getBaseDirectories()
             // Get all the files inside all baseDir
             .flatMap { it.listFiles().orEmpty().toList() }
     }
 
-    override fun getMangaDirectory(name: String): File? {
+    actual fun getMangaDirectory(name: String): File? {
         return getFilesInBaseDirectories()
             // Get the first mangaDir or null
             .firstOrNull { it.isDirectory && it.name == name }
     }
 
-    override fun getFilesInMangaDirectory(name: String): Sequence<File> {
+    actual fun getFilesInMangaDirectory(name: String): Sequence<File> {
         return getFilesInBaseDirectories()
             // Filter out ones that are not related to the manga and is not a directory
             .filter { it.isDirectory && it.name == name }

+ 0 - 0
source-local/src/main/java/tachiyomi/source/local/metadata/EpubFile.kt → source-local/src/androidMain/kotlin/tachiyomi/source/local/metadata/EpubFile.kt


+ 6 - 0
source-local/src/commonMain/kotlin/tachiyomi/source/local/LocalSource.kt

@@ -0,0 +1,6 @@
+package tachiyomi.source.local
+
+import eu.kanade.tachiyomi.source.CatalogueSource
+import eu.kanade.tachiyomi.source.UnmeteredSource
+
+expect class LocalSource : CatalogueSource, UnmeteredSource

+ 1 - 1
source-local/src/main/java/tachiyomi/source/local/image/LocalCoverManager.kt → source-local/src/commonMain/kotlin/tachiyomi/source/local/image/LocalCoverManager.kt

@@ -4,7 +4,7 @@ import eu.kanade.tachiyomi.source.model.SManga
 import java.io.File
 import java.io.InputStream
 
-interface LocalCoverManager {
+expect class LocalCoverManager {
 
     fun find(mangaUrl: String): File?
 

+ 0 - 0
source-local/src/main/java/tachiyomi/source/local/io/Archive.kt → source-local/src/commonMain/kotlin/tachiyomi/source/local/io/Archive.kt


+ 0 - 0
source-local/src/main/java/tachiyomi/source/local/io/Format.kt → source-local/src/commonMain/kotlin/tachiyomi/source/local/io/Format.kt


+ 1 - 1
source-local/src/main/java/tachiyomi/source/local/io/LocalSourceFileSystem.kt → source-local/src/commonMain/kotlin/tachiyomi/source/local/io/LocalSourceFileSystem.kt

@@ -2,7 +2,7 @@ package tachiyomi.source.local.io
 
 import java.io.File
 
-interface LocalSourceFileSystem {
+expect class LocalSourceFileSystem {
 
     fun getBaseDirectories(): Sequence<File>