Add Bible picker flow and chapter navigation UI
This commit is contained in:
229
utils/bibleReferences.js
Normal file
229
utils/bibleReferences.js
Normal file
@@ -0,0 +1,229 @@
|
||||
const BIBLE_TOKEN_REGEX = /@bible:([^\s]+)/gi;
|
||||
|
||||
const normalizeReference = (value = "") => {
|
||||
try {
|
||||
return decodeURIComponent(String(value || ""))
|
||||
.replace(/_/g, " ")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim();
|
||||
} catch (_error) {
|
||||
return String(value || "").replace(/_/g, " ").replace(/\s+/g, " ").trim();
|
||||
}
|
||||
};
|
||||
|
||||
export const encodeBibleReference = (reference = "") => {
|
||||
return String(reference || "").replace(/\s+/g, "_").trim();
|
||||
};
|
||||
|
||||
export const createBibleToken = (reference = "") => {
|
||||
const encoded = encodeBibleReference(reference);
|
||||
if (!encoded) return "";
|
||||
return `@bible:${encoded}`;
|
||||
};
|
||||
|
||||
export const extractBibleReferences = (content = "") => {
|
||||
const seen = new Set();
|
||||
const refs = [];
|
||||
if (!content || typeof content !== "string") return refs;
|
||||
|
||||
let match;
|
||||
while ((match = BIBLE_TOKEN_REGEX.exec(content)) !== null) {
|
||||
const normalized = normalizeReference(match[1]);
|
||||
if (!normalized || seen.has(normalized)) continue;
|
||||
seen.add(normalized);
|
||||
refs.push(normalized);
|
||||
}
|
||||
return refs;
|
||||
};
|
||||
|
||||
export const stripBibleTokens = (content = "") => {
|
||||
if (!content || typeof content !== "string") return "";
|
||||
return content
|
||||
.replace(BIBLE_TOKEN_REGEX, "")
|
||||
.replace(/[ \t]{2,}/g, " ")
|
||||
.replace(/[ \t]+\n/g, "\n")
|
||||
.trim();
|
||||
};
|
||||
|
||||
export const fetchBiblePassage = async (reference = "") => {
|
||||
const safeReference = normalizeReference(reference);
|
||||
if (!safeReference) {
|
||||
throw new Error("Missing Bible reference");
|
||||
}
|
||||
const response = await fetch(`https://bible-api.com/${encodeURIComponent(safeReference)}`);
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to load Bible passage");
|
||||
}
|
||||
const payload = await response.json();
|
||||
return {
|
||||
reference: payload?.reference || safeReference,
|
||||
text: (payload?.text || "").trim(),
|
||||
translation: payload?.translation_name || payload?.translation_id || "KJV",
|
||||
};
|
||||
};
|
||||
|
||||
export const parseBibleReference = (reference = "") => {
|
||||
const normalized = normalizeReference(reference);
|
||||
const match = normalized.match(/^(.*)\s+(\d+)(?::(\d+)(?:-\d+)?)?$/);
|
||||
if (!match) {
|
||||
return {
|
||||
reference: normalized,
|
||||
book: normalized,
|
||||
chapter: 1,
|
||||
verse: 1,
|
||||
chapterReference: normalized,
|
||||
};
|
||||
}
|
||||
const book = (match[1] || "").trim();
|
||||
const chapter = Number(match[2] || "1");
|
||||
const verse = Number(match[3] || "1");
|
||||
return {
|
||||
reference: normalized,
|
||||
book,
|
||||
chapter,
|
||||
verse,
|
||||
chapterReference: `${book} ${chapter}`,
|
||||
};
|
||||
};
|
||||
|
||||
export const BIBLE_BOOKS = [
|
||||
"Genesis",
|
||||
"Exodus",
|
||||
"Leviticus",
|
||||
"Numbers",
|
||||
"Deuteronomy",
|
||||
"Joshua",
|
||||
"Judges",
|
||||
"Ruth",
|
||||
"1 Samuel",
|
||||
"2 Samuel",
|
||||
"1 Kings",
|
||||
"2 Kings",
|
||||
"1 Chronicles",
|
||||
"2 Chronicles",
|
||||
"Ezra",
|
||||
"Nehemiah",
|
||||
"Esther",
|
||||
"Job",
|
||||
"Psalms",
|
||||
"Proverbs",
|
||||
"Ecclesiastes",
|
||||
"Song of Solomon",
|
||||
"Isaiah",
|
||||
"Jeremiah",
|
||||
"Lamentations",
|
||||
"Ezekiel",
|
||||
"Daniel",
|
||||
"Hosea",
|
||||
"Joel",
|
||||
"Amos",
|
||||
"Obadiah",
|
||||
"Jonah",
|
||||
"Micah",
|
||||
"Nahum",
|
||||
"Habakkuk",
|
||||
"Zephaniah",
|
||||
"Haggai",
|
||||
"Zechariah",
|
||||
"Malachi",
|
||||
"Matthew",
|
||||
"Mark",
|
||||
"Luke",
|
||||
"John",
|
||||
"Acts",
|
||||
"Romans",
|
||||
"1 Corinthians",
|
||||
"2 Corinthians",
|
||||
"Galatians",
|
||||
"Ephesians",
|
||||
"Philippians",
|
||||
"Colossians",
|
||||
"1 Thessalonians",
|
||||
"2 Thessalonians",
|
||||
"1 Timothy",
|
||||
"2 Timothy",
|
||||
"Titus",
|
||||
"Philemon",
|
||||
"Hebrews",
|
||||
"James",
|
||||
"1 Peter",
|
||||
"2 Peter",
|
||||
"1 John",
|
||||
"2 John",
|
||||
"3 John",
|
||||
"Jude",
|
||||
"Revelation",
|
||||
];
|
||||
|
||||
export const BIBLE_BOOK_CHAPTERS = {
|
||||
Genesis: 50,
|
||||
Exodus: 40,
|
||||
Leviticus: 27,
|
||||
Numbers: 36,
|
||||
Deuteronomy: 34,
|
||||
Joshua: 24,
|
||||
Judges: 21,
|
||||
Ruth: 4,
|
||||
"1 Samuel": 31,
|
||||
"2 Samuel": 24,
|
||||
"1 Kings": 22,
|
||||
"2 Kings": 25,
|
||||
"1 Chronicles": 29,
|
||||
"2 Chronicles": 36,
|
||||
Ezra: 10,
|
||||
Nehemiah: 13,
|
||||
Esther: 10,
|
||||
Job: 42,
|
||||
Psalms: 150,
|
||||
Proverbs: 31,
|
||||
Ecclesiastes: 12,
|
||||
"Song of Solomon": 8,
|
||||
Isaiah: 66,
|
||||
Jeremiah: 52,
|
||||
Lamentations: 5,
|
||||
Ezekiel: 48,
|
||||
Daniel: 12,
|
||||
Hosea: 14,
|
||||
Joel: 3,
|
||||
Amos: 9,
|
||||
Obadiah: 1,
|
||||
Jonah: 4,
|
||||
Micah: 7,
|
||||
Nahum: 3,
|
||||
Habakkuk: 3,
|
||||
Zephaniah: 3,
|
||||
Haggai: 2,
|
||||
Zechariah: 14,
|
||||
Malachi: 4,
|
||||
Matthew: 28,
|
||||
Mark: 16,
|
||||
Luke: 24,
|
||||
John: 21,
|
||||
Acts: 28,
|
||||
Romans: 16,
|
||||
"1 Corinthians": 16,
|
||||
"2 Corinthians": 13,
|
||||
Galatians: 6,
|
||||
Ephesians: 6,
|
||||
Philippians: 4,
|
||||
Colossians: 4,
|
||||
"1 Thessalonians": 5,
|
||||
"2 Thessalonians": 3,
|
||||
"1 Timothy": 6,
|
||||
"2 Timothy": 4,
|
||||
Titus: 3,
|
||||
Philemon: 1,
|
||||
Hebrews: 13,
|
||||
James: 5,
|
||||
"1 Peter": 5,
|
||||
"2 Peter": 3,
|
||||
"1 John": 5,
|
||||
"2 John": 1,
|
||||
"3 John": 1,
|
||||
Jude: 1,
|
||||
Revelation: 22,
|
||||
};
|
||||
|
||||
export const getBookChapterCount = (book = "") => {
|
||||
return BIBLE_BOOK_CHAPTERS[book] || 1;
|
||||
};
|
||||
Reference in New Issue
Block a user