react-native-simple-epub-reader 0.1.2 → 0.1.3
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/lib/module/components/Reader.js +36 -13
- package/lib/module/components/Reader.js.map +1 -1
- package/lib/module/constants/template.js +214 -255
- package/lib/module/constants/template.js.map +1 -1
- package/lib/module/helpers/downloadEpub.js +8 -1
- package/lib/module/helpers/downloadEpub.js.map +1 -1
- package/lib/typescript/src/components/Reader.d.ts.map +1 -1
- package/lib/typescript/src/constants/template.d.ts +1 -1
- package/lib/typescript/src/constants/template.d.ts.map +1 -1
- package/lib/typescript/src/helpers/downloadEpub.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/Reader.tsx +42 -16
- package/src/constants/template.ts +214 -255
- package/src/helpers/downloadEpub.ts +9 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export default `
|
|
2
|
-
<!
|
|
3
|
-
<html>
|
|
2
|
+
<!DOCTYPE html>
|
|
3
|
+
<html>
|
|
4
4
|
<head>
|
|
5
|
-
<meta charset="utf-8"
|
|
5
|
+
<meta charset="utf-8">
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>EPUB.js</title>
|
|
8
8
|
<script id="jszip"></script>
|
|
@@ -11,7 +11,7 @@ export default `
|
|
|
11
11
|
<style type="text/css">
|
|
12
12
|
body {
|
|
13
13
|
margin: 0;
|
|
14
|
-
background-color: #
|
|
14
|
+
background-color: #211F26;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
#viewer {
|
|
@@ -23,18 +23,16 @@ export default `
|
|
|
23
23
|
align-items: center;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
[ref=
|
|
27
|
-
background: url(
|
|
28
|
-
no-repeat;
|
|
26
|
+
[ref="epubjs-mk-balloon"] {
|
|
27
|
+
background: url("data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPScxLjEnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycgeG1sbnM6eGxpbms9J2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnIHg9JzBweCcgeT0nMHB4JyB2aWV3Qm94PScwIDAgNzUgNzUnPjxnIGZpbGw9JyNCREJEQkQnIGlkPSdidWJibGUnPjxwYXRoIGNsYXNzPSdzdDAnIGQ9J00zNy41LDkuNEMxOS42LDkuNCw1LDIwLjUsNSwzNC4zYzAsNS45LDIuNywxMS4zLDcuMSwxNS42TDkuNiw2NS42bDE5LTcuM2MyLjgsMC42LDUuOCwwLjksOC45LDAuOSBDNTUuNSw1OS4yLDcwLDQ4LjEsNzAsMzQuM0M3MCwyMC41LDU1LjQsOS40LDM3LjUsOS40eicvPjwvZz48L3N2Zz4=") no-repeat;
|
|
29
28
|
width: 20px;
|
|
30
29
|
height: 20px;
|
|
31
30
|
cursor: pointer;
|
|
32
31
|
margin-left: 0;
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
[ref=
|
|
36
|
-
background: url(
|
|
37
|
-
no-repeat;
|
|
34
|
+
[ref="epubjs-mk-heart"] {
|
|
35
|
+
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOUlEQVR4nLWUTWgTURDH14Oe9JiPNqFNujvvzdsm3bdvPxKMFUEPag/iwdaD3j1JDymlCMXiqUeRHvWgFRQUxKPirUU8eFARvCnUj7QXP7DiJtk8easJjRjzIQ784bEz82Pe7MzTtP9tpmnu8UbNpOM4uzvFKF+3GM1BHHIAbwjA7xyY5AaGPuCarZtHmzGcsGM+YevKp2JUrAN4XeW2wSxKMy6wrSkKtbsiJZ96SfnAGZbl8bG6DawhdLwqAK9xYI25XLaufCrmjkjJKQpVF3DLzrDRFtAHXJ9hUNsoxOTH8hn5afGcrBRjkR66w3I/0GoJaPWRO9T63tRGISanmVHzgK1FMBvGmSr/iZeUn5fL8svlRbl5aKQt6bGXjPQ7bKefA5MOIahZOpsuAQmUY3t1pWNSN5WABtwwT2kW4Mki0OqgoMov+YA1rrMTmk3IhCr3hd/5St303EtEV54Yw5xq4y4PcHOFt/etH12xRqQHWFGsn/MFuHAQaPCmGO8b9roQl5OEBpaB862xoZTuc4F+uJDLhv0CF/LZ0DPoe9M097YNNwd2hAMLb9rpnmGrdlr1LrQJO/zH9bMMnBWA4X0n1RV2T6TU6oUc2Pm/vQ0aN/CSAKzfFp0rvWWnI5gNbEnrxWwD59UOL+UzjXc7ftTbYlxezGca0X4Dm+sJ1jQO7LgA/Hoa9eCln5Cv/IQ8i3ogAL+pZdAGMYcQdAGfHSAkmCQkUOc8pXQgWNPUgysAl5XU+Z9gg9gPaBjV+CGbZVoAAAAASUVORK5CYII=") no-repeat;
|
|
38
36
|
width: 20px;
|
|
39
37
|
height: 20px;
|
|
40
38
|
cursor: pointer;
|
|
@@ -43,7 +41,7 @@ export default `
|
|
|
43
41
|
</style>
|
|
44
42
|
</head>
|
|
45
43
|
|
|
46
|
-
<body oncopy=
|
|
44
|
+
<body oncopy='return false' oncut='return false'>
|
|
47
45
|
<div id="viewer"></div>
|
|
48
46
|
|
|
49
47
|
<script>
|
|
@@ -59,151 +57,114 @@ export default `
|
|
|
59
57
|
const allowPopups = window.allowPopups || false;
|
|
60
58
|
|
|
61
59
|
if (!file) {
|
|
62
|
-
const reactNativeWebview =
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
reactNativeWebview.postMessage(
|
|
68
|
-
JSON.stringify({
|
|
69
|
-
type: 'onDisplayError',
|
|
70
|
-
reason: 'Book file is missing',
|
|
71
|
-
})
|
|
72
|
-
);
|
|
60
|
+
const reactNativeWebview = window.ReactNativeWebView !== undefined && window.ReactNativeWebView !== null ? window.ReactNativeWebView : window;
|
|
61
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
62
|
+
type: "onDisplayError",
|
|
63
|
+
reason: "Book file is missing"
|
|
64
|
+
}));
|
|
73
65
|
}
|
|
74
66
|
|
|
75
67
|
if (type === 'epub' || type === 'opf' || type === 'binary') {
|
|
76
68
|
book = ePub(file);
|
|
77
69
|
} else if (type === 'base64') {
|
|
78
|
-
book = ePub(file, { encoding:
|
|
70
|
+
book = ePub(file, { encoding: "base64" });
|
|
79
71
|
} else {
|
|
80
|
-
const reactNativeWebview =
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
reactNativeWebview.postMessage(
|
|
86
|
-
JSON.stringify({
|
|
87
|
-
type: 'onDisplayError',
|
|
88
|
-
reason: 'Missing or invalid file type',
|
|
89
|
-
})
|
|
90
|
-
);
|
|
72
|
+
const reactNativeWebview = window.ReactNativeWebView !== undefined && window.ReactNativeWebView !== null ? window.ReactNativeWebView : window;
|
|
73
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
74
|
+
type: "onDisplayError",
|
|
75
|
+
reason: "Missing or invalid file type"
|
|
76
|
+
}));
|
|
91
77
|
}
|
|
92
78
|
|
|
93
|
-
rendition = book.renderTo(
|
|
94
|
-
width:
|
|
95
|
-
height:
|
|
96
|
-
manager:
|
|
97
|
-
flow:
|
|
79
|
+
rendition = book.renderTo("viewer", {
|
|
80
|
+
width: "100%",
|
|
81
|
+
height: "100%",
|
|
82
|
+
manager: "default",
|
|
83
|
+
flow: "auto",
|
|
98
84
|
snap: undefined,
|
|
99
85
|
spread: undefined,
|
|
100
86
|
fullsize: undefined,
|
|
101
87
|
allowPopups: allowPopups,
|
|
102
|
-
allowScriptedContent: allowScriptedContent
|
|
88
|
+
allowScriptedContent: allowScriptedContent
|
|
103
89
|
});
|
|
104
|
-
|
|
105
|
-
const reactNativeWebview =
|
|
106
|
-
|
|
107
|
-
window.ReactNativeWebView !== null
|
|
108
|
-
? window.ReactNativeWebView
|
|
109
|
-
: window;
|
|
110
|
-
reactNativeWebview.postMessage(JSON.stringify({ type: 'onStarted' }));
|
|
90
|
+
|
|
91
|
+
const reactNativeWebview = window.ReactNativeWebView !== undefined && window.ReactNativeWebView!== null ? window.ReactNativeWebView: window;
|
|
92
|
+
reactNativeWebview.postMessage(JSON.stringify({ type: "onStarted" }));
|
|
111
93
|
|
|
112
94
|
function flatten(chapters) {
|
|
113
|
-
return [].concat.apply(
|
|
114
|
-
[],
|
|
115
|
-
chapters.map((chapter) =>
|
|
116
|
-
[].concat.apply([chapter], flatten(chapter.subitems))
|
|
117
|
-
)
|
|
118
|
-
);
|
|
95
|
+
return [].concat.apply([], chapters.map((chapter) => [].concat.apply([chapter], flatten(chapter.subitems))));
|
|
119
96
|
}
|
|
120
97
|
|
|
121
98
|
function getCfiFromHref(book, href) {
|
|
122
|
-
const [_, id] = href.split('#')
|
|
123
|
-
let section =
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const el = id
|
|
129
|
-
? section.document.getElementById(id)
|
|
130
|
-
: section.document.body;
|
|
131
|
-
return section.cfiFromElement(el);
|
|
99
|
+
const [_, id] = href.split('#')
|
|
100
|
+
let section = book.spine.get(href.split('/')[1]) || book.spine.get(href) || book.spine.get(href.split('/').slice(1).join('/'))
|
|
101
|
+
|
|
102
|
+
const el = (id ? section.document.getElementById(id) : section.document.body)
|
|
103
|
+
return section.cfiFromElement(el)
|
|
132
104
|
}
|
|
133
105
|
|
|
134
106
|
function getChapter(location) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}, null);
|
|
149
|
-
|
|
150
|
-
return match;
|
|
151
|
-
}
|
|
107
|
+
const locationHref = location.start.href
|
|
108
|
+
|
|
109
|
+
let match = flatten(book.navigation.toc)
|
|
110
|
+
.filter((chapter) => {
|
|
111
|
+
return book.canonical(chapter.href).includes(locationHref)
|
|
112
|
+
}, null)
|
|
113
|
+
.reduce((result, chapter) => {
|
|
114
|
+
const locationAfterChapter = ePub.CFI.prototype.compare(location.start.cfi, getCfiFromHref(book, chapter.href)) > 0
|
|
115
|
+
return locationAfterChapter ? chapter : result
|
|
116
|
+
}, null);
|
|
117
|
+
|
|
118
|
+
return match;
|
|
119
|
+
};
|
|
152
120
|
|
|
153
121
|
const makeRangeCfi = (a, b) => {
|
|
154
|
-
const CFI = new ePub.CFI()
|
|
155
|
-
const start = CFI.parse(a),
|
|
156
|
-
end = CFI.parse(b);
|
|
122
|
+
const CFI = new ePub.CFI()
|
|
123
|
+
const start = CFI.parse(a), end = CFI.parse(b)
|
|
157
124
|
const cfi = {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
const len = cfi.start.steps.length
|
|
125
|
+
range: true,
|
|
126
|
+
base: start.base,
|
|
127
|
+
path: {
|
|
128
|
+
steps: [],
|
|
129
|
+
terminal: null
|
|
130
|
+
},
|
|
131
|
+
start: start.path,
|
|
132
|
+
end: end.path
|
|
133
|
+
}
|
|
134
|
+
const len = cfi.start.steps.length
|
|
168
135
|
for (let i = 0; i < len; i++) {
|
|
169
136
|
if (CFI.equalStep(cfi.start.steps[i], cfi.end.steps[i])) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
} else break
|
|
137
|
+
if (i == len - 1) {
|
|
138
|
+
// Last step is equal, check terminals
|
|
139
|
+
if (cfi.start.terminal === cfi.end.terminal) {
|
|
140
|
+
// CFI's are equal
|
|
141
|
+
cfi.path.steps.push(cfi.start.steps[i])
|
|
142
|
+
// Not a range
|
|
143
|
+
cfi.range = false
|
|
144
|
+
}
|
|
145
|
+
} else cfi.path.steps.push(cfi.start.steps[i])
|
|
146
|
+
} else break
|
|
180
147
|
}
|
|
181
|
-
cfi.start.steps = cfi.start.steps.slice(cfi.path.steps.length)
|
|
182
|
-
cfi.end.steps = cfi.end.steps.slice(cfi.path.steps.length)
|
|
183
|
-
|
|
184
|
-
return (
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
CFI.segmentString(cfi.start) +
|
|
191
|
-
',' +
|
|
192
|
-
CFI.segmentString(cfi.end) +
|
|
193
|
-
')'
|
|
194
|
-
);
|
|
195
|
-
};
|
|
148
|
+
cfi.start.steps = cfi.start.steps.slice(cfi.path.steps.length)
|
|
149
|
+
cfi.end.steps = cfi.end.steps.slice(cfi.path.steps.length)
|
|
150
|
+
|
|
151
|
+
return 'epubcfi(' + CFI.segmentString(cfi.base)
|
|
152
|
+
+ '!' + CFI.segmentString(cfi.path)
|
|
153
|
+
+ ',' + CFI.segmentString(cfi.start)
|
|
154
|
+
+ ',' + CFI.segmentString(cfi.end)
|
|
155
|
+
+ ')'
|
|
156
|
+
}
|
|
196
157
|
|
|
197
158
|
if (!enableSelection) {
|
|
198
159
|
rendition.themes.default({
|
|
199
|
-
body: {
|
|
200
|
-
'-webkit-touch-callout': 'none' /* iOS Safari
|
|
201
|
-
'-webkit-user-select': 'none' /* Safari
|
|
202
|
-
'-khtml-user-select': 'none' /* Konqueror HTML
|
|
203
|
-
'-moz-user-select': 'none' /* Firefox
|
|
204
|
-
'-ms-user-select': 'none' /* Internet Explorer/Edge
|
|
205
|
-
'user-select': 'none'
|
|
206
|
-
}
|
|
160
|
+
'body': {
|
|
161
|
+
'-webkit-touch-callout': 'none', /* iOS Safari */
|
|
162
|
+
'-webkit-user-select': 'none', /* Safari */
|
|
163
|
+
'-khtml-user-select': 'none', /* Konqueror HTML */
|
|
164
|
+
'-moz-user-select': 'none', /* Firefox */
|
|
165
|
+
'-ms-user-select': 'none', /* Internet Explorer/Edge */
|
|
166
|
+
'user-select': 'none'
|
|
167
|
+
}
|
|
207
168
|
});
|
|
208
169
|
}
|
|
209
170
|
|
|
@@ -217,94 +178,62 @@ export default `
|
|
|
217
178
|
.then(function () {
|
|
218
179
|
var currentLocation = rendition.currentLocation();
|
|
219
180
|
|
|
220
|
-
reactNativeWebview.postMessage(
|
|
221
|
-
|
|
222
|
-
|
|
181
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
182
|
+
type: "onReady",
|
|
183
|
+
totalLocations: book.locations.total,
|
|
184
|
+
currentLocation: currentLocation,
|
|
185
|
+
progress: currentLocation?.start?.cfi
|
|
186
|
+
? book.locations.percentageFromCfi(currentLocation.start.cfi)
|
|
187
|
+
: 0,
|
|
188
|
+
}));
|
|
189
|
+
|
|
190
|
+
if (initialLocations) {
|
|
191
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
192
|
+
type: "onLocationsReady",
|
|
193
|
+
epubKey: book.key(),
|
|
194
|
+
locations: initialLocations,
|
|
223
195
|
totalLocations: book.locations.total,
|
|
224
196
|
currentLocation: currentLocation,
|
|
225
197
|
progress: currentLocation?.start?.cfi
|
|
226
198
|
? book.locations.percentageFromCfi(currentLocation.start.cfi)
|
|
227
199
|
: 0,
|
|
228
|
-
})
|
|
229
|
-
);
|
|
230
|
-
|
|
231
|
-
if (initialLocations) {
|
|
232
|
-
reactNativeWebview.postMessage(
|
|
233
|
-
JSON.stringify({
|
|
234
|
-
type: 'onLocationsReady',
|
|
235
|
-
epubKey: book.key(),
|
|
236
|
-
locations: initialLocations,
|
|
237
|
-
totalLocations: book.locations.total,
|
|
238
|
-
currentLocation: currentLocation,
|
|
239
|
-
progress: currentLocation?.start?.cfi
|
|
240
|
-
? book.locations.percentageFromCfi(currentLocation.start.cfi)
|
|
241
|
-
: 0,
|
|
242
|
-
})
|
|
243
|
-
);
|
|
200
|
+
}));
|
|
244
201
|
return Promise.resolve();
|
|
245
202
|
}
|
|
246
203
|
|
|
247
|
-
return book.locations
|
|
248
|
-
.
|
|
249
|
-
.
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
JSON.stringify({
|
|
270
|
-
type: 'onLocationsReady',
|
|
271
|
-
epubKey: book.key(),
|
|
272
|
-
locations: [],
|
|
273
|
-
totalLocations: book.locations.total,
|
|
274
|
-
currentLocation: currentLocation,
|
|
275
|
-
progress: 0,
|
|
276
|
-
})
|
|
277
|
-
);
|
|
278
|
-
});
|
|
204
|
+
return book.locations.generate(1600).then(function () {
|
|
205
|
+
var generatedLocation = rendition.currentLocation() || currentLocation;
|
|
206
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
207
|
+
type: "onLocationsReady",
|
|
208
|
+
epubKey: book.key(),
|
|
209
|
+
locations: book.locations.save(),
|
|
210
|
+
totalLocations: book.locations.total,
|
|
211
|
+
currentLocation: generatedLocation,
|
|
212
|
+
progress: generatedLocation?.start?.cfi
|
|
213
|
+
? book.locations.percentageFromCfi(generatedLocation.start.cfi)
|
|
214
|
+
: 0,
|
|
215
|
+
}));
|
|
216
|
+
}).catch(function () {
|
|
217
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
218
|
+
type: "onLocationsReady",
|
|
219
|
+
epubKey: book.key(),
|
|
220
|
+
locations: [],
|
|
221
|
+
totalLocations: book.locations.total,
|
|
222
|
+
currentLocation: currentLocation,
|
|
223
|
+
progress: 0,
|
|
224
|
+
}));
|
|
225
|
+
});
|
|
279
226
|
|
|
280
227
|
book
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
reactNativeWebview.postMessage(
|
|
286
|
-
JSON.stringify({
|
|
287
|
-
type: 'meta',
|
|
288
|
-
metadata: {
|
|
289
|
-
cover: reader.result,
|
|
290
|
-
author: book.package.metadata.creator,
|
|
291
|
-
title: book.package.metadata.title,
|
|
292
|
-
description: book.package.metadata.description,
|
|
293
|
-
language: book.package.metadata.language,
|
|
294
|
-
publisher: book.package.metadata.publisher,
|
|
295
|
-
rights: book.package.metadata.rights,
|
|
296
|
-
},
|
|
297
|
-
})
|
|
298
|
-
);
|
|
299
|
-
};
|
|
300
|
-
reader.readAsDataURL(await fetch(url).then((res) => res.blob()));
|
|
301
|
-
})
|
|
302
|
-
.catch(() => {
|
|
228
|
+
.coverUrl()
|
|
229
|
+
.then(async (url) => {
|
|
230
|
+
var reader = new FileReader();
|
|
231
|
+
reader.onload = (res) => {
|
|
303
232
|
reactNativeWebview.postMessage(
|
|
304
233
|
JSON.stringify({
|
|
305
|
-
type:
|
|
234
|
+
type: "meta",
|
|
306
235
|
metadata: {
|
|
307
|
-
cover:
|
|
236
|
+
cover: reader.result,
|
|
308
237
|
author: book.package.metadata.creator,
|
|
309
238
|
title: book.package.metadata.title,
|
|
310
239
|
description: book.package.metadata.description,
|
|
@@ -314,39 +243,53 @@ export default `
|
|
|
314
243
|
},
|
|
315
244
|
})
|
|
316
245
|
);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
|
|
246
|
+
};
|
|
247
|
+
reader.readAsDataURL(await fetch(url).then((res) => res.blob()));
|
|
248
|
+
})
|
|
249
|
+
.catch(() => {
|
|
320
250
|
reactNativeWebview.postMessage(
|
|
321
251
|
JSON.stringify({
|
|
322
|
-
type:
|
|
323
|
-
|
|
324
|
-
|
|
252
|
+
type: "meta",
|
|
253
|
+
metadata: {
|
|
254
|
+
cover: undefined,
|
|
255
|
+
author: book.package.metadata.creator,
|
|
256
|
+
title: book.package.metadata.title,
|
|
257
|
+
description: book.package.metadata.description,
|
|
258
|
+
language: book.package.metadata.language,
|
|
259
|
+
publisher: book.package.metadata.publisher,
|
|
260
|
+
rights: book.package.metadata.rights,
|
|
261
|
+
},
|
|
325
262
|
})
|
|
326
263
|
);
|
|
327
264
|
});
|
|
265
|
+
|
|
266
|
+
book.loaded.navigation.then(function (item) {
|
|
267
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
268
|
+
type: 'onNavigationLoaded',
|
|
269
|
+
toc: item.toc,
|
|
270
|
+
landmarks: item.landmarks
|
|
271
|
+
}));
|
|
272
|
+
});
|
|
328
273
|
})
|
|
329
274
|
.catch(function (err) {
|
|
330
|
-
reactNativeWebview.postMessage(
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
);
|
|
336
|
-
});
|
|
275
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
276
|
+
type: "onDisplayError",
|
|
277
|
+
reason: err.message || err.toString()
|
|
278
|
+
}));
|
|
279
|
+
});
|
|
337
280
|
|
|
338
281
|
let isAnimating = false;
|
|
339
282
|
const originalNext = rendition.next.bind(rendition);
|
|
340
283
|
const originalPrev = rendition.prev.bind(rendition);
|
|
341
284
|
|
|
342
|
-
rendition.next = function
|
|
285
|
+
rendition.next = function() {
|
|
343
286
|
if (isAnimating) return;
|
|
344
287
|
isAnimating = true;
|
|
345
|
-
|
|
288
|
+
|
|
346
289
|
const container = rendition.manager.container;
|
|
347
290
|
container.style.transition = 'opacity 0.2s ease-out';
|
|
348
291
|
container.style.opacity = '0.4';
|
|
349
|
-
|
|
292
|
+
|
|
350
293
|
setTimeout(() => {
|
|
351
294
|
originalNext();
|
|
352
295
|
setTimeout(() => {
|
|
@@ -359,14 +302,14 @@ export default `
|
|
|
359
302
|
}, 100);
|
|
360
303
|
};
|
|
361
304
|
|
|
362
|
-
rendition.prev = function
|
|
305
|
+
rendition.prev = function() {
|
|
363
306
|
if (isAnimating) return;
|
|
364
307
|
isAnimating = true;
|
|
365
|
-
|
|
308
|
+
|
|
366
309
|
const container = rendition.manager.container;
|
|
367
310
|
container.style.transition = 'opacity 0.2s ease-out';
|
|
368
311
|
container.style.opacity = '0.4';
|
|
369
|
-
|
|
312
|
+
|
|
370
313
|
setTimeout(() => {
|
|
371
314
|
originalPrev();
|
|
372
315
|
setTimeout(() => {
|
|
@@ -384,55 +327,71 @@ export default `
|
|
|
384
327
|
rendition.themes.select('theme');
|
|
385
328
|
});
|
|
386
329
|
|
|
387
|
-
rendition.on(
|
|
330
|
+
rendition.on("relocated", function (location) {
|
|
388
331
|
var percent = book.locations.percentageFromCfi(location.start.cfi);
|
|
389
332
|
var percentage = Math.floor(percent * 100);
|
|
390
333
|
var chapter = getChapter(location);
|
|
391
334
|
|
|
392
|
-
reactNativeWebview.postMessage(
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
})
|
|
400
|
-
);
|
|
335
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
336
|
+
type: "onLocationChange",
|
|
337
|
+
totalLocations: book.locations.total,
|
|
338
|
+
currentLocation: location,
|
|
339
|
+
progress: percentage,
|
|
340
|
+
currentSection: chapter,
|
|
341
|
+
}));
|
|
401
342
|
|
|
402
343
|
if (location.atStart) {
|
|
403
|
-
reactNativeWebview.postMessage(
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
})
|
|
407
|
-
);
|
|
344
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
345
|
+
type: "onBeginning",
|
|
346
|
+
}));
|
|
408
347
|
}
|
|
409
348
|
|
|
410
349
|
if (location.atEnd) {
|
|
411
|
-
reactNativeWebview.postMessage(
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
})
|
|
415
|
-
);
|
|
350
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
351
|
+
type: "onFinish",
|
|
352
|
+
}));
|
|
416
353
|
}
|
|
417
354
|
});
|
|
418
355
|
|
|
419
|
-
rendition.on(
|
|
420
|
-
reactNativeWebview.postMessage(
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
currentSection: book.navigation.get(section.href),
|
|
425
|
-
})
|
|
426
|
-
);
|
|
356
|
+
rendition.on("orientationchange", function (orientation) {
|
|
357
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
358
|
+
type: 'onOrientationChange',
|
|
359
|
+
orientation: orientation
|
|
360
|
+
}));
|
|
427
361
|
});
|
|
428
362
|
|
|
429
|
-
rendition.on(
|
|
430
|
-
reactNativeWebview.postMessage(
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
363
|
+
rendition.on("rendered", function (section) {
|
|
364
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
365
|
+
type: 'onRendered',
|
|
366
|
+
section: section,
|
|
367
|
+
currentSection: book.navigation.get(section.href),
|
|
368
|
+
}));
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
rendition.on("layout", function (layout) {
|
|
372
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
373
|
+
type: 'onLayout',
|
|
374
|
+
layout: layout,
|
|
375
|
+
}));
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
rendition.on("selected", function (cfiRange, contents) {
|
|
379
|
+
book.getRange(cfiRange).then(function (range) {
|
|
380
|
+
if (range) {
|
|
381
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
382
|
+
type: 'onSelected',
|
|
383
|
+
cfiRange: cfiRange,
|
|
384
|
+
text: range.toString(),
|
|
385
|
+
}));
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
rendition.on("resized", function (layout) {
|
|
391
|
+
reactNativeWebview.postMessage(JSON.stringify({
|
|
392
|
+
type: 'onResized',
|
|
393
|
+
layout: layout,
|
|
394
|
+
}));
|
|
436
395
|
});
|
|
437
396
|
</script>
|
|
438
397
|
</body>
|
|
@@ -11,7 +11,15 @@ export const downloadEpub = async (
|
|
|
11
11
|
return file.uri;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
const
|
|
14
|
+
const normalized = url.split('?X-Goog-Algorithm')[0];
|
|
15
|
+
|
|
16
|
+
if (!normalized) {
|
|
17
|
+
throw new Error('Invalid URL provided for EPUB download.');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
console.log({ url });
|
|
21
|
+
|
|
22
|
+
const downloadedFile = await File.downloadFileAsync(normalized, file);
|
|
15
23
|
|
|
16
24
|
return downloadedFile.uri;
|
|
17
25
|
} catch (error) {
|