diff --git a/lib/main.dart b/lib/main.dart index 9a8eda2..75858ce 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,6 +3,7 @@ import 'package:provider/provider.dart'; import 'pages/collection_page.dart'; import 'pages/collections_list_page.dart'; import 'pages/search_page.dart'; +import 'service/search_provider.dart'; import 'service/shared_link_provider.dart'; import 'service/storage.dart'; import 'service/share_intent_service.dart'; @@ -12,8 +13,11 @@ void main() async { WidgetsFlutterBinding.ensureInitialized(); await Storage.initialize(); runApp( - ChangeNotifierProvider( - create: (_) => SharedLinkProvider(), + MultiProvider( + providers: [ + ChangeNotifierProvider(create: (_) => SharedLinkProvider()), + ChangeNotifierProvider(create: (_) => SearchProvider()), + ], child: const MapsBookmarks(), ), ); diff --git a/lib/pages/search_page.dart b/lib/pages/search_page.dart index cdde8e3..83e4a91 100644 --- a/lib/pages/search_page.dart +++ b/lib/pages/search_page.dart @@ -1,23 +1,14 @@ import 'package:flutter/material.dart'; - -import '../model/bookmark.dart'; -import '../service/storage.dart'; +import 'package:provider/provider.dart'; +import '../service/search_provider.dart'; import '../widgets/search_widgets/search_bar_widget.dart'; import '../widgets/search_widgets/search_results_widget.dart'; -class SearchPage extends StatefulWidget { +class SearchPage extends StatelessWidget { 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 Scaffold( @@ -25,17 +16,9 @@ class _SearchPageState extends State { body: Column( children: [ SearchBarWidget( - onEditingComplete: (searchString) => setState(() { - this.searchString = searchString; - }), - ), - Expanded( - child: SearchResultsWidget( - bookmarks: allBookmarks.where( - (bookmark) => bookmark.name.contains(searchString), - ), - ), + onEditingComplete: context.read().setSearchText, ), + Expanded(child: SearchResultsWidget()), ], ), ); diff --git a/lib/service/search_provider.dart b/lib/service/search_provider.dart new file mode 100644 index 0000000..2b3aaf3 --- /dev/null +++ b/lib/service/search_provider.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +class SearchProvider extends ChangeNotifier { + String _searchText = ''; + + void setSearchText(String searchText, {bool silent = false}) { + _searchText = searchText; + if (!silent) notifyListeners(); + } + + String get searchText => _searchText; +} diff --git a/lib/widgets/search_widgets/search_bar_widget.dart b/lib/widgets/search_widgets/search_bar_widget.dart index 46afb15..8f04a63 100644 --- a/lib/widgets/search_widgets/search_bar_widget.dart +++ b/lib/widgets/search_widgets/search_bar_widget.dart @@ -7,10 +7,10 @@ class SearchBarWidget extends StatelessWidget { @override Widget build(BuildContext context) { - TextEditingController searchBarController = TextEditingController(); - return TextField( - controller: searchBarController, - onEditingComplete: () => onEditingComplete(searchBarController.text), - ); + return TextField(onChanged: (text) => onChanged(text, context)); + } + + void onChanged(String text, BuildContext context) { + if (context.mounted) onEditingComplete(text); } } diff --git a/lib/widgets/search_widgets/search_results_widget.dart b/lib/widgets/search_widgets/search_results_widget.dart index 6dea433..ab08232 100644 --- a/lib/widgets/search_widgets/search_results_widget.dart +++ b/lib/widgets/search_widgets/search_results_widget.dart @@ -1,16 +1,24 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import '../../model/bookmark.dart'; import '../../service/notifying.dart'; +import '../../service/search_provider.dart'; +import '../../service/storage.dart' show Storage; import '../../service/url_launcher.dart'; -class SearchResultsWidget extends StatelessWidget { - const SearchResultsWidget({super.key, required this.bookmarks}); +class SearchResultsWidget extends StatefulWidget { + const SearchResultsWidget({super.key}); - final Iterable bookmarks; + @override + State createState() => _SearchResultsWidgetState(); +} + +class _SearchResultsWidgetState extends State { + final List allBookmarks = Storage.loadBookmarks(); Widget bookmarkListItemBuilder(BuildContext context, int index) { - final bookmark = bookmarks.elementAt(index); + final bookmark = filteredBookmarks.elementAt(index); return ListTile( title: Text(bookmark.name), onTap: () => launchUrlFromString(bookmark.link).then((errorCode) { @@ -25,12 +33,18 @@ class SearchResultsWidget extends StatelessWidget { @override Widget build(BuildContext context) { - if (bookmarks.isNotEmpty) { + if (filteredBookmarks.isNotEmpty) { return ListView.builder( itemBuilder: bookmarkListItemBuilder, - itemCount: bookmarks.length, + itemCount: filteredBookmarks.length, ); } return Center(child: Text('Start searching')); } + + Iterable get filteredBookmarks => allBookmarks.where( + (bookmark) => bookmark.name.toLowerCase().contains( + context.watch().searchText.toLowerCase(), + ), + ); }