Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions android/src/main/java/com/reactnativereadium/ReadiumView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@ class ReadiumView(
payload
)
}
is ReaderViewModel.Event.MetadataLoaded -> {
val json = event.metadata.toJSON()
val payload = Arguments.makeNativeMap(json.toMap())
module.receiveEvent(
this.id.toInt(),
ReadiumViewManager.ON_METADATA,
payload
)
}
else -> {
// do nothing
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ class ReadiumViewManager(
MapBuilder.of("bubbled", ON_TABLE_OF_CONTENTS)
)
)
.put(
ON_METADATA,
MapBuilder.of(
"phasedRegistrationNames",
MapBuilder.of("bubbled", ON_METADATA)
)
)
.build()
}

Expand Down Expand Up @@ -141,6 +148,7 @@ class ReadiumViewManager(
companion object {
var ON_LOCATION_CHANGE = "onLocationChange"
var ON_TABLE_OF_CONTENTS = "onTableOfContents"
var ON_METADATA = "onMetadata"
var COMMAND_CREATE = 1
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.readium.r2.navigator.*
import org.readium.r2.shared.publication.Locator
import org.readium.r2.shared.publication.Metadata
import com.reactnativereadium.utils.EventChannel
import kotlinx.coroutines.channels.Channel

Expand Down Expand Up @@ -38,6 +39,7 @@ abstract class BaseReaderFragment : Fragment() {
val viewScope = viewLifecycleOwner.lifecycleScope

channel.send(ReaderViewModel.Event.TableOfContentsLoaded(model.publication.tableOfContents))
channel.send(ReaderViewModel.Event.MetadataLoaded(model.publication.metadata))
navigator.currentLocator
.onEach { channel.send(ReaderViewModel.Event.LocatorUpdate(it)) }
.launchIn(viewScope)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import org.readium.r2.shared.Search
import org.readium.r2.shared.UserException
import org.readium.r2.shared.publication.Link
import org.readium.r2.shared.util.Try
import org.readium.r2.shared.publication.Metadata

@OptIn(Search::class, ExperimentalDecorator::class)
class ReaderViewModel(
Expand Down Expand Up @@ -113,6 +114,7 @@ class ReaderViewModel(
class Failure(val error: UserException) : Event()
class LocatorUpdate(val locator: Locator) : Event()
class TableOfContentsLoaded(val toc: List<Link>) : Event()
class MetadataLoaded(val metadata: Metadata) : Event()
}

sealed class FeedbackEvent {
Expand Down
6 changes: 3 additions & 3 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,7 @@ PODS:
- React-Mapbuffer (0.74.3):
- glog
- React-debug
- react-native-readium (1.2.1):
- react-native-readium (2.0.2):
- R2Navigator
- R2Shared
- R2Streamer
Expand Down Expand Up @@ -1503,7 +1503,7 @@ SPEC CHECKSUMS:
React-jsitracing: 6b3c8c98313642140530f93c46f5a6ca4530b446
React-logger: fa92ba4d3a5d39ac450f59be2a3cec7b099f0304
React-Mapbuffer: 9f68550e7c6839d01411ac8896aea5c868eff63a
react-native-readium: 7f71dab8b9c3eff510a2b7527e7a249691637215
react-native-readium: 3de612400580e915706306b4f8879d7ebd029ed7
react-native-safe-area-context: b7daa1a8df36095a032dff095a1ea8963cb48371
react-native-slider: ce295d2bf830a7990af05b0bd70ab28c133e230c
React-nativeconfig: fa5de9d8f4dbd5917358f8ad3ad1e08762f01dcb
Expand Down Expand Up @@ -1535,7 +1535,7 @@ SPEC CHECKSUMS:
RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
SwiftSoup: 33e8d374021a6c332788f78fa29a93227d8a7699
Yoga: 88480008ccacea6301ff7bf58726e27a72931c8d
Yoga: 04f1db30bb810187397fa4c37dd1868a27af229c

PODFILE CHECKSUM: 686539c4adb72be4e293af103a245974f4ffa466

Expand Down
32 changes: 18 additions & 14 deletions example/src/components/Reader.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import React, { useEffect, useState, useRef } from 'react';
import { StyleSheet, View, Text, Platform, DimensionValue } from 'react-native';
import {
ReadiumView,
Settings,
} from 'react-native-readium';
import type { Link, Locator, File } from 'react-native-readium';
import { ReadiumView, Settings } from 'react-native-readium';
import type { Link, Locator, File, Metadata } from 'react-native-readium';

import RNFS from '../utils/RNFS';
import {
Expand All @@ -22,11 +19,13 @@ export const Reader: React.FC = () => {
const [file, setFile] = useState<File>();
const [location, setLocation] = useState<Locator | Link>();
const [settings, setSettings] = useState<Partial<Settings>>(DEFAULT_SETTINGS);
const [metadata, setMetadata] = useState<Metadata | null>(null);
const ref = useRef<any>();

console.log('Metadata:', JSON.stringify(metadata, null, 2));

useEffect(() => {
async function run() {

if (Platform.OS === 'web') {
setFile({
url: EPUB_URL,
Expand Down Expand Up @@ -56,7 +55,7 @@ export const Reader: React.FC = () => {
}
}

run()
run();
}, []);

if (file) {
Expand All @@ -66,11 +65,13 @@ export const Reader: React.FC = () => {
<View style={styles.button}>
<TableOfContents
items={toc}
onPress={(loc) => setLocation({
href: loc.href,
type: 'application/xhtml+xml',
title: loc.title || '',
})}
onPress={(loc) =>
setLocation({
href: loc.href,
type: 'application/xhtml+xml',
title: loc.title || '',
})
}
/>
</View>
<View style={styles.button}>
Expand All @@ -97,7 +98,10 @@ export const Reader: React.FC = () => {
settings={settings}
onLocationChange={(locator: Locator) => setLocation(locator)}
onTableOfContents={(toc: Link[] | null) => {
if (toc) setToc(toc)
if (toc) setToc(toc);
}}
onMetadata={(metadata: Metadata) => {
if (metadata) setMetadata(metadata);
}}
/>
</View>
Expand All @@ -118,7 +122,7 @@ export const Reader: React.FC = () => {
<Text>downloading file</Text>
</View>
);
}
};

const styles = StyleSheet.create({
container: {
Expand Down
5 changes: 5 additions & 0 deletions ios/ReadiumView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class ReadiumView : UIView, Loggable {
}
@objc var onLocationChange: RCTDirectEventBlock?
@objc var onTableOfContents: RCTDirectEventBlock?
@objc var onMetadata: RCTDirectEventBlock?

func loadBook(
url: String,
Expand Down Expand Up @@ -163,5 +164,9 @@ class ReadiumView : UIView, Loggable {
return link.json
})
])
self.onMetadata?([
"metadata": vc.publication.metadata.json
])

}
}
1 change: 1 addition & 0 deletions ios/ReadiumViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ @interface RCT_EXTERN_MODULE(ReadiumViewManager, RCTViewManager)
RCT_EXPORT_VIEW_PROPERTY(settings, NSDictionary *)
RCT_EXPORT_VIEW_PROPERTY(onLocationChange, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onTableOfContents, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onMetadata, RCTDirectEventBlock)

@end
162 changes: 99 additions & 63 deletions src/components/ReadiumView.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import React, { useCallback, useState, useEffect, forwardRef, ForwardedRef, useRef, createRef } from 'react';
import React, {
useCallback,
useState,
useEffect,
forwardRef,
ForwardedRef,
useRef,
createRef,
} from 'react';
import { View, Platform, findNodeHandle, StyleSheet } from 'react-native';

import type { BaseReadiumViewProps, Dimensions } from '../interfaces';
Expand All @@ -8,74 +16,102 @@ import { BaseReadiumView } from './BaseReadiumView';

export type ReadiumProps = BaseReadiumViewProps;

export const ReadiumView: React.FC<ReadiumProps> = forwardRef(({
onLocationChange: wrappedOnLocationChange,
onTableOfContents: wrappedOnTableOfContents,
settings: unmappedSettings,
...props
}, forwardedRef) => {
const defaultRef = useRef<any>(null);
const [{ height, width }, setDimensions] = useState<Dimensions>({
width: 0,
height: 0,
});

// set the view dimensions on layout
const onLayout = useCallback(({ nativeEvent: { layout: { width, height } }}: any) => {
setDimensions({
width: dimension(width),
height: dimension(height),
export const ReadiumView: React.FC<ReadiumProps> = forwardRef(
(
{
onLocationChange: wrappedOnLocationChange,
onTableOfContents: wrappedOnTableOfContents,
onMetadata: wrappedOnMetadata,
settings: unmappedSettings,
...props
},
forwardedRef
) => {
const defaultRef = useRef<any>(null);
const [{ height, width }, setDimensions] = useState<Dimensions>({
width: 0,
height: 0,
});
}, []);

// wrap the native onLocationChange and extract the raw event value
const onLocationChange = useCallback((event: any) => {
if (wrappedOnLocationChange) {
wrappedOnLocationChange(event.nativeEvent);
}
}, [wrappedOnLocationChange]);
// set the view dimensions on layout
const onLayout = useCallback(
({
nativeEvent: {
layout: { width, height },
},
}: any) => {
setDimensions({
width: dimension(width),
height: dimension(height),
});
},
[]
);

const onTableOfContents = useCallback((event: any) => {
if (wrappedOnTableOfContents) {
const toc = event.nativeEvent.toc || null;
wrappedOnTableOfContents(toc);
}
}, [wrappedOnTableOfContents]);
// wrap the native onLocationChange and extract the raw event value
const onLocationChange = useCallback(
(event: any) => {
if (wrappedOnLocationChange) {
wrappedOnLocationChange(event.nativeEvent);
}
},
[wrappedOnLocationChange]
);

// create the view fragment on android
useEffect(() => {
if (Platform.OS === 'android' && defaultRef.current) {
const viewId = findNodeHandle(defaultRef.current);
createFragment(viewId);
}
}, []);
const onTableOfContents = useCallback(
(event: any) => {
if (wrappedOnTableOfContents) {
const toc = event.nativeEvent.toc || null;
wrappedOnTableOfContents(toc);
}
},
[wrappedOnTableOfContents]
);

// assign the forwarded ref
useEffect(() => {
if (forwardedRef && 'current' in forwardedRef) {
forwardedRef.current = defaultRef.current;
} else if (forwardedRef) {
forwardedRef(defaultRef);
}
}, [defaultRef.current !== null])
const onMetadata = useCallback(
(event: any) => {
if (wrappedOnMetadata) {
wrappedOnMetadata(event.nativeEvent);
}
},
[wrappedOnMetadata]
);

return (
<View
style={styles.container}
onLayout={onLayout}
>
<BaseReadiumView
height={height}
width={width}
{...props}
onLocationChange={onLocationChange}
onTableOfContents={onTableOfContents}
settings={unmappedSettings ? Settings.map(unmappedSettings) : undefined}
ref={defaultRef}
/>
</View>
);
});
// create the view fragment on android
useEffect(() => {
if (Platform.OS === 'android' && defaultRef.current) {
const viewId = findNodeHandle(defaultRef.current);
createFragment(viewId);
}
}, []);

// assign the forwarded ref
useEffect(() => {
if (forwardedRef && 'current' in forwardedRef) {
forwardedRef.current = defaultRef.current;
} else if (forwardedRef) {
forwardedRef(defaultRef);
}
}, [defaultRef.current !== null]);

return (
<View style={styles.container} onLayout={onLayout}>
<BaseReadiumView
height={height}
width={width}
{...props}
onLocationChange={onLocationChange}
onTableOfContents={onTableOfContents}
onMetadata={onMetadata}
settings={
unmappedSettings ? Settings.map(unmappedSettings) : undefined
}
ref={defaultRef}
/>
</View>
);
}
);

const styles = StyleSheet.create({
container: { width: '100%', height: '100%' },
Expand Down
2 changes: 2 additions & 0 deletions src/interfaces/BaseReadiumViewProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { Settings } from './Settings';
import type { Link } from './Link';
import type { Locator } from './Locator';
import type { File } from './File';
import type { Metadata } from './Metadata';

export type BaseReadiumViewProps = {
file: File;
Expand All @@ -12,6 +13,7 @@ export type BaseReadiumViewProps = {
style?: ViewStyle;
onLocationChange?: (locator: Locator) => void;
onTableOfContents?: (toc: Link[] | null) => void;
onMetadata?: (metadata: Metadata) => void;
ref?: any;
height?: number;
width?: number;
Expand Down
Loading