-
Notifications
You must be signed in to change notification settings - Fork 71
/
Navigator.kt
89 lines (77 loc) · 3.52 KB
/
Navigator.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
* Copyright 2021 Readium Foundation. All rights reserved.
* Use of this source code is governed by the BSD-style license
* available in the top-level LICENSE file of the project.
*/
package org.readium.r2.navigator
import kotlinx.coroutines.flow.StateFlow
import org.readium.r2.shared.publication.Link
import org.readium.r2.shared.publication.Locator
import org.readium.r2.shared.util.Url
import org.readium.r2.shared.util.data.ReadError
/**
* Base interface for a navigator rendering a publication.
*
* A few points to keep in mind when implementing this interface:
*
* - **The navigator should have a minimal UX** and be focused only on browsing and interacting with
* the document. However, it offers a rich API to build a user interface around it.
* - **The last read page (progression) should not be persisted and restored by the navigator.**
* Instead, the reading app will save the [Locator] reported by the navigator in [currentLocator],
* and provide the initial location when creating the navigator.
* - **User accessibility settings should override the behavior when needed** (eg. disabling
* animated transition, even when requested by the caller).
* - **The navigator is the single source of truth for the current location.**
* - **The navigator should only provide a minimal gestures/interactions set.** For example,
* scrolling through a web view or zooming a fixed image is expected from the user. But additional
* interactions such as tapping/clicking the edge of the page to skip to the next one should be
* implemented by the reading app, and not the navigator.
*/
public interface Navigator {
/**
* Current position in the publication.
* Can be used to save a bookmark to the current position.
*/
public val currentLocator: StateFlow<Locator>
/**
* Moves to the position in the publication corresponding to the given [Locator].
*/
public fun go(locator: Locator, animated: Boolean = false, completion: () -> Unit = {}): Boolean
/**
* Moves to the position in the publication targeted by the given link.
*/
public fun go(link: Link, animated: Boolean = false, completion: () -> Unit = {}): Boolean
public interface Listener {
/**
* Called when a publication resource failed to be loaded.
*/
public fun onResourceLoadFailed(href: Url, error: ReadError) {}
/**
* Called when the navigator jumps to an explicit location, which might break the linear
* reading progression.
*
* For example, it is called when clicking on internal links or programmatically calling
* [go], but not when turning pages.
*
* You can use this callback to implement a navigation history by differentiating between
* continuous and discontinuous moves.
*/
public fun onJumpToLocator(locator: Locator) {}
}
@Deprecated(
"Use [currentLocator.value] instead",
ReplaceWith("currentLocator.value"),
level = DeprecationLevel.ERROR
)
public val currentLocation: Locator? get() = currentLocator.value
@Deprecated(
"Use [VisualNavigator.Listener] instead",
ReplaceWith("VisualNavigator.Listener"),
level = DeprecationLevel.ERROR
)
public interface VisualListener : VisualNavigator.Listener
}
public interface NavigatorDelegate {
@Deprecated("Observe [currentLocator] instead", level = DeprecationLevel.ERROR)
public fun locationDidChange(navigator: Navigator? = null, locator: Locator) {}
}