From 7674510952b560d985ea92bb7a20ea5a55bc8bb3 Mon Sep 17 00:00:00 2001 From: Jason Date: Sun, 12 Jul 2026 08:53:45 -0500 Subject: [PATCH] Add Strong display modes and book page boundaries --- CHANGELOG.md | 6 ++++ package-lock.json | 4 +-- package.json | 2 +- src-tauri/Cargo.lock | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/tauri.conf.json | 2 +- src/App.css | 21 ++++++-------- src/App.tsx | 60 +++++++++++++++++++++++++++++++++------ 8 files changed, 72 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2eeddc..f4d9f93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.1.6 - 2026-07-12 + +- Made session page anchors book-aware so pages do not silently cross from one book into another. +- Added a visible Strong's display selector with off, highlight, and full-number modes. +- Changed inline Strong's numbers from pill badges to superscript markers. + ## 0.1.5 - 2026-07-12 - Fixed page selection so clicking a verse highlights it in place instead of rebuilding the page around it. diff --git a/package-lock.json b/package-lock.json index 93d9a16..fece8ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "libre-study", - "version": "0.1.5", + "version": "0.1.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "libre-study", - "version": "0.1.5", + "version": "0.1.6", "dependencies": { "@tauri-apps/api": "^2.11.1", "react": "^19.2.7", diff --git a/package.json b/package.json index 6bf6576..2617871 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "libre-study", "private": true, - "version": "0.1.5", + "version": "0.1.6", "type": "module", "scripts": { "dev": "vite --host 127.0.0.1", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 03905aa..d9473df 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -77,7 +77,7 @@ checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" [[package]] name = "app" -version = "0.1.5" +version = "0.1.6" dependencies = [ "log", "rusqlite", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 6e7cc09..a9e3b2f 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "app" -version = "0.1.5" +version = "0.1.6" description = "A Tauri App" authors = ["you"] license = "" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 0a7cacf..067a90c 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "../node_modules/@tauri-apps/cli/config.schema.json", "productName": "Libre Study", - "version": "0.1.5", + "version": "0.1.6", "identifier": "org.librestudy.desktop", "build": { "frontendDist": "../dist", diff --git a/src/App.css b/src/App.css index 7594d6e..a28f9d5 100644 --- a/src/App.css +++ b/src/App.css @@ -125,7 +125,7 @@ textarea:focus-visible { .page-controls { display: grid; - grid-template-columns: minmax(130px, 1.1fr) minmax(130px, 1.3fr) minmax(86px, 0.7fr) minmax(78px, 0.6fr); + grid-template-columns: minmax(130px, 1.1fr) minmax(130px, 1.3fr) minmax(86px, 0.7fr) minmax(78px, 0.6fr) minmax(120px, 0.9fr); gap: 8px; align-items: end; } @@ -250,9 +250,13 @@ textarea:focus-visible { .strong-token { display: inline; position: relative; + cursor: pointer; +} + +.strong-token.highlight, +.strong-token.numbers { border-radius: 3px; box-shadow: inset 0 -0.45em 0 rgba(214, 168, 79, 0.22); - cursor: pointer; } .strong-token:hover, @@ -266,23 +270,16 @@ textarea:focus-visible { } .strong-code { - display: inline-block; - margin: 0 2px 0 3px; - transform: translateY(-0.12em); - border: 1px solid rgba(138, 109, 46, 0.34); - border-radius: 4px; - padding: 0 3px; - background: #fff8e6; + margin-left: 2px; color: #735c0f; font-family: ui-sans-serif, system-ui, sans-serif; font-size: 9px; font-weight: 800; - line-height: 1.35; + line-height: 0; + vertical-align: super; } .strong-token.active .strong-code { - border-color: rgba(47, 111, 94, 0.42); - background: #e7f0eb; color: #225446; } diff --git a/src/App.tsx b/src/App.tsx index 080849c..82cbc61 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,6 +7,7 @@ import './App.css' const tagColors = ['#2f6f5e', '#735c0f', '#8a3ffc', '#b42318', '#245ba7'] const pageSize = 34 type ViewMode = 'page' | 'study' | 'notes' | 'compare' +type StrongDisplayMode = 'off' | 'highlight' | 'numbers' function reference(verse: Verse) { return `${verse.book} ${verse.chapter}:${verse.verse}` @@ -20,6 +21,7 @@ function App() { const [selectedId, setSelectedId] = useState(null) const [pageStartId, setPageStartId] = useState(null) const [selectedStrong, setSelectedStrong] = useState(null) + const [strongDisplay, setStrongDisplay] = useState('highlight') const [tagInput, setTagInput] = useState('') const [noteDraft, setNoteDraft] = useState('') const [loading, setLoading] = useState(true) @@ -85,9 +87,19 @@ function App() { const pageAnchors = useMemo(() => { const source = libraryVerses.length ? libraryVerses : verses const anchors: Verse[] = [] + let index = 0 - for (let index = 0; index < source.length; index += pageSize) { - anchors.push(source[index]) + while (index < source.length) { + const book = source[index].book + let bookVerseIndex = 0 + + while (index < source.length && source[index].book === book) { + if (bookVerseIndex % pageSize === 0) { + anchors.push(source[index]) + } + bookVerseIndex += 1 + index += 1 + } } return anchors @@ -98,7 +110,10 @@ function App() { const pageStartIndex = source.findIndex((verse) => verse.id === pageStartId) const selectedIndex = source.findIndex((verse) => verse.id === selectedVerse.id) const start = Math.max(0, pageStartIndex >= 0 ? pageStartIndex : selectedIndex) - return source.slice(start, start + pageSize) + const book = source[start]?.book + return source + .slice(start, start + pageSize) + .filter((verse) => verse.book === book) }, [libraryVerses, pageStartId, selectedVerse, verses]) const pageRange = pageVerses.length ? `${reference(pageVerses[0])} - ${reference(pageVerses[pageVerses.length - 1])}` @@ -169,8 +184,17 @@ function App() { const source = libraryVerses.length ? libraryVerses : verses const index = source.findIndex((entry) => entry.id === verse.id) if (index < 0) return pageStartId ?? verse.id - const pageIndex = Math.floor(index / pageSize) * pageSize - return source[pageIndex]?.id ?? verse.id + + let anchor = source[index] + for (const pageAnchor of pageAnchors) { + const anchorIndex = source.findIndex((entry) => entry.id === pageAnchor.id) + if (anchorIndex > index) break + if (pageAnchor.book === verse.book) { + anchor = pageAnchor + } + } + + return anchor.id } function selectVerse(verse: Verse) { @@ -184,7 +208,7 @@ function App() { } function renderVerseText(verse: Verse) { - if (!verse.strongs.length) return verse.text + if (!verse.strongs.length || strongDisplay === 'off') return verse.text const parts: ReactNode[] = [] let cursor = 0 @@ -203,10 +227,15 @@ function App() { const linkedText = verse.text.slice(index, index + surface.length) const isActive = entry.strong === selectedStrong + const showCode = strongDisplay === 'numbers' || isActive parts.push( {linkedText} - {(verse.id === selectedId || isActive) ? ( - {entry.strong} + {showCode ? ( + {entry.strong} ) : null} , ) @@ -388,6 +417,19 @@ function App() { ))} +