Procházet zdrojové kódy

Migrate open source licenses screen to Compose

arkon před 2 roky
rodič
revize
1b4d9fc4e9

+ 1 - 3
app/build.gradle.kts

@@ -239,6 +239,7 @@ dependencies {
     }
     implementation(libs.insetter)
     implementation(libs.markwon)
+    implementation(libs.aboutLibraries.compose)
 
     // Conductor
     implementation(libs.bundles.conductor)
@@ -253,9 +254,6 @@ dependencies {
     implementation(libs.acra.http)
     "standardImplementation"(libs.firebase.analytics)
 
-    // Licenses
-    implementation(libs.aboutlibraries.core)
-
     // Shizuku
     implementation(libs.bundles.shizuku)
 

+ 24 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/ComposeController.kt

@@ -7,6 +7,9 @@ import eu.kanade.presentation.theme.TachiyomiTheme
 import eu.kanade.tachiyomi.databinding.ComposeControllerBinding
 import nucleus.presenter.Presenter
 
+/**
+ * Compose controller with a Nucleus presenter.
+ */
 abstract class ComposeController<P : Presenter<*>> : NucleusController<ComposeControllerBinding, P>() {
 
     override fun createBinding(inflater: LayoutInflater): ComposeControllerBinding =
@@ -24,3 +27,24 @@ abstract class ComposeController<P : Presenter<*>> : NucleusController<ComposeCo
 
     @Composable abstract fun ComposeContent()
 }
+
+/**
+ * Basic Compose controller without a presenter.
+ */
+abstract class BasicComposeController : BaseController<ComposeControllerBinding>() {
+
+    override fun createBinding(inflater: LayoutInflater): ComposeControllerBinding =
+        ComposeControllerBinding.inflate(inflater)
+
+    override fun onViewCreated(view: View) {
+        super.onViewCreated(view)
+
+        binding.root.setContent {
+            TachiyomiTheme {
+                ComposeContent()
+            }
+        }
+    }
+
+    @Composable abstract fun ComposeContent()
+}

+ 0 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt

@@ -9,7 +9,6 @@ import eu.kanade.tachiyomi.data.updater.RELEASE_URL
 import eu.kanade.tachiyomi.ui.base.controller.NoAppBarElevationController
 import eu.kanade.tachiyomi.ui.base.controller.openInBrowser
 import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
-import eu.kanade.tachiyomi.ui.more.licenses.LicensesController
 import eu.kanade.tachiyomi.ui.setting.SettingsController
 import eu.kanade.tachiyomi.util.CrashLogUtil
 import eu.kanade.tachiyomi.util.lang.launchNow

+ 35 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/more/LicensesController.kt

@@ -0,0 +1,35 @@
+package eu.kanade.tachiyomi.ui.more
+
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.contentColorFor
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.input.nestedscroll.nestedScroll
+import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
+import com.mikepenz.aboutlibraries.ui.compose.LibrariesContainer
+import com.mikepenz.aboutlibraries.ui.compose.LibraryDefaults.libraryColors
+import eu.kanade.tachiyomi.R
+import eu.kanade.tachiyomi.ui.base.controller.BasicComposeController
+
+class LicensesController : BasicComposeController() {
+
+    override fun getTitle() = resources?.getString(R.string.licenses)
+
+    @Composable
+    override fun ComposeContent() {
+        val nestedScrollInterop = rememberNestedScrollInteropConnection(binding.root)
+
+        LibrariesContainer(
+            modifier = Modifier
+                .fillMaxSize()
+                .nestedScroll(nestedScrollInterop),
+            colors = libraryColors(
+                backgroundColor = MaterialTheme.colorScheme.background,
+                contentColor = contentColorFor(MaterialTheme.colorScheme.background),
+                badgeBackgroundColor = MaterialTheme.colorScheme.primary,
+                badgeContentColor = contentColorFor(MaterialTheme.colorScheme.primary),
+            ),
+        )
+    }
+}

+ 0 - 6
app/src/main/java/eu/kanade/tachiyomi/ui/more/licenses/LicensesAdapter.kt

@@ -1,6 +0,0 @@
-package eu.kanade.tachiyomi.ui.more.licenses
-
-import eu.davidea.flexibleadapter.FlexibleAdapter
-
-class LicensesAdapter(controller: LicensesController) :
-    FlexibleAdapter<LicensesItem>(null, controller, true)

+ 0 - 75
app/src/main/java/eu/kanade/tachiyomi/ui/more/licenses/LicensesController.kt

@@ -1,75 +0,0 @@
-package eu.kanade.tachiyomi.ui.more.licenses
-
-import android.view.LayoutInflater
-import android.view.View
-import androidx.recyclerview.widget.LinearLayoutManager
-import com.mikepenz.aboutlibraries.Libs
-import dev.chrisbanes.insetter.applyInsetter
-import eu.davidea.flexibleadapter.FlexibleAdapter
-import eu.kanade.tachiyomi.R
-import eu.kanade.tachiyomi.databinding.LicensesControllerBinding
-import eu.kanade.tachiyomi.ui.base.controller.BaseController
-import eu.kanade.tachiyomi.util.lang.launchUI
-import eu.kanade.tachiyomi.util.lang.withIOContext
-import eu.kanade.tachiyomi.util.system.openInBrowser
-
-class LicensesController :
-    BaseController<LicensesControllerBinding>(),
-    FlexibleAdapter.OnItemClickListener {
-
-    private var adapter: LicensesAdapter? = null
-
-    override fun getTitle(): String? {
-        return resources?.getString(R.string.licenses)
-    }
-
-    override fun createBinding(inflater: LayoutInflater) = LicensesControllerBinding.inflate(inflater)
-
-    override fun onViewCreated(view: View) {
-        super.onViewCreated(view)
-        binding.recycler.applyInsetter {
-            type(navigationBars = true) {
-                padding()
-            }
-        }
-        binding.progress.applyInsetter {
-            type(navigationBars = true) {
-                padding()
-            }
-        }
-
-        binding.recycler.layoutManager = LinearLayoutManager(view.context)
-        adapter = LicensesAdapter(this)
-        binding.recycler.adapter = adapter
-
-        viewScope.launchUI {
-            val licenseItems = withIOContext {
-                Libs(view.context).libraries
-                    .sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER, { it.libraryName }))
-                    .map { LicensesItem(it) }
-            }
-            binding.progress.hide()
-            adapter?.updateDataSet(licenseItems)
-        }
-    }
-
-    override fun onDestroyView(view: View) {
-        adapter = null
-        super.onDestroyView(view)
-    }
-
-    override fun onItemClick(view: View, position: Int): Boolean {
-        val adapter = adapter ?: return false
-
-        val item = adapter.getItem(position) ?: return false
-        openLicenseWebsite(item)
-        return true
-    }
-
-    private fun openLicenseWebsite(item: LicensesItem) {
-        val website = item.library.libraryWebsite
-        if (website.isNotEmpty()) {
-            activity?.openInBrowser(website)
-        }
-    }
-}

