From 143206cd7256f0bbb70dcf0a0d9687f4d5921b7b Mon Sep 17 00:00:00 2001 From: marco Date: Wed, 14 Jan 2026 22:49:32 +0100 Subject: [PATCH] added simple search feature --- lib/pages/collections_list_page.dart | 7 ++++ lib/pages/search_page.dart | 36 +++++++++++++++++-- .../search_widgets/search_bar_widget.dart | 16 +++++++++ .../search_widgets/search_results_widget.dart | 36 +++++++++++++++++++ 4 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 lib/widgets/search_widgets/search_bar_widget.dart create mode 100644 lib/widgets/search_widgets/search_results_widget.dart diff --git a/lib/pages/collections_list_page.dart b/lib/pages/collections_list_page.dart index 39325f4..28197cf 100644 --- a/lib/pages/collections_list_page.dart +++ b/lib/pages/collections_list_page.dart @@ -7,6 +7,7 @@ import '../service/shared_link_provider.dart'; import '../service/storage.dart'; import '../widgets/create_bookmark_collection_dialog.dart'; import 'collection_page.dart'; +import 'search_page.dart' show SearchPage; class CollectionsListPage extends StatefulWidget { const CollectionsListPage({super.key}); @@ -88,6 +89,12 @@ class _CollectionsListPageState extends State { TextButton( onPressed: () => provider.removeCurrentMapsLink(), child: Text('Cancel'), + ) + else + IconButton( + onPressed: () => + Navigator.of(context).pushNamed(SearchPage.routeName), + icon: Icon(Icons.search), ), ], ), diff --git a/lib/pages/search_page.dart b/lib/pages/search_page.dart index 46c2916..cdde8e3 100644 --- a/lib/pages/search_page.dart +++ b/lib/pages/search_page.dart @@ -1,11 +1,43 @@ import 'package:flutter/material.dart'; -class SearchPage extends StatelessWidget { +import '../model/bookmark.dart'; +import '../service/storage.dart'; +import '../widgets/search_widgets/search_bar_widget.dart'; +import '../widgets/search_widgets/search_results_widget.dart'; + +class SearchPage extends StatefulWidget { const SearchPage({super.key}); + static const String routeName = '/search'; + @override + State createState() => _SearchPageState(); +} + +class _SearchPageState extends State { + final List allBookmarks = Storage.loadBookmarks(); + String searchString = ''; + @override Widget build(BuildContext context) { - return const Placeholder(); + return Scaffold( + appBar: AppBar(title: Text('Search')), + body: Column( + children: [ + SearchBarWidget( + onEditingComplete: (searchString) => setState(() { + this.searchString = searchString; + }), + ), + Expanded( + child: SearchResultsWidget( + bookmarks: allBookmarks.where( + (bookmark) => bookmark.name.contains(searchString), + ), + ), + ), + ], + ), + ); } } diff --git a/lib/widgets/search_widgets/search_bar_widget.dart b/lib/widgets/search_widgets/search_bar_widget.dart new file mode 100644 index 0000000..46afb15 --- /dev/null +++ b/lib/widgets/search_widgets/search_bar_widget.dart @@ -0,0 +1,16 @@ +import 'package:flutter/material.dart'; + +class SearchBarWidget extends StatelessWidget { + const SearchBarWidget({super.key, required this.onEditingComplete}); + + final Function(String searchString) onEditingComplete; + + @override + Widget build(BuildContext context) { + TextEditingController searchBarController = TextEditingController(); + return TextField( + controller: searchBarController, + onEditingComplete: () => onEditingComplete(searchBarController.text), + ); + } +} diff --git a/lib/widgets/search_widgets/search_results_widget.dart b/lib/widgets/search_widgets/search_results_widget.dart new file mode 100644 index 0000000..6dea433 --- /dev/null +++ b/lib/widgets/search_widgets/search_results_widget.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; + +import '../../model/bookmark.dart'; +import '../../service/notifying.dart'; +import '../../service/url_launcher.dart'; + +class SearchResultsWidget extends StatelessWidget { + const SearchResultsWidget({super.key, required this.bookmarks}); + + final Iterable bookmarks; + + Widget bookmarkListItemBuilder(BuildContext context, int index) { + final bookmark = bookmarks.elementAt(index); + return ListTile( + title: Text(bookmark.name), + onTap: () => launchUrlFromString(bookmark.link).then((errorCode) { + if (context.mounted && errorCode != UrlLaunchErrorCode.none) { + Notifying.showUrlErrorSnackbar(context, errorCode); + } else if (context.mounted) { + Navigator.of(context).pop(); + } + }), + ); + } + + @override + Widget build(BuildContext context) { + if (bookmarks.isNotEmpty) { + return ListView.builder( + itemBuilder: bookmarkListItemBuilder, + itemCount: bookmarks.length, + ); + } + return Center(child: Text('Start searching')); + } +}