color for reader's loading/progress indicator

This commit is contained in:
Cuong-Tran 2024-06-23 01:33:33 +07:00
parent c8c4ad7be6
commit a8728f332c
No known key found for this signature in database
GPG key ID: 733AA7624B9315C2
13 changed files with 275 additions and 40 deletions

View file

@ -25,6 +25,7 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.surfaceColorAtElevation
@ -580,7 +581,11 @@ class ReaderActivity : BaseActivity() {
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalAlignment = Alignment.CenterVertically,
) {
CircularProgressIndicator()
CircularProgressIndicator(
// KMK -->
color = MaterialTheme.colorScheme.primary,
// KMK <--
)
Text(stringResource(MR.strings.loading))
}
},
@ -901,8 +906,17 @@ class ReaderActivity : BaseActivity() {
* Called from the presenter when a manga is ready. Used to instantiate the appropriate viewer.
*/
private fun updateViewer() {
// KMK -->
val manga = viewModel.manga
// KMK <--
val prevViewer = viewModel.state.value.viewer
val newViewer = ReadingMode.toViewer(viewModel.getMangaReadingMode(), this)
val newViewer = ReadingMode.toViewer(
viewModel.getMangaReadingMode(),
this,
// KMK -->
seedColor = manga?.asMangaCover()?.vibrantCoverColor,
// KMK <--
)
if (window.sharedElementEnterTransition is MaterialContainerTransform) {
// Wait until transition is complete to avoid crash on API 26
@ -930,7 +944,6 @@ class ReaderActivity : BaseActivity() {
viewModel.state.value.lastShiftDoubleState?.let { newViewer.config.shiftDoublePage = it }
}
val manga = viewModel.state.value.manga
val defaultReaderType = manga?.defaultReaderType(
manga.mangaType(sourceName = sourceManager.get(manga.source)?.name),
)
@ -947,7 +960,12 @@ class ReaderActivity : BaseActivity() {
showReadingModeToast(viewModel.getMangaReadingMode())
}
loadingIndicator = ReaderProgressIndicator(this)
loadingIndicator = ReaderProgressIndicator(
context = this,
// KMK -->
seedColor = manga?.asMangaCover()?.vibrantCoverColor,
// KMK <--
)
binding.readerContainer.addView(loadingIndicator)
startPostponedEnterTransition()

View file

@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.ui.reader.setting
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import dev.icerock.moko.resources.StringResource
import eu.kanade.tachiyomi.R
@ -66,13 +67,45 @@ enum class ReadingMode(
return mode.type is ViewerType.Pager
}
fun toViewer(preference: Int?, activity: ReaderActivity): Viewer {
fun toViewer(
preference: Int?,
activity: ReaderActivity,
// KMK -->
@ColorInt seedColor: Int?
// KMK <--
): Viewer {
return when (fromPreference(preference)) {
LEFT_TO_RIGHT -> L2RPagerViewer(activity)
RIGHT_TO_LEFT -> R2LPagerViewer(activity)
VERTICAL -> VerticalPagerViewer(activity)
WEBTOON -> WebtoonViewer(activity)
CONTINUOUS_VERTICAL -> WebtoonViewer(activity, isContinuous = false)
LEFT_TO_RIGHT -> L2RPagerViewer(
activity,
// KMK -->
seedColor = seedColor,
// KMK <--
)
RIGHT_TO_LEFT -> R2LPagerViewer(
activity,
// KMK -->
seedColor = seedColor,
// KMK <--
)
VERTICAL -> VerticalPagerViewer(
activity,
// KMK -->
seedColor = seedColor,
// KMK <--
)
WEBTOON -> WebtoonViewer(
activity,
// KMK -->
seedColor = seedColor,
// KMK <--
)
CONTINUOUS_VERTICAL -> WebtoonViewer(
activity,
isContinuous = false,
// KMK -->
seedColor = seedColor,
// KMK <--
)
DEFAULT -> throw IllegalStateException("Preference value must be resolved: $preference")
}
}

View file

@ -5,18 +5,25 @@ import android.util.AttributeSet
import android.view.Gravity
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.FrameLayout
import androidx.annotation.ColorInt
import androidx.annotation.IntRange
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.AbstractComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.core.view.isVisible
import com.google.android.material.progressindicator.CircularProgressIndicator
import com.materialkolor.DynamicMaterialTheme
import eu.kanade.domain.ui.UiPreferences
import eu.kanade.presentation.theme.TachiyomiTheme
import tachiyomi.presentation.core.components.CombinedCircularProgressIndicator
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
/**
* A wrapper for [CircularProgressIndicator] that always rotates.
@ -27,6 +34,9 @@ class ReaderProgressIndicator @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
// KMK -->
@ColorInt private val seedColor: Int? = null,
// KMK <--
) : AbstractComposeView(context, attrs, defStyleAttr) {
init {
@ -38,8 +48,25 @@ class ReaderProgressIndicator @JvmOverloads constructor(
@Composable
override fun Content() {
TachiyomiTheme {
CombinedCircularProgressIndicator(progress = { progress })
// KMK -->
val uiPreferences = Injekt.get<UiPreferences>()
val themeDarkAmoled = uiPreferences.themeDarkAmoled().get()
val themeCoverBasedStyle = uiPreferences.themeCoverBasedStyle().get()
if (seedColor != null) {
DynamicMaterialTheme(
seedColor = Color(seedColor),
useDarkTheme = isSystemInDarkTheme(),
withAmoled = themeDarkAmoled,
style = themeCoverBasedStyle,
animate = true,
) {
CombinedCircularProgressIndicator(progress = { progress })
}
} else {
// KMK <--
TachiyomiTheme {
CombinedCircularProgressIndicator(progress = { progress })
}
}
}

View file

@ -2,6 +2,8 @@ package eu.kanade.tachiyomi.ui.reader.viewer
import android.content.Context
import android.util.AttributeSet
import androidx.annotation.ColorInt
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
@ -10,15 +12,26 @@ import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.AbstractComposeView
import com.materialkolor.DynamicMaterialTheme
import eu.kanade.domain.ui.UiPreferences
import eu.kanade.presentation.reader.ChapterTransition
import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
import tachiyomi.domain.manga.model.Manga
import tachiyomi.source.local.isLocal
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
class ReaderTransitionView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
// KMK -->
@ColorInt private val seedColor: Int? = null,
// KMK <--
) :
AbstractComposeView(context, attrs) {
private var data: Data? by mutableStateOf(null)
@ -50,7 +63,10 @@ class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: At
@Composable
override fun Content() {
data?.let {
TachiyomiTheme {
// KMK -->
@Composable
fun content() {
// KMK <--
CompositionLocalProvider(
LocalTextStyle provides MaterialTheme.typography.bodySmall,
LocalContentColor provides MaterialTheme.colorScheme.onBackground,
@ -62,6 +78,26 @@ class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: At
)
}
}
// KMK -->
val uiPreferences = Injekt.get<UiPreferences>()
val themeDarkAmoled = uiPreferences.themeDarkAmoled().get()
val themeCoverBasedStyle = uiPreferences.themeCoverBasedStyle().get()
if (seedColor != null) {
DynamicMaterialTheme(
seedColor = Color(seedColor),
useDarkTheme = isSystemInDarkTheme(),
withAmoled = themeDarkAmoled,
style = themeCoverBasedStyle,
animate = true,
) {
content()
}
} else {
// KMK <--
TachiyomiTheme {
content()
}
}
}
}

View file

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.reader.viewer.pager
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import androidx.annotation.ColorInt
import androidx.core.view.isVisible
import eu.kanade.tachiyomi.databinding.ReaderErrorBinding
import eu.kanade.tachiyomi.source.model.Page
@ -38,6 +39,9 @@ class PagerPageHolder(
val viewer: PagerViewer,
val page: ReaderPage,
private var extraPage: ReaderPage? = null,
// KMK -->
@ColorInt private val seedColor: Int? = null,
// KMK <--
) : ReaderPageImageView(readerThemedContext), ViewPagerAdapter.PositionableView {
/**
@ -49,7 +53,12 @@ class PagerPageHolder(
/**
* Loading progress bar to indicate the current progress.
*/
private val progressIndicator: ReaderProgressIndicator = ReaderProgressIndicator(readerThemedContext)
private val progressIndicator: ReaderProgressIndicator = ReaderProgressIndicator(
context = readerThemedContext,
// KMK -->
seedColor = seedColor,
// KMK <--
)
/**
* Error layout to show when the image fails to load.

View file

@ -8,11 +8,12 @@ import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.LinearLayout
import androidx.annotation.ColorInt
import androidx.appcompat.widget.AppCompatTextView
import com.google.android.material.progressindicator.CircularProgressIndicator
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderButton
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderProgressIndicator
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderTransitionView
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.widget.ViewPagerAdapter
@ -31,6 +32,9 @@ class PagerTransitionHolder(
readerThemedContext: Context,
val viewer: PagerViewer,
val transition: ChapterTransition,
// KMK -->
@ColorInt private val seedColor: Int? = null,
// KMK <--
) : LinearLayout(readerThemedContext), ViewPagerAdapter.PositionableView {
private val scope = MainScope()
@ -58,7 +62,12 @@ class PagerTransitionHolder(
val sidePadding = 64.dpToPx
setPadding(sidePadding, 0, sidePadding, 0)
val transitionView = ReaderTransitionView(context)
val transitionView = ReaderTransitionView(
context,
// KMK -->
seedColor = seedColor,
// KMK <--
)
addView(transitionView)
addView(pagesContainer)
@ -100,8 +109,12 @@ class PagerTransitionHolder(
* Sets the loading state on the pages container.
*/
private fun setLoading() {
val progress = CircularProgressIndicator(context)
progress.isIndeterminate = true
// KMK -->
val progress = ReaderProgressIndicator(
context = context,
seedColor = seedColor,
)
// KMK <--
val textView = AppCompatTextView(context).apply {
wrapContent()

View file

@ -6,6 +6,7 @@ import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup.LayoutParams
import androidx.annotation.ColorInt
import androidx.core.view.children
import androidx.core.view.isGone
import androidx.core.view.isVisible
@ -30,7 +31,12 @@ import kotlin.math.min
* Implementation of a [Viewer] to display pages with a [ViewPager].
*/
@Suppress("LeakingThis")
abstract class PagerViewer(val activity: ReaderActivity) : Viewer {
abstract class PagerViewer(
val activity: ReaderActivity,
// KMK -->
@ColorInt private val seedColor: Int? = null,
// KMK <--
) : Viewer {
val downloadManager: DownloadManager by injectLazy()
@ -50,7 +56,12 @@ abstract class PagerViewer(val activity: ReaderActivity) : Viewer {
/**
* Adapter of the pager.
*/
private val adapter = PagerViewerAdapter(this)
private val adapter = PagerViewerAdapter(
this,
// KMK -->
seedColor = seedColor,
// KMK <--
)
/**
* Currently active item. It can be a chapter page or a chapter transition.

View file

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.reader.viewer.pager
import android.view.View
import android.view.ViewGroup
import androidx.annotation.ColorInt
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
import eu.kanade.tachiyomi.ui.reader.model.InsertPage
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
@ -19,7 +20,12 @@ import kotlin.math.max
/**
* Pager adapter used by this [viewer] to where [ViewerChapters] updates are posted.
*/
class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
class PagerViewerAdapter(
private val viewer: PagerViewer,
// KMK -->
@ColorInt private val seedColor: Int? = null,
// KMK <--
) : ViewPagerAdapter() {
/**
* Paired list of currently set items.
@ -162,8 +168,23 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
val item = joinedItems[position].first
val item2 = joinedItems[position].second
return when (item) {
is ReaderPage -> PagerPageHolder(readerThemedContext, viewer, item, item2 as? ReaderPage)
is ChapterTransition -> PagerTransitionHolder(readerThemedContext, viewer, item)
is ReaderPage -> PagerPageHolder(
readerThemedContext,
viewer,
item,
item2 as? ReaderPage,
// KMK -->
seedColor = seedColor,
// KMK <--
)
is ChapterTransition -> PagerTransitionHolder(
readerThemedContext,
viewer,
item,
// KMK -->
seedColor = seedColor,
// KMK <--
)
// SY --> else -> throw NotImplementedError("Holder for ${item.javaClass} not implemented") SY <--
}
}
@ -378,10 +399,12 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
oldCurrent?.second == current ||
(current.index + 1) < (
(
oldCurrent?.second
?: oldCurrent?.first
) as? ReaderPage
)?.index ?: 0,
(
oldCurrent?.second
?: oldCurrent?.first
) as? ReaderPage
)?.index ?: 0
),
)
// The listener may be removed when we split a page, so the ui may not have updated properly

View file

@ -1,11 +1,17 @@
package eu.kanade.tachiyomi.ui.reader.viewer.pager
import androidx.annotation.ColorInt
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
/**
* Implementation of a left to right PagerViewer.
*/
class L2RPagerViewer(activity: ReaderActivity) : PagerViewer(activity) {
class L2RPagerViewer(
activity: ReaderActivity,
// KMK -->
@ColorInt seedColor: Int? = null,
// KMK <--
) : PagerViewer(activity, seedColor) {
/**
* Creates a new left to right pager.
*/
@ -17,7 +23,12 @@ class L2RPagerViewer(activity: ReaderActivity) : PagerViewer(activity) {
/**
* Implementation of a right to left PagerViewer.
*/
class R2LPagerViewer(activity: ReaderActivity) : PagerViewer(activity) {
class R2LPagerViewer(
activity: ReaderActivity,
// KMK -->
@ColorInt seedColor: Int? = null,
// KMK <--
) : PagerViewer(activity, seedColor) {
/**
* Creates a new right to left pager.
*/
@ -43,7 +54,12 @@ class R2LPagerViewer(activity: ReaderActivity) : PagerViewer(activity) {
/**
* Implementation of a vertical (top to bottom) PagerViewer.
*/
class VerticalPagerViewer(activity: ReaderActivity) : PagerViewer(activity) {
class VerticalPagerViewer(
activity: ReaderActivity,
// KMK -->
@ColorInt seedColor: Int? = null,
// KMK <--
) : PagerViewer(activity, seedColor) {
/**
* Creates a new vertical pager.
*/

View file

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.reader.viewer.webtoon
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.annotation.ColorInt
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
@ -15,7 +16,12 @@ import eu.kanade.tachiyomi.util.system.createReaderThemeContext
/**
* RecyclerView Adapter used by this [viewer] to where [ViewerChapters] updates are posted.
*/
class WebtoonAdapter(val viewer: WebtoonViewer) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
class WebtoonAdapter(
val viewer: WebtoonViewer,
// KMK -->
@ColorInt private val seedColor: Int? = null,
// KMK <--
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
/**
* List of currently set items.
@ -117,11 +123,23 @@ class WebtoonAdapter(val viewer: WebtoonViewer) : RecyclerView.Adapter<RecyclerV
return when (viewType) {
PAGE_VIEW -> {
val view = ReaderPageImageView(readerThemedContext, isWebtoon = true)
WebtoonPageHolder(view, viewer)
WebtoonPageHolder(
view,
viewer,
// KMK -->
seedColor = seedColor,
// KMK <--
)
}
TRANSITION_VIEW -> {
val view = LinearLayout(readerThemedContext)
WebtoonTransitionHolder(view, viewer)
WebtoonTransitionHolder(
view,
viewer,
// KMK -->
seedColor = seedColor,
// KMK <--
)
}
else -> error("Unknown view type")
}

View file

@ -6,6 +6,7 @@ import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.FrameLayout
import androidx.annotation.ColorInt
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.core.view.updateMargins
@ -41,6 +42,9 @@ import tachiyomi.core.common.util.system.logcat
class WebtoonPageHolder(
private val frame: ReaderPageImageView,
viewer: WebtoonViewer,
// KMK -->
@ColorInt private val seedColor: Int? = null,
// KMK <--
) : WebtoonBaseHolder(frame, viewer) {
/**
@ -261,7 +265,12 @@ class WebtoonPageHolder(
progressContainer = FrameLayout(context)
frame.addView(progressContainer, MATCH_PARENT, parentHeight)
val progress = ReaderProgressIndicator(context).apply {
val progress = ReaderProgressIndicator(
context,
// KMK -->
seedColor = seedColor,
// KMK <--
).apply {
updateLayoutParams<FrameLayout.LayoutParams> {
updateMargins(top = parentHeight / 4)
}

View file

@ -4,13 +4,14 @@ import android.view.Gravity
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.LinearLayout
import androidx.annotation.ColorInt
import androidx.appcompat.widget.AppCompatButton
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.view.isNotEmpty
import androidx.core.view.isVisible
import com.google.android.material.progressindicator.CircularProgressIndicator
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderProgressIndicator
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderTransitionView
import eu.kanade.tachiyomi.util.system.dpToPx
import kotlinx.coroutines.Job
@ -26,12 +27,20 @@ import tachiyomi.i18n.MR
class WebtoonTransitionHolder(
val layout: LinearLayout,
viewer: WebtoonViewer,
// KMK -->
@ColorInt private val seedColor: Int? = null,
// KMK <--
) : WebtoonBaseHolder(layout, viewer) {
private val scope = MainScope()
private var stateJob: Job? = null
private val transitionView = ReaderTransitionView(context)
private val transitionView = ReaderTransitionView(
context,
// KMK -->
seedColor = seedColor,
// KMK <--
)
/**
* View container of the current status of the transition page. Child views will be added
@ -102,8 +111,12 @@ class WebtoonTransitionHolder(
* Sets the loading state on the pages container.
*/
private fun setLoading() {
val progress = CircularProgressIndicator(context)
progress.isIndeterminate = true
// KMK -->
val progress = ReaderProgressIndicator(
context = context,
seedColor = seedColor,
)
// KMK <--
val textView = AppCompatTextView(context).apply {
wrapContent()

View file

@ -7,6 +7,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.animation.LinearInterpolator
import androidx.annotation.ColorInt
import androidx.core.app.ActivityCompat
import androidx.core.view.isGone
import androidx.core.view.isVisible
@ -37,6 +38,9 @@ class WebtoonViewer(
val activity: ReaderActivity,
val isContinuous: Boolean = true,
private val tapByPage: Boolean = false,
// KMK -->
@ColorInt private val seedColor: Int? = null,
// KMK <--
) : Viewer {
val downloadManager: DownloadManager by injectLazy()
@ -66,7 +70,12 @@ class WebtoonViewer(
/**
* Adapter of the recycler view.
*/
private val adapter = WebtoonAdapter(this)
private val adapter = WebtoonAdapter(
this,
// KMK -->
seedColor = seedColor,
// KMK <--
)
/**
* Distance to scroll when the user taps on one side of the recycler view.