Added option to change navigation type for reader

Taken from upstream with some tweaks:
*Removed always show at start option
*"Left" and "Right" in reader overlay now say "Next" or "Previous" in LRNav
*Changing Inversion also shows navigation overlay
*Show new user the nav overlay the first time for both paged and webview (since j2k has auto webtoon)

Also unrelated, changed "page transitions" to "animate page transitions"

Co-Authored-By: arkon <4098258+arkon@users.noreply.github.com>
This commit is contained in:
Jays2Kings 2021-03-24 20:13:14 -04:00
parent 380b609847
commit 999247d7dd
59 changed files with 859 additions and 174 deletions

View File

@ -53,6 +53,17 @@ object PreferenceKeys {
const val readWithVolumeKeysInverted = "reader_volume_keys_inverted"
const val navigationModePager = "reader_navigation_mode_pager"
const val navigationModeWebtoon = "reader_navigation_mode_webtoon"
const val pagerNavInverted = "reader_tapping_inverted"
const val webtoonNavInverted = "reader_tapping_inverted_webtoon"
const val showNavigationOverlayNewUser = "reader_navigation_overlay_new_user"
const val showNavigationOverlayNewUserWebtoon = "reader_navigation_overlay_new_user_webtoon"
const val webtoonSidePadding = "webtoon_side_padding"
const val webtoonEnableZoomOut = "webtoon_enable_zoom_out"

View File

@ -10,6 +10,7 @@ import com.f2prateek.rx.preferences.RxSharedPreferences
import com.tfcporciuncula.flow.FlowSharedPreferences
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.onEach
import java.io.File
@ -130,6 +131,18 @@ class PreferencesHelper(val context: Context) {
fun readWithVolumeKeysInverted() = flowPrefs.getBoolean(Keys.readWithVolumeKeysInverted, false)
fun navigationModePager() = flowPrefs.getInt(Keys.navigationModePager, 0)
fun navigationModeWebtoon() = flowPrefs.getInt(Keys.navigationModeWebtoon, 0)
fun pagerNavInverted() = flowPrefs.getEnum(Keys.pagerNavInverted, ViewerNavigation.TappingInvertMode.NONE)
fun webtoonNavInverted() = flowPrefs.getEnum(Keys.webtoonNavInverted, ViewerNavigation.TappingInvertMode.NONE)
fun showNavigationOverlayNewUser() = flowPrefs.getBoolean(Keys.showNavigationOverlayNewUser, true)
fun showNavigationOverlayNewUserWebtoon() = flowPrefs.getBoolean(Keys.showNavigationOverlayNewUserWebtoon, true)
fun updateOnlyNonCompleted() = prefs.getBoolean(Keys.updateOnlyNonCompleted, false)
fun autoUpdateTrack() = prefs.getBoolean(Keys.autoUpdateTrack, true)

View File

@ -534,6 +534,7 @@ class ReaderActivity :
viewer = newViewer
viewer_container.addView(newViewer.getView())
navigation_overlay.isLTR = !(viewer is L2RPagerViewer)
viewer_container.setBackgroundColor(
if (viewer is WebtoonViewer) {
Color.BLACK

View File

@ -0,0 +1,130 @@
package eu.kanade.tachiyomi.ui.reader
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewPropertyAnimator
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
import kotlin.math.abs
class ReaderNavigationOverlayView(context: Context, attributeSet: AttributeSet) : View(context, attributeSet) {
private var viewPropertyAnimator: ViewPropertyAnimator? = null
private var navigation: ViewerNavigation? = null
var isLTR = true
fun setNavigation(navigation: ViewerNavigation, showOnStart: Boolean) {
if (!showOnStart && (this.navigation == null || this.navigation === navigation) && !forceShowOverlay) {
if (this.navigation == null) {
this.navigation = navigation
isVisible = false
}
return
}
forceShowOverlay = false
this.navigation = navigation
invalidate()
if (isVisible) return
viewPropertyAnimator = animate()
.alpha(1f)
.setDuration(FADE_DURATION)
.withStartAction {
isVisible = true
}
.withEndAction {
viewPropertyAnimator = null
}
viewPropertyAnimator?.start()
}
private val regionPaint = Paint()
private val textPaint = Paint().apply {
textAlign = Paint.Align.CENTER
color = Color.WHITE
textSize = 64f
}
private val textBorderPaint = Paint().apply {
textAlign = Paint.Align.CENTER
color = Color.BLACK
textSize = 64f
style = Paint.Style.STROKE
strokeWidth = 8f
}
override fun onDraw(canvas: Canvas?) {
if (navigation == null) return
navigation?.regions?.forEach {
val region = it.invert(navigation!!.invertMode)
val rect = region.rectF
canvas?.save()
// Scale rect from 1f,1f to screen width and height
canvas?.scale(width.toFloat(), height.toFloat())
val directionalRegion = region.type.directionalRegion(isLTR)
regionPaint.color = ContextCompat.getColor(context, directionalRegion.colorRes)
canvas?.drawRect(rect, regionPaint)
canvas?.restore()
// Don't want scale anymore because it messes with drawText
canvas?.save()
// Translate origin to rect start (left, top)
canvas?.translate((width * rect.left), (height * rect.top))
// Calculate center of rect width on screen
val x = width * (abs(rect.left - rect.right) / 2)
// Calculate center of rect height on screen
val y = height * (abs(rect.top - rect.bottom) / 2)
canvas?.drawText(context.getString(directionalRegion.nameRes), x, y, textBorderPaint)
canvas?.drawText(context.getString(directionalRegion.nameRes), x, y, textPaint)
canvas?.restore()
}
}
override fun performClick(): Boolean {
super.performClick()
if (viewPropertyAnimator == null && isVisible) {
viewPropertyAnimator = animate()
.alpha(0f)
.setDuration(FADE_DURATION)
.withEndAction {
isVisible = false
viewPropertyAnimator = null
}
viewPropertyAnimator?.start()
}
return true
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
// Hide overlay if user start tapping or swiping
performClick()
return super.onTouchEvent(event)
}
companion object {
var forceShowOverlay = false
}
}
private const val FADE_DURATION = 1000L

View File

@ -24,7 +24,7 @@ class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: Attri
initPagerPreferences()
}
}
viewer_series.setSelection((context as? ReaderActivity)?.presenter?.manga?.viewer ?: 0)
viewer_series.setSelection((context as? ReaderActivity)?.presenter?.getMangaViewer() ?: 0)
rotation_mode.bindToPreference(preferences.rotation(), 1)
background_color.bindToPreference(preferences.readerTheme(), 0)
show_page_number.bindToPreference(preferences.showPageNumber())

View File

@ -4,6 +4,7 @@ import android.content.Context
import android.util.AttributeSet
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.ui.reader.ReaderNavigationOverlayView
import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.util.view.visibleIf
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
@ -17,6 +18,10 @@ class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: Attribu
zoom_start.bindToPreference(preferences.zoomStart(), 1)
crop_borders.bindToPreference(preferences.cropBorders())
page_transitions.bindToPreference(preferences.pageTransitions())
pager_nav.bindToPreference(preferences.navigationModePager())
pager_invert.bindToPreference(preferences.pagerNavInverted()) {
ReaderNavigationOverlayView.forceShowOverlay = true
}
val mangaViewer = (context as ReaderActivity).presenter.getMangaViewer()
val isWebtoonView = mangaViewer == ReaderActivity.WEBTOON || mangaViewer == ReaderActivity.VERTICAL_PLUS
@ -24,6 +29,10 @@ class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: Attribu
crop_borders_webtoon.bindToPreference(if (hasMargins) preferences.cropBorders() else preferences.cropBordersWebtoon())
webtoon_side_padding.bindToIntPreference(preferences.webtoonSidePadding(), R.array.webtoon_side_padding_values)
webtoon_enable_zoom_out.bindToPreference(preferences.webtoonEnableZoomOut())
webtoon_nav.bindToPreference(preferences.navigationModeWebtoon())
webtoon_invert.bindToPreference(preferences.webtoonNavInverted()) {
ReaderNavigationOverlayView.forceShowOverlay = true
}
updatePagedGroup(!isWebtoonView)
}
@ -36,8 +45,8 @@ class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: Attribu
updatePagedGroup(!isWebtoonView)
}
fun updatePagedGroup(show: Boolean) {
listOf(scale_type, zoom_start, crop_borders, page_transitions).forEach { it.visibleIf(show) }
listOf(crop_borders_webtoon, webtoon_side_padding, webtoon_enable_zoom_out).forEach { it.visibleIf(!show) }
private fun updatePagedGroup(show: Boolean) {
listOf(scale_type, zoom_start, crop_borders, page_transitions, pager_nav, pager_invert).forEach { it.visibleIf(show) }
listOf(crop_borders_webtoon, webtoon_side_padding, webtoon_enable_zoom_out, webtoon_nav, webtoon_invert).forEach { it.visibleIf(!show) }
}
}

