diff --git a/CHANGELOG.md b/CHANGELOG.md index 85a6e2cfba..4aa1f41ca4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,9 @@ All notable changes to this project will be documented in this file. Take a look * `WebSettings.textZoom` will work with more publications than `--USER__fontSize`, even the ones poorly authored. However the page width is not adjusted when changing the font size to keep the optimal line length. * Scroll mode: jumping between two EPUB resources with a horizontal swipe triggers the `Navigator.Listener.onJumpToLocator()` callback. * This can be used to allow the user to go back to their previous location if they swiped across chapters by mistake. +* Support for non-linear EPUB resources with an opt-in in reading apps (contributed by @chrfalch in [#375](https://github.com/readium/kotlin-toolkit/pull/375) and [#376](https://github.com/readium/kotlin-toolkit/pull/376)). + 1. Override loading non-linear resources with `VisualNavigator.Listener.shouldJumpToLink()`. + 2. Present a new `EpubNavigatorFragment` by providing a custom `readingOrder` with only this resource to the constructor. #### Streamer diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt index 9bb6b2032e..498415acb4 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/Navigator.kt @@ -136,6 +136,18 @@ interface VisualNavigator : Navigator { } interface Listener : Navigator.Listener { + + /** + * Called when a link to an internal resource was clicked in the navigator. + * + * You can use this callback to perform custom navigation like opening a new window + * or other operations. + * + * By returning false the navigator wont try to open the link itself and it is up + * to the calling app to decide how to display the link. + */ + fun shouldJumpToLink(link: Link): Boolean { return true } + /** * Called when the user tapped the content, but nothing handled the event internally (eg. * by following an internal link). diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt index 54b5e6b5fe..782912dc7d 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt @@ -270,6 +270,7 @@ class EpubNavigatorFragment internal constructor( requireActivity().application, publication, baseUrl = baseUrl, config = this.config, initialPreferences = initialPreferences, + listener = listener, layout = epubLayout, defaults = defaults ) @@ -494,7 +495,7 @@ class EpubNavigatorFragment internal constructor( is EpubNavigatorViewModel.Event.RunScript -> { run(event.command) } - is EpubNavigatorViewModel.Event.GoTo -> { + is EpubNavigatorViewModel.Event.OpenInternalLink -> { go(event.target) } EpubNavigatorViewModel.Event.InvalidateViewPager -> { @@ -1040,7 +1041,8 @@ class EpubNavigatorFragment internal constructor( * if you use a local HTTP server. * @param initialLocator The first location which should be visible when rendering the * publication. Can be used to restore the last reading location. - * @param readingOrder custom reading order + * @param readingOrder Custom order of resources to display. Used for example to display a + * non-linear resource on its own. * @param listener Optional listener to implement to observe events, such as user taps. * @param config Additional configuration. */ diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorViewModel.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorViewModel.kt index 9ce65e2f86..8d33368173 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorViewModel.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorViewModel.kt @@ -52,6 +52,7 @@ internal class EpubNavigatorViewModel( val config: EpubNavigatorFragment.Configuration, initialPreferences: EpubPreferences, val layout: EpubLayout, + val listener: VisualNavigator.Listener?, private val defaults: EpubDefaults, baseUrl: String?, private val server: WebViewServer?, @@ -76,7 +77,7 @@ internal class EpubNavigatorViewModel( } sealed class Event { - data class GoTo(val target: Link) : Event() + data class OpenInternalLink(val target: Link) : Event() data class OpenExternalLink(val url: Uri) : Event() /** Refreshes all the resources in the view pager. */ object InvalidateViewPager : Event() @@ -205,7 +206,9 @@ internal class EpubNavigatorViewModel( val href = url.toString() val link = internalLinkFromUrl(href) if (link != null) { - _events.send(Event.GoTo(link)) + if (listener?.shouldJumpToLink(link) == true) { + _events.send(Event.OpenInternalLink(link)) + } } else { _events.send(Event.OpenExternalLink(url)) } @@ -384,12 +387,13 @@ internal class EpubNavigatorViewModel( publication: Publication, baseUrl: String?, layout: EpubLayout, + listener: VisualNavigator.Listener?, defaults: EpubDefaults, config: EpubNavigatorFragment.Configuration, initialPreferences: EpubPreferences ) = createViewModelFactory { EpubNavigatorViewModel( - application, publication, config, initialPreferences, layout, + application, publication, config, initialPreferences, layout, listener, defaults = defaults, baseUrl = baseUrl, server = if (baseUrl != null) null