react-native-readium 5.0.0-rc.11 → 5.0.0-rc.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -7
- package/android/src/main/java/com/reactnativereadium/HybridReadiumView.kt +12 -15
- package/ios/HybridReadiumView.swift +9 -24
- package/lib/nitrogen/generated/shared/json/ReadiumViewConfig.json +0 -1
- package/lib/src/components/ReadiumView.js +1 -0
- package/lib/src/components/ReadiumView.types.d.ts +1 -1
- package/lib/src/components/ReadiumView.web.js +12 -3
- package/lib/src/specs/ReadiumView.nitro.d.ts +1 -1
- package/lib/web/hooks/index.d.ts +0 -1
- package/lib/web/hooks/index.js +0 -1
- package/nitrogen/generated/android/c++/JHybridReadiumViewSpec.cpp +4 -9
- package/nitrogen/generated/android/c++/JHybridReadiumViewSpec.hpp +1 -2
- package/nitrogen/generated/android/c++/views/JHybridReadiumViewStateUpdater.cpp +0 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativereadium/HybridReadiumViewSpec.kt +4 -6
- package/nitrogen/generated/ios/c++/HybridReadiumViewSpecSwift.hpp +6 -7
- package/nitrogen/generated/ios/c++/views/HybridReadiumViewComponent.mm +0 -5
- package/nitrogen/generated/ios/swift/HybridReadiumViewSpec.swift +1 -1
- package/nitrogen/generated/ios/swift/HybridReadiumViewSpec_cxx.swift +11 -17
- package/nitrogen/generated/shared/c++/HybridReadiumViewSpec.cpp +1 -2
- package/nitrogen/generated/shared/c++/HybridReadiumViewSpec.hpp +4 -5
- package/nitrogen/generated/shared/c++/views/HybridReadiumViewComponent.cpp +0 -11
- package/nitrogen/generated/shared/c++/views/HybridReadiumViewComponent.hpp +1 -2
- package/nitrogen/generated/shared/json/ReadiumViewConfig.json +0 -1
- package/package.json +1 -1
- package/src/components/ReadiumView.tsx +1 -0
- package/src/components/ReadiumView.types.ts +1 -1
- package/src/components/ReadiumView.web.tsx +9 -3
- package/src/specs/ReadiumView.nitro.ts +1 -1
- package/web/hooks/index.ts +0 -1
- package/lib/web/hooks/useLocationObserver.d.ts +0 -3
- package/lib/web/hooks/useLocationObserver.js +0 -21
- package/web/hooks/useLocationObserver.ts +0 -32
package/README.md
CHANGED
|
@@ -326,8 +326,7 @@ DRM is not supported at this time. However, there is a clear path to [support it
|
|
|
326
326
|
|
|
327
327
|
| Name | Type | Optional | Description |
|
|
328
328
|
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
329
|
-
| `file` | [`File`](https://github.com/5-stones/react-native-readium/blob/main/src/interfaces/File.ts) | :x: | A file object containing the path to the eBook file on disk.
|
|
330
|
-
| `location` | [`Locator`](https://github.com/5-stones/react-native-readium/blob/main/src/interfaces/Locator.ts) \| [`Link`](https://github.com/5-stones/react-native-readium/blob/main/src/interfaces/Link.ts) | :white_check_mark: | A locator prop that allows you to externally control the location of the reader (e.g. Chapters or Bookmarks). <br/><br/>:warning: If you want to set the `location` of an ebook on initial load, you should use the `File.initialLocation` property (look at the `file` prop). See more [here](https://github.com/5-stones/react-native-readium/issues/16#issuecomment-1344128937) |
|
|
329
|
+
| `file` | [`File`](https://github.com/5-stones/react-native-readium/blob/main/src/interfaces/File.ts) | :x: | A file object containing the path to the eBook file on disk. Use `File.initialLocation` to set the reader's position on mount. |
|
|
331
330
|
| `preferences` | [`Partial<Preferences>`](https://github.com/readium/swift-toolkit/blob/main/docs/Guides/Navigator%20Preferences.md#appendix-preference-constraints) | :white_check_mark: | An object that allows you to control various aspects of the reader's UI (epub only) |
|
|
332
331
|
| `decorations` | [`DecorationGroup[]`](https://github.com/5-stones/react-native-readium/blob/main/src/interfaces/Decoration.ts) | :white_check_mark: | An array of decoration groups to render in the publication (e.g. highlights, underlines). |
|
|
333
332
|
| `selectionActions` | [`SelectionAction[]`](https://github.com/5-stones/react-native-readium/blob/main/src/interfaces/SelectionAction.ts) | :white_check_mark: | Custom actions to show in the context menu when the user selects text. |
|
|
@@ -345,11 +344,15 @@ The `ReadiumView` component accepts a ref that exposes imperative navigation met
|
|
|
345
344
|
```tsx
|
|
346
345
|
import React, { useRef } from 'react';
|
|
347
346
|
import { ReadiumView } from 'react-native-readium';
|
|
348
|
-
import type { ReadiumViewRef } from 'react-native-readium';
|
|
347
|
+
import type { ReadiumViewRef, Locator } from 'react-native-readium';
|
|
349
348
|
|
|
350
349
|
const MyComponent: React.FC = () => {
|
|
351
350
|
const ref = useRef<ReadiumViewRef>(null);
|
|
352
351
|
|
|
352
|
+
const goToChapter = (locator: Locator) => {
|
|
353
|
+
ref.current?.goTo(locator);
|
|
354
|
+
};
|
|
355
|
+
|
|
353
356
|
return (
|
|
354
357
|
<>
|
|
355
358
|
<ReadiumView ref={ref} file={file} />
|
|
@@ -360,10 +363,11 @@ const MyComponent: React.FC = () => {
|
|
|
360
363
|
};
|
|
361
364
|
```
|
|
362
365
|
|
|
363
|
-
| Method
|
|
364
|
-
|
|
|
365
|
-
| `
|
|
366
|
-
| `
|
|
366
|
+
| Method | Description |
|
|
367
|
+
| ------------------ | -------------------------------------------------------------------------------- |
|
|
368
|
+
| `goTo(locator)` | Navigate to a specific location in the publication (e.g. a chapter or bookmark). |
|
|
369
|
+
| `goForward()` | Navigate forward in the publication (e.g. next page). |
|
|
370
|
+
| `goBackward()` | Navigate backward in the publication (e.g. previous page). |
|
|
367
371
|
|
|
368
372
|
#### :warning: Web vs Native File URLs
|
|
369
373
|
|
|
@@ -79,12 +79,6 @@ class HybridReadiumView(private val context: android.content.Context) : HybridRe
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
override var location: Locator? = null
|
|
83
|
-
set(value) {
|
|
84
|
-
field = value
|
|
85
|
-
updateLocation()
|
|
86
|
-
}
|
|
87
|
-
|
|
88
82
|
override var preferences: Preferences? = null
|
|
89
83
|
set(value) {
|
|
90
84
|
field = value
|
|
@@ -118,15 +112,6 @@ class HybridReadiumView(private val context: android.content.Context) : HybridRe
|
|
|
118
112
|
}
|
|
119
113
|
}
|
|
120
114
|
|
|
121
|
-
// MARK: - Location
|
|
122
|
-
|
|
123
|
-
private fun updateLocation() {
|
|
124
|
-
val loc = location ?: return
|
|
125
|
-
val frag = fragment ?: return
|
|
126
|
-
val readiumLocator = nitroLocatorToReadium(loc) ?: return
|
|
127
|
-
frag.go(com.reactnativereadium.utils.LinkOrLocator.Locator(readiumLocator), true)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
115
|
// MARK: - Preferences
|
|
131
116
|
|
|
132
117
|
private fun updatePreferences() {
|
|
@@ -159,6 +144,18 @@ class HybridReadiumView(private val context: android.content.Context) : HybridRe
|
|
|
159
144
|
|
|
160
145
|
// MARK: - Imperative navigation
|
|
161
146
|
|
|
147
|
+
override fun goTo(locator: Locator) {
|
|
148
|
+
val action = Runnable {
|
|
149
|
+
val readiumLocator = nitroLocatorToReadium(locator) ?: return@Runnable
|
|
150
|
+
fragment?.go(com.reactnativereadium.utils.LinkOrLocator.Locator(readiumLocator), true)
|
|
151
|
+
}
|
|
152
|
+
if (android.os.Looper.myLooper() == android.os.Looper.getMainLooper()) {
|
|
153
|
+
action.run()
|
|
154
|
+
} else {
|
|
155
|
+
hostView.post(action)
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
162
159
|
override fun goForward() { fragment?.goForward() }
|
|
163
160
|
override fun goBackward() { fragment?.goBackward() }
|
|
164
161
|
override fun destroy() {
|
|
@@ -21,12 +21,6 @@ class HybridReadiumView: HybridReadiumViewSpec {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
var location: Locator? = nil {
|
|
25
|
-
didSet {
|
|
26
|
-
updateLocation()
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
24
|
var preferences: Preferences? = nil {
|
|
31
25
|
didSet {
|
|
32
26
|
updatePreferences()
|
|
@@ -115,24 +109,6 @@ class HybridReadiumView: HybridReadiumViewSpec {
|
|
|
115
109
|
)
|
|
116
110
|
}
|
|
117
111
|
|
|
118
|
-
// MARK: - Location
|
|
119
|
-
|
|
120
|
-
private func updateLocation() {
|
|
121
|
-
Task { @MainActor [weak self] in
|
|
122
|
-
guard let self = self else { return }
|
|
123
|
-
guard let navigator = self.readerViewController?.navigator else { return }
|
|
124
|
-
guard let loc = self.location else { return }
|
|
125
|
-
guard let locator = nitroLocatorToReadium(loc) else { return }
|
|
126
|
-
|
|
127
|
-
let currentLocation = navigator.currentLocation
|
|
128
|
-
if let currentLocation, locator.hashValue == currentLocation.hashValue {
|
|
129
|
-
return
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
_ = await navigator.go(to: locator, options: .animated)
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
112
|
// MARK: - Preferences
|
|
137
113
|
|
|
138
114
|
private func updatePreferences() {
|
|
@@ -267,6 +243,15 @@ class HybridReadiumView: HybridReadiumViewSpec {
|
|
|
267
243
|
|
|
268
244
|
// MARK: - Imperative navigation
|
|
269
245
|
|
|
246
|
+
func goTo(locator: Locator) {
|
|
247
|
+
Task { @MainActor [weak self] in
|
|
248
|
+
guard let self else { return }
|
|
249
|
+
guard let navigator = self.readerViewController?.navigator else { return }
|
|
250
|
+
guard let readiumLocator = nitroLocatorToReadium(locator) else { return }
|
|
251
|
+
_ = await navigator.go(to: readiumLocator, options: .animated)
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
270
255
|
func goForward() {
|
|
271
256
|
Task { @MainActor in
|
|
272
257
|
guard let navigator = readerViewController?.navigator else { return }
|
|
@@ -25,6 +25,7 @@ export const ReadiumView = forwardRef(({ onLocationChange, onPublicationReady, o
|
|
|
25
25
|
});
|
|
26
26
|
}, [onPublicationReady]);
|
|
27
27
|
useImperativeHandle(forwardedRef, () => ({
|
|
28
|
+
goTo: (locator) => hybridRef.current?.goTo(locator),
|
|
28
29
|
goForward: () => hybridRef.current?.goForward(),
|
|
29
30
|
goBackward: () => hybridRef.current?.goBackward(),
|
|
30
31
|
}), []);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Preferences, Locator, File, DecorationGroup, SelectionAction, PublicationReadyEvent, DecorationActivatedEvent, SelectionEvent, SelectionActionEvent } from '../interfaces';
|
|
2
2
|
export type ReadiumViewRef = {
|
|
3
|
+
goTo: (locator: Locator) => void;
|
|
3
4
|
goForward: () => void;
|
|
4
5
|
goBackward: () => void;
|
|
5
6
|
};
|
|
6
7
|
export type ReadiumProps = {
|
|
7
8
|
file: File;
|
|
8
|
-
location?: Locator;
|
|
9
9
|
preferences: Preferences;
|
|
10
10
|
decorations?: DecorationGroup[];
|
|
11
11
|
selectionActions?: SelectionAction[];
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React, { useEffect, useImperativeHandle, useState } from 'react';
|
|
2
2
|
import { View, StyleSheet } from 'react-native';
|
|
3
|
-
import { useNavigator, usePreferencesObserver,
|
|
4
|
-
|
|
3
|
+
import { useNavigator, usePreferencesObserver, useDecorationsObserver, } from '../../web/hooks';
|
|
4
|
+
import { convertToNavigatorLocator } from '../../web/utils/locationNormalizer';
|
|
5
|
+
export const ReadiumView = React.forwardRef(({ file, preferences, decorations, onLocationChange, onPublicationReady, onDecorationActivated, style = {}, height, width, }, ref) => {
|
|
5
6
|
const [container, setContainer] = useState(null);
|
|
6
7
|
const [currentPosition, setCurrentPosition] = useState(null);
|
|
7
8
|
// Convert DecorationGroup[] to DecorationGroups record for web hooks
|
|
@@ -16,6 +17,15 @@ export const ReadiumView = React.forwardRef(({ file, preferences, location, deco
|
|
|
16
17
|
onPositionChange: setCurrentPosition,
|
|
17
18
|
});
|
|
18
19
|
useImperativeHandle(ref, () => ({
|
|
20
|
+
goTo: (locator) => {
|
|
21
|
+
if (!navigator)
|
|
22
|
+
return;
|
|
23
|
+
const navLocator = convertToNavigatorLocator(locator);
|
|
24
|
+
if (navLocator) {
|
|
25
|
+
// @ts-ignore
|
|
26
|
+
navigator.go(navLocator, true, () => { });
|
|
27
|
+
}
|
|
28
|
+
},
|
|
19
29
|
goForward: () => {
|
|
20
30
|
navigator?.goForward(true, () => { });
|
|
21
31
|
},
|
|
@@ -32,7 +42,6 @@ export const ReadiumView = React.forwardRef(({ file, preferences, location, deco
|
|
|
32
42
|
},
|
|
33
43
|
}), [navigator]);
|
|
34
44
|
usePreferencesObserver(navigator, preferences);
|
|
35
|
-
useLocationObserver(navigator, location);
|
|
36
45
|
useDecorationsObserver(navigator, decorationsRecord, onDecorationActivated);
|
|
37
46
|
// Generate position label text
|
|
38
47
|
const positionLabel = currentPosition && positions.length > 0
|
|
@@ -180,7 +180,6 @@ export interface ReadiumFile {
|
|
|
180
180
|
}
|
|
181
181
|
export interface ReadiumViewProps extends HybridViewProps {
|
|
182
182
|
file?: ReadiumFile;
|
|
183
|
-
location?: Locator;
|
|
184
183
|
preferences?: Preferences;
|
|
185
184
|
decorations?: DecorationGroup[];
|
|
186
185
|
selectionActions?: SelectionAction[];
|
|
@@ -191,6 +190,7 @@ export interface ReadiumViewProps extends HybridViewProps {
|
|
|
191
190
|
onSelectionAction?: (event: SelectionActionEvent) => void;
|
|
192
191
|
}
|
|
193
192
|
export interface ReadiumViewMethods extends HybridViewMethods {
|
|
193
|
+
goTo(locator: Locator): void;
|
|
194
194
|
goForward(): void;
|
|
195
195
|
goBackward(): void;
|
|
196
196
|
destroy(): void;
|
package/lib/web/hooks/index.d.ts
CHANGED
package/lib/web/hooks/index.js
CHANGED
|
@@ -157,15 +157,6 @@ namespace margelo::nitro::readium {
|
|
|
157
157
|
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JReadiumFile> /* file */)>("setFile");
|
|
158
158
|
method(_javaPart, file.has_value() ? JReadiumFile::fromCpp(file.value()) : nullptr);
|
|
159
159
|
}
|
|
160
|
-
std::optional<Locator> JHybridReadiumViewSpec::getLocation() {
|
|
161
|
-
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JLocator>()>("getLocation");
|
|
162
|
-
auto __result = method(_javaPart);
|
|
163
|
-
return __result != nullptr ? std::make_optional(__result->toCpp()) : std::nullopt;
|
|
164
|
-
}
|
|
165
|
-
void JHybridReadiumViewSpec::setLocation(const std::optional<Locator>& location) {
|
|
166
|
-
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JLocator> /* location */)>("setLocation");
|
|
167
|
-
method(_javaPart, location.has_value() ? JLocator::fromCpp(location.value()) : nullptr);
|
|
168
|
-
}
|
|
169
160
|
std::optional<Preferences> JHybridReadiumViewSpec::getPreferences() {
|
|
170
161
|
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPreferences>()>("getPreferences");
|
|
171
162
|
auto __result = method(_javaPart);
|
|
@@ -316,6 +307,10 @@ namespace margelo::nitro::readium {
|
|
|
316
307
|
}
|
|
317
308
|
|
|
318
309
|
// Methods
|
|
310
|
+
void JHybridReadiumViewSpec::goTo(const Locator& locator) {
|
|
311
|
+
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JLocator> /* locator */)>("goTo");
|
|
312
|
+
method(_javaPart, JLocator::fromCpp(locator));
|
|
313
|
+
}
|
|
319
314
|
void JHybridReadiumViewSpec::goForward() {
|
|
320
315
|
static const auto method = javaClassStatic()->getMethod<void()>("goForward");
|
|
321
316
|
method(_javaPart);
|
|
@@ -53,8 +53,6 @@ namespace margelo::nitro::readium {
|
|
|
53
53
|
// Properties
|
|
54
54
|
std::optional<ReadiumFile> getFile() override;
|
|
55
55
|
void setFile(const std::optional<ReadiumFile>& file) override;
|
|
56
|
-
std::optional<Locator> getLocation() override;
|
|
57
|
-
void setLocation(const std::optional<Locator>& location) override;
|
|
58
56
|
std::optional<Preferences> getPreferences() override;
|
|
59
57
|
void setPreferences(const std::optional<Preferences>& preferences) override;
|
|
60
58
|
std::optional<std::vector<DecorationGroup>> getDecorations() override;
|
|
@@ -74,6 +72,7 @@ namespace margelo::nitro::readium {
|
|
|
74
72
|
|
|
75
73
|
public:
|
|
76
74
|
// Methods
|
|
75
|
+
void goTo(const Locator& locator) override;
|
|
77
76
|
void goForward() override;
|
|
78
77
|
void goBackward() override;
|
|
79
78
|
void destroy() override;
|
|
@@ -41,10 +41,6 @@ void JHybridReadiumViewStateUpdater::updateViewProps(jni::alias_ref<jni::JClass>
|
|
|
41
41
|
view->setFile(props->file.value);
|
|
42
42
|
props->file.isDirty = false;
|
|
43
43
|
}
|
|
44
|
-
if (props->location.isDirty) {
|
|
45
|
-
view->setLocation(props->location.value);
|
|
46
|
-
props->location.isDirty = false;
|
|
47
|
-
}
|
|
48
44
|
if (props->preferences.isDirty) {
|
|
49
45
|
view->setPreferences(props->preferences.value);
|
|
50
46
|
props->preferences.isDirty = false;
|
|
@@ -48,12 +48,6 @@ abstract class HybridReadiumViewSpec: HybridView() {
|
|
|
48
48
|
@set:Keep
|
|
49
49
|
abstract var file: ReadiumFile?
|
|
50
50
|
|
|
51
|
-
@get:DoNotStrip
|
|
52
|
-
@get:Keep
|
|
53
|
-
@set:DoNotStrip
|
|
54
|
-
@set:Keep
|
|
55
|
-
abstract var location: Locator?
|
|
56
|
-
|
|
57
51
|
@get:DoNotStrip
|
|
58
52
|
@get:Keep
|
|
59
53
|
@set:DoNotStrip
|
|
@@ -143,6 +137,10 @@ abstract class HybridReadiumViewSpec: HybridView() {
|
|
|
143
137
|
}
|
|
144
138
|
|
|
145
139
|
// Methods
|
|
140
|
+
@DoNotStrip
|
|
141
|
+
@Keep
|
|
142
|
+
abstract fun goTo(locator: Locator): Unit
|
|
143
|
+
|
|
146
144
|
@DoNotStrip
|
|
147
145
|
@Keep
|
|
148
146
|
abstract fun goForward(): Unit
|
|
@@ -141,13 +141,6 @@ namespace margelo::nitro::readium {
|
|
|
141
141
|
inline void setFile(const std::optional<ReadiumFile>& file) noexcept override {
|
|
142
142
|
_swiftPart.setFile(file);
|
|
143
143
|
}
|
|
144
|
-
inline std::optional<Locator> getLocation() noexcept override {
|
|
145
|
-
auto __result = _swiftPart.getLocation();
|
|
146
|
-
return __result;
|
|
147
|
-
}
|
|
148
|
-
inline void setLocation(const std::optional<Locator>& location) noexcept override {
|
|
149
|
-
_swiftPart.setLocation(location);
|
|
150
|
-
}
|
|
151
144
|
inline std::optional<Preferences> getPreferences() noexcept override {
|
|
152
145
|
auto __result = _swiftPart.getPreferences();
|
|
153
146
|
return __result;
|
|
@@ -207,6 +200,12 @@ namespace margelo::nitro::readium {
|
|
|
207
200
|
|
|
208
201
|
public:
|
|
209
202
|
// Methods
|
|
203
|
+
inline void goTo(const Locator& locator) override {
|
|
204
|
+
auto __result = _swiftPart.goTo(std::forward<decltype(locator)>(locator));
|
|
205
|
+
if (__result.hasError()) [[unlikely]] {
|
|
206
|
+
std::rethrow_exception(__result.error());
|
|
207
|
+
}
|
|
208
|
+
}
|
|
210
209
|
inline void goForward() override {
|
|
211
210
|
auto __result = _swiftPart.goForward();
|
|
212
211
|
if (__result.hasError()) [[unlikely]] {
|
|
@@ -77,11 +77,6 @@ using namespace margelo::nitro::readium::views;
|
|
|
77
77
|
swiftPart.setFile(newViewProps.file.value);
|
|
78
78
|
newViewProps.file.isDirty = false;
|
|
79
79
|
}
|
|
80
|
-
// location: optional
|
|
81
|
-
if (newViewProps.location.isDirty) {
|
|
82
|
-
swiftPart.setLocation(newViewProps.location.value);
|
|
83
|
-
newViewProps.location.isDirty = false;
|
|
84
|
-
}
|
|
85
80
|
// preferences: optional
|
|
86
81
|
if (newViewProps.preferences.isDirty) {
|
|
87
82
|
swiftPart.setPreferences(newViewProps.preferences.value);
|
|
@@ -11,7 +11,6 @@ import NitroModules
|
|
|
11
11
|
public protocol HybridReadiumViewSpec_protocol: HybridObject, HybridView {
|
|
12
12
|
// Properties
|
|
13
13
|
var file: ReadiumFile? { get set }
|
|
14
|
-
var location: Locator? { get set }
|
|
15
14
|
var preferences: Preferences? { get set }
|
|
16
15
|
var decorations: [DecorationGroup]? { get set }
|
|
17
16
|
var selectionActions: [SelectionAction]? { get set }
|
|
@@ -22,6 +21,7 @@ public protocol HybridReadiumViewSpec_protocol: HybridObject, HybridView {
|
|
|
22
21
|
var onSelectionAction: ((_ event: SelectionActionEvent) -> Void)? { get set }
|
|
23
22
|
|
|
24
23
|
// Methods
|
|
24
|
+
func goTo(locator: Locator) throws -> Void
|
|
25
25
|
func goForward() throws -> Void
|
|
26
26
|
func goBackward() throws -> Void
|
|
27
27
|
func destroy() throws -> Void
|
|
@@ -138,23 +138,6 @@ open class HybridReadiumViewSpec_cxx {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
public final var location: bridge.std__optional_Locator_ {
|
|
142
|
-
@inline(__always)
|
|
143
|
-
get {
|
|
144
|
-
return { () -> bridge.std__optional_Locator_ in
|
|
145
|
-
if let __unwrappedValue = self.__implementation.location {
|
|
146
|
-
return bridge.create_std__optional_Locator_(__unwrappedValue)
|
|
147
|
-
} else {
|
|
148
|
-
return .init()
|
|
149
|
-
}
|
|
150
|
-
}()
|
|
151
|
-
}
|
|
152
|
-
@inline(__always)
|
|
153
|
-
set {
|
|
154
|
-
self.__implementation.location = newValue.value
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
141
|
public final var preferences: bridge.std__optional_Preferences_ {
|
|
159
142
|
@inline(__always)
|
|
160
143
|
get {
|
|
@@ -393,6 +376,17 @@ open class HybridReadiumViewSpec_cxx {
|
|
|
393
376
|
}
|
|
394
377
|
|
|
395
378
|
// Methods
|
|
379
|
+
@inline(__always)
|
|
380
|
+
public final func goTo(locator: Locator) -> bridge.Result_void_ {
|
|
381
|
+
do {
|
|
382
|
+
try self.__implementation.goTo(locator: locator)
|
|
383
|
+
return bridge.create_Result_void_()
|
|
384
|
+
} catch (let __error) {
|
|
385
|
+
let __exceptionPtr = __error.toCpp()
|
|
386
|
+
return bridge.create_Result_void_(__exceptionPtr)
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
396
390
|
@inline(__always)
|
|
397
391
|
public final func goForward() -> bridge.Result_void_ {
|
|
398
392
|
do {
|
|
@@ -16,8 +16,6 @@ namespace margelo::nitro::readium {
|
|
|
16
16
|
registerHybrids(this, [](Prototype& prototype) {
|
|
17
17
|
prototype.registerHybridGetter("file", &HybridReadiumViewSpec::getFile);
|
|
18
18
|
prototype.registerHybridSetter("file", &HybridReadiumViewSpec::setFile);
|
|
19
|
-
prototype.registerHybridGetter("location", &HybridReadiumViewSpec::getLocation);
|
|
20
|
-
prototype.registerHybridSetter("location", &HybridReadiumViewSpec::setLocation);
|
|
21
19
|
prototype.registerHybridGetter("preferences", &HybridReadiumViewSpec::getPreferences);
|
|
22
20
|
prototype.registerHybridSetter("preferences", &HybridReadiumViewSpec::setPreferences);
|
|
23
21
|
prototype.registerHybridGetter("decorations", &HybridReadiumViewSpec::getDecorations);
|
|
@@ -34,6 +32,7 @@ namespace margelo::nitro::readium {
|
|
|
34
32
|
prototype.registerHybridSetter("onSelectionChange", &HybridReadiumViewSpec::setOnSelectionChange);
|
|
35
33
|
prototype.registerHybridGetter("onSelectionAction", &HybridReadiumViewSpec::getOnSelectionAction);
|
|
36
34
|
prototype.registerHybridSetter("onSelectionAction", &HybridReadiumViewSpec::setOnSelectionAction);
|
|
35
|
+
prototype.registerHybridMethod("goTo", &HybridReadiumViewSpec::goTo);
|
|
37
36
|
prototype.registerHybridMethod("goForward", &HybridReadiumViewSpec::goForward);
|
|
38
37
|
prototype.registerHybridMethod("goBackward", &HybridReadiumViewSpec::goBackward);
|
|
39
38
|
prototype.registerHybridMethod("destroy", &HybridReadiumViewSpec::destroy);
|
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
|
|
16
16
|
// Forward declaration of `ReadiumFile` to properly resolve imports.
|
|
17
17
|
namespace margelo::nitro::readium { struct ReadiumFile; }
|
|
18
|
-
// Forward declaration of `Locator` to properly resolve imports.
|
|
19
|
-
namespace margelo::nitro::readium { struct Locator; }
|
|
20
18
|
// Forward declaration of `Preferences` to properly resolve imports.
|
|
21
19
|
namespace margelo::nitro::readium { struct Preferences; }
|
|
22
20
|
// Forward declaration of `DecorationGroup` to properly resolve imports.
|
|
23
21
|
namespace margelo::nitro::readium { struct DecorationGroup; }
|
|
24
22
|
// Forward declaration of `SelectionAction` to properly resolve imports.
|
|
25
23
|
namespace margelo::nitro::readium { struct SelectionAction; }
|
|
24
|
+
// Forward declaration of `Locator` to properly resolve imports.
|
|
25
|
+
namespace margelo::nitro::readium { struct Locator; }
|
|
26
26
|
// Forward declaration of `PublicationReadyEvent` to properly resolve imports.
|
|
27
27
|
namespace margelo::nitro::readium { struct PublicationReadyEvent; }
|
|
28
28
|
// Forward declaration of `DecorationActivatedEvent` to properly resolve imports.
|
|
@@ -34,11 +34,11 @@ namespace margelo::nitro::readium { struct SelectionActionEvent; }
|
|
|
34
34
|
|
|
35
35
|
#include "ReadiumFile.hpp"
|
|
36
36
|
#include <optional>
|
|
37
|
-
#include "Locator.hpp"
|
|
38
37
|
#include "Preferences.hpp"
|
|
39
38
|
#include "DecorationGroup.hpp"
|
|
40
39
|
#include <vector>
|
|
41
40
|
#include "SelectionAction.hpp"
|
|
41
|
+
#include "Locator.hpp"
|
|
42
42
|
#include <functional>
|
|
43
43
|
#include "PublicationReadyEvent.hpp"
|
|
44
44
|
#include "DecorationActivatedEvent.hpp"
|
|
@@ -74,8 +74,6 @@ namespace margelo::nitro::readium {
|
|
|
74
74
|
// Properties
|
|
75
75
|
virtual std::optional<ReadiumFile> getFile() = 0;
|
|
76
76
|
virtual void setFile(const std::optional<ReadiumFile>& file) = 0;
|
|
77
|
-
virtual std::optional<Locator> getLocation() = 0;
|
|
78
|
-
virtual void setLocation(const std::optional<Locator>& location) = 0;
|
|
79
77
|
virtual std::optional<Preferences> getPreferences() = 0;
|
|
80
78
|
virtual void setPreferences(const std::optional<Preferences>& preferences) = 0;
|
|
81
79
|
virtual std::optional<std::vector<DecorationGroup>> getDecorations() = 0;
|
|
@@ -95,6 +93,7 @@ namespace margelo::nitro::readium {
|
|
|
95
93
|
|
|
96
94
|
public:
|
|
97
95
|
// Methods
|
|
96
|
+
virtual void goTo(const Locator& locator) = 0;
|
|
98
97
|
virtual void goForward() = 0;
|
|
99
98
|
virtual void goBackward() = 0;
|
|
100
99
|
virtual void destroy() = 0;
|
|
@@ -36,16 +36,6 @@ namespace margelo::nitro::readium::views {
|
|
|
36
36
|
throw std::runtime_error(std::string("ReadiumView.file: ") + exc.what());
|
|
37
37
|
}
|
|
38
38
|
}()),
|
|
39
|
-
location([&]() -> CachedProp<std::optional<Locator>> {
|
|
40
|
-
try {
|
|
41
|
-
const react::RawValue* rawValue = rawProps.at("location", nullptr, nullptr);
|
|
42
|
-
if (rawValue == nullptr) return sourceProps.location;
|
|
43
|
-
const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
|
|
44
|
-
return CachedProp<std::optional<Locator>>::fromRawValue(*runtime, value, sourceProps.location);
|
|
45
|
-
} catch (const std::exception& exc) {
|
|
46
|
-
throw std::runtime_error(std::string("ReadiumView.location: ") + exc.what());
|
|
47
|
-
}
|
|
48
|
-
}()),
|
|
49
39
|
preferences([&]() -> CachedProp<std::optional<Preferences>> {
|
|
50
40
|
try {
|
|
51
41
|
const react::RawValue* rawValue = rawProps.at("preferences", nullptr, nullptr);
|
|
@@ -140,7 +130,6 @@ namespace margelo::nitro::readium::views {
|
|
|
140
130
|
bool HybridReadiumViewProps::filterObjectKeys(const std::string& propName) {
|
|
141
131
|
switch (hashString(propName)) {
|
|
142
132
|
case hashString("file"): return true;
|
|
143
|
-
case hashString("location"): return true;
|
|
144
133
|
case hashString("preferences"): return true;
|
|
145
134
|
case hashString("decorations"): return true;
|
|
146
135
|
case hashString("selectionActions"): return true;
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
|
|
19
19
|
#include "ReadiumFile.hpp"
|
|
20
20
|
#include <optional>
|
|
21
|
-
#include "Locator.hpp"
|
|
22
21
|
#include "Preferences.hpp"
|
|
23
22
|
#include "DecorationGroup.hpp"
|
|
24
23
|
#include <vector>
|
|
25
24
|
#include "SelectionAction.hpp"
|
|
25
|
+
#include "Locator.hpp"
|
|
26
26
|
#include <functional>
|
|
27
27
|
#include "PublicationReadyEvent.hpp"
|
|
28
28
|
#include "DecorationActivatedEvent.hpp"
|
|
@@ -52,7 +52,6 @@ namespace margelo::nitro::readium::views {
|
|
|
52
52
|
|
|
53
53
|
public:
|
|
54
54
|
CachedProp<std::optional<ReadiumFile>> file;
|
|
55
|
-
CachedProp<std::optional<Locator>> location;
|
|
56
55
|
CachedProp<std::optional<Preferences>> preferences;
|
|
57
56
|
CachedProp<std::optional<std::vector<DecorationGroup>>> decorations;
|
|
58
57
|
CachedProp<std::optional<std::vector<SelectionAction>>> selectionActions;
|
package/package.json
CHANGED
|
@@ -67,6 +67,7 @@ export const ReadiumView = forwardRef<ReadiumViewRef, ReadiumProps>(
|
|
|
67
67
|
useImperativeHandle(
|
|
68
68
|
forwardedRef,
|
|
69
69
|
() => ({
|
|
70
|
+
goTo: (locator) => hybridRef.current?.goTo(locator),
|
|
70
71
|
goForward: () => hybridRef.current?.goForward(),
|
|
71
72
|
goBackward: () => hybridRef.current?.goBackward(),
|
|
72
73
|
}),
|
|
@@ -11,13 +11,13 @@ import type {
|
|
|
11
11
|
} from '../interfaces';
|
|
12
12
|
|
|
13
13
|
export type ReadiumViewRef = {
|
|
14
|
+
goTo: (locator: Locator) => void;
|
|
14
15
|
goForward: () => void;
|
|
15
16
|
goBackward: () => void;
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
export type ReadiumProps = {
|
|
19
20
|
file: File;
|
|
20
|
-
location?: Locator;
|
|
21
21
|
preferences: Preferences;
|
|
22
22
|
decorations?: DecorationGroup[];
|
|
23
23
|
selectionActions?: SelectionAction[];
|
|
@@ -5,9 +5,9 @@ import { View, StyleSheet } from 'react-native';
|
|
|
5
5
|
import {
|
|
6
6
|
useNavigator,
|
|
7
7
|
usePreferencesObserver,
|
|
8
|
-
useLocationObserver,
|
|
9
8
|
useDecorationsObserver,
|
|
10
9
|
} from '../../web/hooks';
|
|
10
|
+
import { convertToNavigatorLocator } from '../../web/utils/locationNormalizer';
|
|
11
11
|
import type { ReadiumProps as BaseReadiumProps, ReadiumViewRef as BaseReadiumViewRef } from './ReadiumView.types';
|
|
12
12
|
|
|
13
13
|
export type ReadiumProps = BaseReadiumProps & {
|
|
@@ -27,7 +27,6 @@ export const ReadiumView = React.forwardRef<ReadiumViewRef, ReadiumProps>(
|
|
|
27
27
|
{
|
|
28
28
|
file,
|
|
29
29
|
preferences,
|
|
30
|
-
location,
|
|
31
30
|
decorations,
|
|
32
31
|
onLocationChange,
|
|
33
32
|
onPublicationReady,
|
|
@@ -57,6 +56,14 @@ export const ReadiumView = React.forwardRef<ReadiumViewRef, ReadiumProps>(
|
|
|
57
56
|
useImperativeHandle(
|
|
58
57
|
ref,
|
|
59
58
|
() => ({
|
|
59
|
+
goTo: (locator) => {
|
|
60
|
+
if (!navigator) return;
|
|
61
|
+
const navLocator = convertToNavigatorLocator(locator);
|
|
62
|
+
if (navLocator) {
|
|
63
|
+
// @ts-ignore
|
|
64
|
+
navigator.go(navLocator, true, () => {});
|
|
65
|
+
}
|
|
66
|
+
},
|
|
60
67
|
goForward: () => {
|
|
61
68
|
navigator?.goForward(true, () => {});
|
|
62
69
|
},
|
|
@@ -76,7 +83,6 @@ export const ReadiumView = React.forwardRef<ReadiumViewRef, ReadiumProps>(
|
|
|
76
83
|
);
|
|
77
84
|
|
|
78
85
|
usePreferencesObserver(navigator, preferences);
|
|
79
|
-
useLocationObserver(navigator, location);
|
|
80
86
|
useDecorationsObserver(navigator, decorationsRecord, onDecorationActivated);
|
|
81
87
|
|
|
82
88
|
// Generate position label text
|
|
@@ -228,7 +228,6 @@ export interface ReadiumFile {
|
|
|
228
228
|
|
|
229
229
|
export interface ReadiumViewProps extends HybridViewProps {
|
|
230
230
|
file?: ReadiumFile;
|
|
231
|
-
location?: Locator;
|
|
232
231
|
preferences?: Preferences;
|
|
233
232
|
decorations?: DecorationGroup[];
|
|
234
233
|
selectionActions?: SelectionAction[];
|
|
@@ -240,6 +239,7 @@ export interface ReadiumViewProps extends HybridViewProps {
|
|
|
240
239
|
}
|
|
241
240
|
|
|
242
241
|
export interface ReadiumViewMethods extends HybridViewMethods {
|
|
242
|
+
goTo(locator: Locator): void;
|
|
243
243
|
goForward(): void;
|
|
244
244
|
goBackward(): void;
|
|
245
245
|
destroy(): void;
|
package/web/hooks/index.ts
CHANGED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { useRef } from 'react';
|
|
2
|
-
import { useDeepCompareEffect } from 'use-deep-compare';
|
|
3
|
-
export const useLocationObserver = (navigator, location) => {
|
|
4
|
-
// Track the last location we navigated to, preventing feedback loops:
|
|
5
|
-
// navigator.go() → positionChanged → onLocationChange → setLocation → go() again
|
|
6
|
-
const lastNavigatedRef = useRef(null);
|
|
7
|
-
const locator = location;
|
|
8
|
-
const href = locator?.href;
|
|
9
|
-
const progression = locator?.locations?.progression;
|
|
10
|
-
useDeepCompareEffect(() => {
|
|
11
|
-
if (!navigator || !location)
|
|
12
|
-
return;
|
|
13
|
-
const fingerprint = `${href}:${progression}`;
|
|
14
|
-
if (fingerprint === lastNavigatedRef.current) {
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
lastNavigatedRef.current = fingerprint;
|
|
18
|
-
// @ts-ignore
|
|
19
|
-
navigator.go(location, true, () => { });
|
|
20
|
-
}, [href, progression, !!navigator]);
|
|
21
|
-
};
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { useRef } from 'react';
|
|
2
|
-
import { useDeepCompareEffect } from 'use-deep-compare';
|
|
3
|
-
import { EpubNavigator } from '@readium/navigator';
|
|
4
|
-
|
|
5
|
-
import type { Link, Locator } from '../../src/interfaces';
|
|
6
|
-
|
|
7
|
-
export const useLocationObserver = (
|
|
8
|
-
navigator?: EpubNavigator | null,
|
|
9
|
-
location?: Link | Locator | null
|
|
10
|
-
) => {
|
|
11
|
-
// Track the last location we navigated to, preventing feedback loops:
|
|
12
|
-
// navigator.go() → positionChanged → onLocationChange → setLocation → go() again
|
|
13
|
-
const lastNavigatedRef = useRef<string | null>(null);
|
|
14
|
-
|
|
15
|
-
const locator = location as Locator | null;
|
|
16
|
-
const href = locator?.href;
|
|
17
|
-
const progression = locator?.locations?.progression;
|
|
18
|
-
|
|
19
|
-
useDeepCompareEffect(() => {
|
|
20
|
-
if (!navigator || !location) return;
|
|
21
|
-
|
|
22
|
-
const fingerprint = `${href}:${progression}`;
|
|
23
|
-
|
|
24
|
-
if (fingerprint === lastNavigatedRef.current) {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
lastNavigatedRef.current = fingerprint;
|
|
29
|
-
// @ts-ignore
|
|
30
|
-
navigator.go(location, true, () => {});
|
|
31
|
-
}, [href, progression, !!navigator]);
|
|
32
|
-
};
|