Skip to content
This repository was archived by the owner on Jul 29, 2022. It is now read-only.

Conversation

johanpoirier
Copy link
Contributor

@johanpoirier johanpoirier commented Jul 13, 2020

This is the implementation of the EpubNavigatorFragment following the slack discussion with @mickael-menu

I have still a lot of questions on this issue, some of them will be posted as comments.


lateinit var activity: AppCompatActivity
lateinit var listener: IR2Activity
lateinit var activity: IR2Activity
Copy link
Contributor Author

@johanpoirier johanpoirier Jul 13, 2020

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 ?

Copy link
Member

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))
Copy link
Contributor Author

@johanpoirier johanpoirier Jul 13, 2020

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 ?

Copy link
Member

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
Copy link
Member

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.

Copy link
Contributor Author

@johanpoirier johanpoirier left a 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
Copy link
Contributor Author

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.

Copy link
Member

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.

// }
// }
//
// }
Copy link
Contributor Author

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.

Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Member

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.

Comment on lines 289 to 298
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
}
Copy link
Contributor Author

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?

Copy link
Member

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")
Copy link
Contributor Author

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.

Copy link
Member

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.

Suggested change
get() = TODO("Not yet implemented")
get() = publication.contentLayout.readingProgression

}
}
Publication.TYPE.DiViNa -> TODO()
Publication.TYPE.PDF -> TODO()
Copy link
Member

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?

Copy link
Member

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

@johanpoirier
Copy link
Contributor Author

@mickael-menu does this PR needs more work?

@mickael-menu
Copy link
Member

@johanpoirier

@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 (ImageNavigatorFragment), if you want to complete the PR. Audiobooks will be handled differently, as we want to provide a chromeless navigator to leave full control over the UX for reading apps. So it doesn't make sense as a Fragment.

@stevenzeck
Copy link
Contributor

stevenzeck commented Jul 25, 2020

Is this a small part of readium/kotlin-toolkit#176?

@johanpoirier
Copy link
Contributor Author

Is this a small part of readium/kotlin-toolkit#176?

Yes it is.

@johanpoirier johanpoirier marked this pull request as ready for review August 4, 2020 08:27
@paulocoutinhox
Copy link

+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
Copy link
Member

@mickael-menu mickael-menu left a 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!

@mickael-menu mickael-menu merged commit f374c0e into readium:alpha Aug 7, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants