App quality: offline badge, per-note history, keyboard study mode, notes import
- Study cards say whether the Bible text works offline, with a button to save the missing book (notes are always kept on the device). - Each note keeps its last 12 versions with Restore (History under each note). - Keyboard-only study: 1/2/3 write in Observe/Interpret/Apply, C/W/X/P switch resource tabs, V compares, Esc leaves a note box; listed under "?". - Export > Import notes: bring Word/Markdown/text notes into the matching chunks without overwriting anything; can mark them as not your own. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
648c3206df
commit
67645cf1df
14 files changed
+421
-7
No files matched your search
@@ -468,6 +468,35 @@ describe('Study workspace', () => {
|
||||
expect(screen.queryByText(/is this from ai\?/i)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('a note keeps earlier versions that can be restored', async () => {
|
||||
const user = await studyOneChunk();
|
||||
const observe = screen.getByRole('textbox', { name: 'Observe' });
|
||||
fireEvent.focus(observe);
|
||||
fireEvent.change(observe, { target: { value: 'First thought about the passage.' } });
|
||||
fireEvent.blur(observe);
|
||||
fireEvent.focus(observe);
|
||||
fireEvent.change(observe, { target: { value: 'Completely rewritten.' } });
|
||||
fireEvent.blur(observe);
|
||||
await user.click(screen.getByRole('button', { name: 'History' }));
|
||||
const list = screen.getByRole('list', { name: /observe history/i });
|
||||
expect(within(list).getByText(/first thought about the passage/i)).toBeInTheDocument();
|
||||
await user.click(within(list).getAllByRole('button', { name: 'Restore' }).find((b) => !b.disabled));
|
||||
expect(screen.getByRole('textbox', { name: 'Observe' })).toHaveValue('First thought about the passage.');
|
||||
});
|
||||
|
||||
test('keyboard: 1 / 2 / 3 jump into a note, Esc leaves it, and V opens Compare', async () => {
|
||||
const user = await studyOneChunk();
|
||||
await user.keyboard('2');
|
||||
expect(screen.getByRole('textbox', { name: 'Interpret' })).toHaveFocus();
|
||||
await user.keyboard('{Escape}');
|
||||
expect(screen.getByRole('textbox', { name: 'Interpret' })).not.toHaveFocus();
|
||||
await user.keyboard('3');
|
||||
expect(screen.getByRole('textbox', { name: 'Apply' })).toHaveFocus();
|
||||
await user.keyboard('{Escape}');
|
||||
await user.keyboard('v');
|
||||
expect(screen.getByRole('dialog', { name: /compare/i })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('compare translations: the Observe / Interpret / Apply boxes edit the same notes', async () => {
|
||||
const user = await studyOneChunk();
|
||||
await user.click(screen.getByRole('button', { name: /compare…/i }));
|
||||
|
||||
Reference in new issue
Block a user