Option to prefer Rtl reader
This commit is contained in:
@@ -70,7 +70,7 @@ dependencies {
|
|||||||
implementation 'androidx.activity:activity-ktx:1.2.0-beta01'
|
implementation 'androidx.activity:activity-ktx:1.2.0-beta01'
|
||||||
implementation 'androidx.fragment:fragment-ktx:1.3.0-beta01'
|
implementation 'androidx.fragment:fragment-ktx:1.3.0-beta01'
|
||||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0-beta01'
|
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0-beta01'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||||
implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha06'
|
implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha06'
|
||||||
implementation 'androidx.viewpager2:viewpager2:1.1.0-alpha01'
|
implementation 'androidx.viewpager2:viewpager2:1.1.0-alpha01'
|
||||||
|
|||||||
@@ -88,6 +88,11 @@ class AppSettings private constructor(resources: Resources, private val prefs: S
|
|||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val isPreferRtlReader by BoolPreferenceDelegate(
|
||||||
|
resources.getString(R.string.key_reader_prefer_rtl),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
val trackSources by StringSetPreferenceDelegate(
|
val trackSources by StringSetPreferenceDelegate(
|
||||||
resources.getString(R.string.key_track_sources),
|
resources.getString(R.string.key_track_sources),
|
||||||
arraySetOf(TRACK_FAVOURITES, TRACK_HISTORY)
|
arraySetOf(TRACK_FAVOURITES, TRACK_HISTORY)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package org.koitharu.kotatsu.core.prefs
|
|||||||
|
|
||||||
enum class ReaderMode(val id: Int) {
|
enum class ReaderMode(val id: Int) {
|
||||||
|
|
||||||
UNKNOWN(0),
|
|
||||||
STANDARD(1),
|
STANDARD(1),
|
||||||
WEBTOON(2),
|
WEBTOON(2),
|
||||||
REVERSED(3);
|
REVERSED(3);
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import org.koin.core.component.KoinComponent
|
|||||||
import org.koin.core.component.get
|
import org.koin.core.component.get
|
||||||
import org.koitharu.kotatsu.BuildConfig
|
import org.koitharu.kotatsu.BuildConfig
|
||||||
import org.koitharu.kotatsu.core.model.MangaPage
|
import org.koitharu.kotatsu.core.model.MangaPage
|
||||||
import org.koitharu.kotatsu.core.prefs.ReaderMode
|
|
||||||
import org.koitharu.kotatsu.utils.ext.await
|
import org.koitharu.kotatsu.utils.ext.await
|
||||||
import org.koitharu.kotatsu.utils.ext.medianOrNull
|
import org.koitharu.kotatsu.utils.ext.medianOrNull
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
@@ -24,7 +23,7 @@ object MangaUtils : KoinComponent {
|
|||||||
*/
|
*/
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
suspend fun determineReaderMode(pages: List<MangaPage>): ReaderMode? {
|
suspend fun determineMangaIsWebtoon(pages: List<MangaPage>): Boolean? {
|
||||||
try {
|
try {
|
||||||
val page = pages.medianOrNull() ?: return null
|
val page = pages.medianOrNull() ?: return null
|
||||||
val url = page.source.repository.getPageFullUrl(page)
|
val url = page.source.repository.getPageFullUrl(page)
|
||||||
@@ -45,10 +44,7 @@ object MangaUtils : KoinComponent {
|
|||||||
getBitmapSize(it.body?.byteStream())
|
getBitmapSize(it.body?.byteStream())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return when {
|
return size.width * 2 < size.height
|
||||||
size.width * 2 < size.height -> ReaderMode.WEBTOON
|
|
||||||
else -> ReaderMode.STANDARD
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
package org.koitharu.kotatsu.ui.base
|
package org.koitharu.kotatsu.ui.base
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Parcelable
|
|
||||||
import androidx.annotation.LayoutRes
|
import androidx.annotation.LayoutRes
|
||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
||||||
import moxy.MvpAppCompatFragment
|
import moxy.MvpAppCompatFragment
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import org.koitharu.kotatsu.utils.delegates.ParcelableArgumentDelegate
|
|
||||||
import org.koitharu.kotatsu.utils.delegates.StringArgumentDelegate
|
|
||||||
|
|
||||||
abstract class BaseFragment(
|
abstract class BaseFragment(
|
||||||
@LayoutRes contentLayoutId: Int
|
@LayoutRes contentLayoutId: Int
|
||||||
@@ -15,11 +12,6 @@ abstract class BaseFragment(
|
|||||||
|
|
||||||
protected val coil by inject<ImageLoader>()
|
protected val coil by inject<ImageLoader>()
|
||||||
|
|
||||||
fun stringArg(name: String) = StringArgumentDelegate(name)
|
|
||||||
|
|
||||||
@Deprecated("Use extension", replaceWith = ReplaceWith("parcelableArgument(name)"))
|
|
||||||
fun <T : Parcelable> arg(name: String) = ParcelableArgumentDelegate<T>(name)
|
|
||||||
|
|
||||||
open fun getTitle(): CharSequence? = null
|
open fun getTitle(): CharSequence? = null
|
||||||
|
|
||||||
override fun onAttach(context: Context) {
|
override fun onAttach(context: Context) {
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh
|
|||||||
replace(R.id.container, ReversedReaderFragment.newInstance(state))
|
replace(R.id.container, ReversedReaderFragment.newInstance(state))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> if (currentReader !is PagerReaderFragment) {
|
ReaderMode.STANDARD -> if (currentReader !is PagerReaderFragment) {
|
||||||
supportFragmentManager.commit {
|
supportFragmentManager.commit {
|
||||||
replace(R.id.container, PagerReaderFragment.newInstance(state))
|
replace(R.id.container, PagerReaderFragment.newInstance(state))
|
||||||
}
|
}
|
||||||
@@ -135,7 +135,7 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh
|
|||||||
when (mode) {
|
when (mode) {
|
||||||
ReaderMode.WEBTOON -> R.drawable.ic_script
|
ReaderMode.WEBTOON -> R.drawable.ic_script
|
||||||
ReaderMode.REVERSED -> R.drawable.ic_read_reversed
|
ReaderMode.REVERSED -> R.drawable.ic_read_reversed
|
||||||
else -> R.drawable.ic_book_page
|
ReaderMode.STANDARD -> R.drawable.ic_book_page
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
appbar_top.postDelayed(1000) {
|
appbar_top.postDelayed(1000) {
|
||||||
@@ -158,70 +158,70 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh
|
|||||||
outState.putParcelable(EXTRA_STATE, state)
|
outState.putParcelable(EXTRA_STATE, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
R.id.action_reader_mode -> {
|
when (item.itemId) {
|
||||||
ReaderConfigDialog.show(
|
R.id.action_reader_mode -> {
|
||||||
supportFragmentManager, when (reader) {
|
ReaderConfigDialog.show(
|
||||||
is PagerReaderFragment -> ReaderMode.STANDARD
|
supportFragmentManager, when (reader) {
|
||||||
is WebtoonReaderFragment -> ReaderMode.WEBTOON
|
is PagerReaderFragment -> ReaderMode.STANDARD
|
||||||
is ReversedReaderFragment -> ReaderMode.REVERSED
|
is WebtoonReaderFragment -> ReaderMode.WEBTOON
|
||||||
else -> ReaderMode.UNKNOWN
|
is ReversedReaderFragment -> ReaderMode.REVERSED
|
||||||
}
|
else -> {
|
||||||
)
|
showWaitWhileLoading()
|
||||||
true
|
return false
|
||||||
}
|
}
|
||||||
R.id.action_settings -> {
|
}
|
||||||
startActivity(SimpleSettingsActivity.newReaderSettingsIntent(this))
|
)
|
||||||
true
|
}
|
||||||
}
|
R.id.action_settings -> {
|
||||||
R.id.action_chapters -> {
|
startActivity(SimpleSettingsActivity.newReaderSettingsIntent(this))
|
||||||
ChaptersDialog.show(
|
}
|
||||||
supportFragmentManager,
|
R.id.action_chapters -> {
|
||||||
state.manga.chapters.orEmpty(),
|
ChaptersDialog.show(
|
||||||
state.chapterId
|
supportFragmentManager,
|
||||||
)
|
state.manga.chapters.orEmpty(),
|
||||||
true
|
state.chapterId
|
||||||
}
|
)
|
||||||
R.id.action_screen_rotate -> {
|
}
|
||||||
orientationHelper.toggleOrientation()
|
R.id.action_screen_rotate -> {
|
||||||
true
|
orientationHelper.toggleOrientation()
|
||||||
}
|
}
|
||||||
R.id.action_pages_thumbs -> {
|
R.id.action_pages_thumbs -> {
|
||||||
if (reader?.hasItems == true) {
|
if (reader?.hasItems == true) {
|
||||||
val pages = reader?.getPages()
|
val pages = reader?.getPages()
|
||||||
if (!pages.isNullOrEmpty()) {
|
if (!pages.isNullOrEmpty()) {
|
||||||
PagesThumbnailsSheet.show(
|
PagesThumbnailsSheet.show(
|
||||||
supportFragmentManager, pages,
|
supportFragmentManager, pages,
|
||||||
state.chapter?.name ?: title?.toString().orEmpty()
|
state.chapter?.name ?: title?.toString().orEmpty()
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
showWaitWhileLoading()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
showWaitWhileLoading()
|
showWaitWhileLoading()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
showWaitWhileLoading()
|
|
||||||
}
|
}
|
||||||
true
|
R.id.action_save_page -> {
|
||||||
}
|
if (reader?.hasItems == true) {
|
||||||
R.id.action_save_page -> {
|
if (ContextCompat.checkSelfPermission(
|
||||||
if (reader?.hasItems == true) {
|
this,
|
||||||
if (ContextCompat.checkSelfPermission(
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
this,
|
) == PackageManager.PERMISSION_GRANTED
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
) {
|
||||||
) == PackageManager.PERMISSION_GRANTED
|
onActivityResult(true)
|
||||||
) {
|
} else {
|
||||||
onActivityResult(true)
|
registerForActivityResult(
|
||||||
|
ActivityResultContracts.RequestPermission(),
|
||||||
|
this
|
||||||
|
).launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
registerForActivityResult(
|
showWaitWhileLoading()
|
||||||
ActivityResultContracts.RequestPermission(),
|
|
||||||
this
|
|
||||||
).launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
showWaitWhileLoading()
|
|
||||||
}
|
}
|
||||||
true
|
else -> return super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
else -> super.onOptionsItemSelected(item)
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResult(result: Boolean) {
|
override fun onActivityResult(result: Boolean) {
|
||||||
|
|||||||
@@ -18,9 +18,8 @@ class ReaderConfigDialog : AlertDialogFragment(R.layout.dialog_reader_config),
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
mode = arguments?.getInt(ARG_MODE, ReaderMode.UNKNOWN.id)
|
mode = arguments?.getInt(ARG_MODE)
|
||||||
?.let { ReaderMode.valueOf(it) }
|
?.let { ReaderMode.valueOf(it) }
|
||||||
?.takeUnless { it == ReaderMode.UNKNOWN }
|
|
||||||
?: ReaderMode.STANDARD
|
?: ReaderMode.STANDARD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.koin.core.component.inject
|
|||||||
import org.koitharu.kotatsu.BuildConfig
|
import org.koitharu.kotatsu.BuildConfig
|
||||||
import org.koitharu.kotatsu.core.model.Manga
|
import org.koitharu.kotatsu.core.model.Manga
|
||||||
import org.koitharu.kotatsu.core.model.MangaPage
|
import org.koitharu.kotatsu.core.model.MangaPage
|
||||||
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
import org.koitharu.kotatsu.core.prefs.ReaderMode
|
import org.koitharu.kotatsu.core.prefs.ReaderMode
|
||||||
import org.koitharu.kotatsu.domain.MangaDataRepository
|
import org.koitharu.kotatsu.domain.MangaDataRepository
|
||||||
import org.koitharu.kotatsu.domain.MangaUtils
|
import org.koitharu.kotatsu.domain.MangaUtils
|
||||||
@@ -28,27 +29,29 @@ import org.koitharu.kotatsu.utils.ext.mimeType
|
|||||||
class ReaderPresenter : BasePresenter<ReaderView>() {
|
class ReaderPresenter : BasePresenter<ReaderView>() {
|
||||||
|
|
||||||
private val dataRepository by inject<MangaDataRepository>()
|
private val dataRepository by inject<MangaDataRepository>()
|
||||||
|
private val appSettings by inject<AppSettings>()
|
||||||
|
|
||||||
fun init(manga: Manga) {
|
fun init(manga: Manga) {
|
||||||
presenterScope.launch {
|
presenterScope.launch {
|
||||||
viewState.onLoadingStateChanged(isLoading = true)
|
viewState.onLoadingStateChanged(isLoading = true)
|
||||||
try {
|
try {
|
||||||
val mode = withContext(Dispatchers.IO) {
|
val mode = withContext(Dispatchers.Default) {
|
||||||
val repo = manga.source.repository
|
val repo = manga.source.repository
|
||||||
val chapter =
|
val chapter =
|
||||||
(manga.chapters ?: throw RuntimeException("Chapters is null")).random()
|
(manga.chapters ?: throw RuntimeException("Chapters is null")).random()
|
||||||
var mode = dataRepository.getReaderMode(manga.id)
|
var mode = dataRepository.getReaderMode(manga.id)
|
||||||
if (mode == null) {
|
if (mode == null) {
|
||||||
val pages = repo.getPages(chapter)
|
val pages = repo.getPages(chapter)
|
||||||
mode = MangaUtils.determineReaderMode(pages)
|
val isWebtoon = MangaUtils.determineMangaIsWebtoon(pages)
|
||||||
if (mode != null) {
|
mode = getReaderMode(isWebtoon)
|
||||||
|
if (isWebtoon != null) {
|
||||||
dataRepository.savePreferences(
|
dataRepository.savePreferences(
|
||||||
manga = manga,
|
manga = manga,
|
||||||
mode = mode
|
mode = mode
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mode ?: ReaderMode.UNKNOWN
|
mode
|
||||||
}
|
}
|
||||||
viewState.onInitReader(manga, mode)
|
viewState.onInitReader(manga, mode)
|
||||||
} catch (_: CancellationException) {
|
} catch (_: CancellationException) {
|
||||||
@@ -101,6 +104,12 @@ class ReaderPresenter : BasePresenter<ReaderView>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getReaderMode(isWebtoon: Boolean?) = when {
|
||||||
|
isWebtoon == true -> ReaderMode.WEBTOON
|
||||||
|
appSettings.isPreferRtlReader -> ReaderMode.REVERSED
|
||||||
|
else -> ReaderMode.STANDARD
|
||||||
|
}
|
||||||
|
|
||||||
companion object : KoinComponent {
|
companion object : KoinComponent {
|
||||||
|
|
||||||
fun saveState(state: ReaderState) {
|
fun saveState(state: ReaderState) {
|
||||||
|
|||||||
@@ -3,14 +3,16 @@ package org.koitharu.kotatsu.ui.search
|
|||||||
import moxy.ktx.moxyPresenter
|
import moxy.ktx.moxyPresenter
|
||||||
import org.koitharu.kotatsu.core.model.MangaSource
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
import org.koitharu.kotatsu.ui.list.MangaListFragment
|
import org.koitharu.kotatsu.ui.list.MangaListFragment
|
||||||
|
import org.koitharu.kotatsu.utils.ext.parcelableArgument
|
||||||
|
import org.koitharu.kotatsu.utils.ext.stringArgument
|
||||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||||
|
|
||||||
class SearchFragment : MangaListFragment<Unit>() {
|
class SearchFragment : MangaListFragment<Unit>() {
|
||||||
|
|
||||||
private val presenter by moxyPresenter(factory = ::SearchPresenter)
|
private val presenter by moxyPresenter(factory = ::SearchPresenter)
|
||||||
|
|
||||||
private val query by stringArg(ARG_QUERY)
|
private val query by stringArgument(ARG_QUERY)
|
||||||
private val source by arg<MangaSource>(ARG_SOURCE)
|
private val source by parcelableArgument<MangaSource>(ARG_SOURCE)
|
||||||
|
|
||||||
override fun onRequestMoreItems(offset: Int) {
|
override fun onRequestMoreItems(offset: Int) {
|
||||||
presenter.loadList(source, query.orEmpty(), offset)
|
presenter.loadList(source, query.orEmpty(), offset)
|
||||||
|
|||||||
@@ -2,14 +2,15 @@ package org.koitharu.kotatsu.ui.search.global
|
|||||||
|
|
||||||
import moxy.ktx.moxyPresenter
|
import moxy.ktx.moxyPresenter
|
||||||
import org.koitharu.kotatsu.ui.list.MangaListFragment
|
import org.koitharu.kotatsu.ui.list.MangaListFragment
|
||||||
|
import org.koitharu.kotatsu.utils.ext.stringArgument
|
||||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||||
|
|
||||||
|
|
||||||
class GlobalSearchFragment: MangaListFragment<Unit>() {
|
class GlobalSearchFragment : MangaListFragment<Unit>() {
|
||||||
|
|
||||||
private val presenter by moxyPresenter(factory = ::GlobalSearchPresenter)
|
private val presenter by moxyPresenter(factory = ::GlobalSearchPresenter)
|
||||||
|
|
||||||
private val query by stringArg(ARG_QUERY)
|
private val query by stringArgument(ARG_QUERY)
|
||||||
|
|
||||||
override fun onRequestMoreItems(offset: Int) {
|
override fun onRequestMoreItems(offset: Int) {
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
|
|||||||
@@ -20,4 +20,9 @@ inline fun <T : Parcelable> Fragment.parcelableArgument(name: String) =
|
|||||||
lazy<T>(LazyThreadSafetyMode.NONE) {
|
lazy<T>(LazyThreadSafetyMode.NONE) {
|
||||||
requireArguments().getParcelable(name)
|
requireArguments().getParcelable(name)
|
||||||
?: error("No argument $name passed in ${javaClass.simpleName}")
|
?: error("No argument $name passed in ${javaClass.simpleName}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun Fragment.stringArgument(name: String) = lazy(LazyThreadSafetyMode.NONE) {
|
||||||
|
arguments?.getString(name)
|
||||||
|
}
|
||||||
@@ -160,4 +160,6 @@
|
|||||||
<string name="update_check_failed">Ошибка при проверке обновления</string>
|
<string name="update_check_failed">Ошибка при проверке обновления</string>
|
||||||
<string name="no_update_available">Нет доступных обновлений</string>
|
<string name="no_update_available">Нет доступных обновлений</string>
|
||||||
<string name="right_to_left">Справа налево</string>
|
<string name="right_to_left">Справа налево</string>
|
||||||
|
<string name="prefer_rtl_reader">Предпочитать режим Справа налево</string>
|
||||||
|
<string name="prefer_rtl_reader_summary">Вы можете настроить режим чтения для каждой манги отдельно</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
<string name="key_notifications_vibrate">notifications_vibrate</string>
|
<string name="key_notifications_vibrate">notifications_vibrate</string>
|
||||||
<string name="key_notifications_light">notifications_light</string>
|
<string name="key_notifications_light">notifications_light</string>
|
||||||
<string name="key_reader_animation">reader_animation</string>
|
<string name="key_reader_animation">reader_animation</string>
|
||||||
|
<string name="key_reader_prefer_rtl">reader_prefer_rtl</string>
|
||||||
<string name="key_app_password">app_password</string>
|
<string name="key_app_password">app_password</string>
|
||||||
<string name="key_protect_app">protect_app</string>
|
<string name="key_protect_app">protect_app</string>
|
||||||
<string name="key_app_version">app_version</string>
|
<string name="key_app_version">app_version</string>
|
||||||
|
|||||||
@@ -161,4 +161,6 @@
|
|||||||
<string name="update_check_failed">Update check failed</string>
|
<string name="update_check_failed">Update check failed</string>
|
||||||
<string name="no_update_available">No updates available</string>
|
<string name="no_update_available">No updates available</string>
|
||||||
<string name="right_to_left">Right to left</string>
|
<string name="right_to_left">Right to left</string>
|
||||||
|
<string name="prefer_rtl_reader">Prefer Right to left reader</string>
|
||||||
|
<string name="prefer_rtl_reader_summary">You can set up the reading mode for each manga separately</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -70,6 +70,13 @@
|
|||||||
android:title="@string/pages_animation"
|
android:title="@string/pages_animation"
|
||||||
app:iconSpaceReserved="false" />
|
app:iconSpaceReserved="false" />
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="@string/key_reader_prefer_rtl"
|
||||||
|
android:summary="@string/prefer_rtl_reader_summary"
|
||||||
|
android:title="@string/prefer_rtl_reader"
|
||||||
|
app:iconSpaceReserved="false" />
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="@string/new_chapters"
|
android:title="@string/new_chapters"
|
||||||
app:allowDividerAbove="true"
|
app:allowDividerAbove="true"
|
||||||
|
|||||||
@@ -13,8 +13,15 @@
|
|||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:title="@string/pages_animation"
|
|
||||||
android:key="@string/key_reader_animation"
|
android:key="@string/key_reader_animation"
|
||||||
|
android:title="@string/pages_animation"
|
||||||
|
app:iconSpaceReserved="false" />
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="@string/key_reader_prefer_rtl"
|
||||||
|
android:summary="@string/prefer_rtl_reader_summary"
|
||||||
|
android:title="@string/prefer_rtl_reader"
|
||||||
app:iconSpaceReserved="false" />
|
app:iconSpaceReserved="false" />
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
Reference in New Issue
Block a user