Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation
import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode
import eu.kanade.tachiyomi.ui.reader.viewer.Viewer
import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer
import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer
import tachiyomi.presentation.core.components.material.padding

private val readerBarsSlideAnimationSpec = tween<IntOffset>(200)
Expand Down Expand Up @@ -65,7 +66,7 @@ fun ReaderAppBars(
onClickCropBorder: () -> Unit,
onClickSettings: () -> Unit,
) {
val isRtl = viewer is R2LPagerViewer
val isRtl = viewer is R2LPagerViewer || (viewer is WebtoonViewer && viewer.isRightToLeft)
val backgroundColor = MaterialTheme.colorScheme
.surfaceColorAtElevation(3.dp)
.copy(alpha = if (isSystemInDarkTheme()) 0.9f else 0.95f)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,20 @@ enum class ReadingMode(
Direction.Vertical,
ViewerType.Webtoon,
),
WEBTOON_HORIZONTAL_RTL(
MR.strings.webtoon_horizontal_rtl_plus_viewer,
R.drawable.ic_reader_webtoon_horizontal_rtl_24dp,
0x00000006,
Direction.Horizontal,
ViewerType.Webtoon,
),
WEBTOON_HORIZONTAL_LTR(
MR.strings.webtoon_horizontal_ltr_plus_viewer,
R.drawable.ic_reader_webtoon_horizontal_ltr_24dp,
0x00000007,
Direction.Horizontal,
ViewerType.Webtoon,
),
;

companion object {
Expand All @@ -72,6 +86,8 @@ enum class ReadingMode(
RIGHT_TO_LEFT -> R2LPagerViewer(activity)
VERTICAL -> VerticalPagerViewer(activity)
WEBTOON -> WebtoonViewer(activity)
WEBTOON_HORIZONTAL_RTL -> WebtoonViewer(activity, isHorizontal = true, isRightToLeft = true)
WEBTOON_HORIZONTAL_LTR -> WebtoonViewer(activity, isHorizontal = true)
CONTINUOUS_VERTICAL -> WebtoonViewer(activity, isContinuous = false)
DEFAULT -> throw IllegalStateException("Preference value must be resolved: $preference")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ class WebtoonPageHolder(
}

private fun refreshLayoutParams() {
frame.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT).apply {
val width = if (viewer.isHorizontal) WRAP_CONTENT else MATCH_PARENT
val height = if (viewer.isHorizontal) MATCH_PARENT else WRAP_CONTENT

frame.layoutParams = FrameLayout.LayoutParams(width, height).apply {
if (!viewer.isContinuous) {
bottomMargin = 15.dpToPx
}
Expand Down Expand Up @@ -201,7 +204,11 @@ class WebtoonPageHolder(
isAnimated,
ReaderPageImageView.Config(
zoomDuration = viewer.config.doubleTapAnimDuration,
minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_FIT_WIDTH,
minimumScaleType = if (viewer.isHorizontal) {
SubsamplingScaleImageView.SCALE_TYPE_FIT_HEIGHT
} else {
SubsamplingScaleImageView.SCALE_TYPE_FIT_WIDTH
},
cropBorders = viewer.config.imageCropBorders,
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class WebtoonRecyclerView @JvmOverloads constructor(
var originalHeight = 0
private set
private var heightSet = false
var originalWidth = 0
private set
private var widthSet = false
private var firstVisibleItemPosition = 0
private var lastVisibleItemPosition = 0
private var currentScale = DEFAULT_RATE
Expand All @@ -55,9 +58,15 @@ class WebtoonRecyclerView @JvmOverloads constructor(
private var isManuallyScrolling = false
private var tapDuringManualScroll = false

var isHorizontal = false

override fun onMeasure(widthSpec: Int, heightSpec: Int) {
halfWidth = MeasureSpec.getSize(widthSpec) / 2
halfHeight = MeasureSpec.getSize(heightSpec) / 2
if (!widthSet) {
originalWidth = MeasureSpec.getSize(widthSpec)
widthSet = true
}
if (!heightSet) {
originalHeight = MeasureSpec.getSize(heightSpec)
heightSet = true
Expand Down Expand Up @@ -97,7 +106,7 @@ class WebtoonRecyclerView @JvmOverloads constructor(

private fun getPositionX(positionX: Float): Float {
if (currentScale < 1) {
return 0f
return (originalWidth / 2 - halfWidth).toFloat()
}
val maxPositionX = halfWidth * (currentScale - 1)
return positionX.coerceIn(-maxPositionX, maxPositionX)
Expand Down Expand Up @@ -193,11 +202,19 @@ class WebtoonRecyclerView @JvmOverloads constructor(

setScaleRate(currentScale)

layoutParams.height = if (currentScale < 1) {
(originalHeight / currentScale).toInt()
if (currentScale < 1) {
if (isHorizontal) {
layoutParams.width = (originalWidth / currentScale).toInt()
layoutParams.height = originalHeight
} else {
layoutParams.height = (originalHeight / currentScale).toInt()
layoutParams.width = originalWidth
}
} else {
originalHeight
layoutParams.width = originalWidth
layoutParams.height = originalHeight
}
halfWidth = layoutParams.width / 2
halfHeight = layoutParams.height / 2

if (currentScale != DEFAULT_RATE) {
Expand Down Expand Up @@ -245,8 +262,10 @@ class WebtoonRecyclerView @JvmOverloads constructor(
if (!isZooming && doubleTapZoom) {
if (scaleX != DEFAULT_RATE) {
zoom(currentScale, DEFAULT_RATE, x, 0f, y, 0f)
layoutParams.width = originalWidth
layoutParams.height = originalHeight
halfHeight = layoutParams.height / 2
halfWidth = originalWidth / 2
halfHeight = originalHeight / 2
requestLayout()
} else {
val toScale = 2f
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ import kotlin.math.min
/**
* Implementation of a [Viewer] to display pages with a [RecyclerView].
*/
class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = true) : Viewer {
class WebtoonViewer(
val activity: ReaderActivity,
val isContinuous: Boolean = true,
val isHorizontal: Boolean = false,
val isRightToLeft: Boolean = false,
) : Viewer {

val downloadManager: DownloadManager by injectLazy()

Expand All @@ -50,12 +55,21 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
/**
* Distance to scroll when the user taps on one side of the recycler view.
*/
private val scrollDistance = activity.resources.displayMetrics.heightPixels * 3 / 4
private val scrollDistance = if (isHorizontal) {
activity.resources.displayMetrics.widthPixels * 3 / 4
} else {
activity.resources.displayMetrics.heightPixels * 3 / 4
}

/**
* Layout manager of the recycler view.
*/
private val layoutManager = WebtoonLayoutManager(activity, scrollDistance)
private val layoutManager = WebtoonLayoutManager(activity, scrollDistance).apply {
orientation = if (isHorizontal) RecyclerView.HORIZONTAL else RecyclerView.VERTICAL
if (isHorizontal && isRightToLeft) {
reverseLayout = true
}
}

/**
* Configuration used by this viewer, like allow taps, or crop image borders.
Expand All @@ -79,6 +93,7 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
.threshold

init {
recycler.isHorizontal = isHorizontal
recycler.setItemViewCacheSize(RECYCLER_VIEW_CACHE_SIZE)
recycler.isVisible = false // Don't let the recycler layout yet
recycler.layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
Expand Down Expand Up @@ -283,21 +298,25 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
* Scrolls up by [scrollDistance].
*/
private fun scrollUp() {
val dx = if (isHorizontal) -scrollDistance else 0
val dy = if (isHorizontal) 0 else -scrollDistance
if (config.usePageTransitions) {
recycler.smoothScrollBy(0, -scrollDistance)
recycler.smoothScrollBy(dx, dy)
} else {
recycler.scrollBy(0, -scrollDistance)
recycler.scrollBy(dx, dy)
}
}

/**
* Scrolls down by [scrollDistance].
*/
private fun scrollDown() {
val dx = if (isHorizontal) scrollDistance else 0
val dy = if (isHorizontal) 0 else scrollDistance
if (config.usePageTransitions) {
recycler.smoothScrollBy(0, scrollDistance)
recycler.smoothScrollBy(dx, dy)
} else {
recycler.scrollBy(0, scrollDistance)
recycler.scrollBy(dx, dy)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:pivotX="12"
android:pivotY="12"
android:rotation="-90"
android:scaleX="0.65"
android:scaleY="0.65">
<path
android:fillColor="#000"
android:pathData="M11.992,19l3,-3l-2,0l0,-11l-2,0l0,11l-2,0l3,3z" />
</group>
<path
android:fillColor="#000"
android:pathData="M17,1L7,1A2.0059,2.0059 0,0 0,5 3L5,21a2.0059,2.0059 0,0 0,2 2L17,23a2.0059,2.0059 0,0 0,2 -2L19,3A2.0059,2.0059 0,0 0,17 1ZM17,21L7,21L7,3L17,3Z" />
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:pivotX="12"
android:pivotY="12"
android:rotation="90"
android:scaleX="0.65"
android:scaleY="0.65">
<path
android:fillColor="#000"
android:pathData="M11.992,19l3,-3l-2,0l0,-11l-2,0l0,11l-2,0l3,3z" />
</group>
<path
android:fillColor="#000"
android:pathData="M17,1L7,1A2.0059,2.0059 0,0 0,5 3L5,21a2.0059,2.0059 0,0 0,2 2L17,23a2.0059,2.0059 0,0 0,2 -2L19,3A2.0059,2.0059 0,0 0,17 1ZM17,21L7,21L7,3L17,3Z" />
</vector>
2 changes: 2 additions & 0 deletions i18n/src/commonMain/moko-resources/base/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,8 @@
<string name="vertical_viewer">Paged (vertical)</string>
<string name="webtoon_viewer">Long strip</string>
<string name="vertical_plus_viewer">Long strip with gaps</string>
<string name="webtoon_horizontal_rtl_plus_viewer">Horizontal long strip (right to left)</string>
<string name="webtoon_horizontal_ltr_plus_viewer">Horizontal long strip (left to right)</string>
<string name="pager_viewer">Paged</string>
<string name="pref_viewer_nav">Tap zones</string>
<string name="pref_image_scale_type">Scale type</string>
Expand Down