+ 0 - 21
app/src/main/java/eu/kanade/tachiyomi/ui/more/licenses/LicensesHolder.kt

@@ -1,21 +0,0 @@
-package eu.kanade.tachiyomi.ui.more.licenses
-
-import android.annotation.SuppressLint
-import android.view.View
-import com.mikepenz.aboutlibraries.entity.Library
-import eu.davidea.flexibleadapter.FlexibleAdapter
-import eu.davidea.viewholders.FlexibleViewHolder
-import eu.kanade.tachiyomi.databinding.LicensesItemBinding
-
-class LicensesHolder(view: View, adapter: FlexibleAdapter<*>) :
-    FlexibleViewHolder(view, adapter) {
-
-    private val binding = LicensesItemBinding.bind(view)
-
-    @SuppressLint("SetTextI18n")
-    fun bind(library: Library) {
-        binding.name.text = "${library.libraryName} ${library.libraryVersion}"
-        binding.artifactId.text = library.libraryArtifactId
-        binding.license.text = library.licenses?.joinToString { it.licenseName }
-    }
-}

+ 0 - 41
app/src/main/java/eu/kanade/tachiyomi/ui/more/licenses/LicensesItem.kt

@@ -1,41 +0,0 @@
-package eu.kanade.tachiyomi.ui.more.licenses
-
-import android.view.View
-import androidx.recyclerview.widget.RecyclerView
-import com.mikepenz.aboutlibraries.entity.Library
-import eu.davidea.flexibleadapter.FlexibleAdapter
-import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
-import eu.davidea.flexibleadapter.items.IFlexible
-import eu.kanade.tachiyomi.R
-
-class LicensesItem(val library: Library) : AbstractFlexibleItem<LicensesHolder>() {
-
-    override fun getLayoutRes(): Int {
-        return R.layout.licenses_item
-    }
-
-    override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LicensesHolder {
-        return LicensesHolder(view, adapter)
-    }
-
-    override fun bindViewHolder(
-        adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>,
-        holder: LicensesHolder,
-        position: Int,
-        payloads: List<Any?>?,
-    ) {
-        holder.bind(library)
-    }
-
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (other is LicensesItem) {
-            return library.hashCode() == other.hashCode()
-        }
-        return false
-    }
-
-    override fun hashCode(): Int {
-        return library.hashCode()
-    }
-}