View File

@ -21,26 +21,28 @@ class ReaderSpinnerView @JvmOverloads constructor(context: Context, attrs: Attri
private var selectedPosition = 0
private var pref: Preference<Int>? = null
private var prefOffset = 0
private var popup:PopupMenu? = null
var onItemSelectedListener: ((Int) -> Unit)? = null
set(value) {
field = value
if (value != null) {
val popup = makeSettingsPopup()
setOnTouchListener(popup.dragToOpenListener)
popup = makeSettingsPopup()
setOnTouchListener(popup?.dragToOpenListener)
setOnClickListener {
popup.show()
popup?.show()
}
}
}
init {
inflate(context, R.layout.reader_preference, this)
val a = context.obtainStyledAttributes(attrs, R.styleable.ReaderPreferenceView, 0, 0)
val a = context.obtainStyledAttributes(attrs, R.styleable.ReaderSpinnerView, 0, 0)
val str = a.getString(R.styleable.ReaderPreferenceView_title) ?: ""
val str = a.getString(R.styleable.ReaderSpinnerView_title) ?: ""
title_view.text = str
val entries = (a.getTextArray(R.styleable.ReaderPreferenceView_android_entries) ?: emptyArray()).map { it.toString() }
val entries = (a.getTextArray(R.styleable.ReaderSpinnerView_android_entries) ?: emptyArray()).map { it.toString() }
this.entries = entries
detail_view.text = entries.firstOrNull().orEmpty()
@ -49,15 +51,39 @@ class ReaderSpinnerView @JvmOverloads constructor(context: Context, attrs: Attri
}
fun setSelection(selection: Int) {
popup?.menu?.get(selectedPosition)?.isCheckable = false
popup?.menu?.get(selectedPosition)?.isChecked = false
selectedPosition = selection
detail_view.text = entries.getOrNull(selection).orEmpty()
popup?.menu?.get(selectedPosition)?.isCheckable = true
popup?.menu?.get(selectedPosition)?.isChecked = true
}
fun bindToPreference(pref: Preference<Int>, offset: Int = 0, block: ((Int) -> Unit)? = null) {
setSelection(pref.get() - offset)
this.pref = pref
prefOffset = offset
val popup = makeSettingsPopup(pref, prefOffset, block)
popup = makeSettingsPopup(pref, prefOffset, block)
setOnTouchListener(popup?.dragToOpenListener)
setOnClickListener {
popup?.show()
}
}
inline fun <reified T : Enum<T>> bindToPreference(pref: Preference<T>) {
val enumConstants = T::class.java.enumConstants
enumConstants?.indexOf(pref.get())?.let { setSelection(it) }
val popup = makeSettingsPopup(pref)
setOnTouchListener(popup.dragToOpenListener)
setOnClickListener {
popup.show()
}
}
inline fun <reified T : Enum<T>> bindToPreference(pref: Preference<T>, crossinline block: ((Int) -> Unit)) {
val enumConstants = T::class.java.enumConstants
enumConstants?.indexOf(pref.get())?.let { setSelection(it) }
val popup = makeSettingsPopup(pref, block)
setOnTouchListener(popup.dragToOpenListener)
setOnClickListener {
popup.show()
@ -69,13 +95,45 @@ class ReaderSpinnerView @JvmOverloads constructor(context: Context, attrs: Attri
this.pref = pref
prefOffset = 0
val intValues = resources.getStringArray(intValuesResource).map { it.toIntOrNull() }
val popup = makeSettingsPopup(pref, intValues, block)
setOnTouchListener(popup.dragToOpenListener)
popup = makeSettingsPopup(pref, intValues, block)
setOnTouchListener(popup?.dragToOpenListener)
setOnClickListener {
popup.show()
popup?.show()
}
}
inline fun <reified T : Enum<T>> makeSettingsPopup(preference: Preference<T>): PopupMenu {
val popup = popup()
// Set a listener so we are notified if a menu item is clicked
popup.setOnMenuItemClickListener { menuItem ->
val pos = popup.menuClicked(menuItem)
onItemSelectedListener?.invoke(pos)
true
}
// Set a listener so we are notified if a menu item is clicked
popup.setOnMenuItemClickListener { menuItem ->
val enumConstants = T::class.java.enumConstants
val pos = popup.menuClicked(menuItem)
enumConstants?.get(pos)?.let { preference.set(it) }
true
}
return popup
}
inline fun <reified T : Enum<T>> makeSettingsPopup(preference: Preference<T>, crossinline block: ((Int) -> Unit)): PopupMenu {
val popup = popup()
// Set a listener so we are notified if a menu item is clicked
popup.setOnMenuItemClickListener { menuItem ->
val enumConstants = T::class.java.enumConstants
val pos = popup.menuClicked(menuItem)
enumConstants?.get(pos)?.let { preference.set(it) }
block(pos)
true
}
return popup
}
private fun makeSettingsPopup(preference: Preference<Int>, intValues: List<Int?>, block: ((Int) -> Unit)? = null): PopupMenu {
val popup = popup()
// Set a listener so we are notified if a menu item is clicked
@ -112,7 +170,7 @@ class ReaderSpinnerView @JvmOverloads constructor(context: Context, attrs: Attri
return popup
}
private fun PopupMenu.menuClicked(menuItem: MenuItem): Int {
fun PopupMenu.menuClicked(menuItem: MenuItem): Int {
val pos = menuItem.itemId
menu[selectedPosition].isCheckable = false
menu[selectedPosition].isChecked = false
@ -122,7 +180,7 @@ class ReaderSpinnerView @JvmOverloads constructor(context: Context, attrs: Attri
return pos
}
private fun popup(): PopupMenu {
fun popup(): PopupMenu {
val popup = PopupMenu(context, this, Gravity.END)
entries.forEachIndexed { index, entry ->
popup.menu.add(0, index, 0, entry)

View File

@ -17,12 +17,23 @@ abstract class ViewerConfig(preferences: PreferencesHelper) {
var imagePropertyChangedListener: (() -> Unit)? = null
var navigationModeChangedListener: (() -> Unit)? = null
var tappingEnabled = true
var tappingInverted = ViewerNavigation.TappingInvertMode.NONE
var doubleTapAnimDuration = 500
var volumeKeysEnabled = false
var volumeKeysInverted = false
var alwaysShowChapterTransition = true
var navigationOverlayForNewUser = false
var navigationMode = 0
protected set
abstract var navigator: ViewerNavigation
protected set
init {
preferences.readWithTapping()
.register({ tappingEnabled = it })
@ -51,4 +62,8 @@ abstract class ViewerConfig(preferences: PreferencesHelper) {
}
.launchIn(scope)
}
protected abstract fun defaultNavigation(): ViewerNavigation
abstract fun updateNavigation(navigationMode: Int)
}

View File

@ -0,0 +1,72 @@
package eu.kanade.tachiyomi.ui.reader.viewer
import android.graphics.PointF
import android.graphics.RectF
import androidx.annotation.StringRes
import eu.kanade.tachiyomi.R
abstract class ViewerNavigation {
sealed class NavigationRegion(@StringRes val nameRes: Int, val colorRes: Int) {
object MENU : NavigationRegion(R.string.menu, R.color.navigation_menu)
object PREV : NavigationRegion(R.string.previous, R.color.navigation_prev)
object NEXT : NavigationRegion(R.string.next, R.color.navigation_next)
object LEFT : NavigationRegion(R.string.left, R.color.navigation_left)
object RIGHT : NavigationRegion(R.string.right, R.color.navigation_right)
fun directionalRegion(LTR: Boolean): NavigationRegion {
return if (this === LEFT || this === RIGHT) {
if (if (LTR) this === LEFT else this === RIGHT) NEXT else PREV
}
else this
}
}
data class Region(
val rectF: RectF,
val type: NavigationRegion
) {
fun invert(invertMode: TappingInvertMode): Region {
if (invertMode == TappingInvertMode.NONE) return this
return this.copy(
rectF = this.rectF.invert(invertMode)
)
}
}
private var constantMenuRegion: RectF = RectF(0f, 0f, 1f, 0.05f)
abstract var regions: List<Region>
var invertMode: TappingInvertMode = TappingInvertMode.NONE
fun getAction(pos: PointF): NavigationRegion {
val x = pos.x
val y = pos.y
val region = regions.map { it.invert(invertMode) }
.find { it.rectF.contains(x, y) }
return when {
region != null -> region.type
constantMenuRegion.contains(x, y) -> NavigationRegion.MENU
else -> NavigationRegion.MENU
}
}
enum class TappingInvertMode(val shouldInvertHorizontal: Boolean = false, val shouldInvertVertical: Boolean = false) {
NONE,
HORIZONTAL(shouldInvertHorizontal = true),
VERTICAL(shouldInvertVertical = true),
BOTH(shouldInvertHorizontal = true, shouldInvertVertical = true)
}
}
fun RectF.invert(invertMode: ViewerNavigation.TappingInvertMode): RectF {
val horizontal = invertMode.shouldInvertHorizontal
val vertical = invertMode.shouldInvertVertical
return when {
horizontal && vertical -> RectF(1f - this.right, 1f - this.bottom, 1f - this.left, 1f - this.top)
vertical -> RectF(this.left, 1f - this.bottom, this.right, 1f - this.top)
horizontal -> RectF(1f - this.right, this.top, 1f - this.left, this.bottom)
else -> this
}
}

View File

@ -0,0 +1,32 @@
package eu.kanade.tachiyomi.ui.reader.viewer.navigation
import android.graphics.RectF
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
/**
* Visualization of default state without any inversion
* +---+---+---+
* | N | N | N | P: Previous
* +---+---+---+
* | N | M | N | M: Menu
* +---+---+---+
* | N | P | N | N: Next
* +---+---+---+
*/
class EdgeNavigation : ViewerNavigation() {
override var regions: List<Region> = listOf(
Region(
rectF = RectF(0f, 0f, 0.33f, 1f),
type = NavigationRegion.NEXT
),
Region(
rectF = RectF(0.33f, 0.66f, 0.66f, 1f),
type = NavigationRegion.PREV
),
Region(
rectF = RectF(0.66f, 0f, 1f, 1f),
type = NavigationRegion.NEXT
),
)
}

View File

@ -0,0 +1,28 @@
package eu.kanade.tachiyomi.ui.reader.viewer.navigation
import android.graphics.RectF
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
/**
* Visualization of default state without any inversion
* +---+---+---+
* | M | M | M | P: Previous
* +---+---+---+
* | P | N | N | M: Menu
* +---+---+---+
* | P | N | N | N: Next
* +---+---+---+
*/
class KindlishNavigation : ViewerNavigation() {
override var regions: List<Region> = listOf(
Region(
rectF = RectF(0.33f, 0.33f, 1f, 1f),
type = NavigationRegion.NEXT
),
Region(
rectF = RectF(0f, 0.33f, 0.33f, 1f),
type = NavigationRegion.PREV
)
)
}

View File

@ -0,0 +1,36 @@
package eu.kanade.tachiyomi.ui.reader.viewer.navigation
import android.graphics.RectF
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
/**
* Visualization of default state without any inversion
* +---+---+---+
* | P | P | P | P: Previous
* +---+---+---+
* | P | M | N | M: Menu
* +---+---+---+
* | N | N | N | N: Next
* +---+---+---+
*/
open class LNavigation : ViewerNavigation() {
override var regions: List<Region> = listOf(
Region(
rectF = RectF(0f, 0.33f, 0.33f, 0.66f),
type = NavigationRegion.PREV
),
Region(
rectF = RectF(0f, 0f, 1f, 0.33f),
type = NavigationRegion.PREV
),
Region(
rectF = RectF(0.66f, 0.33f, 1f, 0.66f),
type = NavigationRegion.NEXT
),
Region(
rectF = RectF(0f, 0.66f, 1f, 1f),
type = NavigationRegion.NEXT
)
)
}

View File

@ -0,0 +1,28 @@
package eu.kanade.tachiyomi.ui.reader.viewer.navigation
import android.graphics.RectF
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
/**
* Visualization of default state without any inversion
* +---+---+---+
* | N | M | P | P: Move Right
* +---+---+---+
* | N | M | P | M: Menu
* +---+---+---+
* | N | M | P | N: Move Left
* +---+---+---+
*/
class RightAndLeftNavigation : ViewerNavigation() {
override var regions: List<Region> = listOf(
Region(
rectF = RectF(0f, 0f, 0.33f, 1f),
type = NavigationRegion.LEFT
),
Region(
rectF = RectF(0.66f, 0f, 1f, 1f),
type = NavigationRegion.RIGHT
),
)
}

View File

@ -2,6 +2,11 @@ package eu.kanade.tachiyomi.ui.reader.viewer.pager
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerConfig
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
import eu.kanade.tachiyomi.ui.reader.viewer.navigation.EdgeNavigation
import eu.kanade.tachiyomi.ui.reader.viewer.navigation.KindlishNavigation
import eu.kanade.tachiyomi.ui.reader.viewer.navigation.LNavigation
import eu.kanade.tachiyomi.ui.reader.viewer.navigation.RightAndLeftNavigation
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -33,6 +38,15 @@ class PagerConfig(private val viewer: PagerViewer, preferences: PreferencesHelpe
preferences.imageScaleType()
.register({ imageScaleType = it }, { imagePropertyChangedListener?.invoke() })
preferences.navigationModePager()
.register({ navigationMode = it }, { updateNavigation(navigationMode) })
preferences.pagerNavInverted()
.register({ tappingInverted = it }, {
navigator.invertMode = it
navigationModeChangedListener?.invoke()
})
preferences.zoomStart()
.register({ zoomTypeFromPreference(it) }, { imagePropertyChangedListener?.invoke() })
@ -41,6 +55,11 @@ class PagerConfig(private val viewer: PagerViewer, preferences: PreferencesHelpe
preferences.readerTheme()
.register({ readerTheme = it }, { imagePropertyChangedListener?.invoke() })
navigationOverlayForNewUser = preferences.showNavigationOverlayNewUser().get()
if (navigationOverlayForNewUser) {
preferences.showNavigationOverlayNewUser().set(false)
}
}
private fun zoomTypeFromPreference(value: Int) {
@ -60,6 +79,30 @@ class PagerConfig(private val viewer: PagerViewer, preferences: PreferencesHelpe
}
}
override var navigator: ViewerNavigation = defaultNavigation()
set(value) {
field = value.also { it.invertMode = this.tappingInverted }
}
override fun defaultNavigation(): ViewerNavigation {
return when (viewer) {
is VerticalPagerViewer -> LNavigation()
else -> RightAndLeftNavigation()
}
}
override fun updateNavigation(navigationMode: Int) {
navigator = when (navigationMode) {
0 -> defaultNavigation()
1 -> LNavigation()
2 -> KindlishNavigation()
3 -> EdgeNavigation()
4 -> RightAndLeftNavigation()
else -> defaultNavigation()
}
navigationModeChangedListener?.invoke()
}
enum class ZoomType {
Left, Center, Right
}

View File

@ -93,11 +93,11 @@ class PagerTransitionHolder(
textView.text = if (nextChapter != null) {
SpannableStringBuilder().apply {
append(context.getString(R.string.finished))
append(context.getString(R.string.finished_chapter))
setSpan(StyleSpan(Typeface.BOLD), 0, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
append("\n${transition.from.chapter.name}\n\n")
val currSize = length
append(context.getString(R.string.next))
append(context.getString(R.string.next_chapter))
setSpan(StyleSpan(Typeface.BOLD), currSize, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
append("\n${nextChapter.chapter.name}\n\n")
}
@ -118,11 +118,11 @@ class PagerTransitionHolder(
textView.text = if (prevChapter != null) {
SpannableStringBuilder().apply {
append(context.getString(R.string.current))
append(context.getString(R.string.current_chapter))
setSpan(StyleSpan(Typeface.BOLD), 0, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
append("\n${transition.from.chapter.name}\n\n")
val currSize = length
append(context.getString(R.string.previous))
append(context.getString(R.string.previous_chapter))
setSpan(StyleSpan(Typeface.BOLD), currSize, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
append("\n${prevChapter.chapter.name}\n\n")
}

View File

@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.ui.reader.viewer.pager
import android.graphics.PointF
import android.view.InputDevice
import android.view.KeyEvent
import android.view.MotionEvent
@ -12,8 +13,10 @@ import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
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.ViewerNavigation
import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.visible
import kotlinx.android.synthetic.main.reader_activity.*
import timber.log.Timber
/**
@ -81,18 +84,31 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
}
}
)
pager.tapListener = { event ->
val positionX = event.x
when {
positionX < pager.width * 0.33f && config.tappingEnabled -> moveLeft()
positionX > pager.width * 0.66f && config.tappingEnabled -> moveRight()
else -> activity.toggleMenu()
pager.tapListener = f@{ event ->
if (!config.tappingEnabled) {
activity.toggleMenu()
return@f
}
val pos = PointF(event.rawX / pager.width, event.rawY / pager.height)
val navigator = config.navigator
when (navigator.getAction(pos)) {
ViewerNavigation.NavigationRegion.MENU -> activity.toggleMenu()
ViewerNavigation.NavigationRegion.NEXT -> moveToNext()
ViewerNavigation.NavigationRegion.PREV -> moveToPrevious()
ViewerNavigation.NavigationRegion.RIGHT -> moveRight()
ViewerNavigation.NavigationRegion.LEFT -> moveLeft()
}
}
config.imagePropertyChangedListener = {
refreshAdapter()
}
config.navigationModeChangedListener = {
val showOnStart = config.navigationOverlayForNewUser
activity.navigation_overlay.setNavigation(config.navigator, showOnStart)
}
}
/**

View File

@ -2,6 +2,11 @@ package eu.kanade.tachiyomi.ui.reader.viewer.webtoon
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerConfig
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
import eu.kanade.tachiyomi.ui.reader.viewer.navigation.EdgeNavigation
import eu.kanade.tachiyomi.ui.reader.viewer.navigation.KindlishNavigation
import eu.kanade.tachiyomi.ui.reader.viewer.navigation.LNavigation
import eu.kanade.tachiyomi.ui.reader.viewer.navigation.RightAndLeftNavigation
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -21,9 +26,19 @@ class WebtoonConfig(preferences: PreferencesHelper = Injekt.get()) : ViewerConfi
var enableZoomOut = false
private set
var zoomPropertyChangedListener: ((Boolean) -> Unit)? = null
init {
preferences.navigationModeWebtoon()
.register({ navigationMode = it }, { updateNavigation(it) })
preferences.webtoonNavInverted()
.register({ tappingInverted = it }, {
navigator.invertMode = it
navigationModeChangedListener?.invoke()
})
preferences.cropBordersWebtoon()
.register({ webtoonCropBorders = it }, { imagePropertyChangedListener?.invoke() })
@ -35,5 +50,31 @@ class WebtoonConfig(preferences: PreferencesHelper = Injekt.get()) : ViewerConfi
preferences.webtoonEnableZoomOut()
.register({ enableZoomOut = it }, { zoomPropertyChangedListener?.invoke(it) })
navigationOverlayForNewUser = preferences.showNavigationOverlayNewUserWebtoon().get()
if (navigationOverlayForNewUser) {
preferences.showNavigationOverlayNewUserWebtoon().set(false)
}
}
override var navigator: ViewerNavigation = defaultNavigation()
set(value) {
field = value.also { it.invertMode = tappingInverted }
}
override fun defaultNavigation(): ViewerNavigation {
return LNavigation()
}
override fun updateNavigation(navigationMode: Int) {
this.navigator = when (navigationMode) {
0 -> defaultNavigation()
1 -> LNavigation()
2 -> KindlishNavigation()
3 -> EdgeNavigation()
4 -> RightAndLeftNavigation()
else -> defaultNavigation()
}
navigationModeChangedListener?.invoke()
}
}

View File

@ -95,11 +95,11 @@ class WebtoonTransitionHolder(
textView.text = if (nextChapter != null) {
SpannableStringBuilder().apply {
append(context.getString(R.string.finished))
append(context.getString(R.string.finished_chapter))
setSpan(StyleSpan(Typeface.BOLD), 0, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
append("\n${transition.from.chapter.name}\n\n")
val currSize = length
append(context.getString(R.string.next))
append(context.getString(R.string.next_chapter))
setSpan(StyleSpan(Typeface.BOLD), currSize, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
append("\n${nextChapter.chapter.name}\n\n")
}
@ -120,11 +120,11 @@ class WebtoonTransitionHolder(
textView.text = if (prevChapter != null) {
SpannableStringBuilder().apply {
append(context.getString(R.string.current))
append(context.getString(R.string.current_chapter))
setSpan(StyleSpan(Typeface.BOLD), 0, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
append("\n${transition.from.chapter.name}\n\n")
val currSize = length
append(context.getString(R.string.previous))
append(context.getString(R.string.previous_chapter))
setSpan(StyleSpan(Typeface.BOLD), currSize, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
append("\n${prevChapter.chapter.name}\n\n")
}

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.ui.reader.viewer.webtoon
import android.graphics.Color
import android.graphics.PointF
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
@ -13,7 +14,9 @@ import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
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.ViewerNavigation
import eu.kanade.tachiyomi.util.view.visible
import kotlinx.android.synthetic.main.reader_activity.*
import rx.subscriptions.CompositeSubscription
import timber.log.Timber
import kotlin.math.max
@ -95,15 +98,21 @@ class WebtoonViewer(val activity: ReaderActivity, val hasMargins: Boolean = fals
}
}
)
recycler.tapListener = { event ->
val positionX = event.rawX
val positionY = event.rawY
when {
positionY < recycler.height * 0.25 && config.tappingEnabled -> scrollUp()
positionY > recycler.height * 0.75 && config.tappingEnabled -> scrollDown()
positionX < recycler.width * 0.33 && config.tappingEnabled -> scrollUp()
positionX > recycler.width * 0.66 && config.tappingEnabled -> scrollDown()
else -> activity.toggleMenu()
recycler.tapListener = f@{ event ->
if (!config.tappingEnabled) {
activity.toggleMenu()
return@f
}
val pos = PointF(event.rawX / recycler.width, event.rawY / recycler.height)
if (!config.tappingEnabled) activity.toggleMenu()
else {
val navigator = config.navigator
when (navigator.getAction(pos)) {
ViewerNavigation.NavigationRegion.MENU -> activity.toggleMenu()
ViewerNavigation.NavigationRegion.NEXT, ViewerNavigation.NavigationRegion.RIGHT -> scrollDown()
ViewerNavigation.NavigationRegion.PREV, ViewerNavigation.NavigationRegion.LEFT -> scrollUp()
}
}
}
@ -115,6 +124,11 @@ class WebtoonViewer(val activity: ReaderActivity, val hasMargins: Boolean = fals
frame.enableZoomOut = it
}
config.navigationModeChangedListener = {
val showOnStart = config.navigationOverlayForNewUser
activity.navigation_overlay.setNavigation(config.navigator, showOnStart)
}
frame.layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
frame.addView(recycler)
}

View File

@ -4,6 +4,7 @@ import android.os.Build
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
import kotlinx.coroutines.flow.launchIn
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
@ -43,7 +44,7 @@ class SettingsReaderController : SettingsController() {
}
switchPreference {
key = Keys.enableTransitions
titleRes = R.string.page_transitions
titleRes = R.string.animate_page_transitions
defaultValue = true
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@ -124,6 +125,38 @@ class SettingsReaderController : SettingsController() {
preferenceCategory {
titleRes = R.string.paged
intListPreference(activity) {
key = Keys.navigationModePager
titleRes = R.string.nav_layout
entries = context.resources.getStringArray(R.array.reader_nav).also { values ->
entryRange = 0..values.size
}.toList()
defaultValue = "0"
summary = "%s"
preferences.readWithTapping().asImmediateFlow { isVisible = it }.launchIn(viewScope)
}
listPreference(activity) {
key = Keys.pagerNavInverted
titleRes = R.string.invert_tapping
entriesRes = arrayOf(
R.string.none,
R.string.horizontally,
R.string.vertically,
R.string.both_axes
)
entryValues = listOf(
ViewerNavigation.TappingInvertMode.NONE.name,
ViewerNavigation.TappingInvertMode.HORIZONTAL.name,
ViewerNavigation.TappingInvertMode.VERTICAL.name,
ViewerNavigation.TappingInvertMode.BOTH.name
)
defaultValue = ViewerNavigation.TappingInvertMode.NONE.name
summary = "%s"
preferences.readWithTapping().asImmediateFlow { isVisible = it }.launchIn(viewScope)
}
intListPreference(activity) {
key = Keys.imageScaleType
titleRes = R.string.scale_type
@ -159,6 +192,38 @@ class SettingsReaderController : SettingsController() {
preferenceCategory {
titleRes = R.string.webtoon
intListPreference(activity) {
key = Keys.navigationModeWebtoon
titleRes = R.string.nav_layout
entries = context.resources.getStringArray(R.array.reader_nav).also { values ->
entryRange = 0..values.size
}.toList()
defaultValue = "0"
summary = "%s"
preferences.readWithTapping().asImmediateFlow { isVisible = it }.launchIn(viewScope)
}
listPreference(activity) {
key = Keys.webtoonNavInverted
titleRes = R.string.invert_tapping
entriesRes = arrayOf(
R.string.none,
R.string.horizontally,
R.string.vertically,
R.string.both_axes
)
entryValues = listOf(
ViewerNavigation.TappingInvertMode.NONE.name,
ViewerNavigation.TappingInvertMode.HORIZONTAL.name,
ViewerNavigation.TappingInvertMode.VERTICAL.name,
ViewerNavigation.TappingInvertMode.BOTH.name
)
defaultValue = ViewerNavigation.TappingInvertMode.NONE.name
summary = "%s"
preferences.readWithTapping().asImmediateFlow { isVisible = it }.launchIn(viewScope)
}
switchPreference {
key = Keys.cropBordersWebtoon
titleRes = R.string.crop_borders

View File

@ -34,6 +34,12 @@
android:layout_height="match_parent"
android:visibility="gone" />
<eu.kanade.tachiyomi.ui.reader.ReaderNavigationOverlayView
android:id="@+id/navigation_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<FrameLayout
android:id="@+id/reader_menu"
android:layout_width="match_parent"

View File

@ -36,7 +36,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/next"
android:contentDescription="@string/next_chapter"
android:padding="@dimen/material_layout_keylines_screen_edge_margin"
android:tint="?actionBarTintColor"
android:tooltipText="@string/view_chapters"

View File

@ -16,6 +16,22 @@
android:paddingTop="0dp"
android:paddingEnd="@dimen/material_component_dialogs_padding_around_content_area">
<eu.kanade.tachiyomi.ui.reader.settings.ReaderSpinnerView
android:id="@+id/pager_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
app:title="@string/nav_layout"
android:entries="@array/reader_nav" />
<eu.kanade.tachiyomi.ui.reader.settings.ReaderSpinnerView
android:id="@+id/pager_invert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
app:title="@string/invert_tapping"
android:entries="@array/invert_tapping_mode" />
<eu.kanade.tachiyomi.ui.reader.settings.ReaderSpinnerView
android:id="@+id/scale_type"
android:layout_width="match_parent"
@ -46,11 +62,26 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:text="@string/page_transitions"
android:text="@string/animate_page_transitions"
android:textColor="?android:attr/textColorPrimary" />
<!-- Webtoon Prefs -->
<eu.kanade.tachiyomi.ui.reader.settings.ReaderSpinnerView
android:id="@+id/webtoon_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
app:title="@string/nav_layout"
android:entries="@array/reader_nav" />
<eu.kanade.tachiyomi.ui.reader.settings.ReaderSpinnerView
android:id="@+id/webtoon_invert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
app:title="@string/invert_tapping"
android:entries="@array/invert_tapping_mode" />
<eu.kanade.tachiyomi.ui.reader.settings.ReaderSpinnerView
android:id="@+id/webtoon_side_padding"

View File

@ -24,7 +24,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="6dp"
android:contentDescription="@string/previous"
android:contentDescription="@string/previous_chapter"
android:padding="8dp"
android:src="@drawable/ic_expand_less_24dp"
android:tint="@android:color/white"
@ -53,7 +53,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:contentDescription="@string/next"
android:contentDescription="@string/next_chapter"
android:padding="8dp"
android:src="@drawable/ic_expand_more_24dp"
android:tint="@android:color/white"

View File

@ -299,10 +299,10 @@
<string name="select">تحديد</string>
<string name="migrate">ترحيل</string>
<string name="copy">نسخ</string>
<string name="finished">تمَّ الانتهاء من:</string>
<string name="current">الحالي:</string>
<string name="next">التّالي:</string>
<string name="previous">السّابق:</string>
<string name="finished_chapter">تمَّ الانتهاء من:</string>
<string name="current_chapter">الحالي:</string>
<string name="next_chapter">التّالي:</string>
<string name="previous_chapter">السّابق:</string>
<string name="theres_no_next_chapter">لا يوجدُ فصل تالي</string>
<string name="theres_no_previous_chapter">لا يوجدُ فصل سابق</string>
<string name="loading_pages">جار تحميل الصّفحات…</string>

View File

@ -331,10 +331,10 @@
<string name="started">Начало</string>
<string name="type">Тип</string>
<string name="url_not_set_click_again">Мангата няма връзка с акаунта, молим отново да натиснете заглавието и да изберете мангата</string>
<string name="finished">Завършени:</string>
<string name="current">Текущи:</string>
<string name="next">Следва:</string>
<string name="previous">Предишна:</string>
<string name="finished_chapter">Завършени:</string>
<string name="current_chapter">Текущи:</string>
<string name="next_chapter">Следва:</string>
<string name="previous_chapter">Предишна:</string>
<string name="theres_no_next_chapter">Няма повече глави</string>
<string name="theres_no_previous_chapter">Няма предишна глава</string>
<string name="loading_pages">Зареждане на страниците…</string>

View File

@ -296,10 +296,10 @@
<string name="started">শুরু হয়েছে</string>
<string name="type">ধরণ</string>
<string name="dark_blue">গাঢ় নীল</string>
<string name="finished">"শেষ :"</string>
<string name="current">"এখনকার :"</string>
<string name="next">আসছে :</string>
<string name="previous">পূর্ববর্তী :</string>
<string name="finished_chapter">"শেষ :"</string>
<string name="current_chapter">"এখনকার :"</string>
<string name="next_chapter">আসছে :</string>
<string name="previous_chapter">পূর্ববর্তী :</string>
<string name="theres_no_next_chapter">কোন পরের অধ্যায় আছে</string>
<string name="theres_no_previous_chapter">কোন পূর্ববর্তী অধ্যায় আছে</string>
<string name="loading_pages">পৃষ্ঠা লোড হচ্ছে …</string>

View File

@ -272,10 +272,10 @@
<string name="decode_image_error">No s\'ha pogut descodificar la imatge</string>
<string name="use_image_as_cover">Voleu definir aquesta imatge com a portada\?</string>
<string name="viewer_for_this_series">Lector per a aquesta sèrie</string>
<string name="finished">Finalitzat:</string>
<string name="current">Actual:</string>
<string name="next">Següent:</string>
<string name="previous">Anterior:</string>
<string name="finished_chapter">Finalitzat:</string>
<string name="current_chapter">Actual:</string>
<string name="next_chapter">Següent:</string>
<string name="previous_chapter">Anterior:</string>
<string name="theres_no_next_chapter">No hi ha capítol següent</string>
<string name="theres_no_previous_chapter">No hi ha capítol anterior</string>
<string name="loading_pages">S\'estan carregant les pàgines…</string>

View File

@ -138,10 +138,10 @@
<string name="page_">Stránka: %1$d</string>
<string name="next_chapter_not_found">Další kapitola nenalezena</string>
<string name="decode_image_error">Obrázek nemohl být dekódován</string>
<string name="finished">Dokončeno:</string>
<string name="current">Aktuální:</string>
<string name="next">Následující:</string>
<string name="previous">Předchozí:</string>
<string name="finished_chapter">Dokončeno:</string>
<string name="current_chapter">Aktuální:</string>
<string name="next_chapter">Následující:</string>
<string name="previous_chapter">Předchozí:</string>
<string name="theres_no_next_chapter">Žádná další kapitola</string>
<string name="theres_no_previous_chapter">Žádná předchozí kapitola</string>
<string name="loading_pages">Načítání stránek…</string>

View File

@ -269,10 +269,10 @@
<string name="decode_image_error">Das Bild konnte nicht dekodiert werden</string>
<string name="use_image_as_cover">Wollen Sie dieses Bild als Vorschaubild setzen?</string>
<string name="viewer_for_this_series">Leser dieser Serie</string>
<string name="finished">Beendet:</string>
<string name="current">Aktuell:</string>
<string name="next">Nächste:</string>
<string name="previous">Vorherige:</string>
<string name="finished_chapter">Beendet:</string>
<string name="current_chapter">Aktuell:</string>
<string name="next_chapter">Nächste:</string>
<string name="previous_chapter">Vorherige:</string>
<string name="theres_no_next_chapter">Es gibt kein nächstes Kapitel</string>
<string name="theres_no_previous_chapter">Es gibt kein vorheriges Kapitel</string>
<string name="loading_pages">Lade Seiten…</string>

View File

@ -270,10 +270,10 @@
<string name="decode_image_error">Δεν ήταν δυνατή η αποκωδικοποίηση της εικόνας</string>
<string name="use_image_as_cover">Θέλετε να ορίσετε αυτήν την εικόνα ως εξώφυλλο;</string>
<string name="viewer_for_this_series">Αναγνώστης για αυτήν τη σειρά</string>
<string name="finished">Διαβασμένο:</string>
<string name="current">Τρέχον:</string>
<string name="next">Επόμενο:</string>
<string name="previous">Προηγούμενο:</string>
<string name="finished_chapter">Διαβασμένο:</string>
<string name="current_chapter">Τρέχον:</string>
<string name="next_chapter">Επόμενο:</string>
<string name="previous_chapter">Προηγούμενο:</string>
<string name="theres_no_next_chapter">Δεν υπάρχει επόμενο κεφάλαιο</string>
<string name="theres_no_previous_chapter">Δεν υπάρχει προηγούμενο κεφάλαιο</string>
<string name="loading_pages">Φόρτωση σελίδων…</string>

View File

@ -304,8 +304,8 @@ También asegúrese de haber iniciado sesión en las fuentes que lo requieren an
<string name="language_">Idioma: %1$s</string>
<string name="normal">Normal</string>
<string name="fast">Rápida</string>
<string name="next">Siguiente:</string>
<string name="previous">Anterior:</string>
<string name="next_chapter">Siguiente:</string>
<string name="previous_chapter">Anterior:</string>
<string name="theres_no_next_chapter">No hay capítulo siguiente</string>
<string name="theres_no_previous_chapter">No hay capítulo anterior</string>
<string name="migrate">Migrar</string>
@ -325,8 +325,8 @@ También asegúrese de haber iniciado sesión en las fuentes que lo requieren an
<string name="started">Empezado</string>
<string name="type">Tipo</string>
<string name="url_not_set_click_again">La dirección del manga no está fijada, por favor haga clic en el título y seleccione el manga de nuevo</string>
<string name="finished">Finalizado:</string>
<string name="current">Actual:</string>
<string name="finished_chapter">Finalizado:</string>
<string name="current_chapter">Actual:</string>
<string name="loading_pages">Cargando páginas…</string>
<string name="failed_to_load_pages_">Error al cargar páginas: %1$s</string>
<string name="select">Seleccionar</string>

View File

@ -27,10 +27,10 @@
<string name="decode_image_error">Kuvaa ei voitu decoodata</string>
<string name="use_image_as_cover">Haluatko asettaa tämän kuvan kansikuvaksi\?</string>
<string name="viewer_for_this_series">Katselin tälle sarjalle</string>
<string name="finished">Valmistunut:</string>
<string name="current">Nykyinen:</string>
<string name="next">Seuraava:</string>
<string name="previous">Aiempi:</string>
<string name="finished_chapter">Valmistunut:</string>
<string name="current_chapter">Nykyinen:</string>
<string name="next_chapter">Seuraava:</string>
<string name="previous_chapter">Aiempi:</string>
<string name="theres_no_next_chapter">Seuraavaa lukua ei ole</string>
<string name="theres_no_previous_chapter">Aiempaa lukua ei ole</string>
<string name="loading_pages">Ladataan sivuja…</string>

View File

@ -327,10 +327,10 @@ Assurez-vous que vous êtes connecté à des sources qui le demande avant de com
<string name="untrusted">Non fiable</string>
<string name="pager_viewer">Pager</string>
<string name="rereading">Relecture</string>
<string name="finished">A jour :</string>
<string name="current">En cours :</string>
<string name="next">Suivant :</string>
<string name="previous">Précédent :</string>
<string name="finished_chapter">A jour :</string>
<string name="current_chapter">En cours :</string>
<string name="next_chapter">Suivant :</string>
<string name="previous_chapter">Précédent :</string>
<string name="theres_no_next_chapter">C\'était le dernier chapitre</string>
<string name="theres_no_previous_chapter">Il n\'y a pas de chapitre précédent</string>
<string name="loading_pages">Chargement des pages…</string>

View File

@ -293,10 +293,10 @@
<string name="started">शुरू कर दिया है</string>
<string name="type">प्रकार</string>
<string name="url_not_set_click_again">मंगा यूआरएल सेट नहीं है कृपया शीर्षक पर क्लिक करें और फिर मंगा का चयन करें</string>
<string name="finished">समाप्त:</string>
<string name="current">प्रचलित:</string>
<string name="next">अगला:</string>
<string name="previous">पिछला:</string>
<string name="finished_chapter">समाप्त:</string>
<string name="current_chapter">प्रचलित:</string>
<string name="next_chapter">अगला:</string>
<string name="previous_chapter">पिछला:</string>
<string name="theres_no_next_chapter">कोई अगला अध्याय नहीं है</string>
<string name="theres_no_previous_chapter">कोई पिछला अध्याय नहीं है</string>
<string name="loading_pages">पेज लोड हो रहे है …</string>

View File

@ -294,10 +294,10 @@
<string name="type">Tipe</string>
<string name="url_not_set_click_again">URL Manga belum siap, silahkan klik judul dan pilih manga lagi</string>
<string name="dark_blue">Biru gelap</string>
<string name="finished">Selesai:</string>
<string name="current">Saat ini:</string>
<string name="next">Selanjutnya:</string>
<string name="previous">Sebelumnya:</string>
<string name="finished_chapter">Selesai:</string>
<string name="current_chapter">Saat ini:</string>
<string name="next_chapter">Selanjutnya:</string>
<string name="previous_chapter">Sebelumnya:</string>
<string name="theres_no_next_chapter">Tidak ada chapter lanjutannya</string>
<string name="theres_no_previous_chapter">Tidak ada chapter sebelumnya</string>
<string name="loading_pages">Memuat halaman…</string>

View File

@ -328,10 +328,10 @@
<string name="migrate">Migrare</string>
<string name="copy">Copia</string>
<string name="common">Comune</string>
<string name="finished">Finito:</string>
<string name="current">Corrente:</string>
<string name="next">Prossimo:</string>
<string name="previous">Precedente:</string>
<string name="finished_chapter">Finito:</string>
<string name="current_chapter">Corrente:</string>
<string name="next_chapter">Prossimo:</string>
<string name="previous_chapter">Precedente:</string>
<string name="theres_no_next_chapter">Nessun capitolo successivo</string>
<string name="theres_no_previous_chapter">Nessun capitolo precedente</string>
<string name="loading_pages">Caricamento pagine…</string>

View File

@ -213,10 +213,10 @@
<string name="decode_image_error">이미지를 디코드 할 수 없습니다</string>
<string name="use_image_as_cover">이 이미지를 표지로 설정하시겠습니까\?</string>
<string name="viewer_for_this_series">이 시리즈에 대한 뷰어</string>
<string name="finished">완료:</string>
<string name="current">현재:</string>
<string name="next">다음:</string>
<string name="previous">이전:</string>
<string name="finished_chapter">완료:</string>
<string name="current_chapter">현재:</string>
<string name="next_chapter">다음:</string>
<string name="previous_chapter">이전:</string>
<string name="theres_no_next_chapter">다움 챕터가 없습니다</string>
<string name="theres_no_previous_chapter">이전 챕터가 없습니다</string>
<string name="loading_pages">페이지 로딩중…</string>

View File

@ -297,10 +297,10 @@
<string name="started">Bermula</string>
<string name="type">Jenis</string>
<string name="url_not_set_click_again">Manga url tidak ditetapkan, sila klik tajuk dan pilih manga sekali lagi</string>
<string name="finished">Selesai:</string>
<string name="current">Sekarang:</string>
<string name="next">Seterusnya:</string>
<string name="previous">Sebelumnya:</string>
<string name="finished_chapter">Selesai:</string>
<string name="current_chapter">Sekarang:</string>
<string name="next_chapter">Seterusnya:</string>
<string name="previous_chapter">Sebelumnya:</string>
<string name="theres_no_next_chapter">Tiada bab seterusnya dijumpai</string>
<string name="theres_no_previous_chapter">Tiada bab sebelumnya dijumpai</string>
<string name="loading_pages">Memuatkan halaman…</string>

View File

@ -261,10 +261,10 @@
<string name="page_">Side: %1$d</string>
<string name="next_chapter_not_found">Fant ikke neste kapittel</string>
<string name="decode_image_error">Kunne ikke dekode bildet</string>
<string name="finished">Fullført:</string>
<string name="current">Nåværende:</string>
<string name="next">Neste:</string>
<string name="previous">Forrige:</string>
<string name="finished_chapter">Fullført:</string>
<string name="current_chapter">Nåværende:</string>
<string name="next_chapter">Neste:</string>
<string name="previous_chapter">Forrige:</string>
<string name="theres_no_next_chapter">Det finnes ikke flere kapittel</string>
<string name="theres_no_previous_chapter">Det er ikke noe tidligere kapittel</string>
<string name="loading_pages">Laster inn sider…</string>

View File

@ -294,10 +294,10 @@ Zorg ook dat je ingelogd bent voor bronnen die dit vereisen alvorens je het teru
<string name="started">Gestart</string>
<string name="type">Soort</string>
<string name="url_not_set_click_again">Manga url is niet ingesteld, klik alstublieft op de titel en selecteer de manga opnieuw</string>
<string name="finished">Afgerond:</string>
<string name="current">Huidige:</string>
<string name="next">Volgende:</string>
<string name="previous">Vorige:</string>
<string name="finished_chapter">Afgerond:</string>
<string name="current_chapter">Huidige:</string>
<string name="next_chapter">Volgende:</string>
<string name="previous_chapter">Vorige:</string>
<string name="theres_no_next_chapter">Er is geen volgend hoofdstuk</string>
<string name="theres_no_previous_chapter">Er is geen vorig hoofdstuk</string>
<string name="loading_pages">Pagina\'s aan het laden…</string>

View File

@ -280,10 +280,10 @@
<string name="decode_image_error">Nie udało się wczytać obrazka</string>
<string name="use_image_as_cover">Czy chcesz ustawić ten obrazek jako okładkę?</string>
<string name="viewer_for_this_series">Widok dla tej serii</string>
<string name="finished">Przeczytany:</string>
<string name="current">Obecny:</string>
<string name="next">Następny:</string>
<string name="previous">Poprzedni:</string>
<string name="finished_chapter">Przeczytany:</string>
<string name="current_chapter">Obecny:</string>
<string name="next_chapter">Następny:</string>
<string name="previous_chapter">Poprzedni:</string>
<string name="theres_no_next_chapter">Brak następnego rozdziału</string>
<string name="theres_no_previous_chapter">Brak wcześniejszych rozdziałów</string>
<string name="loading_pages">Ładowanie stron...</string>

View File

@ -273,10 +273,10 @@
<string name="decode_image_error">Não foi possível descodificar a imagem</string>
<string name="use_image_as_cover">Deseja usar esta imagem como capa?</string>
<string name="viewer_for_this_series">Leitura para esta série</string>
<string name="finished">Concluído:</string>
<string name="current">Atual:</string>
<string name="next">Próximo:</string>
<string name="previous">Anterior:</string>
<string name="finished_chapter">Concluído:</string>
<string name="current_chapter">Atual:</string>
<string name="next_chapter">Próximo:</string>
<string name="previous_chapter">Anterior:</string>
<string name="theres_no_next_chapter">Não há próximo capítulo</string>
<string name="theres_no_previous_chapter">Não há capítulo anterior</string>
<string name="loading_pages">Carregando páginas…</string>

View File

@ -321,10 +321,10 @@
<string name="set_as_cover">Usar como capa</string>
<string name="cover_updated">Capa atualizada</string>
<string name="use_image_as_cover">Deseja usar esta imagem como capa\?</string>
<string name="finished">Concluído:</string>
<string name="current">Atual:</string>
<string name="next">Próximo:</string>
<string name="previous">Anterior:</string>
<string name="finished_chapter">Concluído:</string>
<string name="current_chapter">Atual:</string>
<string name="next_chapter">Próximo:</string>
<string name="previous_chapter">Anterior:</string>
<string name="theres_no_next_chapter">Não há próximo capítulo</string>
<string name="theres_no_previous_chapter">Não há capítulo anterior</string>
<string name="loading_pages">Carregando páginas…</string>

View File

@ -269,10 +269,10 @@
<string name="decode_image_error">Imaginea nu a putu fi decodată</string>
<string name="use_image_as_cover">Doriți să setați această imagine drept copertă\?</string>
<string name="viewer_for_this_series">Cititor al acestei serii</string>
<string name="finished">Terminat:</string>
<string name="current">Actual:</string>
<string name="next">Următorul:</string>
<string name="previous">Precedent:</string>
<string name="finished_chapter">Terminat:</string>
<string name="current_chapter">Actual:</string>
<string name="next_chapter">Următorul:</string>
<string name="previous_chapter">Precedent:</string>
<string name="theres_no_next_chapter">Nu există capitolul următor</string>
<string name="theres_no_previous_chapter">Nu există capitolul precedent</string>
<string name="loading_pages">Încărcând paginile…</string>

View File

@ -471,14 +471,14 @@
<string name="current">Текущая:</string>
<string name="finished">Закончена:</string>
<string name="next">Следующая:</string>
<string name="current_chapter">Текущая:</string>
<string name="finished_chapter">Закончена:</string>
<string name="next_chapter">Следующая:</string>
<string name="theres_no_next_chapter">Следующей части нет</string>
<string name="theres_no_previous_chapter">Предыдущей части нет</string>
<string name="failed_to_load_pages_">Не удалось загрузить страницы: %1$s</string>
<string name="loading_pages">Идёт загрузка страниц…</string>
<string name="previous">Предыдущая:</string>
<string name="previous_chapter">Предыдущая:</string>
<string name="unknown">Неизвестно</string>
<string name="unknown_error">Неизвестная ошибка</string>

View File

@ -271,10 +271,10 @@
<string name="decode_image_error">No est istadu possìbile decodificare s\'immàgine</string>
<string name="use_image_as_cover">Cheres impostare custa immàgine comente cobertedda\?</string>
<string name="viewer_for_this_series">Visualizadore pro custa sèrie</string>
<string name="finished">Acabadu:</string>
<string name="current">Atuale:</string>
<string name="next">Imbeniente:</string>
<string name="previous">Antepostu:</string>
<string name="finished_chapter">Acabadu:</string>
<string name="current_chapter">Atuale:</string>
<string name="next_chapter">Imbeniente:</string>
<string name="previous_chapter">Antepostu:</string>
<string name="theres_no_next_chapter">Non b\'at unu capìtulu imbeniente</string>
<string name="theres_no_previous_chapter">Non b\'at unu capìtulu antepostu</string>
<string name="loading_pages">Carrighende pàginas…</string>

View File

@ -270,10 +270,10 @@
<string name="decode_image_error">Bilden kunde inte avkodas</string>
<string name="use_image_as_cover">Vill du ställa in denna bilden som omslaget\?</string>
<string name="viewer_for_this_series">Visare för denna serie</string>
<string name="finished">Färdig:</string>
<string name="current">Nuvarande:</string>
<string name="next">Nästa:</string>
<string name="previous">Tidigare:</string>
<string name="finished_chapter">Färdig:</string>
<string name="current_chapter">Nuvarande:</string>
<string name="next_chapter">Nästa:</string>
<string name="previous_chapter">Tidigare:</string>
<string name="theres_no_next_chapter">Det finns inget mer kapitel</string>
<string name="theres_no_previous_chapter">Det finns inget tidigare kapitel</string>
<string name="loading_pages">Laddar sidor…</string>

View File

@ -282,10 +282,10 @@
<string name="decode_image_error">ไม่สามารถถอดรหัสรูปภาพได้</string>
<string name="use_image_as_cover">คุณต้องการที่จะตั้งค่าภาพเป็นภาพที่ปกใช่มั้ย\?</string>
<string name="viewer_for_this_series">ตัวแสดงสำหรับชุดนี้</string>
<string name="finished">เสร็จแล้ว:</string>
<string name="current">ปัจจุบัน:</string>
<string name="next">ต่อไป:</string>
<string name="previous">ก่อนหน้า:</string>
<string name="finished_chapter">เสร็จแล้ว:</string>
<string name="current_chapter">ปัจจุบัน:</string>
<string name="next_chapter">ต่อไป:</string>
<string name="previous_chapter">ก่อนหน้า:</string>
<string name="theres_no_next_chapter">ไม่มีบทต่อไป</string>
<string name="theres_no_previous_chapter">ไม่มีบทก่อนหน้านี้</string>
<string name="loading_pages">กำลังโหลดหน้า …</string>

View File

@ -283,10 +283,10 @@
<string name="decode_image_error">Hindi ma-decode ang larawan</string>
<string name="use_image_as_cover">Gusto mo bang i-set ang larawang ito bilang pabalat\?</string>
<string name="viewer_for_this_series">Viewer para sa seryeng ito</string>
<string name="finished">Natapos:</string>
<string name="current">Kasalukuyan:</string>
<string name="next">Susunod:</string>
<string name="previous">Nakaraan:</string>
<string name="finished_chapter">Natapos:</string>
<string name="current_chapter">Kasalukuyan:</string>
<string name="next_chapter">Susunod:</string>
<string name="previous_chapter">Nakaraan:</string>
<string name="theres_no_next_chapter">Walang susunod na kabanata</string>
<string name="theres_no_previous_chapter">Walang nakaraang kabanata</string>
<string name="loading_pages">Kinakarga ang mga pahina…</string>

View File

@ -295,10 +295,10 @@
<string name="no_network_connection">Ağ bağlantısı yok</string>
<string name="download_paused">İndirme duraklatıldı</string>
<string name="common">Genel</string>
<string name="finished">Biten:</string>
<string name="current">Şu anki:</string>
<string name="next">Sonraki:</string>
<string name="previous">Önceki:</string>
<string name="finished_chapter">Biten:</string>
<string name="current_chapter">Şu anki:</string>
<string name="next_chapter">Sonraki:</string>
<string name="previous_chapter">Önceki:</string>
<string name="theres_no_next_chapter">Sonraki bölüm yok</string>
<string name="theres_no_previous_chapter">Önceki bölüm yok</string>
<string name="loading_pages">Sayfalar yükleniyor…</string>

View File

@ -270,10 +270,10 @@
<string name="decode_image_error">Зображення не може бути декодовано</string>
<string name="use_image_as_cover">Ви бажаєте встановити цю картинку як обкладинку\?</string>
<string name="viewer_for_this_series">Відображення для цієї серії</string>
<string name="finished">Завершено:</string>
<string name="current">Поточна:</string>
<string name="next">Наступна:</string>
<string name="previous">Попередня:</string>
<string name="finished_chapter">Завершено:</string>
<string name="current_chapter">Поточна:</string>
<string name="next_chapter">Наступна:</string>
<string name="previous_chapter">Попередня:</string>
<string name="theres_no_next_chapter">Наступної частини немає</string>
<string name="theres_no_previous_chapter">Попередньої частини немає</string>
<string name="loading_pages">Завантаження сторінок…</string>

View File

@ -326,10 +326,10 @@
<string name="started">Đã bắt đầu</string>
<string name="type">Loại</string>
<string name="url_not_set_click_again">Đường dẫn truyện chưa được đặt, vui lòng nhấn vào tiêu đề và chọn lại truyện một lần nữa</string>
<string name="finished">Đã đọc xong:</string>
<string name="current">Đang đọc:</string>
<string name="next">Chương kế:</string>
<string name="previous">Chương trước:</string>
<string name="finished_chapter">Đã đọc xong:</string>
<string name="current_chapter">Đang đọc:</string>
<string name="next_chapter">Chương kế:</string>
<string name="previous_chapter">Chương trước:</string>
<string name="theres_no_next_chapter">Không có chương tiếp theo</string>
<string name="theres_no_previous_chapter">Không có chương trước đó</string>
<string name="loading_pages">Đang tải trang…</string>

View File

@ -270,10 +270,10 @@
\n请尝试更换图片解码器或选择以下选项</string>
<string name="use_image_as_cover">要将此页设为封面吗?</string>
<string name="viewer_for_this_series">阅读模式</string>
<string name="finished">已读完:</string>
<string name="current">"当前: "</string>
<string name="next">下一章:</string>
<string name="previous">"上一章: "</string>
<string name="finished_chapter">已读完:</string>
<string name="current_chapter">"当前: "</string>
<string name="next_chapter">下一章:</string>
<string name="previous_chapter">"上一章: "</string>
<string name="theres_no_next_chapter">下面没有啦</string>
<string name="theres_no_previous_chapter">前面没有啦</string>
<string name="loading_pages">页面加载中…</string>

View File

@ -271,8 +271,8 @@
<string name="category_with_name_exists">已有名稱相同的分類!</string>
<string name="page_">第 %1$d 頁</string>
<string name="next_chapter_not_found">找不到下一章</string>
<string name="finished">已閱畢:</string>
<string name="next">下一章:</string>
<string name="finished_chapter">已閱畢:</string>
<string name="next_chapter">下一章:</string>
<string name="new_chapters_found">發現新章節</string>
<string name="skip_read_chapters">略過已讀的章節</string>
<string name="remove_after_read">閱畢後刪除</string>
@ -306,8 +306,8 @@
<string name="type">類型</string>
<string name="url_not_set_click_again">漫畫網址未設置,請點擊標題再選擇一次漫畫</string>
<string name="this_will_remove_the_read_date_question">這將會清除此章節的閱讀日期,確定嗎?</string>
<string name="current">當前章節:</string>
<string name="previous">上一章:</string>
<string name="current_chapter">當前章節:</string>
<string name="previous_chapter">上一章:</string>
<string name="source_dash_chapter_">%1$s - 第%2$s章</string>
<string name="could_not_download_chapter_can_try_again">下載時發生錯誤。請再試一次</string>
<string name="could_not_download_unexpected_error">下載時發生不可預期的錯誤</string>

View File

@ -62,6 +62,21 @@
<item>@string/screen</item>
</string-array>
<string-array name="reader_nav">
<item>@string/default_value</item>
<item>@string/l_nav</item>
<item>@string/kindlish_nav</item>
<item>@string/edge_nav</item>
<item>@string/right_and_left_nav</item>
</string-array>
<string-array name="invert_tapping_mode">
<item>@string/none</item>
<item>@string/horizontally</item>
<item>@string/vertically</item>
<item>@string/both_axes</item>
</string-array>
<string-array name="clean_up_downloads">
<item>@string/clean_orphaned_downloads</item>
<item>@string/clean_read_downloads</item>

View File

@ -16,7 +16,7 @@
<attr name="tabBarIconColor" format="reference|integer"/>
<attr name="tabBarIconInactive" format="reference|integer"/>
<declare-styleable name="ReaderPreferenceView">
<declare-styleable name="ReaderSpinnerView">
<attr name="title" format="reference|string"/>
<attr name="android:entries"/>
<attr name="summary" format="reference|string" />

View File

@ -62,4 +62,12 @@
<color name="md_red_500">#F44336</color>
<color name="pale_green">#99CC99</color>
<!-- Navigation overlay colors -->
<color name="navigation_next">#CB84E296</color>
<color name="navigation_prev">#CCFF7733</color>
<color name="navigation_menu">#CC95818D</color>
<color name="navigation_right">#CCA6CFD5</color>
<color name="navigation_left">#CC7D1128</color>
</resources>

View File

@ -290,10 +290,10 @@
<string name="decode_image_error">The image could not be decoded</string>
<string name="use_image_as_cover">Use this image as cover art?</string>
<string name="viewer_for_this_series">Viewer for this series</string>
<string name="finished">Finished:</string>
<string name="current">Current:</string>
<string name="next">Next:</string>
<string name="previous">Previous:</string>
<string name="finished_chapter">Finished:</string>
<string name="current_chapter">Current:</string>
<string name="next_chapter">Next:</string>
<string name="previous_chapter">Previous:</string>
<string name="theres_no_next_chapter">There\'s no next chapter</string>
<string name="theres_no_previous_chapter">There\'s no previous chapter</string>
<string name="loading_pages">Loading pages…</string>
@ -303,7 +303,7 @@
<!-- Reader settings -->
<string name="fullscreen">Fullscreen</string>
<string name="page_transitions">Page transitions</string>
<string name="animate_page_transitions">Animate page transitions</string>
<string name="enable_zoom_out">Enable zoom out</string>
<string name="double_tap_anim_speed">Double tap animation speed</string>
<string name="show_page_number">Show page number</string>
@ -339,6 +339,7 @@
<string name="continuous_vertical">Continuous vertical</string>
<string name="paged">Paged</string>
<string name="scale_type">Scale type</string>
<string name="nav_layout">Navigation layout</string>
<string name="fit_screen">Fit screen</string>
<string name="stretch">Stretch</string>
<string name="fit_width">Fit width</string>
@ -363,6 +364,15 @@
<string name="webtoon_side_padding_15">15%</string>
<string name="webtoon_side_padding_20">20%</string>
<string name="webtoon_side_padding_25">25%</string>
<string name="l_nav">L shaped</string>
<string name="kindlish_nav">Kindle-ish</string>
<string name="edge_nav">Edge</string>
<string name="right_and_left_nav">Right and Left</string>
<string name="invert_tapping">Invert tapping</string>
<string name="none">None</string>
<string name="horizontally">Horizontally</string>
<string name="vertically">Vertically</string>
<string name="both_axes">Both Axes</string>
<!-- Manga details -->
<string name="about_this_">About this %1$s</string>
@ -792,12 +802,14 @@
<string name="mark_as_unread">Mark as unread</string>
<string name="mark_previous_as_read">Mark previous as read</string>
<string name="mark_previous_as_unread">Mark previous as unread</string>
<string name="menu">menu</string>
<string name="more">More</string>
<string name="move_to_bottom">Move to bottom</string>
<string name="move_to_top">Move to top</string>
<string name="moved_to_">Moved to %1$s</string>
<string name="never">Never</string>
<string name="newest">Newest</string>
<string name="next">Next</string>
<string name="no_animation">No animation</string>
<string name="normal">Normal</string>
<string name="oldest">Oldest</string>
@ -809,6 +821,7 @@
<string name="picture_saved">Picture saved</string>
<string name="pin">Pin</string>
<string name="pinned">Pinned</string>
<string name="previous">Previous</string>
<string name="refresh">Refresh</string>
<string name="refreshing">Refreshing</string>
<string name="remove">Remove</string>