feat(app): notes in the studyset screen, written in the whole window
- A Notes tab beside Flashcards lists a studyset's notes in order: the
title ("Untitled note" without one) and when each was last edited
("Edited 5 minutes ago", by the calendar from yesterday on, the date
after a week); Edit and Delete behind its options. Deleting asks,
then offers Undo for a moment (`NoteDeletions`). With none, the tab
says so.
- "Create a note" in Add material opens a new note over the tabs; so
does a note of the list. The note: a title, its tags once it exists,
and its text at reading width; the app bar says how saving stands.
- `NoteEditorBloc` saves after 5 seconds without typing, when the app
goes to the background, and when the note is closed (the bloc saves
as it closes, so leaving never waits, and the write outlives the
screen). Each save builds on the revisions the editor started from;
another device's change takes over a note with nothing unsaved, and
merges with one that has. A note changed differently on two devices
is read-only until the person keeps a version of each field in
conflict. A new note is created by its first save, never when left
blank; a note deleted elsewhere says it no longer exists.
- The editor gains a format bar, docked below it while it has the
focus (`RichContentEditor(formatBar: true)`): alignment, bold,
italic, underline, superscript and subscript. It takes no focus, so
the selection stays. Superscript and subscript are inline marks of
their own, drawn by the font's raised and lowered glyphs in editors
and read-only text alike.
- The library's and the topics' counts include notes (a studyset with
what is inside it, as for cards).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
f3b56f2c0c
commit
502ce36a30
1 changed files with 2694 additions and 21 deletions
|
|
@ -310,6 +310,12 @@ abstract class AppLocalizations {
|
|||
/// **'{count, plural, =1{1 flashcard} other{{count} flashcards}}'**
|
||||
String studysetCountFlashcards(int count);
|
||||
|
||||
/// No description provided for @studysetCountNotes.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{count, plural, =1{1 note} other{{count} notes}}'**
|
||||
String studysetCountNotes(int count);
|
||||
|
||||
/// No description provided for @studysetNoContent.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
@ -394,6 +400,186 @@ abstract class AppLocalizations {
|
|||
/// **'Flashcards'**
|
||||
String get studysetTabFlashcards;
|
||||
|
||||
/// No description provided for @studysetTabNotes.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Notes'**
|
||||
String get studysetTabNotes;
|
||||
|
||||
/// No description provided for @studysetCreateNote.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Create a note'**
|
||||
String get studysetCreateNote;
|
||||
|
||||
/// No description provided for @notesEmpty.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'No notes yet'**
|
||||
String get notesEmpty;
|
||||
|
||||
/// No description provided for @notesEmptyHint.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Notes will appear here when you add them.'**
|
||||
String get notesEmptyHint;
|
||||
|
||||
/// No description provided for @noteUntitled.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Untitled note'**
|
||||
String get noteUntitled;
|
||||
|
||||
/// No description provided for @noteEdited.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Edited {when}'**
|
||||
String noteEdited(String when);
|
||||
|
||||
/// No description provided for @timeJustNow.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'just now'**
|
||||
String get timeJustNow;
|
||||
|
||||
/// No description provided for @timeMinutesAgo.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{count, plural, =1{1 minute ago} other{{count} minutes ago}}'**
|
||||
String timeMinutesAgo(int count);
|
||||
|
||||
/// No description provided for @timeHoursAgo.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{count, plural, =1{1 hour ago} other{{count} hours ago}}'**
|
||||
String timeHoursAgo(int count);
|
||||
|
||||
/// No description provided for @timeDaysAgo.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{count, plural, =1{yesterday} other{{count} days ago}}'**
|
||||
String timeDaysAgo(int count);
|
||||
|
||||
/// No description provided for @noteOptions.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Note options'**
|
||||
String get noteOptions;
|
||||
|
||||
/// No description provided for @noteEdit.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Edit'**
|
||||
String get noteEdit;
|
||||
|
||||
/// No description provided for @noteDelete.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Delete'**
|
||||
String get noteDelete;
|
||||
|
||||
/// No description provided for @noteDeleteTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Delete note?'**
|
||||
String get noteDeleteTitle;
|
||||
|
||||
/// No description provided for @noteDeleteMessage.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'This note will be removed from the studyset. You can undo this for a few seconds.'**
|
||||
String get noteDeleteMessage;
|
||||
|
||||
/// No description provided for @noteDeleteConfirm.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Delete'**
|
||||
String get noteDeleteConfirm;
|
||||
|
||||
/// No description provided for @noteDeleted.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Note deleted'**
|
||||
String get noteDeleted;
|
||||
|
||||
/// No description provided for @noteNewTitleFor.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'New note in \"{title}\"'**
|
||||
String noteNewTitleFor(String title);
|
||||
|
||||
/// No description provided for @noteTitleFor.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Note in \"{title}\"'**
|
||||
String noteTitleFor(String title);
|
||||
|
||||
/// No description provided for @noteTitleHint.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Title'**
|
||||
String get noteTitleHint;
|
||||
|
||||
/// No description provided for @noteEditing.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Editing…'**
|
||||
String get noteEditing;
|
||||
|
||||
/// No description provided for @noteSaving.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Saving…'**
|
||||
String get noteSaving;
|
||||
|
||||
/// No description provided for @noteSaved.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Saved'**
|
||||
String get noteSaved;
|
||||
|
||||
/// No description provided for @noteSaveFailed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Save failed'**
|
||||
String get noteSaveFailed;
|
||||
|
||||
/// No description provided for @noteConflict.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'This note was changed differently on another device. Keep one version to go on writing.'**
|
||||
String get noteConflict;
|
||||
|
||||
/// No description provided for @noteFieldTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Title'**
|
||||
String get noteFieldTitle;
|
||||
|
||||
/// No description provided for @noteFieldBody.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Text'**
|
||||
String get noteFieldBody;
|
||||
|
||||
/// No description provided for @noteKeepThis.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Keep this'**
|
||||
String get noteKeepThis;
|
||||
|
||||
/// No description provided for @noteAddTags.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Add tags'**
|
||||
String get noteAddTags;
|
||||
|
||||
/// No description provided for @noteTags.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Tags'**
|
||||
String get noteTags;
|
||||
|
||||
/// No description provided for @studysetFlashcardsEmpty.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
@ -1258,6 +1444,54 @@ abstract class AppLocalizations {
|
|||
/// **'Keep this'**
|
||||
String get composerKeepThis;
|
||||
|
||||
/// No description provided for @formatAlignLeft.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Align left'**
|
||||
String get formatAlignLeft;
|
||||
|
||||
/// No description provided for @formatAlignCenter.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Center'**
|
||||
String get formatAlignCenter;
|
||||
|
||||
/// No description provided for @formatAlignRight.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Align right'**
|
||||
String get formatAlignRight;
|
||||
|
||||
/// No description provided for @formatBold.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Bold'**
|
||||
String get formatBold;
|
||||
|
||||
/// No description provided for @formatItalic.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Italic'**
|
||||
String get formatItalic;
|
||||
|
||||
/// No description provided for @formatUnderline.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Underline'**
|
||||
String get formatUnderline;
|
||||
|
||||
/// No description provided for @formatSuperscript.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Superscript'**
|
||||
String get formatSuperscript;
|
||||
|
||||
/// No description provided for @formatSubscript.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Subscript'**
|
||||
String get formatSubscript;
|
||||
|
||||
/// No description provided for @vocabularyReading.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
|
|||
Loading…
Reference in a new issue