Fix chapter listing API and restore font size controls
This commit is contained in:
@@ -96,15 +96,13 @@ app.get('/books/:book', async (req, res) => {
|
||||
return res.status(404).json({ error: `No chapters found for book '${book}'` });
|
||||
}
|
||||
|
||||
// Combine all chapters
|
||||
let fullBook = `# ${book}\n\n`;
|
||||
for (const chapterFile of chapterFiles) {
|
||||
const chapterPath = path.join(bookDir, chapterFile);
|
||||
const chapterContent = await readMarkdownFile(chapterPath);
|
||||
fullBook += chapterContent + '\n\n';
|
||||
}
|
||||
// Extract chapter numbers from filenames (e.g., "Chapter_01.md" -> "1")
|
||||
const chapters = chapterFiles.map(file => {
|
||||
const match = file.match(/Chapter_(\d+)\.md$/);
|
||||
return match ? parseInt(match[1], 10).toString() : null;
|
||||
}).filter(Boolean);
|
||||
|
||||
res.type('text/markdown').send(fullBook);
|
||||
res.json({ chapters });
|
||||
} catch (error) {
|
||||
res.status(404).json({ error: `Book '${req.params.book}' not found` });
|
||||
}
|
||||
|
||||
@@ -117,19 +117,36 @@ const BibleReader: React.FC<BibleReaderProps> = ({ book, chapter, onBack, format
|
||||
<div className="flex items-center space-x-2">
|
||||
<span className="text-sm text-gray-600 dark:text-gray-400">Font Size:</span>
|
||||
<div className="flex space-x-1">
|
||||
{(['small', 'medium', 'large'] as const).map((size) => (
|
||||
<button
|
||||
key={size}
|
||||
onClick={() => setFontSize(size)}
|
||||
onClick={() => setFontSize('small')}
|
||||
className={`px-3 py-1 text-xs rounded ${
|
||||
fontSize === size
|
||||
fontSize === 'small'
|
||||
? 'bg-blue-600 text-white'
|
||||
: 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-300 dark:hover:bg-gray-600'
|
||||
} transition-colors`}
|
||||
>
|
||||
{size.charAt(0).toUpperCase() + size.slice(1)}
|
||||
Small
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setFontSize('medium')}
|
||||
className={`px-3 py-1 text-xs rounded ${
|
||||
fontSize === 'medium'
|
||||
? 'bg-blue-600 text-white'
|
||||
: 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-300 dark:hover:bg-gray-600'
|
||||
} transition-colors`}
|
||||
>
|
||||
Medium
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setFontSize('large')}
|
||||
className={`px-3 py-1 text-xs rounded ${
|
||||
fontSize === 'large'
|
||||
? 'bg-blue-600 text-white'
|
||||
: 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-300 dark:hover:bg-gray-600'
|
||||
} transition-colors`}
|
||||
>
|
||||
Large
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -20,21 +20,16 @@ const ChapterSelector: React.FC<ChapterSelectorProps> = ({ book, onChapterSelect
|
||||
const loadChapters = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const bookContent = await getBook(book);
|
||||
const response = await getBook(book);
|
||||
|
||||
// Parse markdown to extract chapter numbers
|
||||
const lines = bookContent.split('\n');
|
||||
const chapterNumbers: string[] = [];
|
||||
|
||||
for (const line of lines) {
|
||||
// Look for chapter headers like "# 1" or "# 1\n"
|
||||
const chapterMatch = line.match(/^#\s+(\d+)/);
|
||||
if (chapterMatch) {
|
||||
chapterNumbers.push(chapterMatch[1]);
|
||||
// The API now returns { chapters: ["1", "2", "3", ...] }
|
||||
if (response.chapters) {
|
||||
setChapters(response.chapters);
|
||||
} else {
|
||||
// Fallback: generate chapter numbers 1-50 (most books have fewer than 50 chapters)
|
||||
const fallbackChapters = Array.from({ length: 50 }, (_, i) => (i + 1).toString());
|
||||
setChapters(fallbackChapters);
|
||||
}
|
||||
}
|
||||
|
||||
setChapters(chapterNumbers);
|
||||
} catch (error) {
|
||||
console.error('Failed to load chapters:', error);
|
||||
// Fallback: generate chapter numbers 1-50 (most books have fewer than 50 chapters)
|
||||
|
||||
@@ -18,7 +18,7 @@ export const getBooks = async (): Promise<BookData> => {
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const getBook = async (book: string): Promise<string> => {
|
||||
export const getBook = async (book: string): Promise<{ chapters: string[] }> => {
|
||||
const response = await api.get(`/books/${book}`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user