feat: Add continuous Bible reading mode, backend-driven translation API integration, localized book names, and preference caching
This commit is contained in:
88
Views/Bible.js
Normal file
88
Views/Bible.js
Normal file
@@ -0,0 +1,88 @@
|
||||
import React from "react";
|
||||
import { FlatList, View } from "react-native";
|
||||
import { Button, Chip, Text } from "react-native-paper";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { BIBLE_BOOKS, getBookChapterCount } from "../utils/bibleReferences.js";
|
||||
import i18n from "../i18nMessages.js";
|
||||
|
||||
const Bible = () => {
|
||||
const navigation = useNavigation();
|
||||
const [selectedBook, setSelectedBook] = React.useState("");
|
||||
const [activeStep, setActiveStep] = React.useState("book");
|
||||
|
||||
const selectedBookChapterCount = React.useMemo(() => getBookChapterCount(selectedBook), [selectedBook]);
|
||||
const chapterOptions = React.useMemo(
|
||||
() => Array.from({ length: selectedBookChapterCount }, (_v, i) => String(i + 1)),
|
||||
[selectedBookChapterCount]
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1, paddingHorizontal: 12, paddingTop: 12 }}>
|
||||
<Text style={{ fontSize: 22, fontWeight: "700", marginBottom: 6 }}>{i18n.t("message.bible") || "Read the Bible"}</Text>
|
||||
<Text style={{ color: "#6b7280", marginBottom: 10 }}>
|
||||
{i18n.t("message.biblePickerSubtitlePost") || "Select a book and chapter to start reading."}
|
||||
</Text>
|
||||
|
||||
<View style={{ flexDirection: "row", marginBottom: 10 }}>
|
||||
<Button mode={activeStep === "book" ? "contained-tonal" : "text"} onPress={() => setActiveStep("book")}>
|
||||
{i18n.t("message.book") || "Book"}
|
||||
</Button>
|
||||
<Button
|
||||
mode={activeStep === "chapter" ? "contained-tonal" : "text"}
|
||||
disabled={!selectedBook}
|
||||
onPress={() => setActiveStep("chapter")}
|
||||
>
|
||||
{i18n.t("message.chapter") || "Chapter"}
|
||||
</Button>
|
||||
</View>
|
||||
|
||||
{activeStep === "book" ? (
|
||||
<>
|
||||
<Text style={{ fontSize: 14, fontWeight: "600", marginBottom: 8 }}>{i18n.t("message.books") || "Books"}</Text>
|
||||
<FlatList
|
||||
data={BIBLE_BOOKS}
|
||||
numColumns={2}
|
||||
keyExtractor={(item) => item}
|
||||
renderItem={({ item }) => (
|
||||
<Chip
|
||||
selected={selectedBook === item}
|
||||
style={{ marginRight: 6, marginBottom: 6, width: "48%" }}
|
||||
onPress={() => {
|
||||
setSelectedBook(item);
|
||||
setActiveStep("chapter");
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</Chip>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{activeStep === "chapter" ? (
|
||||
<>
|
||||
<Text style={{ fontSize: 14, fontWeight: "600", marginBottom: 8 }}>
|
||||
{i18n.t("message.chapters") || "Chapters"} {selectedBook ? `(${selectedBook})` : ""}
|
||||
</Text>
|
||||
<FlatList
|
||||
data={chapterOptions}
|
||||
numColumns={6}
|
||||
keyExtractor={(item) => item}
|
||||
renderItem={({ item }) => (
|
||||
<Chip
|
||||
style={{ marginRight: 6, marginBottom: 6, minWidth: 44 }}
|
||||
onPress={() => {
|
||||
navigation.navigate("BibleChapter", { reference: `${selectedBook} ${item}`, selectable: false });
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</Chip>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default Bible;
|
||||
Reference in New Issue
Block a user