Skip to content
This repository was archived by the owner on Jul 29, 2022. It is now read-only.
Closed
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 @@ -13,6 +13,7 @@ import android.content.SharedPreferences
import android.graphics.PointF
import android.view.View
import androidx.lifecycle.LiveData
import androidx.viewpager2.widget.ViewPager2
import org.readium.r2.navigator.pager.R2ViewPager
import org.readium.r2.shared.publication.Link
import org.readium.r2.shared.publication.Locator
Expand All @@ -27,7 +28,7 @@ interface IR2Activity {
val publicationFileName: String
val publicationPath: String
val bookId: Long
val resourcePager: R2ViewPager?
val resourcePager: ViewPager2?
get() = null
val allowToggleActionBar: Boolean
get() = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import org.readium.r2.shared.publication.ReadingProgression
open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(context, attrs) {

lateinit var listener: Listener
lateinit var navigator: Navigator
lateinit var navigator: VisualNavigator

var progression: Double = 0.0
var overrideUrlLoading = true
Expand Down Expand Up @@ -75,18 +75,18 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte
listener.onScroll()

if (scrollMode) {
if (listener.readingProgression == ReadingProgression.RTL) {
if (navigator.readingProgression == ReadingProgression.RTL) {
[email protected]("scrollRightRTL();") { result ->
if (result.contains("edge")) {
listener.goBackward(animated = animated)
navigator.goBackward(animated = animated)
}
}
} else {
listener.goForward(animated = animated)
navigator.goForward(animated = animated)
}
} else {
if ([email protected](1)) {
listener.goForward(animated = animated)
navigator.goRight(animated = animated)
}
[email protected]("scrollRight();", null)
}
Expand All @@ -99,20 +99,24 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte
listener.onScroll()

if (scrollMode) {
if (listener.readingProgression == ReadingProgression.RTL) {
if (navigator.readingProgression == ReadingProgression.RTL) {
[email protected]("scrollLeftRTL();") { result ->
if (result.contains("edge")) {
listener.goForward(animated = animated)
navigator.goForward(animated = animated)
}
}
} else {
listener.goBackward(animated = animated)
navigator.goBackward(animated = animated)
}
} else {
if ([email protected](-1)) {
listener.goBackward(animated = animated)
navigator.goLeft(animated = animated)
}
// This is a temporary fix to prevent the webview from snapping to the beginning
// of the resource when paging between them in RTL layouts
if (navigator.readingProgression == ReadingProgression.LTR) {
[email protected]("scrollLeft();", null)
}
Comment on lines +115 to 119
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stevenzeck What did you mean by temporary? Do you have any idea on how to fix this in a more permanent way?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was temporary in that I was hoping there was a different problem, but I couldn't find one. I'll remove that part of the comment.

[email protected]("scrollLeft();", null)
}
}
}
Expand Down Expand Up @@ -217,7 +221,7 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte
}

fun scrollToPosition(progression: Double) {
this.evaluateJavascript("scrollToPosition(\"$progression\", \"${listener.readingProgression.value}\");", null)
this.evaluateJavascript("scrollToPosition(\"$progression\", \"${navigator.readingProgression.value}\");", null)
}

fun setScrollMode(scrollMode: Boolean) {
Expand Down Expand Up @@ -283,7 +287,6 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte
}

interface Listener {
val readingProgression: ReadingProgression
fun onPageLoaded()
fun onPageChanged(pageIndex: Int, totalPages: Int, url: String)
fun onPageEnded(end: Boolean)
Expand All @@ -292,7 +295,5 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte
fun onProgressionChanged(progression: Double)
fun onHighlightActivated(id: String)
fun onHighlightAnnotationMarkActivated(id: String)
fun goForward(animated: Boolean = false, completion: () -> Unit = {}): Boolean
fun goBackward(animated: Boolean = false, completion: () -> Unit = {}): Boolean
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.viewpager.widget.ViewPager
import androidx.viewpager2.widget.ViewPager2
import kotlinx.coroutines.*
import org.readium.r2.navigator.Navigator
import org.readium.r2.navigator.R
Expand All @@ -36,7 +37,7 @@ class ImageNavigatorFragment(
) : Fragment(), CoroutineScope by MainScope(), VisualNavigator {

internal lateinit var positions: List<Locator>
internal lateinit var resourcePager: R2ViewPager
internal lateinit var resourcePager: ViewPager2

internal lateinit var preferences: SharedPreferences

Expand All @@ -55,17 +56,16 @@ class ImageNavigatorFragment(

preferences = requireContext().getSharedPreferences("org.readium.r2.settings", Context.MODE_PRIVATE)
resourcePager = view.findViewById(R.id.resourcePager)
resourcePager.type = Publication.TYPE.CBZ

positions = runBlocking { publication.positions() }

resourcePager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
resourcePager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
notifyCurrentLocation()
}
})

adapter = R2PagerAdapter(currentActivity.supportFragmentManager, publication.readingOrder, publication.metadata.title, Publication.TYPE.CBZ)
adapter = R2PagerAdapter(currentActivity.supportFragmentManager, lifecycle, publication.readingOrder, publication.metadata.title, Publication.TYPE.CBZ)

resourcePager.adapter = adapter

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.viewpager.widget.ViewPager
import androidx.viewpager2.widget.ViewPager2
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -81,7 +82,7 @@ open class R2CbzActivity : AppCompatActivity(), CoroutineScope, IR2Activity, Vis
get() = Dispatchers.Main

override lateinit var preferences: SharedPreferences
override lateinit var resourcePager: R2ViewPager
override lateinit var resourcePager: ViewPager2
override lateinit var publicationPath: String
override lateinit var publication: Publication
override lateinit var publicationIdentifier: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.viewpager.widget.ViewPager
import androidx.viewpager2.widget.ViewPager2
import kotlinx.coroutines.*
import org.readium.r2.navigator.*
import org.readium.r2.navigator.R
Expand Down Expand Up @@ -47,7 +48,7 @@ class EpubNavigatorFragment(


internal lateinit var positions: List<Locator>
lateinit var resourcePager: R2ViewPager
lateinit var resourcePager: ViewPager2

private lateinit var resourcesSingle: ArrayList<Pair<Int, String>>
private lateinit var resourcesDouble: ArrayList<Triple<Int, String, String>>
Expand All @@ -70,7 +71,6 @@ class EpubNavigatorFragment(
preferences = requireContext().getSharedPreferences("org.readium.r2.settings", Context.MODE_PRIVATE)

resourcePager = view.findViewById(R.id.resourcePager)
resourcePager.type = Publication.TYPE.EPUB

resourcesSingle = ArrayList()
resourcesDouble = ArrayList()
Expand Down Expand Up @@ -117,33 +117,33 @@ class EpubNavigatorFragment(


if (publication.metadata.presentation.layout == EpubLayout.REFLOWABLE) {
adapter = R2PagerAdapter(supportFragmentManager, resourcesSingle, publication.metadata.title, Publication.TYPE.EPUB)
resourcePager.type = Publication.TYPE.EPUB
resourcePager.isUserInputEnabled = false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stevenzeck Why did you need to switch off isUserInputEnabled?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the equivalent of onInterceptTouchEvent/onTouchEvent from the original ViewPager. We have to prevent the ViewPager from paging via user input and do it ourselves, otherwise it will go from resource to resource instead of page to page.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I guess this is the reason FXL EPUB can't be interacted with. Since they are not paginated, maybe this can be done selectively only for reflowable. However I wonder why links are working in reflowable EPUBs despite isUserInputEnabled?

adapter = R2PagerAdapter(supportFragmentManager, lifecycle, resourcesSingle, publication.metadata.title, Publication.TYPE.EPUB)
} else {
resourcePager.type = Publication.TYPE.FXL
adapter = when (preferences.getInt(COLUMN_COUNT_REF, 0)) {
1 -> {
R2PagerAdapter(supportFragmentManager, resourcesSingle, publication.metadata.title, Publication.TYPE.FXL)
R2PagerAdapter(supportFragmentManager, lifecycle, resourcesSingle, publication.metadata.title, Publication.TYPE.FXL)
}
2 -> {
R2PagerAdapter(supportFragmentManager, resourcesDouble, publication.metadata.title, Publication.TYPE.FXL)
R2PagerAdapter(supportFragmentManager, lifecycle, resourcesDouble, publication.metadata.title, Publication.TYPE.FXL)
}
else -> {
// TODO based on device
// TODO decide if 1 page or 2 page
R2PagerAdapter(supportFragmentManager, resourcesSingle, publication.metadata.title, Publication.TYPE.FXL)
R2PagerAdapter(supportFragmentManager, lifecycle, resourcesSingle, publication.metadata.title, Publication.TYPE.FXL)
}
}
}
resourcePager.adapter = adapter

resourcePager.direction = publication.contentLayout.readingProgression
// resourcePager.direction = publication.contentLayout.readingProgression
resourcePager.layoutDirection = View.LAYOUT_DIRECTION_LTR

if (publication.cssStyle == ReadingProgression.RTL.value) {
resourcePager.direction = ReadingProgression.RTL
resourcePager.layoutDirection = View.LAYOUT_DIRECTION_RTL
}
Comment on lines +139 to 144
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

publication.cssStyle will soon be deprecated, so I think we can rely exclusively on publication.contentLayout.readingProgression for now. Something along the line:

resourcePager.layoutDirection = when (publication.contentLayout.readingProgression) {
    ReadingProgression.RTL -> View.Layout_DIRECTION_RTL
    else -> View.Layout_DIRECTION_LTR
}

I'm not yet sure if TTB and BTT will need to be handled differently with the ViewPager2. But it's not used yet anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I was wondering what TTB and BTT are exactly and how they would factor into this. Will make the change you suggested.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's for vertical reading progression: top-to-bottom and bottom-to-top.

I wonder if we could not handle them with https://developer.android.com/reference/kotlin/androidx/viewpager2/widget/ViewPager2#setorientation And then combining it with Layout_DIRECTION_RTL, maybe it would be equivalent to BTT.


resourcePager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
resourcePager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {

override fun onPageSelected(position: Int) {
// if (publication.metadata.presentation.layout == EpubLayout.REFLOWABLE) {
Expand Down Expand Up @@ -317,11 +317,11 @@ class EpubNavigatorFragment(

override fun goForward(animated: Boolean, completion: () -> Unit): Boolean {
launch {
if (resourcePager.currentItem < resourcePager.adapter!!.count - 1) {
if (resourcePager.currentItem < resourcePager.adapter!!.itemCount - 1) {

resourcePager.setCurrentItem(resourcePager.currentItem + 1, animated)

if (currentFragment?.activity?.layoutDirectionIsRTL() ?: publication.contentLayout.readingProgression == ReadingProgression.RTL) {
if (publication.contentLayout.readingProgression == ReadingProgression.RTL) {
// The view has RTL layout
currentFragment?.webView?.apply {
progression = 1.0
Expand All @@ -345,7 +345,7 @@ class EpubNavigatorFragment(

resourcePager.setCurrentItem(resourcePager.currentItem - 1, animated)

if (currentFragment?.activity?.layoutDirectionIsRTL() ?: publication.contentLayout.readingProgression == ReadingProgression.RTL) {
if (publication.contentLayout.readingProgression == ReadingProgression.RTL) {
// The view has RTL layout
currentFragment?.webView?.apply {
progression = 0.0
Expand All @@ -363,11 +363,12 @@ class EpubNavigatorFragment(
return true
}

// FIXME this isn't used
private val r2PagerAdapter: R2PagerAdapter
get() = resourcePager.adapter as R2PagerAdapter

private val currentFragment: R2EpubPageFragment? get() =
r2PagerAdapter.mFragments.get(r2PagerAdapter.getItemId(resourcePager.currentItem)) as? R2EpubPageFragment
val currentFragment: R2EpubPageFragment? get() =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stevenzeck Could you set currentFragment as internal to keep the internals of EpubNavigatorFragment private?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.

adapter.fm.findFragmentByTag("f${resourcePager.currentItem}") as? R2EpubPageFragment

override val readingProgression: ReadingProgression
get() = publication.contentLayout.readingProgression
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import android.view.ActionMode
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.LiveData
import androidx.viewpager2.widget.ViewPager2
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -49,7 +50,7 @@ open class R2EpubActivity: AppCompatActivity(), IR2Activity, IR2Selectable, IR2H
get() = Dispatchers.Main

override lateinit var preferences: SharedPreferences
override lateinit var resourcePager: R2ViewPager
override lateinit var resourcePager: ViewPager2
override lateinit var publicationPath: String
override lateinit var publicationFileName: String
override lateinit var publication: Publication
Expand All @@ -60,15 +61,16 @@ open class R2EpubActivity: AppCompatActivity(), IR2Activity, IR2Selectable, IR2H

protected var navigatorDelegate: NavigatorDelegate? = null

// FIXME This isn't used
val adapter: R2PagerAdapter get() =
resourcePager.adapter as R2PagerAdapter

private val currentFragment: R2EpubPageFragment? get() =
adapter.mFragments.get(adapter.getItemId(resourcePager.currentItem)) as? R2EpubPageFragment

private val navigatorFragment: EpubNavigatorFragment get() =
supportFragmentManager.findFragmentById(R.id.epub_navigator) as EpubNavigatorFragment

private val currentFragment: R2EpubPageFragment? get() =
navigatorFragment.currentFragment

// For backward compatibility, we expose these properties only through the `R2EpubActivity`.
val positions: List<Locator> get() = navigatorFragment.positions
val currentPagerPosition: Int get() = navigatorFragment.currentPagerPosition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,39 +136,36 @@ class R2EpubPageFragment : Fragment() {
super.onPageFinished(view, url)

val epubNavigator = (webView.navigator as? EpubNavigatorFragment)
val currentFragment: R2EpubPageFragment = (epubNavigator?.resourcePager?.adapter as R2PagerAdapter).getCurrentFragment() as R2EpubPageFragment

if ([email protected] == currentFragment.tag) {
var locations = epubNavigator.pendingLocator?.locations
epubNavigator.pendingLocator = null
var locations = epubNavigator?.pendingLocator?.locations
epubNavigator?.pendingLocator = null

// TODO this seems to be needed, will need to test more
if (url!!.indexOf("#") > 0) {
val id = url.substring(url.indexOf('#'))
webView.loadUrl("javascript:scrollAnchor($id);")
locations = Locator.Locations(fragments = listOf(id))
}
// TODO this seems to be needed, will need to test more
if (url!!.indexOf("#") > 0) {
val id = url.substring(url.indexOf('#'))
webView.loadUrl("javascript:scrollAnchor($id);")
locations = Locator.Locations(fragments = listOf(id))
}

if (locations != null && locations.fragments.isEmpty()) {
locations.progression?.let { progression ->
currentFragment.webView.progression = progression

if (webView.scrollMode) {
currentFragment.webView.scrollToPosition(progression)
} else {
// FIXME: We need a better way to wait, because if the value is too low it fails
(object : CountDownTimer(200, 1) {
override fun onTick(millisUntilFinished: Long) {}
override fun onFinish() {
currentFragment.webView.calculateCurrentItem()
currentFragment.webView.setCurrentItem(currentFragment.webView.mCurItem, false)
}
}).start()
}
if (locations != null && locations.fragments.isEmpty()) {
locations.progression?.let { progression ->
[email protected] = progression

if (webView.scrollMode) {
[email protected](progression)
} else {
// FIXME: We need a better way to wait, because if the value is too low it fails
(object : CountDownTimer(200, 1) {
override fun onTick(millisUntilFinished: Long) {}
override fun onFinish() {
[email protected]()
[email protected]([email protected], false)
}
}).start()
}
}

}

webView.listener.onPageLoaded()
}

Expand Down
Loading