diff --git a/lib/pages/collection_page.dart b/lib/pages/collection_page.dart index 67c4dc0..b8d3b98 100644 --- a/lib/pages/collection_page.dart +++ b/lib/pages/collection_page.dart @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import '../model/bookmark.dart'; +import '../model/maps_link_metadata.dart'; import '../service/bookmarks_provider.dart'; +import '../service/shared_link_provider.dart'; import '../service/storage.dart'; import '../service/url_launcher.dart'; import '../widgets/create_bookmark_dialog.dart'; @@ -16,17 +19,29 @@ class CollectionPage extends StatefulWidget { } class _CollectionPageState extends State { + MapsLinkMetadata? selectedMapsLink; + void onAddButtonPressed() => showDialog( context: context, builder: (context) => CreateBookmarkDialog( collectionId: BookmarksProvider.selectedCollectionId!, onSavePressed: onBookmarkSaved, + selectedMapsLink: selectedMapsLink, ), ); + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (selectedMapsLink != null) onAddButtonPressed(); + }); + } + void onBookmarkSaved(Bookmark bookmark) { Storage.addBookmark(bookmark); setState(() {}); + context.read().removeCurrentMapsLink(); } Widget bookmarkListBuilder(BuildContext context, Bookmark bookmark) { @@ -38,6 +53,8 @@ class _CollectionPageState extends State { @override Widget build(BuildContext context) { + SharedLinkProvider provider = context.watch(); + selectedMapsLink = provider.currentMapsLinkMetadata; if (BookmarksProvider.selectedCollectionId == null) { Navigator.of(context).pop(); } @@ -49,7 +66,18 @@ class _CollectionPageState extends State { ); return Scaffold( - appBar: AppBar(title: Text(collection.name)), + appBar: AppBar( + title: selectedMapsLink != null + ? Text('Add to ${collection.name}') + : Text(collection.name), + actions: [ + if (selectedMapsLink != null) + TextButton( + onPressed: () => provider.removeCurrentMapsLink(), + child: Text('Cancel'), + ), + ], + ), body: ListView.builder( itemBuilder: (context, index) => bookmarkListBuilder(context, bookmarks.elementAt(index)), @@ -57,7 +85,7 @@ class _CollectionPageState extends State { ), floatingActionButton: FloatingActionButton( onPressed: onAddButtonPressed, - child: Icon(Icons.add), + child: Icon(selectedMapsLink != null ? Icons.save : Icons.add), ), ); } diff --git a/lib/pages/collections_list_page.dart b/lib/pages/collections_list_page.dart index da1cece..624f20c 100644 --- a/lib/pages/collections_list_page.dart +++ b/lib/pages/collections_list_page.dart @@ -18,12 +18,23 @@ class CollectionsListPage extends StatefulWidget { class _CollectionsListPageState extends State { final collections = Storage.loadCollections(); + bool addingNewBookmark = false; @override Widget build(BuildContext context) { final provider = context.watch(); + addingNewBookmark = provider.currentMapsLinkMetadata != null; return Scaffold( - appBar: AppBar(), + appBar: AppBar( + title: addingNewBookmark ? Text('Choose Collection') : null, + actions: [ + if (addingNewBookmark) + TextButton( + onPressed: () => provider.removeCurrentMapsLink(), + child: Text('Cancel'), + ), + ], + ), floatingActionButton: FloatingActionButton( onPressed: onAddButtonPressed, child: Icon(Icons.add), @@ -32,9 +43,9 @@ class _CollectionsListPageState extends State { itemBuilder: itemBuilder, itemCount: collections.length, ), - bottomSheet: provider.currentMapsLinkMetadata == null - ? null - : BottomSheet(onClosing: () {}, builder: bottomSheetBuilder), + // bottomSheet: provider.currentMapsLinkMetadata == null + // ? null + // : BottomSheet(onClosing: () {}, builder: bottomSheetBuilder), ); } @@ -51,29 +62,34 @@ class _CollectionsListPageState extends State { ); } - void onAddButtonPressed() => showDialog( - context: context, - builder: (context) => - CreateBookmarkCollectionDialog(onSavePressed: onCollectionSaved), - ); + void onAddButtonPressed() => + showDialog( + context: context, + builder: (context) => + CreateBookmarkCollectionDialog(onSavePressed: onCollectionSaved), + ).whenComplete(() { + if (addingNewBookmark) navigateToCollection(collections.last.id); + }); void onCollectionSaved(String name) { collections.add(Collection(name: name)); - setState(() {}); Storage.saveCollections(collections); + setState(() {}); } Widget itemBuilder(BuildContext context, int index) { final collection = collections.elementAt(index); return ListTile( title: Text(collection.name), - onTap: () { - BookmarksProvider.selectedCollectionId = collection.id; - Navigator.pushNamed(context, CollectionPage.routeName); - }, + onTap: () => navigateToCollection(collection.id), ); } + void navigateToCollection(int collectionId) { + BookmarksProvider.selectedCollectionId = collectionId; + Navigator.pushNamed(context, CollectionPage.routeName); + } + @override void didChangeDependencies() { super.didChangeDependencies(); diff --git a/lib/service/shared_link_provider.dart b/lib/service/shared_link_provider.dart index 4c35262..6b5e732 100644 --- a/lib/service/shared_link_provider.dart +++ b/lib/service/shared_link_provider.dart @@ -6,13 +6,18 @@ import '../model/maps_link_metadata.dart'; class SharedLinkProvider extends ChangeNotifier { MapsLinkMetadata? _currentMapsLinkMetadata; - void setCurrentMapsLink(String mapsLink) async { + void setCurrentMapsLink(String mapsLink, {bool silent = false}) async { final metadata = await MetadataFetch.extract(mapsLink); _currentMapsLinkMetadata = MapsLinkMetadata( url: mapsLink, placeName: metadata?.title ?? '', ); - notifyListeners(); + if (!silent) notifyListeners(); + } + + void removeCurrentMapsLink({bool silent = false}) { + _currentMapsLinkMetadata = null; + if (!silent) notifyListeners(); } MapsLinkMetadata? get currentMapsLinkMetadata => _currentMapsLinkMetadata; diff --git a/lib/widgets/create_bookmark_dialog.dart b/lib/widgets/create_bookmark_dialog.dart index 8778ae9..2eb461a 100644 --- a/lib/widgets/create_bookmark_dialog.dart +++ b/lib/widgets/create_bookmark_dialog.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../model/bookmark.dart'; +import '../model/maps_link_metadata.dart'; class CreateBookmarkDialog extends StatelessWidget { const CreateBookmarkDialog({ @@ -9,10 +10,12 @@ class CreateBookmarkDialog extends StatelessWidget { required this.collectionId, required this.onSavePressed, this.selectedBookmark, + this.selectedMapsLink, }); final void Function(Bookmark bookmark) onSavePressed; final int collectionId; final Bookmark? selectedBookmark; + final MapsLinkMetadata? selectedMapsLink; @override Widget build(BuildContext context) { @@ -20,6 +23,12 @@ class CreateBookmarkDialog extends StatelessWidget { final linkController = TextEditingController(); final descriptionController = TextEditingController(); + if (selectedMapsLink != null) { + nameController.text = selectedMapsLink!.placeName; + linkController.text = selectedMapsLink!.url; + descriptionController.text = selectedMapsLink!.description; + } + return AlertDialog( title: Text('Create Bookmark'), content: SingleChildScrollView( @@ -82,19 +91,28 @@ class CreateBookmarkDialog extends StatelessWidget { ), ), actions: [ - FloatingActionButton( - onPressed: () { - onSavePressed( - Bookmark( - collectionId: collectionId, - name: nameController.text, - link: linkController.text, - description: descriptionController.text, - ), - ); - Navigator.of(context).pop(); - }, - child: Icon(Icons.save), + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: Text('Cancel'), + ), + FloatingActionButton( + onPressed: () { + onSavePressed( + Bookmark( + collectionId: collectionId, + name: nameController.text, + link: linkController.text, + description: descriptionController.text, + ), + ); + Navigator.of(context).pop(); + }, + child: Icon(Icons.save), + ), + ], ), ], );