Files
EMI-ExpoAPP/components/BibleEmbeddedView.js
2026-02-24 15:56:48 -05:00

119 lines
3.8 KiB
JavaScript

import React, { useMemo, useState } from "react";
import { StyleSheet, Text, View } from "react-native";
import { ActivityIndicator, Chip } from "react-native-paper";
import { useNavigation } from "@react-navigation/native";
import { extractBibleReferences, fetchBiblePassage } from "../utils/bibleReferences.js";
const BibleEmbeddedView = ({ content = "", compact = false, openChapterOnPress = false }) => {
const navigation = useNavigation();
const references = useMemo(() => extractBibleReferences(content), [content]);
const [selectedRef, setSelectedRef] = useState("");
const [byReference, setByReference] = useState({});
if (!references.length) return null;
const handleSelectReference = async (reference) => {
if (openChapterOnPress) {
navigation.navigate("BibleChapter", { reference });
return;
}
setSelectedRef(reference);
const current = byReference[reference];
if (current?.loading || current?.text || current?.error) return;
setByReference((prev) => ({ ...prev, [reference]: { loading: true } }));
try {
const data = await fetchBiblePassage(reference);
setByReference((prev) => ({ ...prev, [reference]: { loading: false, ...data } }));
} catch (_error) {
setByReference((prev) => ({ ...prev, [reference]: { loading: false, error: true } }));
}
};
const selectedData = selectedRef ? byReference[selectedRef] : null;
return (
<View style={[styles.container, compact ? styles.compactContainer : null]}>
<Text style={styles.label}>Bible</Text>
<View style={styles.chipsWrap}>
{references.map((reference) => (
<Chip
key={reference}
mode={selectedRef === reference ? "flat" : "outlined"}
selected={selectedRef === reference}
compact
style={styles.chip}
onPress={() => handleSelectReference(reference)}
>
{reference}
</Chip>
))}
</View>
{selectedData?.loading ? <ActivityIndicator size="small" style={styles.loader} /> : null}
{selectedData?.text ? (
<View style={styles.previewBox}>
<Text style={styles.previewText}>{selectedData.text.slice(0, compact ? 160 : 280)}</Text>
<Text style={styles.previewMeta}>
{selectedData.reference} ({selectedData.translation})
</Text>
</View>
) : null}
{selectedData?.error ? <Text style={styles.errorText}>Unable to load this passage.</Text> : null}
</View>
);
};
export default BibleEmbeddedView;
const styles = StyleSheet.create({
container: {
paddingTop: 6,
paddingHorizontal: 8,
},
compactContainer: {
paddingTop: 4,
paddingHorizontal: 0,
},
label: {
fontSize: 12,
color: "#4b5563",
fontWeight: "700",
marginBottom: 4,
},
chipsWrap: {
flexDirection: "row",
flexWrap: "wrap",
},
chip: {
marginRight: 6,
marginBottom: 6,
backgroundColor: "#f8fafc",
},
loader: {
alignSelf: "flex-start",
},
previewBox: {
marginTop: 2,
backgroundColor: "#f8fafc",
borderWidth: 1,
borderColor: "#e5e7eb",
borderRadius: 10,
padding: 8,
},
previewText: {
fontSize: 13,
color: "#111827",
},
previewMeta: {
marginTop: 4,
fontSize: 11,
color: "#6b7280",
fontWeight: "600",
},
errorText: {
marginTop: 2,
fontSize: 12,
color: "#b91c1c",
},
});