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