Browse Source

Consolidate Compose content/theme setting

arkon 2 years ago
parent
commit
46ac9fe970

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

@@ -3,17 +3,12 @@ package eu.kanade.tachiyomi.ui.base.controller
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
-import androidx.compose.foundation.layout.consumeWindowInsets
-import androidx.compose.material3.LocalContentColor
-import androidx.compose.material3.MaterialTheme
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
-import androidx.compose.ui.platform.ViewCompositionStrategy
 import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
-import eu.kanade.presentation.theme.TachiyomiTheme
 import eu.kanade.tachiyomi.databinding.ComposeControllerBinding
 import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
+import eu.kanade.tachiyomi.util.view.setComposeContent
 import nucleus.presenter.Presenter
 
 abstract class FullComposeController<P : Presenter<*>>(bundle: Bundle? = null) :
@@ -27,14 +22,8 @@ abstract class FullComposeController<P : Presenter<*>>(bundle: Bundle? = null) :
         super.onViewCreated(view)
 
         binding.root.apply {
-            consumeWindowInsets = false
-            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
-            setContent {
-                TachiyomiTheme {
-                    CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
-                        ComposeContent()
-                    }
-                }
+            setComposeContent {
+                ComposeContent()
             }
         }
     }
@@ -54,15 +43,9 @@ abstract class ComposeController<P : Presenter<*>>(bundle: Bundle? = null) :
         super.onViewCreated(view)
 
         binding.root.apply {
-            consumeWindowInsets = false
-            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
-            setContent {
+            setComposeContent {
                 val nestedScrollInterop = rememberNestedScrollInteropConnection()
-                TachiyomiTheme {
-                    CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
-                        ComposeContent(nestedScrollInterop)
-                    }
-                }
+                ComposeContent(nestedScrollInterop)
             }
         }
     }
@@ -82,15 +65,9 @@ abstract class BasicComposeController :
         super.onViewCreated(view)
 
         binding.root.apply {
-            consumeWindowInsets = false
-            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
-            setContent {
+            setComposeContent {
                 val nestedScrollInterop = rememberNestedScrollInteropConnection()
-                TachiyomiTheme {
-                    CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
-                        ComposeContent(nestedScrollInterop)
-                    }
-                }
+                ComposeContent(nestedScrollInterop)
             }
         }
     }
@@ -107,15 +84,9 @@ abstract class SearchableComposeController<P : BasePresenter<*>>(bundle: Bundle?
         super.onViewCreated(view)
 
         binding.root.apply {
-            consumeWindowInsets = false
-            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
-            setContent {
+            setComposeContent {
                 val nestedScrollInterop = rememberNestedScrollInteropConnection()
-                TachiyomiTheme {
-                    CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
-                        ComposeContent(nestedScrollInterop)
-                    }
-                }
+                ComposeContent(nestedScrollInterop)
             }
         }
     }

+ 67 - 79
app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryAdapter.kt

@@ -3,17 +3,11 @@ package eu.kanade.tachiyomi.ui.library
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
-import androidx.compose.foundation.layout.consumeWindowInsets
-import androidx.compose.material3.LocalContentColor
-import androidx.compose.material3.LocalTextStyle
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateListOf
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.input.nestedscroll.nestedScroll
 import androidx.compose.ui.platform.ComposeView
-import androidx.compose.ui.platform.ViewCompositionStrategy
 import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
 import com.google.accompanist.swiperefresh.SwipeRefresh
 import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
@@ -23,7 +17,6 @@ import eu.kanade.presentation.library.components.LibraryComfortableGrid
 import eu.kanade.presentation.library.components.LibraryCompactGrid
 import eu.kanade.presentation.library.components.LibraryCoverOnlyGrid
 import eu.kanade.presentation.library.components.LibraryList
-import eu.kanade.presentation.theme.TachiyomiTheme
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.database.models.LibraryManga
 import eu.kanade.tachiyomi.data.library.LibraryUpdateService
