Migrate reader slider and next/prev buttons to Compose
This commit is contained in:
parent
3c79777e66
commit
9a10656bf0
@ -0,0 +1,121 @@
|
||||
package eu.kanade.presentation.reader
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.SkipNext
|
||||
import androidx.compose.material.icons.outlined.SkipPrevious
|
||||
import androidx.compose.material3.FilledIconButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButtonDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Slider
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import eu.kanade.presentation.util.isTabletUi
|
||||
import eu.kanade.tachiyomi.R
|
||||
|
||||
@Composable
|
||||
fun ChapterNavigator(
|
||||
isRtl: Boolean,
|
||||
onNextChapter: () -> Unit,
|
||||
enabledNext: Boolean,
|
||||
onPreviousChapter: () -> Unit,
|
||||
enabledPrevious: Boolean,
|
||||
currentPage: Int,
|
||||
totalPages: Int,
|
||||
onSliderValueChange: (Int) -> Unit,
|
||||
) {
|
||||
val isTabletUi = isTabletUi()
|
||||
val horizontalPadding = if (isTabletUi) 24.dp else 16.dp
|
||||
val layoutDirection = if (isRtl) LayoutDirection.Rtl else LayoutDirection.Ltr
|
||||
|
||||
val backgroundColor = MaterialTheme.colorScheme.surface.copy(alpha = 0.9f)
|
||||
val haptic = LocalHapticFeedback.current
|
||||
|
||||
// We explicitly handle direction based on the reader viewer rather than the system direction
|
||||
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = horizontalPadding),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
val isLeftEnabled = if (isRtl) enabledNext else enabledPrevious
|
||||
if (isLeftEnabled) {
|
||||
FilledIconButton(
|
||||
onClick = if (isRtl) onNextChapter else onPreviousChapter,
|
||||
colors = IconButtonDefaults.filledIconButtonColors(
|
||||
containerColor = backgroundColor,
|
||||
),
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.SkipPrevious,
|
||||
contentDescription = stringResource(if (isRtl) R.string.action_next_chapter else R.string.action_previous_chapter),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (totalPages > 1) {
|
||||
CompositionLocalProvider(LocalLayoutDirection provides layoutDirection) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.clip(RoundedCornerShape(24.dp))
|
||||
.background(backgroundColor)
|
||||
.padding(horizontal = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(text = currentPage.toString())
|
||||
|
||||
Slider(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(horizontal = 8.dp),
|
||||
value = currentPage.toFloat(),
|
||||
valueRange = 1f..totalPages.toFloat(),
|
||||
steps = totalPages,
|
||||
onValueChange = {
|
||||
onSliderValueChange(it.toInt() - 1)
|
||||
haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove)
|
||||
},
|
||||
)
|
||||
|
||||
Text(text = totalPages.toString())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Spacer(Modifier.weight(1f))
|
||||
}
|
||||
|
||||
val isRightEnabled = if (isRtl) enabledPrevious else enabledNext
|
||||
if (isRightEnabled) {
|
||||
FilledIconButton(
|
||||
onClick = if (isRtl) onPreviousChapter else onNextChapter,
|
||||
colors = IconButtonDefaults.filledIconButtonColors(
|
||||
containerColor = backgroundColor,
|
||||
),
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.SkipNext,
|
||||
contentDescription = stringResource(if (isRtl) R.string.action_previous_chapter else R.string.action_next_chapter),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -6,18 +6,15 @@ import android.app.ProgressDialog
|
||||
import android.app.assist.AssistContent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.graphics.ColorMatrix
|
||||
import android.graphics.ColorMatrixColorFilter
|
||||
import android.graphics.Paint
|
||||
import android.graphics.drawable.RippleDrawable
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.Gravity
|
||||
import android.view.HapticFeedbackConstants
|
||||
import android.view.KeyEvent
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
@ -37,17 +34,16 @@ import androidx.core.transition.doOnEnd
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
import com.google.android.material.shape.MaterialShapeDrawable
|
||||
import com.google.android.material.slider.Slider
|
||||
import com.google.android.material.transition.platform.MaterialContainerTransform
|
||||
import dev.chrisbanes.insetter.applyInsetter
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.domain.manga.model.orientationType
|
||||
import eu.kanade.presentation.reader.ChapterNavigator
|
||||
import eu.kanade.presentation.reader.PageIndicatorText
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
||||
@ -66,14 +62,12 @@ import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsSheet
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderProgressIndicator
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer
|
||||
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
||||
import eu.kanade.tachiyomi.util.preference.toggle
|
||||
import eu.kanade.tachiyomi.util.system.applySystemAnimatorScale
|
||||
import eu.kanade.tachiyomi.util.system.createReaderThemeContext
|
||||
import eu.kanade.tachiyomi.util.system.getThemeColor
|
||||
import eu.kanade.tachiyomi.util.system.hasDisplayCutout
|
||||
import eu.kanade.tachiyomi.util.system.isNightMode
|
||||
import eu.kanade.tachiyomi.util.system.toShareIntent
|
||||
@ -101,7 +95,6 @@ import tachiyomi.core.util.system.logcat
|
||||
import tachiyomi.domain.manga.model.Manga
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
|
||||
class ReaderActivity : BaseActivity() {
|
||||
|
||||
@ -113,9 +106,6 @@ class ReaderActivity : BaseActivity() {
|
||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
}
|
||||
}
|
||||
|
||||
private const val ENABLED_BUTTON_IMAGE_ALPHA = 255
|
||||
private const val DISABLED_BUTTON_IMAGE_ALPHA = 64
|
||||
}
|
||||
|
||||
private val readerPreferences: ReaderPreferences by injectLazy()
|
||||
@ -128,12 +118,6 @@ class ReaderActivity : BaseActivity() {
|
||||
|
||||
val hasCutout by lazy { hasDisplayCutout() }
|
||||
|
||||
/**
|
||||
* Viewer used to display the pages (pager, webtoon, ...).
|
||||
*/
|
||||
var viewer: BaseViewer? = null
|
||||
private set
|
||||
|
||||
/**
|
||||
* Whether the menu is currently visible.
|
||||
*/
|
||||
@ -255,8 +239,7 @@ class ReaderActivity : BaseActivity() {
|
||||
*/
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
viewer?.destroy()
|
||||
viewer = null
|
||||
viewModel.state.value.viewer?.destroy()
|
||||
config = null
|
||||
menuToggleToast?.cancel()
|
||||
readingModeToast?.cancel()
|
||||
@ -365,7 +348,7 @@ class ReaderActivity : BaseActivity() {
|
||||
* Dispatches a key event. If the viewer doesn't handle it, call the default implementation.
|
||||
*/
|
||||
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
||||
val handled = viewer?.handleKeyEvent(event) ?: false
|
||||
val handled = viewModel.state.value.viewer?.handleKeyEvent(event) ?: false
|
||||
return handled || super.dispatchKeyEvent(event)
|
||||
}
|
||||
|
||||
@ -374,7 +357,7 @@ class ReaderActivity : BaseActivity() {
|
||||
* implementation.
|
||||
*/
|
||||
override fun dispatchGenericMotionEvent(event: MotionEvent): Boolean {
|
||||
val handled = viewer?.handleGenericMotionEvent(event) ?: false
|
||||
val handled = viewModel.state.value.viewer?.handleGenericMotionEvent(event) ?: false
|
||||
return handled || super.dispatchGenericMotionEvent(event)
|
||||
}
|
||||
|
||||
@ -416,46 +399,30 @@ class ReaderActivity : BaseActivity() {
|
||||
|
||||
PageIndicatorText(
|
||||
currentPage = state.currentPage,
|
||||
totalPages = state.viewerChapters?.currChapter?.pages?.size ?: -1,
|
||||
totalPages = state.totalPages,
|
||||
)
|
||||
}
|
||||
|
||||
// Init listeners on bottom menu
|
||||
binding.pageSlider.addOnSliderTouchListener(
|
||||
object : Slider.OnSliderTouchListener {
|
||||
override fun onStartTrackingTouch(slider: Slider) {
|
||||
isScrollingThroughPages = true
|
||||
}
|
||||
binding.readerNav.setComposeContent {
|
||||
val state by viewModel.state.collectAsState()
|
||||
|
||||
override fun onStopTrackingTouch(slider: Slider) {
|
||||
isScrollingThroughPages = false
|
||||
}
|
||||
},
|
||||
)
|
||||
binding.pageSlider.addOnChangeListener { slider, value, fromUser ->
|
||||
if (viewer != null && fromUser) {
|
||||
isScrollingThroughPages = true
|
||||
moveToPageIndex(value.toInt())
|
||||
slider.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
|
||||
}
|
||||
}
|
||||
binding.leftChapter.setOnClickListener {
|
||||
if (viewer != null) {
|
||||
if (viewer is R2LPagerViewer) {
|
||||
loadNextChapter()
|
||||
} else {
|
||||
loadPreviousChapter()
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.rightChapter.setOnClickListener {
|
||||
if (viewer != null) {
|
||||
if (viewer is R2LPagerViewer) {
|
||||
loadPreviousChapter()
|
||||
} else {
|
||||
loadNextChapter()
|
||||
}
|
||||
}
|
||||
if (state.viewer == null) return@setComposeContent
|
||||
val isRtl = state.viewer is R2LPagerViewer
|
||||
|
||||
ChapterNavigator(
|
||||
isRtl = isRtl,
|
||||
onNextChapter = ::loadNextChapter,
|
||||
enabledNext = state.viewerChapters?.nextChapter != null,
|
||||
onPreviousChapter = ::loadPreviousChapter,
|
||||
enabledPrevious = state.viewerChapters?.prevChapter != null,
|
||||
currentPage = state.currentPage,
|
||||
totalPages = state.totalPages,
|
||||
onSliderValueChange = {
|
||||
isScrollingThroughPages = true
|
||||
moveToPageIndex(it)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
initBottomShortcuts()
|
||||
@ -466,18 +433,6 @@ class ReaderActivity : BaseActivity() {
|
||||
}
|
||||
binding.toolbarBottom.background = toolbarBackground.copy(this@ReaderActivity)
|
||||
|
||||
binding.readerSeekbar.background = toolbarBackground.copy(this@ReaderActivity)?.apply {
|
||||
setCornerSize(999F)
|
||||
}
|
||||
listOf(binding.leftChapter, binding.rightChapter).forEach {
|
||||
it.background = binding.readerSeekbar.background.copy(this)
|
||||
it.foreground = RippleDrawable(
|
||||
ColorStateList.valueOf(getThemeColor(android.R.attr.colorControlHighlight)),
|
||||
null,
|
||||
it.background,
|
||||
)
|
||||
}
|
||||
|
||||
val toolbarColor = ColorUtils.setAlphaComponent(
|
||||
toolbarBackground.resolvedTintColor,
|
||||
toolbarBackground.alpha,
|
||||
@ -671,7 +626,7 @@ class ReaderActivity : BaseActivity() {
|
||||
* and the toolbar title.
|
||||
*/
|
||||
private fun setManga(manga: Manga) {
|
||||
val prevViewer = viewer
|
||||
val prevViewer = viewModel.state.value.viewer
|
||||
|
||||
val viewerMode = ReadingModeType.fromPreference(viewModel.getMangaReadingMode(resolveDefault = false))
|
||||
binding.actionReadingMode.setImageResource(viewerMode.iconRes)
|
||||
@ -693,7 +648,7 @@ class ReaderActivity : BaseActivity() {
|
||||
prevViewer.destroy()
|
||||
binding.viewerContainer.removeAllViews()
|
||||
}
|
||||
viewer = newViewer
|
||||
viewModel.onViewerLoaded(newViewer)
|
||||
updateViewerInset(readerPreferences.fullscreen().get())
|
||||
binding.viewerContainer.addView(newViewer.getView())
|
||||
|
||||
@ -703,15 +658,6 @@ class ReaderActivity : BaseActivity() {
|
||||
|
||||
supportActionBar?.title = manga.title
|
||||
|
||||
binding.pageSlider.isRTL = newViewer is R2LPagerViewer
|
||||
if (newViewer is R2LPagerViewer) {
|
||||
binding.leftChapter.setTooltip(R.string.action_next_chapter)
|
||||
binding.rightChapter.setTooltip(R.string.action_previous_chapter)
|
||||
} else {
|
||||
binding.leftChapter.setTooltip(R.string.action_previous_chapter)
|
||||
binding.rightChapter.setTooltip(R.string.action_next_chapter)
|
||||
}
|
||||
|
||||
val loadingIndicatorContext = createReaderThemeContext()
|
||||
loadingIndicator = ReaderProgressIndicator(loadingIndicatorContext).apply {
|
||||
updateLayoutParams<FrameLayout.LayoutParams> {
|
||||
@ -751,26 +697,9 @@ class ReaderActivity : BaseActivity() {
|
||||
*/
|
||||
private fun setChapters(viewerChapters: ViewerChapters) {
|
||||
binding.readerContainer.removeView(loadingIndicator)
|
||||
viewer?.setChapters(viewerChapters)
|
||||
viewModel.state.value.viewer?.setChapters(viewerChapters)
|
||||
binding.toolbar.subtitle = viewerChapters.currChapter.chapter.name
|
||||
|
||||
val currentChapterPageCount = viewerChapters.currChapter.pages?.size ?: 1
|
||||
binding.readerSeekbar.isInvisible = currentChapterPageCount == 1
|
||||
|
||||
val leftChapterObject = if (viewer is R2LPagerViewer) viewerChapters.nextChapter else viewerChapters.prevChapter
|
||||
val rightChapterObject = if (viewer is R2LPagerViewer) viewerChapters.prevChapter else viewerChapters.nextChapter
|
||||
|
||||
if (leftChapterObject == null && rightChapterObject == null) {
|
||||
binding.leftChapter.isVisible = false
|
||||
binding.rightChapter.isVisible = false
|
||||
} else {
|
||||
binding.leftChapter.isEnabled = leftChapterObject != null
|
||||
binding.leftChapter.imageAlpha = if (leftChapterObject != null) ENABLED_BUTTON_IMAGE_ALPHA else DISABLED_BUTTON_IMAGE_ALPHA
|
||||
|
||||
binding.rightChapter.isEnabled = rightChapterObject != null
|
||||
binding.rightChapter.imageAlpha = if (rightChapterObject != null) ENABLED_BUTTON_IMAGE_ALPHA else DISABLED_BUTTON_IMAGE_ALPHA
|
||||
}
|
||||
|
||||
// Invalidate menu to show proper chapter bookmark state
|
||||
invalidateOptionsMenu()
|
||||
|
||||
@ -812,7 +741,7 @@ class ReaderActivity : BaseActivity() {
|
||||
* page is not found.
|
||||
*/
|
||||
private fun moveToPageIndex(index: Int) {
|
||||
val viewer = viewer ?: return
|
||||
val viewer = viewModel.state.value.viewer ?: return
|
||||
val currentChapter = viewModel.getCurrentChapter() ?: return
|
||||
val page = currentChapter.pages?.getOrNull(index) ?: return
|
||||
viewer.moveToPage(page)
|
||||
@ -847,21 +776,6 @@ class ReaderActivity : BaseActivity() {
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun onPageSelected(page: ReaderPage) {
|
||||
viewModel.onPageSelected(page)
|
||||
val pages = page.chapter.pages ?: return
|
||||
|
||||
// Set page numbers
|
||||
if (viewer !is R2LPagerViewer) {
|
||||
binding.leftPageText.text = "${page.number}"
|
||||
binding.rightPageText.text = "${pages.size}"
|
||||
} else {
|
||||
binding.rightPageText.text = "${page.number}"
|
||||
binding.leftPageText.text = "${pages.size}"
|
||||
}
|
||||
|
||||
// Set slider progress
|
||||
binding.pageSlider.isEnabled = pages.size > 1
|
||||
binding.pageSlider.valueTo = max(pages.lastIndex.toFloat(), 1f)
|
||||
binding.pageSlider.value = page.index.toFloat()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -989,7 +903,7 @@ class ReaderActivity : BaseActivity() {
|
||||
* Updates viewer inset depending on fullscreen reader preferences.
|
||||
*/
|
||||
fun updateViewerInset(fullscreen: Boolean) {
|
||||
viewer?.getView()?.applyInsetter {
|
||||
viewModel.state.value.viewer?.getView()?.applyInsetter {
|
||||
if (!fullscreen) {
|
||||
type(navigationBars = true, statusBars = true) {
|
||||
padding()
|
||||
|
@ -1,30 +0,0 @@
|
||||
package eu.kanade.tachiyomi.ui.reader
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import com.google.android.material.slider.Slider
|
||||
|
||||
/**
|
||||
* Slider to show current chapter progress.
|
||||
*/
|
||||
class ReaderSlider @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
) : Slider(context, attrs) {
|
||||
|
||||
init {
|
||||
stepSize = 1f
|
||||
setLabelFormatter { value ->
|
||||
(value.toInt() + 1).toString()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the slider should draw from right to left.
|
||||
*/
|
||||
var isRTL: Boolean
|
||||
set(value) {
|
||||
layoutDirection = if (value) LAYOUT_DIRECTION_RTL else LAYOUT_DIRECTION_LTR
|
||||
}
|
||||
get() = layoutDirection == LAYOUT_DIRECTION_RTL
|
||||
}
|
@ -33,6 +33,7 @@ import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.Viewer
|
||||
import eu.kanade.tachiyomi.util.chapter.removeDuplicates
|
||||
import eu.kanade.tachiyomi.util.editCover
|
||||
import eu.kanade.tachiyomi.util.lang.byteSize
|
||||
@ -396,6 +397,14 @@ class ReaderViewModel(
|
||||
eventChannel.trySend(Event.ReloadViewerChapters)
|
||||
}
|
||||
|
||||
fun onViewerLoaded(viewer: Viewer?) {
|
||||
mutableState.update {
|
||||
it.copy(
|
||||
viewer = viewer,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called every time a page changes on the reader. Used to mark the flag of chapters being
|
||||
* read, update tracking services, enqueue downloaded chapter deletion, and updating the active chapter if this
|
||||
@ -881,7 +890,15 @@ class ReaderViewModel(
|
||||
val viewerChapters: ViewerChapters? = null,
|
||||
val isLoadingAdjacentChapter: Boolean = false,
|
||||
val currentPage: Int = -1,
|
||||
)
|
||||
|
||||
/**
|
||||
* Viewer used to display the pages (pager, webtoon, ...).
|
||||
*/
|
||||
val viewer: Viewer? = null,
|
||||
) {
|
||||
val totalPages: Int
|
||||
get() = viewerChapters?.currChapter?.pages?.size ?: -1
|
||||
}
|
||||
|
||||
sealed class Event {
|
||||
object ReloadViewerChapters : Event()
|
||||
|
@ -34,7 +34,7 @@ class ReaderReadingModeSettings @JvmOverloads constructor(context: Context, attr
|
||||
|
||||
initGeneralPreferences()
|
||||
|
||||
when ((context as ReaderActivity).viewer) {
|
||||
when ((context as ReaderActivity).viewModel.state.value.viewer) {
|
||||
is PagerViewer -> initPagerPreferences()
|
||||
is WebtoonViewer -> initWebtoonPreferences()
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.Viewer
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.L2RPagerViewer
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.VerticalPagerViewer
|
||||
@ -31,7 +31,7 @@ enum class ReadingModeType(val prefValue: Int, @StringRes val stringRes: Int, @D
|
||||
|
||||
fun fromSpinner(position: Int?) = values().find { value -> value.prefValue == position } ?: DEFAULT
|
||||
|
||||
fun toViewer(preference: Int?, activity: ReaderActivity): BaseViewer {
|
||||
fun toViewer(preference: Int?, activity: ReaderActivity): Viewer {
|
||||
return when (fromPreference(preference)) {
|
||||
LEFT_TO_RIGHT -> L2RPagerViewer(activity)
|
||||
RIGHT_TO_LEFT -> R2LPagerViewer(activity)
|
||||
|
@ -9,7 +9,7 @@ import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
|
||||
/**
|
||||
* Interface for implementing a viewer.
|
||||
*/
|
||||
interface BaseViewer {
|
||||
interface Viewer {
|
||||
|
||||
/**
|
||||
* Returns the view this viewer uses.
|
@ -17,7 +17,7 @@ import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
|
||||
import eu.kanade.tachiyomi.ui.reader.model.InsertPage
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.Viewer
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation.NavigationRegion
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.cancel
|
||||
@ -26,10 +26,10 @@ import uy.kohesive.injekt.injectLazy
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* Implementation of a [BaseViewer] to display pages with a [ViewPager].
|
||||
* Implementation of a [Viewer] to display pages with a [ViewPager].
|
||||
*/
|
||||
@Suppress("LeakingThis")
|
||||
abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
|
||||
abstract class PagerViewer(val activity: ReaderActivity) : Viewer {
|
||||
|
||||
val downloadManager: DownloadManager by injectLazy()
|
||||
|
||||
|
@ -18,7 +18,7 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||
import eu.kanade.tachiyomi.ui.reader.model.StencilPage
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.Viewer
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation.NavigationRegion
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.cancel
|
||||
@ -30,9 +30,9 @@ import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* Implementation of a [BaseViewer] to display pages with a [RecyclerView].
|
||||
* Implementation of a [Viewer] to display pages with a [RecyclerView].
|
||||
*/
|
||||
class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = true) : BaseViewer {
|
||||
class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = true) : Viewer {
|
||||
|
||||
val downloadManager: DownloadManager by injectLazy()
|
||||
|
||||
|
@ -12,7 +12,6 @@ import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.PowerManager
|
||||
import android.util.TypedValue
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.appcompat.view.ContextThemeWrapper
|
||||
@ -89,19 +88,6 @@ fun Context.hasPermission(permission: String) = PermissionChecker.checkSelfPermi
|
||||
return color
|
||||
}
|
||||
|
||||
@ColorInt fun Context.getThemeColor(attr: Int): Int {
|
||||
val tv = TypedValue()
|
||||
return if (this.theme.resolveAttribute(attr, tv, true)) {
|
||||
if (tv.resourceId != 0) {
|
||||
getColor(tv.resourceId)
|
||||
} else {
|
||||
tv.data
|
||||
}
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
val Context.powerManager: PowerManager
|
||||
get() = getSystemService()!!
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/black"
|
||||
android:pathData="M6,18l8.5,-6L6,6v12zM16,6v12h2V6h-2z" />
|
||||
</vector>
|
@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/black"
|
||||
android:pathData="M6,6h2v12L6,18zM9.5,12l8.5,6L18,6z" />
|
||||
</vector>
|
@ -59,82 +59,12 @@
|
||||
android:layout_gravity="bottom"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
<androidx.compose.ui.platform.ComposeView
|
||||
android:id="@+id/reader_nav"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layoutDirection="ltr"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/left_chapter"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:contentDescription="@string/action_previous_chapter"
|
||||
android:padding="@dimen/screen_edge_margin"
|
||||
app:srcCompat="@drawable/ic_skip_previous_24dp"
|
||||
app:tint="?attr/colorOnSurface" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/reader_seekbar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:clickable="true"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
tools:ignore="KeyboardInaccessibleWidget">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/left_page_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:minWidth="32dp"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:textSize="15sp"
|
||||
tools:text="1" />
|
||||
|
||||
<!--
|
||||
Wonky way of setting height due to issues with horizontally centering the thumb in Android 5.
|
||||
See https://stackoverflow.com/questions/15701767/android-thumb-is-not-centered-in-seekbar
|
||||
-->
|
||||
<eu.kanade.tachiyomi.ui.reader.ReaderSlider
|
||||
android:id="@+id/page_slider"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:maxHeight="?attr/actionBarSize"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
app:tickVisible="true"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/right_page_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:minWidth="32dp"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:textSize="15sp"
|
||||
tools:text="15" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/right_chapter"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:contentDescription="@string/action_next_chapter"
|
||||
android:padding="@dimen/screen_edge_margin"
|
||||
app:srcCompat="@drawable/ic_skip_next_24dp"
|
||||
app:tint="?attr/colorOnSurface" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layoutDirection="ltr" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/toolbar_bottom"
|
||||
|
Loading…
Reference in New Issue
Block a user