Add own-work tracking, Claude hand-off check, and weekly recall

- Long pastes into Observe/Interpret/Apply are tagged as pasted; notes show
  Mine / N pasted and an own-words share. Pastes follow text through merges.
- The "-> Claude" buttons on the Script stage ask first when a chunk lacks
  enough of the user's own (non-pasted) words.
- Weekly recall card on Home: write a passage from memory, compare with notes,
  self-rate; recalls are saved on the chunk and synced.
- Recall history on Home with an eight-week strip and the full list.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-10-14 12:25:49 -04:00
1 parent edc5a65d2b
commit 0c8a632cff
11 files changed
+429 -5

No files matched your search

+27
View File
@@ -221,6 +221,32 @@ export function useProjectLibrary({
});
};
// Saves a weekly recall (what you remembered, and how it went) on one chunk of a stored study.
const saveChunkRecall = (id, chunkId, recall) => {
const loaded = loadProjectById(id);
if (!loaded) return;
const updated = {
...loaded,
lastEdited: Date.now(),
chapters: loaded.chapters.map((ch) => ({
...ch,
chunks: ch.chunks.map((c) => (c.id === chunkId ? { ...c, recalls: [...(c.recalls ?? []), recall] } : c)),
})),
};
saveProjectToStorage(updated);
unsyncedStudies.add(id);
setProjectIndex(loadProjectIndex());
if (project?.id === id) setProject(updated);
saveRemoteProject(updated, { baseEdited: getSyncBase(id) }).then((result) => {
if (result.ok) {
const serverEdited = result.data?.lastEdited ?? updated.lastEdited;
setSyncBase(id, serverEdited);
unsyncedStudies.remove(id);
try { saveProjectToStorage({ ...updated, lastEdited: serverEdited }); setProjectIndex(loadProjectIndex()); } catch { /* already saved */ }
} else if (result.status === 409) toast('That study changed on another device. Open it to choose which version to keep.', { tone: 'error' });
});
};
// Deleting is immediate here, with an Undo for a few seconds; only after that is the server copy
// removed (and straight away if the tab is closed first, so a deleted project never comes back).
const finishDelete = (id) => {
@@ -287,6 +313,7 @@ export function useProjectLibrary({
openStudyChunk,
renameProjectInStorage,
setProjectSeries,
saveChunkRecall,
deleteProject,
pullLatestFromServer,
};