Teaching: hide-notes-until share, session length check, slides export
- A study share link can hide the owner's notes until a chosen time: the server sends only passages and discussion questions until then, with a banner in the shared view (new share_reveal column, migrated on start). - Outline: a session length with "N of M min planned, X min over" and a marker on the point where the plan runs past it. - Export > Slides: printable 16:9 slides (title, passage, outline points with their verse, discussion questions) for one session or all; light or dark. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
67645cf1df
commit
2c7c7145c4
14 files changed
+303
-33
No files matched your search
@@ -25,3 +25,27 @@ export async function checkShareAccess({ expiresAt, passHash, supplied }, now =
|
||||
if (!(await bcrypt.compare(given, passHash))) return { ok: false, status: 401, needsPasscode: true, error: 'That passcode is not right.' };
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
// "Hide my notes until…": before the reveal time a shared study shows only the passages and the discussion questions
|
||||
// (no notes, outline, script, words or group notes), and says when the rest appears. The strip is done here, on the
|
||||
// server, so the hidden text never reaches the browser. After the time (or with none set) the study is sent whole.
|
||||
const OPEN_CHUNK_FIELDS = ['id', 'startVerse', 'endVerse', 'spilloverEndVerse', 'episodeNumber', 'episodeTitle', 'discussionQuestions'];
|
||||
|
||||
export function hideUntilReveal(project, revealAt, now = Date.now()) {
|
||||
if (!revealAt || revealAt <= now || !project || typeof project !== 'object') return project;
|
||||
return {
|
||||
id: project.id, title: project.title, translation: project.translation, series: project.series, outline: [],
|
||||
hiddenUntil: revealAt,
|
||||
chapters: (Array.isArray(project.chapters) ? project.chapters : []).map((ch) => ({
|
||||
book: ch.book, bookAbbrev: ch.bookAbbrev, chapter: ch.chapter, verses: ch.verses,
|
||||
chunks: (Array.isArray(ch.chunks) ? ch.chunks : []).map((chunk) => Object.fromEntries(OPEN_CHUNK_FIELDS.filter((f) => f in chunk).map((f) => [f, chunk[f]]))),
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
// A reveal time from the browser -> ms in the future (up to a year), or null for "no hiding"
|
||||
export function revealFromInput(value, now = Date.now()) {
|
||||
const n = Number(value);
|
||||
if (!value || !Number.isFinite(n) || n <= now) return null;
|
||||
return Math.min(n, now + 365 * 86_400_000);
|
||||
}
|
||||
Reference in new issue
Block a user