-
Notifications
You must be signed in to change notification settings - Fork 29
Use epub navigator fragment #148
Conversation
r2-navigator/src/main/java/org/readium/r2/navigator/IR2Activity.kt
Outdated
Show resolved
Hide resolved
|
||
lateinit var activity: AppCompatActivity | ||
lateinit var listener: IR2Activity | ||
lateinit var activity: IR2Activity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the WebView
should access the Activity
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. To properly decouple the web view from the Activity
and the EpubNavigatorFragment
(it could potentially be used with other fragments), you can add a R2BasicWebView.Listener
interface with all the APIs you need to remove activity
, fragment
and listener
.
Something like:
interface R2BasicWebView.Listener {
fun onPageLoaded()
fun onScroll()
fun onTap() // To replace the `listener.toggleActionBar()`
fun onProgressionChanged(Double)
fun onHighlightActivated(id)
fun onHighlightAnnotationMarkActivated(id)
fun goForward(animated: Boolean)
fun goBackward(animated: Boolean)
}
Additionally, you can also add a readingProgression: ReadingProgression
property, because we need it to do the scrollToPosition()
JS call. You can also save the scroll mode set in setScrollMode()
in a scrollMode
variable, to not need access to the preferences.
With all this, the scrollLeft/Right()
functions can be simplified with something like:
@android.webkit.JavascriptInterface
open fun scrollRight(animated: Boolean = false) {
uiScope.launch {
// The whole supportActionBar piece of code should be done in the Fragment.
listener.onScroll()
if (scrollMode) {
if (readingProgression == ReadingProgression.RTL) {
this@R2BasicWebView.evaluateJavascript("scrollRightRTL();") { result ->
if (result.contains("edge")) {
listener.goBackward(animated = animated)
}
}
} else {
listener.goForward(animated = animated)
}
} else {
if (!this@R2BasicWebView.canScrollHorizontally(1)) {
listener.goForward(animated = animated)
}
this@R2BasicWebView.evaluateJavascript("scrollRight();", null)
}
}
}
By the way you can check out the comments on this PR which is related to this: #112
@android.webkit.JavascriptInterface | ||
fun centerTapped() { | ||
listener.toggleActionBar() | ||
listener.onTap(PointF(0F, 0F)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here : why is the WebView
behaving in the name of the Activity
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it shouldn't, you can use listener.onTap()
described in the other comment, and then in the Fragment
you can call the actual VisualListener.onTap()
with the point. Until we have a real Point
value, you can use the center of the Fragment
as a reference, because using (0, 0)
might trigger some issues if an app decides to do some action when tapping on the left border (e.g. going backward).
|
||
// Initialize a new instance of LayoutInflater service | ||
val inflater = activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater | ||
val inflater = fragment.requireActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@johanpoirier For this we should be able to use context.getSystemService
without having the fragment
or activity
as dependency.
4c92cfb
to
f2bee1d
Compare
f2bee1d
to
4407424
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a larger issue with the locators. The table of content is not working anymore and the last reading position is not restored.
divinaWebView = findViewById(R.id.divinaWebView) | ||
divinaWebView.activity = this | ||
divinaWebView.listener = this | ||
//divinaWebView.listener = this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not doing anything for DiViNa right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, that's fine as we'll tackle DiViNa soon with an updated version of the JS player.
// } | ||
// } | ||
// | ||
// } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know what to do with this block of code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to keep it as this is what handles the restoration inside a resource.
That's probably why you see this issue you described in another comment:
The table of content is not working anymore and the last reading position is not restored.
What issue do you have with this piece of code?
If it's val epubNavigator = (webView.navigator as? R2EpubActivity)
, I think we can adapt it without changing too much stuff by using the EpubNavigatorFragment
instead:
val epubNavigator = (webView.navigator as? EpubNavigator)
Alternatively, we can create a R2EpubPageFragment.Listener
to expose the pendingLocator
from the EpubNavigatorFragment
, or reuse the one from R2BasicWebView.Listener
and access it through webView.listener.pendingLocator
.
R2EpubPageFragment.Listener
is probably cleaner but I'll do more clean up later on in the EPUB navigator, so as long as the code is private, you can implement what's the most convenient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I changed the first line to that:
val epubNavigator = (webView.navigator as? EpubNavigatorFragment)
val currentFragment: R2EpubPageFragment = (epubNavigator?.resourcePager?.adapter as R2PagerAdapter).getCurrentFragment() as R2EpubPageFragment
But this line is never true when a chapter reaches the end:
if (this@R2EpubPageFragment.tag == currentFragment.tag) {
I may need an interactive review if you have some time before the end of the week.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I may need an interactive review if you have some time before the end of the week.
Sure, I'll try to take a look tomorrow.
interface Listener { | ||
fun onPageLoaded() {} | ||
fun onScroll() {} | ||
fun onTap(point: PointF): Boolean = false | ||
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 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mickael-menu did you have that in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah exactly 👍
} | ||
|
||
override val readingProgression: ReadingProgression | ||
get() = TODO("Not yet implemented") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know how and where to set this variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You just need to report the one from the Publication
, this is an alias to expose it to reading apps.
get() = TODO("Not yet implemented") | |
get() = publication.contentLayout.readingProgression |
} | ||
} | ||
Publication.TYPE.DiViNa -> TODO() | ||
Publication.TYPE.PDF -> TODO() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@johanpoirier Publication.Type.PDF
is not part of r2-shared
at the moment, could you make sure that the PR builds with the alpha
branches of the other repos?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also have some issues in the test-app with some APIs that doesn't exist in the Web View:
r2-testapp/src/main/java/org/readium/r2/testapp/epub/UserSettings.kt: (375, 73): Unresolved reference: setScrollMode
@mickael-menu does this PR needs more work? |
I won't have the time to do a complete review before 2 weeks (holidays), but if it works in your app, it should be fine. We're still missing the navigator for CBZ ( |
Is this a small part of readium/kotlin-toolkit#176? |
Yes it is. |
+1 |
Fix NavigatorDelegate Make the glue Listeners internals
…, otherwise it will not be used during configuration changes
Rename Navigator.VisualListener to VisualNavigator.Listener Fix shadowed members goLeft() and goRight() Implement goForward/goBackward for CBZ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@johanpoirier Thanks again for this most-wanted contribution!
This is the implementation of the
EpubNavigatorFragment
following the slack discussion with @mickael-menuI have still a lot of questions on this issue, some of them will be posted as comments.