Redesign the study side: Outline, Study, Script and Export stages
Build and Push Docker Image / build-and-push (push) Successful in 4m15s
Build and Push Docker Image / build-and-push (push) Successful in 4m15s
Studies now move through a stage bar in the reader's themes. Outline splits chunks by clicking between verses (join merges notes) and suggests chunks from section headings. Study is three panes: outline, passage with an Observe / Interpret / Apply accordion, and commentary / word study / cross-refs / people & places for the chunk; original words are added by clicking them in the interlinear. Script drafts an outline from notes; Export holds files and the share link. Home, Import and the Pronunciation guide are restyled. Study projects are BSB only. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b1bc1c8ea4
commit
31abee0695
31 files changed
+1911
-2460
No files matched your search
@@ -46,6 +46,7 @@ export function useWordStudy({ project, allChunks, updateProject, notify }) {
|
||||
}));
|
||||
};
|
||||
|
||||
// Adds a blank word entry and returns its id (so the UI can open it for editing).
|
||||
const addGreekWord = (chunkId) => {
|
||||
const newWord = {
|
||||
id: makeId(),
|
||||
@@ -70,6 +71,42 @@ export function useWordStudy({ project, allChunks, updateProject, notify }) {
|
||||
),
|
||||
})),
|
||||
}));
|
||||
return newWord.id;
|
||||
};
|
||||
|
||||
// Adds a fully filled-in entry for an original word picked from the interlinear
|
||||
// (Strong's number, lexeme, transliteration and gloss come with the click).
|
||||
const addWordFromInterlinear = async (chunkId, w) => {
|
||||
const chunk = allChunks.find((c) => c.id === chunkId);
|
||||
const key = String(w?.s ?? '').toUpperCase();
|
||||
if (!chunk || !key) return null;
|
||||
if (chunk.greekWords.some((x) => (x.strongNumber || '').toUpperCase() === key)) {
|
||||
notify('That word is already in this chunk.', 1800);
|
||||
return chunk.greekWords.find((x) => (x.strongNumber || '').toUpperCase() === key).id;
|
||||
}
|
||||
let entry = null;
|
||||
try { entry = (key.startsWith('H') ? await loadHebrewDict() : await loadGreekDict())[key] ?? null; } catch { /* dictionary unavailable — keep what the click gave us */ }
|
||||
const newWord = {
|
||||
id: makeId(),
|
||||
query: key,
|
||||
strongNumber: key,
|
||||
englishGloss: w.g || '',
|
||||
lexeme: w.o || entry?.lemma || '',
|
||||
transliteration: w.t || entry?.translit || entry?.xlit || '',
|
||||
partOfSpeech: '',
|
||||
shortDefinition: entry?.kjv_def || w.g || '',
|
||||
definitionHtml: entry ? buildGreekDefinitionHtml(key, entry) : '',
|
||||
loading: false,
|
||||
};
|
||||
updateProject((current) => ({
|
||||
...current,
|
||||
chapters: current.chapters.map((ch) => ({
|
||||
...ch,
|
||||
chunks: ch.chunks.map((c) => (c.id === chunkId ? { ...c, greekWords: [...c.greekWords, newWord] } : c)),
|
||||
})),
|
||||
}));
|
||||
notify(`Added ${newWord.lexeme || key} to word study.`, 1800);
|
||||
return newWord.id;
|
||||
};
|
||||
|
||||
const removeGreekWord = (chunkId, wordId) => {
|
||||
@@ -332,6 +369,7 @@ export function useWordStudy({ project, allChunks, updateProject, notify }) {
|
||||
suggestSelection, setSuggestSelection,
|
||||
updateChunkWord,
|
||||
addGreekWord,
|
||||
addWordFromInterlinear,
|
||||
removeGreekWord,
|
||||
lookupWord,
|
||||
suggestGreekWordsForChunk,
|
||||
|
||||
Reference in new issue
Block a user