+ 0 - 21
app/src/main/res/layout/licenses_controller.xml

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content">
-
-    <com.google.android.material.progressindicator.CircularProgressIndicator
-        android:id="@+id/progress"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerInParent="true"
-        android:indeterminate="true" />
-
-    <androidx.recyclerview.widget.RecyclerView
-        android:id="@+id/recycler"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:clipToPadding="false"
-        tools:listitem="@layout/licenses_item" />
-
-</RelativeLayout>

+ 0 - 34
app/src/main/res/layout/licenses_item.xml

@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:background="@drawable/list_item_selector_background"
-    android:paddingHorizontal="16dp"
-    android:paddingVertical="8dp"
-    android:orientation="vertical">
-
-    <TextView
-        android:id="@+id/name"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textAppearance="?attr/textAppearanceTitleSmall"
-        tools:text="Library name" />
-
-    <TextView
-        android:id="@+id/artifact_id"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textAppearance="?attr/textAppearanceBodyMedium"
-        android:textColor="?android:attr/textColorSecondary"
-        tools:text="artifact:id:1.0" />
-
-    <TextView
-        android:id="@+id/license"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textAppearance="?attr/textAppearanceBodyMedium"
-        android:textColor="?android:attr/textColorSecondary"
-        tools:text="Apache Version 2.0" />
-
-</LinearLayout>

+ 1 - 1
build.gradle.kts

@@ -2,7 +2,7 @@ buildscript {
     dependencies {
         classpath(libs.android.shortcut.gradle)
         classpath(libs.google.services.gradle)
-        classpath(libs.aboutlibraries.gradle)
+        classpath(libs.aboutLibraries.gradle)
         classpath(kotlinx.serialization.gradle)
         classpath("com.squareup.sqldelight:gradle-plugin:1.5.3")
     }

+ 3 - 3
gradle/libs.versions.toml

@@ -1,5 +1,5 @@
 [versions]
-aboutlib_version = "8.9.4"
+aboutlib_version = "10.1.0"
 okhttp_version = "4.9.3"
 nucleus_version = "3.0.0"
 coil_version = "2.0.0-rc03"
@@ -83,8 +83,8 @@ logcat = "com.squareup.logcat:logcat:0.1"
 acra-http = "ch.acra:acra-http:5.9.1"
 firebase-analytics = "com.google.firebase:firebase-analytics-ktx:20.0.2"
 
-aboutlibraries-core = { module = "com.mikepenz:aboutlibraries-core", version.ref = "aboutlib_version" }
-aboutlibraries-gradle = { module = "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin", version.ref = "aboutlib_version" }
+aboutLibraries-gradle = { module = "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin", version.ref = "aboutlib_version" }
+aboutLibraries-compose = { module = "com.mikepenz:aboutlibraries-compose", version.ref ="aboutlib_version" }
 
 shizuku-api = { module = "dev.rikka.shizuku:api", version.ref = "shizuku_version" }
 shizuku-provider = { module = "dev.rikka.shizuku:provider", version.ref = "shizuku_version" }