Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into merge-develop
Browse files Browse the repository at this point in the history
  • Loading branch information
qnga committed Oct 4, 2023
2 parents 8ce3359 + f87dd95 commit a1f5eec
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 12 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ All notable changes to this project will be documented in this file. Take a look
* 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 keyboard events in the EPUB, PDF and image navigators. See `VisualNavigator.addInputListener()`.
* 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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,18 @@ public interface VisualNavigator : Navigator {
public fun removeInputListener(listener: InputListener)

public 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.
*/
public fun shouldJumpToLink(link: Link): Boolean { return true }

@Deprecated("Use `addInputListener` instead", level = DeprecationLevel.ERROR)
public fun onTap(point: PointF): Boolean = false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package org.readium.r2.navigator.epub
import androidx.fragment.app.FragmentFactory
import org.readium.r2.navigator.ExperimentalDecorator
import org.readium.r2.shared.ExperimentalReadiumApi
import org.readium.r2.shared.publication.Link
import org.readium.r2.shared.publication.Locator
import org.readium.r2.shared.publication.Publication
import org.readium.r2.shared.publication.epub.EpubLayout
Expand Down Expand Up @@ -38,9 +39,23 @@ public class EpubNavigatorFactory(
private val layout: EpubLayout =
publication.metadata.presentation.layout ?: EpubLayout.REFLOWABLE

/**
* Creates a factory for [EpubNavigatorFragment].
*
* @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 to override the publication's one.
* @param initialPreferences The set of preferences that should be initially applied to the
* navigator.
* @param listener Optional listener to implement to observe navigator events.
* @param paginationListener Optional listener to implement to observe events related to
* pagination.
* @param configuration Additional configuration.
*/
@OptIn(ExperimentalDecorator::class)
public fun createFragmentFactory(
initialLocator: Locator?,
readingOrder: List<Link>? = null,
initialPreferences: EpubPreferences = EpubPreferences(),
listener: EpubNavigatorFragment.Listener? = null,
paginationListener: EpubNavigatorFragment.PaginationListener? = null,
Expand All @@ -49,6 +64,7 @@ public class EpubNavigatorFactory(
EpubNavigatorFragment(
publication = publication,
initialLocator = initialLocator,
readingOrder = readingOrder,
initialPreferences = initialPreferences,
listener = listener,
paginationListener = paginationListener,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ public typealias JavascriptInterfaceFactory = (resource: Link) -> Any?
public class EpubNavigatorFragment internal constructor(
override val publication: Publication,
private val initialLocator: Locator?,
readingOrder: List<Link>?,
private val initialPreferences: EpubPreferences,
internal val listener: Listener?,
internal val paginationListener: PaginationListener?,
Expand Down Expand Up @@ -286,12 +287,21 @@ public class EpubNavigatorFragment internal constructor(
publication,
config = this.config,
initialPreferences = initialPreferences,
listener = listener,
layout = epubLayout,
defaults = defaults
)
}

internal lateinit var positionsByReadingOrder: List<List<Locator>>
private val readingOrder: List<Link> = readingOrder ?: publication.readingOrder

private val positionsByReadingOrder: List<List<Locator>> =
if (readingOrder != null) {
emptyList()
} else {
runBlocking { publication.positionsByReadingOrder() }
}

internal lateinit var positions: List<Locator>

internal lateinit var resourcePager: R2ViewPager
Expand Down Expand Up @@ -321,12 +331,11 @@ public class EpubNavigatorFragment internal constructor(
_binding = ReadiumNavigatorViewpagerBinding.inflate(inflater, container, false)
var view: View = binding.root

positionsByReadingOrder = runBlocking { publication.positionsByReadingOrder() }
positions = positionsByReadingOrder.flatten()

when (viewModel.layout) {
EpubLayout.REFLOWABLE -> {
resourcesSingle = publication.readingOrder.mapIndexed { index, link ->
resourcesSingle = readingOrder.mapIndexed { index, link ->
PageResource.EpubReflowable(
link = link,
url = viewModel.urlTo(link),
Expand All @@ -341,9 +350,9 @@ public class EpubNavigatorFragment internal constructor(

// TODO needs work, currently showing two resources for fxl, needs to understand which two resources, left & right, or only right etc.
var doublePageLeft: Link? = null
var doublePageRight: Link?
var doublePageRight: Link? = null

for ((index, link) in publication.readingOrder.withIndex()) {
for ((index, link) in readingOrder.withIndex()) {
val url = viewModel.urlTo(link)
resourcesSingle.add(PageResource.EpubFxl(leftLink = link, leftUrl = url))

Expand Down Expand Up @@ -517,7 +526,7 @@ public 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 -> {
Expand Down Expand Up @@ -915,7 +924,7 @@ public class EpubNavigatorFragment internal constructor(
locatorToResourceAtIndex(resourcePager.currentItem + 1)

private fun locatorToResourceAtIndex(index: Int): Locator? =
publication.readingOrder.getOrNull(index)
readingOrder.getOrNull(index)
?.let { publication.locatorFromLink(it) }

private val r2PagerAdapter: R2PagerAdapter?
Expand Down Expand Up @@ -952,8 +961,8 @@ public class EpubNavigatorFragment internal constructor(

override val currentLocator: StateFlow<Locator> get() = _currentLocator
private val _currentLocator = MutableStateFlow(
initialLocator?.let { publication.normalizeLocator(it) }
?: requireNotNull(publication.locatorFromLink(publication.readingOrder.first()))
initialLocator
?: requireNotNull(publication.locatorFromLink(this.readingOrder.first()))
)

/**
Expand All @@ -964,7 +973,7 @@ public class EpubNavigatorFragment internal constructor(
override suspend fun firstVisibleElementLocator(): Locator? {
if (!::resourcePager.isInitialized) return null

val resource = publication.readingOrder[resourcePager.currentItem]
val resource = readingOrder[resourcePager.currentItem]
return currentReflowablePageFragment?.webView?.findFirstVisibleLocator()
?.copy(
href = resource.url(),
Expand Down Expand Up @@ -1071,6 +1080,8 @@ public class EpubNavigatorFragment internal constructor(
* @param initialLocator The first location which should be visible when rendering the
* publication. Can be used to restore the last reading location.
* @param listener Optional listener to implement to observe events, such as user taps.
* @param readingOrder Custom order of resources to display. Used for example to display a
* non-linear resource on its own.
* @param config Additional configuration.
*/
@Deprecated(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ internal class EpubNavigatorViewModel(
val config: EpubNavigatorFragment.Configuration,
initialPreferences: EpubPreferences,
val layout: EpubLayout,
val listener: VisualNavigator.Listener?,
private val defaults: EpubDefaults,
private val server: WebViewServer
) : AndroidViewModel(application) {
Expand All @@ -66,7 +67,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: Url) : Event()

/** Refreshes all the resources in the view pager. */
Expand Down Expand Up @@ -177,7 +178,9 @@ internal class EpubNavigatorViewModel(
fun navigateToUrl(url: AbsoluteUrl) = viewModelScope.launch {
val link = internalLinkFromUrl(url)
if (link != null) {
_events.send(Event.GoTo(link))
if (listener?.shouldJumpToLink(link) == true) {
_events.send(Event.OpenInternalLink(link))
}
} else {
_events.send(Event.OpenExternalLink(url))
}
Expand Down Expand Up @@ -338,6 +341,7 @@ internal class EpubNavigatorViewModel(
application: Application,
publication: Publication,
layout: EpubLayout,
listener: VisualNavigator.Listener?,
defaults: EpubDefaults,
config: EpubNavigatorFragment.Configuration,
initialPreferences: EpubPreferences
Expand All @@ -348,6 +352,7 @@ internal class EpubNavigatorViewModel(
config,
initialPreferences,
layout,
listener,
defaults = defaults,
server = WebViewServer(
application,
Expand Down

0 comments on commit a1f5eec

Please sign in to comment.