From cd4e48414045301e5e15f97f8537d0f449634b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Chiotti?= <44336112+maelchiotti@users.noreply.github.com> Date: Sun, 5 Jan 2025 17:48:35 +0100 Subject: [PATCH] Add rich text notes class and migration (#354) * [303] feat: add rich text notes class and migration * [303] style: fix comment --- lib/common/actions/notes/add.dart | 5 +- lib/common/constants/notes.dart | 22 +-- lib/common/logs/app_logger.dart | 16 +- lib/common/preferences/preference_key.dart | 3 + lib/models/deprecated/note.dart | 47 ++++++ lib/models/note/note.dart | 147 ++++-------------- lib/models/note/rich_text/rich_text_note.dart | 116 ++++++++++++++ lib/pages/editor/editor_page.dart | 11 +- lib/services/backup/backup_service.dart | 4 +- lib/services/database_service.dart | 12 +- lib/services/migration/migration_service.dart | 69 ++++++++ lib/services/notes/notes_service.dart | 32 ++-- 12 files changed, 329 insertions(+), 155 deletions(-) create mode 100644 lib/models/deprecated/note.dart create mode 100644 lib/models/note/rich_text/rich_text_note.dart create mode 100644 lib/services/migration/migration_service.dart diff --git a/lib/common/actions/notes/add.dart b/lib/common/actions/notes/add.dart index 67ad9952..0750df86 100644 --- a/lib/common/actions/notes/add.dart +++ b/lib/common/actions/notes/add.dart @@ -1,10 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'select.dart'; + import '../../../models/note/note.dart'; import '../../../navigation/navigator_utils.dart'; import '../../../providers/notes/notes_provider.dart'; import '../../../providers/notifiers/notifiers.dart'; +import 'select.dart'; /// Adds a note. /// @@ -14,7 +15,7 @@ Future addNote(BuildContext context, WidgetRef ref, {String? content}) asy exitNotesSelectionMode(context, ref); } - final note = content == null ? Note.empty() : Note.content(content); + final note = content == null ? RichTextNote.empty() : RichTextNote.content(content); // If some content was provided, immediately save the note without waiting for changes in the editor if (content != null) { diff --git a/lib/common/constants/notes.dart b/lib/common/constants/notes.dart index d1858b33..96a30537 100644 --- a/lib/common/constants/notes.dart +++ b/lib/common/constants/notes.dart @@ -2,7 +2,7 @@ import '../../models/note/note.dart'; import '../../utils/localizations_utils.dart'; /// Note displayed on the very first run of the application to welcome the user. -final welcomeNote = Note( +final welcomeNote = RichTextNote( deleted: false, pinned: true, createdTime: DateTime.now(), @@ -14,7 +14,7 @@ final welcomeNote = Note( /// Notes used when running integration tests. final integrationTestNotes = List.generate( 100, - (index) => Note( + (index) => RichTextNote( deleted: false, pinned: false, createdTime: DateTime(2000, 01, 01, 12).subtract(Duration(minutes: index)), @@ -25,7 +25,7 @@ final integrationTestNotes = List.generate( )..addAll( List.generate( 100, - (index) => Note( + (index) => RichTextNote( deleted: true, pinned: false, createdTime: DateTime(2000, 01, 01, 12).subtract(Duration(minutes: index)), @@ -38,7 +38,7 @@ final integrationTestNotes = List.generate( /// Notes used when taking screenshots of the application for the stores. final screenshotNotes = [ - Note( + RichTextNote( deleted: false, pinned: true, createdTime: DateTime(2000, 01, 01, 12), @@ -47,7 +47,7 @@ final screenshotNotes = [ content: '[{"insert":"Simple","attributes":{"b":true}},{"insert":", "},{"insert":"local","attributes":{"i":true}},{"insert":", "},{"insert":"material design","attributes":{"u":true}},{"insert":" notes\\n"}]', ), - Note( + RichTextNote( deleted: false, pinned: false, createdTime: DateTime(2000, 01, 01, 11, 55), @@ -56,7 +56,7 @@ final screenshotNotes = [ content: '[{"insert":"Write text notes"},{"insert":"\\n","attributes":{"block":"cl","checked":true}},{"insert":"Use formatting options and undo/redo"},{"insert":"\\n","attributes":{"block":"cl","checked":true}},{"insert":"Use quick action to add from your homescreen"},{"insert":"\\n","attributes":{"block":"cl","checked":true}}]', ), - Note( + RichTextNote( deleted: false, pinned: false, createdTime: DateTime(2000, 01, 01, 11, 50), @@ -64,7 +64,7 @@ final screenshotNotes = [ title: "Organize", content: '[{"insert":"Search, sort and display in a list or a grid\\nPin and recover from the bin\\n"}]', ), - Note( + RichTextNote( deleted: false, pinned: false, createdTime: DateTime(2000, 01, 01, 11, 50), @@ -72,7 +72,7 @@ final screenshotNotes = [ title: "Categorize", content: '[{"insert":"Categorize notes with labels\\nPin, hide and colorize labels\\n"}]', ), - Note( + RichTextNote( deleted: false, pinned: false, createdTime: DateTime(2000, 01, 01, 11, 45), @@ -81,7 +81,7 @@ final screenshotNotes = [ content: '[{"insert":"Create a note from shared text\\nShare notes as text and export as Markdown\\nBackup notes as JSON\\n"}]', ), - Note( + RichTextNote( deleted: false, pinned: false, createdTime: DateTime(2000, 01, 01, 11, 40), @@ -90,7 +90,7 @@ final screenshotNotes = [ content: "[{\"insert\":\"Choose your language\\nChoose your theme (including black and dynamic)\\nHide features you don't need\\n\"}]", ), - Note( + RichTextNote( deleted: false, pinned: false, createdTime: DateTime(2000, 01, 01, 11, 35), @@ -98,7 +98,7 @@ final screenshotNotes = [ title: "Protect", content: '[{"insert":"Your data never leaves your device\\nEncrypt your exports\\n"}]', ), - Note( + RichTextNote( deleted: true, pinned: false, createdTime: DateTime(2000, 01, 01, 12), diff --git a/lib/common/logs/app_logger.dart b/lib/common/logs/app_logger.dart index 9d8f4d7f..69fd2485 100644 --- a/lib/common/logs/app_logger.dart +++ b/lib/common/logs/app_logger.dart @@ -3,17 +3,17 @@ import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import '../constants/constants.dart'; -import '../enums/mime_type.dart'; -import '../extensions/date_time_extensions.dart'; -import '../extensions/string_extension.dart'; -import '../../l10n/app_localizations/app_localizations.g.dart'; -import '../../utils/files_utils.dart'; -import '../../utils/snack_bar_utils.dart'; import 'package:logger/logger.dart' hide FileOutput; import 'package:path/path.dart'; import 'package:path_provider/path_provider.dart'; +import '../../l10n/app_localizations/app_localizations.g.dart'; +import '../../utils/files_utils.dart'; +import '../../utils/snack_bar_utils.dart'; +import '../constants/constants.dart'; +import '../enums/mime_type.dart'; +import '../extensions/date_time_extensions.dart'; +import '../extensions/string_extension.dart'; import 'filters/debug_filter.dart'; import 'filters/release_filter.dart'; @@ -71,7 +71,7 @@ class AppLogger { _fileLogger.e(details.exceptionAsString().firstLine, error: details.exception, stackTrace: details.stack); }; PlatformDispatcher.instance.onError = (exception, stackTrace) { - _fileLogger.e(exception.toString().firstLine, error: exception, stackTrace: stackTrace); + e(exception.toString().firstLine ?? 'Unknown exception', exception, stackTrace); return true; }; diff --git a/lib/common/preferences/preference_key.dart b/lib/common/preferences/preference_key.dart index dee49b86..a782d434 100644 --- a/lib/common/preferences/preference_key.dart +++ b/lib/common/preferences/preference_key.dart @@ -56,6 +56,9 @@ enum PreferenceKey { sortMethod('editedDate', backup: false), sortAscending(false, backup: false), layout('list', backup: false), + + // Database + databaseVersion(1), ; /// Default value of this preference. diff --git a/lib/models/deprecated/note.dart b/lib/models/deprecated/note.dart new file mode 100644 index 00000000..19e30c41 --- /dev/null +++ b/lib/models/deprecated/note.dart @@ -0,0 +1,47 @@ +import 'package:isar/isar.dart'; +import 'package:json_annotation/json_annotation.dart'; + +import '../label/label.dart'; + +part 'note.g.dart'; + +// ignore_for_file: must_be_immutable, public_member_api_docs + +List _labelToJson(IsarLinks