diff --git a/kjvstudy_org/routes/misc.py b/kjvstudy_org/routes/misc.py index 284c864..2c87388 100644 --- a/kjvstudy_org/routes/misc.py +++ b/kjvstudy_org/routes/misc.py @@ -229,3 +229,23 @@ async def verse_of_the_day_page(request: Request): "breadcrumbs": breadcrumbs } ) + + +@router.get("/bookmarks", response_class=HTMLResponse) +async def bookmarks_page(request: Request): + """Bookmarks page - displays user's saved bookmarks from localStorage""" + books = bible.get_books() + + breadcrumbs = [ + {"text": "Home", "url": "/"}, + {"text": "Bookmarks", "url": None} + ] + + return templates.TemplateResponse( + request, + "bookmarks.html", + { + "books": books, + "breadcrumbs": breadcrumbs + } + ) diff --git a/kjvstudy_org/static/base.js b/kjvstudy_org/static/base.js index 3b460e2..7157d79 100644 --- a/kjvstudy_org/static/base.js +++ b/kjvstudy_org/static/base.js @@ -32,6 +32,82 @@ function toggleFontSize() { } } +// Copy page text to clipboard +function copyPageText() { + var btn = document.getElementById('copy-btn'); + var article = document.querySelector('article'); + if (!article) return; + + var clone = article.cloneNode(true); + clone.querySelectorAll('.breadcrumb, .breadcrumb-actions, .sidenote, .marginnote, .toc, script, style, nav, button').forEach(function(el) { + el.remove(); + }); + + var text = (clone.textContent || clone.innerText || '').trim(); + + navigator.clipboard.writeText(text).then(function() { + if (btn) { + btn.classList.add('copied'); + setTimeout(function() { + btn.classList.remove('copied'); + }, 1500); + } + }); +} + +// Bookmark functionality +function getBookmarks() { + try { + return JSON.parse(localStorage.getItem('kjvBookmarks') || '[]'); + } catch (e) { + return []; + } +} + +function saveBookmarks(bookmarks) { + localStorage.setItem('kjvBookmarks', JSON.stringify(bookmarks)); +} + +function isBookmarked(url) { + var bookmarks = getBookmarks(); + return bookmarks.some(function(b) { return b.url === url; }); +} + +function toggleBookmark() { + var btn = document.getElementById('bookmark-btn'); + var url = window.location.pathname; + var title = document.title.replace(' - KJV Study', '').replace(' - KJV Bible', ''); + var bookmarks = getBookmarks(); + + var existingIndex = bookmarks.findIndex(function(b) { return b.url === url; }); + + if (existingIndex >= 0) { + // Remove bookmark + bookmarks.splice(existingIndex, 1); + if (btn) btn.classList.remove('bookmarked'); + } else { + // Add bookmark + bookmarks.unshift({ + url: url, + title: title, + date: new Date().toISOString() + }); + if (btn) btn.classList.add('bookmarked'); + } + + saveBookmarks(bookmarks); +} + +// Check bookmark state on page load +(function() { + document.addEventListener('DOMContentLoaded', function() { + var btn = document.getElementById('bookmark-btn'); + if (btn && isBookmarked(window.location.pathname)) { + btn.classList.add('bookmarked'); + } + }); +})(); + // Page speech toggle (for breadcrumb button) - triggers spacebar speech function togglePageSpeech() { // Simulate spacebar press to use existing speech system diff --git a/kjvstudy_org/templates/base.html b/kjvstudy_org/templates/base.html index 6296890..c5bddba 100644 --- a/kjvstudy_org/templates/base.html +++ b/kjvstudy_org/templates/base.html @@ -427,6 +427,22 @@ content: '■'; } + .breadcrumb-action-btn.copy-btn::before { + content: '⎘'; + } + + .breadcrumb-action-btn.copy-btn.copied::before { + content: '✓'; + } + + .breadcrumb-action-btn.bookmark-btn::before { + content: '☆'; + } + + .breadcrumb-action-btn.bookmark-btn.bookmarked::before { + content: '★'; + } + /* Large font size */ [data-font-size="large"] article { font-size: 1.1rem; @@ -1418,6 +1434,8 @@ + + {% for crumb in breadcrumbs %} diff --git a/kjvstudy_org/templates/bookmarks.html b/kjvstudy_org/templates/bookmarks.html new file mode 100644 index 0000000..cfccfb2 --- /dev/null +++ b/kjvstudy_org/templates/bookmarks.html @@ -0,0 +1,199 @@ +{% extends "base.html" %} + +{% block title %}Bookmarks - KJV Study{% endblock %} +{% block description %}Your saved bookmarks from KJV Study.{% endblock %} + +{% block head %} + +{% endblock %} + +{% block content %} +
+

Bookmarks

+ +
+ +
+
+ + +{% endblock %}