diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index 09d3370..d8c110e 100644 --- a/lib/i18n/strings.g.dart +++ b/lib/i18n/strings.g.dart @@ -4,9 +4,9 @@ /// To regenerate, run: `dart run slang` /// /// Locales: 2 -/// Strings: 290 (145 per locale) +/// Strings: 294 (147 per locale) /// -/// Built on 2024-02-27 at 00:35 UTC +/// Built on 2024-02-27 at 14:35 UTC // coverage:ignore-file // ignore_for_file: type=lint @@ -315,6 +315,7 @@ class _StringsBookmarksAddBookmarkEn { // Translations String get addBookmark => 'Add new bookmark'; + String get editBookmark => 'Edit bookmark'; String get bookmarkUrl => 'Bookmark URL'; String get bookmarkDetails => 'Bookmark details'; String get validateUrl => 'Validate URL'; @@ -335,6 +336,7 @@ class _StringsBookmarksAddBookmarkEn { String get addTag => 'Add tag'; String get others => 'Others'; String get savingBookmark => 'Saving bookmark...'; + String get bookmarkSavedSuccessfully => 'Bookmark saved successfully.'; String get errorSavingBookmark => 'An error occured when saving the new bookmark.'; String get leaveEmptyUseWebsiteTitle => 'Leave empty to use the website\'s title.'; String get leaveEmptyUseWebsiteDescription => 'Leave empty to use the website\'s description.'; @@ -646,6 +648,7 @@ class _StringsBookmarksAddBookmarkEs implements _StringsBookmarksAddBookmarkEn { // Translations @override String get addBookmark => 'Añadir nuevo marcador'; + @override String get editBookmark => 'Editar marcador'; @override String get url => 'URL'; @override String get bookmarkUrl => 'URL del marcador'; @override String get bookmarkDetails => 'Detalles del marcador'; @@ -666,6 +669,7 @@ class _StringsBookmarksAddBookmarkEs implements _StringsBookmarksAddBookmarkEn { @override String get addTag => 'Añadir etiqueta'; @override String get others => 'Otros'; @override String get savingBookmark => 'Guardando marcador...'; + @override String get bookmarkSavedSuccessfully => 'Marcador guardado correctamente'; @override String get errorSavingBookmark => 'Ocurrió un error al guardar el nuevo marcador.'; @override String get leaveEmptyUseWebsiteTitle => 'Dejar vacío para usar el título del sitio web.'; @override String get leaveEmptyUseWebsiteDescription => 'Dejar vacío para usar la descripción del sitio web.'; @@ -836,6 +840,7 @@ extension on Translations { case 'bookmarks.dates.todayAt': return ({required Object time}) => 'Today, ${time}'; case 'bookmarks.dates.yesterdayAt': return ({required Object time}) => 'Yesterday, ${time}'; case 'bookmarks.addBookmark.addBookmark': return 'Add new bookmark'; + case 'bookmarks.addBookmark.editBookmark': return 'Edit bookmark'; case 'bookmarks.addBookmark.bookmarkUrl': return 'Bookmark URL'; case 'bookmarks.addBookmark.bookmarkDetails': return 'Bookmark details'; case 'bookmarks.addBookmark.validateUrl': return 'Validate URL'; @@ -856,6 +861,7 @@ extension on Translations { case 'bookmarks.addBookmark.addTag': return 'Add tag'; case 'bookmarks.addBookmark.others': return 'Others'; case 'bookmarks.addBookmark.savingBookmark': return 'Saving bookmark...'; + case 'bookmarks.addBookmark.bookmarkSavedSuccessfully': return 'Bookmark saved successfully.'; case 'bookmarks.addBookmark.errorSavingBookmark': return 'An error occured when saving the new bookmark.'; case 'bookmarks.addBookmark.leaveEmptyUseWebsiteTitle': return 'Leave empty to use the website\'s title.'; case 'bookmarks.addBookmark.leaveEmptyUseWebsiteDescription': return 'Leave empty to use the website\'s description.'; @@ -989,6 +995,7 @@ extension on _StringsEs { case 'bookmarks.dates.todayAt': return ({required Object time}) => 'Hoy, ${time}'; case 'bookmarks.dates.yesterdayAt': return ({required Object time}) => 'Ayer, ${time}'; case 'bookmarks.addBookmark.addBookmark': return 'Añadir nuevo marcador'; + case 'bookmarks.addBookmark.editBookmark': return 'Editar marcador'; case 'bookmarks.addBookmark.url': return 'URL'; case 'bookmarks.addBookmark.bookmarkUrl': return 'URL del marcador'; case 'bookmarks.addBookmark.bookmarkDetails': return 'Detalles del marcador'; @@ -1009,6 +1016,7 @@ extension on _StringsEs { case 'bookmarks.addBookmark.addTag': return 'Añadir etiqueta'; case 'bookmarks.addBookmark.others': return 'Otros'; case 'bookmarks.addBookmark.savingBookmark': return 'Guardando marcador...'; + case 'bookmarks.addBookmark.bookmarkSavedSuccessfully': return 'Marcador guardado correctamente'; case 'bookmarks.addBookmark.errorSavingBookmark': return 'Ocurrió un error al guardar el nuevo marcador.'; case 'bookmarks.addBookmark.leaveEmptyUseWebsiteTitle': return 'Dejar vacío para usar el título del sitio web.'; case 'bookmarks.addBookmark.leaveEmptyUseWebsiteDescription': return 'Dejar vacío para usar la descripción del sitio web.'; diff --git a/lib/i18n/strings_en.i18n.json b/lib/i18n/strings_en.i18n.json index 373dc2d..d9d39b4 100644 --- a/lib/i18n/strings_en.i18n.json +++ b/lib/i18n/strings_en.i18n.json @@ -51,6 +51,7 @@ }, "addBookmark": { "addBookmark": "Add new bookmark", + "editBookmark": "Edit bookmark", "bookmarkUrl": "Bookmark URL", "bookmarkDetails": "Bookmark details", "validateUrl": "Validate URL", @@ -71,6 +72,7 @@ "addTag": "Add tag", "others": "Others", "savingBookmark": "Saving bookmark...", + "bookmarkSavedSuccessfully": "Bookmark saved successfully.", "errorSavingBookmark": "An error occured when saving the new bookmark.", "leaveEmptyUseWebsiteTitle": "Leave empty to use the website's title.", "leaveEmptyUseWebsiteDescription": "Leave empty to use the website's description." diff --git a/lib/i18n/strings_es.i18n.json b/lib/i18n/strings_es.i18n.json index 94d0835..2166ac1 100644 --- a/lib/i18n/strings_es.i18n.json +++ b/lib/i18n/strings_es.i18n.json @@ -51,6 +51,7 @@ }, "addBookmark": { "addBookmark": "Añadir nuevo marcador", + "editBookmark": "Editar marcador", "url": "URL", "bookmarkUrl": "URL del marcador", "bookmarkDetails": "Detalles del marcador", @@ -71,6 +72,7 @@ "addTag": "Añadir etiqueta", "others": "Otros", "savingBookmark": "Guardando marcador...", + "bookmarkSavedSuccessfully": "Marcador guardado correctamente", "errorSavingBookmark": "Ocurrió un error al guardar el nuevo marcador.", "leaveEmptyUseWebsiteTitle": "Dejar vacío para usar el título del sitio web.", "leaveEmptyUseWebsiteDescription": "Dejar vacío para usar la descripción del sitio web." diff --git a/lib/models/data/check_bookmark.dart b/lib/models/data/check_bookmark.dart index 8257aa9..73028f7 100644 --- a/lib/models/data/check_bookmark.dart +++ b/lib/models/data/check_bookmark.dart @@ -1,5 +1,7 @@ +import 'package:linkdy/models/data/bookmarks.dart'; + class CheckBookmark { - final dynamic bookmark; + final Bookmark? bookmark; final Metadata? metadata; CheckBookmark({ @@ -8,12 +10,12 @@ class CheckBookmark { }); factory CheckBookmark.fromJson(Map json) => CheckBookmark( - bookmark: json["bookmark"], + bookmark: json["bookmark"] != null ? Bookmark.fromJson(json["bookmark"]) : null, metadata: json["metadata"] == null ? null : Metadata.fromJson(json["metadata"]), ); Map toJson() => { - "bookmark": bookmark, + "bookmark": bookmark?.toJson(), "metadata": metadata?.toJson(), }; } diff --git a/lib/models/data/set_bookmark_data.dart b/lib/models/data/set_bookmark_data.dart index df32220..793d76e 100644 --- a/lib/models/data/set_bookmark_data.dart +++ b/lib/models/data/set_bookmark_data.dart @@ -6,6 +6,7 @@ class SetBookmarkData { final bool unread; final bool shared; final String tagNames; + final String notes; const SetBookmarkData({ required this.url, @@ -15,6 +16,7 @@ class SetBookmarkData { required this.unread, required this.shared, required this.tagNames, + required this.notes, }); Map toJson() { @@ -25,6 +27,7 @@ class SetBookmarkData { "is_archived": isArchived, "unread": unread, "shared": shared, + "notes": notes, }; if (tagNames != "") { ret = { diff --git a/lib/screens/bookmarks/model/add_link.model.dart b/lib/screens/bookmarks/model/bookmark_form.model.dart similarity index 90% rename from lib/screens/bookmarks/model/add_link.model.dart rename to lib/screens/bookmarks/model/bookmark_form.model.dart index 48068fb..880d201 100644 --- a/lib/screens/bookmarks/model/add_link.model.dart +++ b/lib/screens/bookmarks/model/bookmark_form.model.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:linkdy/constants/enums.dart'; import 'package:linkdy/models/data/check_bookmark.dart'; -class AddBookmarkModel { +class BookmarkFormModel { final TextEditingController urlController; String? urlError; CheckBookmark? checkBookmark; @@ -15,8 +15,9 @@ class AddBookmarkModel { String? tagsError; List tags; final TextEditingController notesController; + int? editBookmarkId; - AddBookmarkModel({ + BookmarkFormModel({ required this.urlController, this.urlError, this.checkBookmark, @@ -28,5 +29,6 @@ class AddBookmarkModel { this.tagsError, required this.tags, required this.notesController, + this.editBookmarkId, }); } diff --git a/lib/screens/bookmarks/provider/add_bookmark.provider.dart b/lib/screens/bookmarks/provider/bookmark_form.provider.dart similarity index 72% rename from lib/screens/bookmarks/provider/add_bookmark.provider.dart rename to lib/screens/bookmarks/provider/bookmark_form.provider.dart index 7b71a8b..205bdd6 100644 --- a/lib/screens/bookmarks/provider/add_bookmark.provider.dart +++ b/lib/screens/bookmarks/provider/bookmark_form.provider.dart @@ -1,10 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:linkdy/constants/global_keys.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:linkdy/screens/bookmarks/provider/bookmarks.provider.dart'; -import 'package:linkdy/screens/bookmarks/model/add_link.model.dart'; +import 'package:linkdy/screens/bookmarks/model/bookmark_form.model.dart'; +import 'package:linkdy/constants/global_keys.dart'; +import 'package:linkdy/models/data/bookmarks.dart'; import 'package:linkdy/utils/snackbar.dart'; import 'package:linkdy/models/data/tags.dart'; import 'package:linkdy/i18n/strings.g.dart'; @@ -17,7 +18,7 @@ import 'package:linkdy/models/api_response.dart'; import 'package:linkdy/models/data/check_bookmark.dart'; import 'package:linkdy/providers/api_client.provider.dart'; -part 'add_bookmark.provider.g.dart'; +part 'bookmark_form.provider.g.dart'; @riverpod Future> checkBookmark(CheckBookmarkRef ref, String url) async { @@ -32,10 +33,10 @@ FutureOr> getTags(GetTagsRef ref) async { } @riverpod -class AddBookmark extends _$AddBookmark { +class BookmarkForm extends _$BookmarkForm { @override - AddBookmarkModel build() { - return AddBookmarkModel( + BookmarkFormModel build() { + return BookmarkFormModel( urlController: TextEditingController(), titleController: TextEditingController(), descriptionController: TextEditingController(), @@ -45,6 +46,25 @@ class AddBookmark extends _$AddBookmark { ); } + void initializeProvider(Bookmark bookmark) { + state.editBookmarkId = bookmark.id; + state.checkBookmark = CheckBookmark( + bookmark: bookmark, + metadata: Metadata( + url: bookmark.url, + description: bookmark.websiteDescription, + title: bookmark.websiteTitle, + ), + ); + state.checkBookmarkLoadStatus = LoadStatus.loaded; + state.urlController.text = bookmark.url ?? ''; + state.titleController.text = bookmark.title ?? ''; + state.descriptionController.text = bookmark.description ?? ''; + state.tags = bookmark.tagNames ?? []; + state.notesController.text = bookmark.notes ?? ''; + state.markAsUnread = bookmark.unread ?? false; + } + void validateUrl(String value) { state.checkBookmark = null; state.checkBookmarkLoadStatus = null; @@ -78,7 +98,7 @@ class AddBookmark extends _$AddBookmark { ref.notifyListeners(); } - void addBookmark() async { + void saveBookmark() async { final newBookmark = SetBookmarkData( url: state.urlController.text, title: state.titleController.text != "" ? state.titleController.text : state.checkBookmark?.metadata?.title ?? '', @@ -89,18 +109,26 @@ class AddBookmark extends _$AddBookmark { unread: state.markAsUnread, shared: false, tagNames: state.tags.join(","), + notes: state.notesController.text, ); final processModal = ProcessModal(); processModal.open(t.bookmarks.addBookmark.savingBookmark); - final result = await ref.watch(apiClientProvider)!.postBookmark(newBookmark); + final result = state.editBookmarkId != null + ? await ref.watch(apiClientProvider)!.putUpdateBookmark(state.editBookmarkId!, newBookmark) + : await ref.watch(apiClientProvider)!.postBookmark(newBookmark); processModal.close(); if (result.successful == true) { ref.read(bookmarksProvider.notifier).refresh(); ref.watch(routerProvider).pop(); + showSnackbar( + key: ScaffoldMessengerKeys.bookmarks, + label: t.bookmarks.addBookmark.bookmarkSavedSuccessfully, + color: Colors.green, + ); } else { showSnackbar( key: ScaffoldMessengerKeys.addBookmark, diff --git a/lib/screens/bookmarks/provider/add_bookmark.provider.g.dart b/lib/screens/bookmarks/provider/bookmark_form.provider.g.dart similarity index 91% rename from lib/screens/bookmarks/provider/add_bookmark.provider.g.dart rename to lib/screens/bookmarks/provider/bookmark_form.provider.g.dart index 615eeb8..e572b8a 100644 --- a/lib/screens/bookmarks/provider/add_bookmark.provider.g.dart +++ b/lib/screens/bookmarks/provider/bookmark_form.provider.g.dart @@ -1,6 +1,6 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'add_bookmark.provider.dart'; +part of 'bookmark_form.provider.dart'; // ************************************************************************** // RiverpodGenerator @@ -175,20 +175,20 @@ final getTagsProvider = ); typedef GetTagsRef = AutoDisposeFutureProviderRef>; -String _$addBookmarkHash() => r'a350eee7aeed2fabae90966afadc609ee5eef895'; +String _$bookmarkFormHash() => r'e0a6612cb2a409f488614e3e91619f41055df61b'; -/// See also [AddBookmark]. -@ProviderFor(AddBookmark) -final addBookmarkProvider = - AutoDisposeNotifierProvider.internal( - AddBookmark.new, - name: r'addBookmarkProvider', +/// See also [BookmarkForm]. +@ProviderFor(BookmarkForm) +final bookmarkFormProvider = + AutoDisposeNotifierProvider.internal( + BookmarkForm.new, + name: r'bookmarkFormProvider', debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$addBookmarkHash, + const bool.fromEnvironment('dart.vm.product') ? null : _$bookmarkFormHash, dependencies: null, allTransitiveDependencies: null, ); -typedef _$AddBookmark = AutoDisposeNotifier; +typedef _$BookmarkForm = AutoDisposeNotifier; // ignore_for_file: type=lint // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/lib/screens/bookmarks/provider/common_functions.dart b/lib/screens/bookmarks/provider/common_functions.dart index 626f025..a8ed8bc 100644 --- a/lib/screens/bookmarks/provider/common_functions.dart +++ b/lib/screens/bookmarks/provider/common_functions.dart @@ -58,6 +58,7 @@ class BookmarkCommonFunctions { unread: bookmark.unread == true ? false : true, tagNames: bookmark.tagNames?.join(",") ?? '', title: bookmark.title ?? '', + notes: bookmark.notes ?? '', ), ); diff --git a/lib/screens/bookmarks/ui/add_bookmark_modal.dart b/lib/screens/bookmarks/ui/bookmark_form_modal.dart similarity index 80% rename from lib/screens/bookmarks/ui/add_bookmark_modal.dart rename to lib/screens/bookmarks/ui/bookmark_form_modal.dart index 0f9e879..95d3158 100644 --- a/lib/screens/bookmarks/ui/add_bookmark_modal.dart +++ b/lib/screens/bookmarks/ui/bookmark_form_modal.dart @@ -1,24 +1,42 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:easy_autocomplete/easy_autocomplete.dart'; -import 'package:linkdy/screens/bookmarks/provider/add_bookmark.provider.dart'; +import 'package:linkdy/screens/bookmarks/provider/bookmark_form.provider.dart'; import 'package:linkdy/widgets/section_label.dart'; +import 'package:linkdy/models/data/bookmarks.dart'; import 'package:linkdy/i18n/strings.g.dart'; import 'package:linkdy/constants/global_keys.dart'; import 'package:linkdy/constants/enums.dart'; -class AddBookmarkModal extends ConsumerWidget { +class BookmarkFormModal extends ConsumerStatefulWidget { final bool fullscreen; + final Bookmark? bookmark; - const AddBookmarkModal({ + const BookmarkFormModal({ super.key, required this.fullscreen, + this.bookmark, }); @override - Widget build(BuildContext context, WidgetRef ref) { + BookmarkFormModalState createState() => BookmarkFormModalState(); +} + +class BookmarkFormModalState extends ConsumerState { + @override + void initState() { + if (widget.bookmark != null) { + ref.read(bookmarkFormProvider.notifier).initializeProvider(widget.bookmark!); + } + super.initState(); + } + + @override + Widget build(BuildContext context) { return ScaffoldMessenger( key: ScaffoldMessengerKeys.addBookmark, child: Dialog.fullscreen( @@ -35,11 +53,15 @@ class AddBookmarkModal extends ConsumerWidget { leading: CloseButton( onPressed: () => Navigator.pop(context), ), - title: Text(t.bookmarks.addBookmark.addBookmark), + title: Text( + widget.bookmark != null + ? t.bookmarks.addBookmark.editBookmark + : t.bookmarks.addBookmark.addBookmark, + ), actions: [ IconButton( - onPressed: ref.watch(addBookmarkProvider).checkBookmark != null - ? () => ref.read(addBookmarkProvider.notifier).addBookmark() + onPressed: ref.watch(bookmarkFormProvider).checkBookmark != null + ? () => ref.read(bookmarkFormProvider.notifier).saveBookmark() : null, icon: const Icon(Icons.save_rounded), tooltip: t.generic.save, @@ -59,9 +81,7 @@ class AddBookmarkModal extends ConsumerWidget { handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), ), SliverList.list( - children: const [ - _ModalContent(), - ], + children: const [_ModalContent()], ), ], ), @@ -79,10 +99,12 @@ class _ModalContent extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final provider = ref.watch(addBookmarkProvider); + final provider = ref.watch(bookmarkFormProvider); final tags = ref.watch(getTagsProvider); + final enabledFields = provider.checkBookmark != null; + return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -99,7 +121,7 @@ class _ModalContent extends ConsumerWidget { padding: const EdgeInsets.symmetric(horizontal: 16), child: TextFormField( controller: provider.urlController, - onChanged: ref.read(addBookmarkProvider.notifier).validateUrl, + onChanged: ref.read(bookmarkFormProvider.notifier).validateUrl, enabled: provider.checkBookmarkLoadStatus != LoadStatus.loading, autocorrect: false, decoration: InputDecoration( @@ -122,7 +144,7 @@ class _ModalContent extends ConsumerWidget { onPressed: provider.checkBookmarkLoadStatus == null && provider.urlError == null && provider.urlController.text != "" - ? () => ref.read(addBookmarkProvider.notifier).checkUrlDetails() + ? () => ref.read(bookmarkFormProvider.notifier).checkUrlDetails() : null, style: ButtonStyle( foregroundColor: provider.checkBookmarkLoadStatus == LoadStatus.loaded @@ -189,7 +211,7 @@ class _ModalContent extends ConsumerWidget { floatingLabelBehavior: provider.checkBookmark != null ? FloatingLabelBehavior.always : FloatingLabelBehavior.auto, helperText: t.bookmarks.addBookmark.leaveEmptyUseWebsiteTitle, - enabled: provider.checkBookmark != null, + enabled: enabledFields, ), ), ), @@ -210,7 +232,7 @@ class _ModalContent extends ConsumerWidget { floatingLabelBehavior: provider.checkBookmark != null ? FloatingLabelBehavior.always : FloatingLabelBehavior.auto, helperText: t.bookmarks.addBookmark.leaveEmptyUseWebsiteDescription, - enabled: provider.checkBookmark != null, + enabled: enabledFields, ), ), ), @@ -226,13 +248,13 @@ class _ModalContent extends ConsumerWidget { padding: const EdgeInsets.symmetric(horizontal: 16), child: Column( children: [ - if (provider.checkBookmark != null) + if (enabledFields == true) Row( children: [ Expanded( child: EasyAutocomplete( controller: provider.tagsController, - onChanged: ref.read(addBookmarkProvider.notifier).validateTagInput, + onChanged: ref.read(bookmarkFormProvider.notifier).validateTagInput, suggestions: tags.value?.content?.results?.map((t) => t.name!).toList() ?? [], decoration: InputDecoration( border: const OutlineInputBorder( @@ -252,8 +274,8 @@ class _ModalContent extends ConsumerWidget { ), onSubmitted: provider.tagsController.text != "" && provider.tagsError == null ? (v) { - ref.read(addBookmarkProvider.notifier).setTags([...provider.tags, v]); - ref.read(addBookmarkProvider.notifier).clearTagsController(); + ref.read(bookmarkFormProvider.notifier).setTags([...provider.tags, v]); + ref.read(bookmarkFormProvider.notifier).clearTagsController(); } : null, ), @@ -263,9 +285,9 @@ class _ModalContent extends ConsumerWidget { onPressed: provider.tagsController.text != "" && provider.tagsError == null ? () { ref - .read(addBookmarkProvider.notifier) + .read(bookmarkFormProvider.notifier) .setTags([...provider.tags, provider.tagsController.text]); - ref.read(addBookmarkProvider.notifier).clearTagsController(); + ref.read(bookmarkFormProvider.notifier).clearTagsController(); } : null, icon: const Icon(Icons.check_rounded), @@ -273,7 +295,7 @@ class _ModalContent extends ConsumerWidget { ), ], ), - if (provider.checkBookmark != null) const SizedBox(height: 16), + if (enabledFields == true) const SizedBox(height: 16), SizedBox( height: 40, child: provider.tags.isNotEmpty @@ -284,7 +306,7 @@ class _ModalContent extends ConsumerWidget { itemBuilder: (context, index) => InputChip( label: Text(provider.tags[index]), onDeleted: () => ref - .read(addBookmarkProvider.notifier) + .read(bookmarkFormProvider.notifier) .setTags(provider.tags.where((tag) => tag != provider.tags[index]).toList()), ), ) @@ -329,7 +351,7 @@ class _ModalContent extends ConsumerWidget { minLines: null, maxLines: null, textAlignVertical: TextAlignVertical.top, - enabled: provider.checkBookmark != null, + enabled: enabledFields, ), ), ), @@ -339,7 +361,7 @@ class _ModalContent extends ConsumerWidget { title: Text(t.bookmarks.addBookmark.markAsUnread), value: provider.markAsUnread, onChanged: provider.checkBookmark != null - ? (v) => ref.read(addBookmarkProvider.notifier).updateMarkAsUnread(v) + ? (v) => ref.read(bookmarkFormProvider.notifier).updateMarkAsUnread(v) : null, ), const SizedBox(height: 16), @@ -347,3 +369,26 @@ class _ModalContent extends ConsumerWidget { ); } } + +void openBookmarkFormModal({ + required BuildContext context, + required double width, + Bookmark? bookmark, +}) { + showGeneralDialog( + context: context, + barrierColor: !(width > 700 || !(Platform.isAndroid || Platform.isIOS)) ? Colors.transparent : Colors.black54, + transitionBuilder: (context, anim1, anim2, child) { + return SlideTransition( + position: Tween(begin: const Offset(0, 1), end: const Offset(0, 0)).animate( + CurvedAnimation(parent: anim1, curve: Curves.easeInOutCubicEmphasized), + ), + child: child, + ); + }, + pageBuilder: (context, animation, secondaryAnimation) => BookmarkFormModal( + fullscreen: width <= 700, + bookmark: bookmark, + ), + ); +} diff --git a/lib/screens/bookmarks/ui/bookmark_item.dart b/lib/screens/bookmarks/ui/bookmark_item.dart index 36e0015..70b9452 100644 --- a/lib/screens/bookmarks/ui/bookmark_item.dart +++ b/lib/screens/bookmarks/ui/bookmark_item.dart @@ -21,14 +21,16 @@ class BookmarkItem extends ConsumerWidget { final void Function(Bookmark bookmark) onDelete; final void Function(Bookmark bookmark) onReadUnread; final void Function(Bookmark bookmark) onArchiveUnarchive; + final void Function(Bookmark bookmark) onEdit; const BookmarkItem({ - Key? key, + super.key, required this.bookmark, required this.onDelete, required this.onReadUnread, required this.onArchiveUnarchive, - }) : super(key: key); + required this.onEdit, + }); @override Widget build(BuildContext context, WidgetRef ref) { @@ -77,7 +79,7 @@ class BookmarkItem extends ConsumerWidget { extentRatio: 0.5, children: [ SlidableAction( - onPressed: (ctx) => {}, + onPressed: (ctx) => onEdit(bookmark), backgroundColor: Colors.green, label: t.bookmarks.bookmarkOptions.edit, icon: Icons.edit_rounded, diff --git a/lib/screens/bookmarks/ui/bookmarks.dart b/lib/screens/bookmarks/ui/bookmarks.dart index f9cd2d2..edc641d 100644 --- a/lib/screens/bookmarks/ui/bookmarks.dart +++ b/lib/screens/bookmarks/ui/bookmarks.dart @@ -6,12 +6,13 @@ import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:linkdy/screens/bookmarks/provider/bookmarks.provider.dart'; import 'package:linkdy/screens/bookmarks/ui/bookmark_item.dart'; -import 'package:linkdy/screens/bookmarks/ui/add_bookmark_modal.dart'; +import 'package:linkdy/screens/bookmarks/ui/bookmark_form_modal.dart'; import 'package:linkdy/screens/bookmarks/ui/delete_bookmark_modal.dart'; import 'package:linkdy/screens/bookmarks/ui/search_bookmarks.dart'; import 'package:linkdy/widgets/error_screen.dart'; import 'package:linkdy/widgets/no_data_screen.dart'; +import 'package:linkdy/models/data/bookmarks.dart'; import 'package:linkdy/constants/enums.dart'; import 'package:linkdy/constants/global_keys.dart'; import 'package:linkdy/i18n/strings.g.dart'; @@ -25,22 +26,6 @@ class BookmarksScreen extends ConsumerWidget { final width = MediaQuery.of(context).size.width; - void openAddModal() { - showGeneralDialog( - context: context, - barrierColor: !(width > 700 || !(Platform.isAndroid || Platform.isIOS)) ? Colors.transparent : Colors.black54, - transitionBuilder: (context, anim1, anim2, child) { - return SlideTransition( - position: Tween(begin: const Offset(0, 1), end: const Offset(0, 0)).animate( - CurvedAnimation(parent: anim1, curve: Curves.easeInOutCubicEmphasized), - ), - child: child, - ); - }, - pageBuilder: (context, animation, secondaryAnimation) => AddBookmarkModal(fullscreen: width <= 700), - ); - } - void openSearchModal() { showGeneralDialog( context: context, @@ -150,6 +135,7 @@ class BookmarksScreen extends ConsumerWidget { ), ), onArchiveUnarchive: ref.read(bookmarksProvider.notifier).archiveUnarchive, + onEdit: (b) => openBookmarkFormModal(context: context, width: width, bookmark: b), ); }, ), @@ -162,7 +148,7 @@ class BookmarksScreen extends ConsumerWidget { ), ), floatingActionButton: FloatingActionButton( - onPressed: openAddModal, + onPressed: () => openBookmarkFormModal(context: context, width: width), child: const Icon(Icons.add_rounded), ), ), diff --git a/lib/screens/bookmarks/ui/search_bookmarks.dart b/lib/screens/bookmarks/ui/search_bookmarks.dart index ad4a662..bb255be 100644 --- a/lib/screens/bookmarks/ui/search_bookmarks.dart +++ b/lib/screens/bookmarks/ui/search_bookmarks.dart @@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:linkdy/screens/bookmarks/provider/search_bookmarks.provider.dart'; +import 'package:linkdy/screens/bookmarks/ui/bookmark_form_modal.dart'; import 'package:linkdy/screens/bookmarks/ui/bookmark_item.dart'; import 'package:linkdy/screens/bookmarks/ui/delete_bookmark_modal.dart'; import 'package:linkdy/widgets/enter_search_term_screen.dart'; @@ -27,6 +28,8 @@ class SearchBookmarksModal extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final provider = ref.watch(searchBookmarksProvider); + final width = MediaQuery.of(context).size.width; + bool scrollListener(ScrollUpdateNotification scrollNotification) { if (scrollNotification.metrics.extentAfter < 100 && provider.loadingMore == false && @@ -135,6 +138,7 @@ class SearchBookmarksModal extends ConsumerWidget { ), ), onArchiveUnarchive: ref.read(searchBookmarksProvider.notifier).archiveUnarchive, + onEdit: (b) => openBookmarkFormModal(context: context, width: width, bookmark: b), ); }, ), diff --git a/lib/screens/tag_bookmarks/ui/tag_bookmarks.dart b/lib/screens/tag_bookmarks/ui/tag_bookmarks.dart index a3dc33e..ae17b53 100644 --- a/lib/screens/tag_bookmarks/ui/tag_bookmarks.dart +++ b/lib/screens/tag_bookmarks/ui/tag_bookmarks.dart @@ -1,14 +1,15 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; -import 'package:linkdy/constants/global_keys.dart'; +import 'package:linkdy/screens/bookmarks/ui/bookmark_form_modal.dart'; import 'package:linkdy/screens/bookmarks/ui/bookmark_item.dart'; import 'package:linkdy/screens/bookmarks/ui/delete_bookmark_modal.dart'; import 'package:linkdy/screens/tag_bookmarks/provider/tag_bookmarks.provider.dart'; import 'package:linkdy/widgets/error_screen.dart'; import 'package:linkdy/widgets/no_data_screen.dart'; +import 'package:linkdy/constants/global_keys.dart'; import 'package:linkdy/models/data/tags.dart'; import 'package:linkdy/constants/enums.dart'; import 'package:linkdy/providers/router.provider.dart'; @@ -57,6 +58,8 @@ class TagBookmarksScreenState extends ConsumerState { final provider = ref.watch(tagBookmarksProvider); + final width = MediaQuery.of(context).size.width; + bool scrollListener(ScrollUpdateNotification scrollNotification) { if (scrollNotification.metrics.extentAfter < 100 && provider.loadingMore == false && @@ -144,6 +147,7 @@ class TagBookmarksScreenState extends ConsumerState { ), ), onArchiveUnarchive: ref.read(tagBookmarksProvider.notifier).archiveUnarchive, + onEdit: (b) => openBookmarkFormModal(context: context, width: width, bookmark: b), ); }, ),