@@ -31,6 +24,7 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import eu.kanade.tachiyomi.databinding.ComposeControllerBinding
 import eu.kanade.tachiyomi.ui.library.setting.DisplayModeSetting
 import eu.kanade.tachiyomi.util.system.toast
+import eu.kanade.tachiyomi.util.view.setComposeContent
 import eu.kanade.tachiyomi.widget.RecyclerViewPagerAdapter
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
@@ -101,80 +95,74 @@ class LibraryAdapter(
      */
     override fun bindView(view: View, position: Int) {
         (view as ComposeView).apply {
-            consumeWindowInsets = false
-            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
-            setContent {
-                TachiyomiTheme {
-                    CompositionLocalProvider(LocalTextStyle provides MaterialTheme.typography.bodySmall, LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
-                        val nestedScrollInterop = rememberNestedScrollInteropConnection()
-
-                        val category = presenter.categories[position]
-                        val displayMode = presenter.getDisplayMode(index = position)
-                        val mangaList by presenter.getMangaForCategory(categoryId = category.id)
-
-                        val onClickManga = { manga: LibraryManga ->
-                            if (presenter.hasSelection().not()) {
-                                onClickManga(manga)
-                            } else {
-                                presenter.toggleSelection(manga)
-                            }
+            setComposeContent {
+                val nestedScrollInterop = rememberNestedScrollInteropConnection()
+
+                val category = presenter.categories[position]
+                val displayMode = presenter.getDisplayMode(index = position)
+                val mangaList by presenter.getMangaForCategory(categoryId = category.id)
+
+                val onClickManga = { manga: LibraryManga ->
+                    if (presenter.hasSelection().not()) {
+                        onClickManga(manga)
+                    } else {
+                        presenter.toggleSelection(manga)
+                    }
+                }
+                val onLongClickManga = { manga: LibraryManga ->
+                    presenter.toggleSelection(manga)
+                }
+
+                SwipeRefresh(
+                    modifier = Modifier.nestedScroll(nestedScrollInterop),
+                    state = rememberSwipeRefreshState(isRefreshing = false),
+                    onRefresh = {
+                        if (LibraryUpdateService.start(context, category)) {
+                            context.toast(R.string.updating_category)
                         }
-                        val onLongClickManga = { manga: LibraryManga ->
-                            presenter.toggleSelection(manga)
+                    },
+                    indicator = { s, trigger ->
+                        SwipeRefreshIndicator(
+                            state = s,
+                            refreshTriggerDistance = trigger,
+                        )
+                    },
+                ) {
+                    when (displayMode) {
+                        DisplayModeSetting.LIST -> {
+                            LibraryList(
+                                items = mangaList,
+                                selection = presenter.selection,
+                                onClick = onClickManga,
+                                onLongClick = onLongClickManga,
+                            )
                         }
-
-                        SwipeRefresh(
-                            modifier = Modifier.nestedScroll(nestedScrollInterop),
-                            state = rememberSwipeRefreshState(isRefreshing = false),
-                            onRefresh = {
-                                if (LibraryUpdateService.start(context, category)) {
-                                    context.toast(R.string.updating_category)
-                                }
-                            },
-                            indicator = { s, trigger ->
-                                SwipeRefreshIndicator(
-                                    state = s,
-                                    refreshTriggerDistance = trigger,
-                                )
-                            },
-                        ) {
-                            when (displayMode) {
-                                DisplayModeSetting.LIST -> {
-                                    LibraryList(
-                                        items = mangaList,
-                                        selection = presenter.selection,
-                                        onClick = onClickManga,
-                                        onLongClick = onLongClickManga,
-                                    )
-                                }
-                                DisplayModeSetting.COMPACT_GRID -> {
-                                    LibraryCompactGrid(
-                                        items = mangaList,
-                                        columns = presenter.columns,
-                                        selection = presenter.selection,
-                                        onClick = onClickManga,
-                                        onLongClick = onLongClickManga,
-                                    )
-                                }
-                                DisplayModeSetting.COMFORTABLE_GRID -> {
-                                    LibraryComfortableGrid(
-                                        items = mangaList,
-                                        columns = presenter.columns,
-                                        selection = presenter.selection,
-                                        onClick = onClickManga,
-                                        onLongClick = onLongClickManga,
-                                    )
-                                }
-                                DisplayModeSetting.COVER_ONLY_GRID -> {
-                                    LibraryCoverOnlyGrid(
-                                        items = mangaList,
-                                        columns = presenter.columns,
-                                        selection = presenter.selection,
-                                        onClick = onClickManga,
-                                        onLongClick = onLongClickManga,
-                                    )
-                                }
-                            }
+                        DisplayModeSetting.COMPACT_GRID -> {
+                            LibraryCompactGrid(
+                                items = mangaList,
+                                columns = presenter.columns,
+                                selection = presenter.selection,
+                                onClick = onClickManga,
+                                onLongClick = onLongClickManga,
+                            )
+                        }
+                        DisplayModeSetting.COMFORTABLE_GRID -> {
+                            LibraryComfortableGrid(
+                                items = mangaList,
+                                columns = presenter.columns,
+                                selection = presenter.selection,
+                                onClick = onClickManga,
+                                onLongClick = onLongClickManga,
+                            )
+                        }
+                        DisplayModeSetting.COVER_ONLY_GRID -> {
+                            LibraryCoverOnlyGrid(
+                                items = mangaList,
+                                columns = presenter.columns,
+                                selection = presenter.selection,
+                                onClick = onClickManga,
+                                onLongClick = onLongClickManga,
+                            )
                         }
                     }
                 }

+ 3 - 6
app/src/main/java/eu/kanade/tachiyomi/ui/setting/track/BaseOAuthLoginActivity.kt

@@ -3,12 +3,11 @@ package eu.kanade.tachiyomi.ui.setting.track
 import android.content.Intent
 import android.net.Uri
 import android.os.Bundle
-import androidx.activity.compose.setContent
 import eu.kanade.presentation.components.LoadingScreen
-import eu.kanade.presentation.theme.TachiyomiTheme
 import eu.kanade.tachiyomi.data.track.TrackManager
 import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
 import eu.kanade.tachiyomi.ui.main.MainActivity
+import eu.kanade.tachiyomi.util.view.setComposeContent
 import uy.kohesive.injekt.injectLazy
 
 abstract class BaseOAuthLoginActivity : BaseActivity() {
@@ -20,10 +19,8 @@ abstract class BaseOAuthLoginActivity : BaseActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
 
-        setContent {
-            TachiyomiTheme {
-                LoadingScreen()
-            }
+        setComposeContent {
+            LoadingScreen()
         }
 
         handleResult(intent.data)

+ 11 - 14
app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewActivity.kt

@@ -4,8 +4,6 @@ import android.content.Context
 import android.content.Intent
 import android.os.Bundle
 import android.widget.Toast
-import androidx.activity.compose.setContent
-import eu.kanade.presentation.theme.TachiyomiTheme
 import eu.kanade.presentation.webview.WebViewScreen
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.network.NetworkHelper
@@ -16,6 +14,7 @@ import eu.kanade.tachiyomi.util.system.WebViewUtil
 import eu.kanade.tachiyomi.util.system.logcat
 import eu.kanade.tachiyomi.util.system.openInBrowser
 import eu.kanade.tachiyomi.util.system.toast
+import eu.kanade.tachiyomi.util.view.setComposeContent
 import okhttp3.HttpUrl.Companion.toHttpUrl
 import uy.kohesive.injekt.injectLazy
 
@@ -44,18 +43,16 @@ class WebViewActivity : BaseActivity() {
             headers = source.headers.toMultimap().mapValues { it.value.getOrNull(0) ?: "" }.toMutableMap()
         }
 
-        setContent {
-            TachiyomiTheme {
-                WebViewScreen(
-                    onUp = { finish() },
-                    initialTitle = intent.extras?.getString(TITLE_KEY),
-                    url = url,
-                    headers = headers,
-                    onShare = this::shareWebpage,
-                    onOpenInBrowser = this::openInBrowser,
-                    onClearCookies = this::clearCookies,
-                )
-            }
+        setComposeContent {
+            WebViewScreen(
+                onUp = { finish() },
+                initialTitle = intent.extras?.getString(TITLE_KEY),
+                url = url,
+                headers = headers,
+                onShare = this::shareWebpage,
+                onOpenInBrowser = this::openInBrowser,
+                onClearCookies = this::clearCookies,
+            )
         }
     }
 

+ 42 - 69
app/src/main/java/eu/kanade/tachiyomi/util/view/ViewExtensions.kt

@@ -5,42 +5,71 @@ package eu.kanade.tachiyomi.util.view
 import android.annotation.SuppressLint
 import android.content.Context
 import android.content.res.Resources
-import android.graphics.Point
 import android.graphics.Rect
 import android.graphics.drawable.Drawable
-import android.text.TextUtils
 import android.view.Gravity
 import android.view.Menu
 import android.view.MenuItem
 import android.view.View
 import android.view.ViewGroup
-import android.widget.TextView
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
 import androidx.annotation.MenuRes
 import androidx.annotation.StringRes
 import androidx.appcompat.content.res.AppCompatResources
 import androidx.appcompat.view.menu.MenuBuilder
 import androidx.appcompat.widget.PopupMenu
 import androidx.appcompat.widget.TooltipCompat
+import androidx.compose.foundation.layout.consumeWindowInsets
+import androidx.compose.material3.LocalContentColor
+import androidx.compose.material3.LocalTextStyle
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionContext
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.platform.ViewCompositionStrategy
 import androidx.core.view.children
 import androidx.core.view.descendants
 import androidx.core.view.forEach
 import androidx.recyclerview.widget.RecyclerView
-import androidx.viewpager.widget.ViewPager
-import com.google.android.material.chip.Chip
-import com.google.android.material.chip.ChipGroup
 import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
 import com.google.android.material.shape.MaterialShapeDrawable
 import com.google.android.material.snackbar.Snackbar
+import eu.kanade.presentation.theme.TachiyomiTheme
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.util.system.getResourceColor
 
-/**
- * Returns coordinates of view.
- * Used for animation
- *
- * @return coordinates of view
- */
-fun View.getCoordinates() = Point((left + right) / 2, (top + bottom) / 2)
+inline fun ComposeView.setComposeContent(crossinline content: @Composable () -> Unit) {
+    consumeWindowInsets = false
+    setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
+    setContent {
+        TachiyomiTheme {
+            CompositionLocalProvider(
+                LocalTextStyle provides MaterialTheme.typography.bodySmall,
+                LocalContentColor provides MaterialTheme.colorScheme.onBackground,
+            ) {
+                content()
+            }
+        }
+    }
+}
+
+inline fun ComponentActivity.setComposeContent(
+    parent: CompositionContext? = null,
+    crossinline content: @Composable () -> Unit,
+) {
+    setContent(parent) {
+        TachiyomiTheme {
+            CompositionLocalProvider(
+                LocalTextStyle provides MaterialTheme.typography.bodySmall,
+                LocalContentColor provides MaterialTheme.colorScheme.onBackground,
+            ) {
+                content()
+            }
+        }
+    }
+}
 
 /**
  * Shows a snackbar in this view.
@@ -164,39 +193,6 @@ inline fun ExtendedFloatingActionButton.shrinkOnScroll(recycler: RecyclerView):
     return listener
 }
 
-/**
- * Replaces chips in a ChipGroup.
- *
- * @param items List of strings that are shown as individual chips.
- * @param onClick Optional on click listener for each chip.
- * @param onLongClick Optional on long click listener for each chip.
- */
-inline fun ChipGroup.setChips(
-    items: List<String>?,
-    noinline onClick: ((item: String) -> Unit)? = null,
-    noinline onLongClick: ((item: String) -> Unit)? = null,
-) {
-    removeAllViews()
-
-    items?.forEach { item ->
-        val chip = Chip(context).apply {
-            text = item
-            if (onClick != null) { setOnClickListener { onClick(item) } }
-            if (onLongClick != null) { setOnLongClickListener { onLongClick(item); true } }
-        }
-
-        addView(chip)
-    }
-}
-
-/**
- * Sets TextView max lines dynamically. Can only be called when the view is already laid out.
- */
-inline fun TextView.setMaxLinesAndEllipsize(_ellipsize: TextUtils.TruncateAt = TextUtils.TruncateAt.END) = post {
-    maxLines = (measuredHeight - paddingTop - paddingBottom) / lineHeight
-    ellipsize = _ellipsize
-}
-
 /**
  * Callback will be run immediately when no animation running
  */
@@ -228,29 +224,6 @@ inline fun <reified T> ViewGroup.findDescendant(): T? {
     return descendants.find { it is T } as? T
 }
 
-/**
- * Returns the active child view of a ViewPager according to the LayoutParams
- */
-fun ViewPager.getActivePageView(): View? {
-    if (null == adapter || adapter?.count == 0 || childCount == 0) {
-        return null
-    }
-
-    val positionField = ViewPager.LayoutParams::class.java.getDeclaredField("position")
-    positionField.isAccessible = true
-    return children.find { child ->
-        val layoutParams = child.layoutParams as ViewPager.LayoutParams
-        try {
-            if (!layoutParams.isDecor && positionField.getInt(layoutParams) == currentItem) {
-                return@find true
-            }
-        } catch (e: NoSuchFieldException) {
-        } catch (e: IllegalAccessException) {
-        }
-        false
-    }
-}
-
 /**
  * Returns a deep copy of the provided [Drawable]
  */

+ 0 - 66
app/src/main/res/layout/chapters_item.xml

@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="fill_parent"
-    android:layout_height="wrap_content"
-    android:background="@drawable/list_item_selector_background"
-    android:minHeight="?android:attr/listPreferredItemHeight"
-    android:paddingVertical="10dp"
-    android:paddingStart="16dp"
-    android:paddingEnd="5dp">
-
-    <ImageView
-        android:id="@+id/bookmark_icon"
-        android:layout_width="16dp"
-        android:layout_height="0dp"
-        android:layout_marginEnd="4dp"
-        android:contentDescription="@string/action_filter_bookmarked"
-        android:visibility="gone"
-        app:layout_constraintBottom_toBottomOf="@id/chapter_title"
-        app:layout_constraintEnd_toStartOf="@id/chapter_title"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="@+id/chapter_title"
-        app:srcCompat="@drawable/ic_bookmark_24dp"
-        app:tint="?attr/colorAccent"
-        tools:visibility="visible" />
-
-    <TextView
-        android:id="@+id/chapter_title"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:ellipsize="end"
-        android:maxLines="1"
-        android:textAppearance="?attr/textAppearanceBodyMedium"
-        app:layout_constraintBottom_toTopOf="@+id/chapter_description"
-        app:layout_constraintEnd_toStartOf="@+id/download"
-        app:layout_constraintStart_toEndOf="@+id/bookmark_icon"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintVertical_chainStyle="packed"
-        tools:text="Title" />
-
-    <TextView
-        android:id="@+id/chapter_description"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="6dp"
-        android:ellipsize="end"
-        android:singleLine="true"
-        android:textAppearance="?attr/textAppearanceBodyMedium"
-        android:textSize="12sp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/download"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/chapter_title"
-        tools:text="22/02/2016 • Scanlator • Page: 45" />
-
-    <eu.kanade.tachiyomi.ui.manga.chapter.ChapterDownloadView
-        android:id="@+id/download"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:paddingStart="4dp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
-
-</androidx.constraintlayout.widget.ConstraintLayout>

+ 0 - 1
app/src/main/res/layout/library_controller.xml

@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent">