From 15105a7f337e9838dc5d329a8d9171b6ca48c333 Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Tue, 4 Jun 2024 16:58:53 +0300 Subject: [PATCH] Add: search by category --- lib/pages/main.dart | 78 +++++++++++++++++++++++++++++++++++---------- pubspec.lock | 76 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 135 insertions(+), 19 deletions(-) diff --git a/lib/pages/main.dart b/lib/pages/main.dart index 21dac70..caca34c 100644 --- a/lib/pages/main.dart +++ b/lib/pages/main.dart @@ -8,6 +8,7 @@ import 'package:gymlink_module_web/pages/basket.dart'; import 'package:gymlink_module_web/pages/detail.dart'; import 'package:gymlink_module_web/pages/order_history.dart'; import 'package:gymlink_module_web/providers/cart.dart'; +import 'package:gymlink_module_web/providers/main.dart'; import 'package:gymlink_module_web/tools/items.dart'; import 'package:gymlink_module_web/tools/prefs.dart'; import 'package:gymlink_module_web/tools/relative.dart'; @@ -69,7 +70,9 @@ class _MainPageState extends State { int cartLength = 0; int itemViewCount = 0; bool isLoading = false; + bool isSearching = false; List categories = []; + GymCategory? selectedCategory; @override void initState() { @@ -79,17 +82,9 @@ class _MainPageState extends State { cartLength = value.length; }); }); - getItems(context).then((value) => setState(() { - filteredData = value; - itemViewCount = min(5, value.length); - WidgetsBinding.instance.addPostFrameCallback((_) { - for (var element in filteredData.sublist(0, itemViewCount)) { - precacheImage(NetworkImage(element.images[0].url), context); - } - }); - })); getCategories(context).then((value) => setState(() { categories = value; + _onSearch(); })); } @@ -106,18 +101,30 @@ class _MainPageState extends State { } } - void _onSearch() async { - final data = await getItems(context, searchText: searchText); + void _searchItems({String searchText = '', String categoryId = ''}) async { + setState(() { + isSearching = true; + }); + final data = + await getItems(context, searchText: searchText, categoryId: categoryId); setState(() { filteredData = data; - itemViewCount = - min(filteredData.length, searchText == '' ? 5 : itemViewCount); + itemViewCount = min(filteredData.length, 5); + debugPrint(itemViewCount.toString()); }); WidgetsBinding.instance.addPostFrameCallback((_) { for (var element in filteredData.sublist(0, itemViewCount)) { precacheImage(NetworkImage(element.images[0].url), context); } }); + setState(() { + isSearching = false; + }); + } + + void _onSearch() async { + final categoryId = selectedCategory == null ? '' : selectedCategory!.id; + _searchItems(searchText: searchText, categoryId: categoryId); } @override @@ -136,7 +143,7 @@ class _MainPageState extends State { Expanded( child: TextField( onChanged: (value) => setState(() { - searchText = value; + searchText = value.trim().toLowerCase(); if (searchText == '') { _onSearch(); } @@ -203,6 +210,43 @@ class _MainPageState extends State { ], ), ), + SizedBox( + height: 60, + child: ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemCount: categories.length, + itemBuilder: (context, index) { + final category = categories[index]; + return GestureDetector( + onTap: () { + setState(() { + selectedCategory = + selectedCategory == category ? null : category; + }); + _onSearch(); + }, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 10, vertical: 10), + child: Chip( + label: Text(category.name), + //FIXME: проблема с цветом + backgroundColor: selectedCategory == category + ? context + .read() + .theme + .primaryColorLight + : Colors.white, + labelStyle: TextStyle( + color: selectedCategory == category + ? Colors.white + : Colors.black), + ), + ), + ); + }), + ), Expanded( child: LazyLoadScrollView( onEndOfPage: _onLoad, @@ -210,9 +254,9 @@ class _MainPageState extends State { child: Scrollbar( child: ListView( children: [ - filteredData.isEmpty && searchText != '' + filteredData.isEmpty && searchText != '' && !isSearching ? const Center(child: Text('Ничего не найдено')) - : filteredData.isEmpty + : isSearching ? const Center(child: CircularProgressIndicator()) : GridView.builder( physics: const NeverScrollableScrollPhysics(), @@ -247,7 +291,7 @@ class _MainPageState extends State { ); }, ), - itemViewCount > 0 + itemViewCount > 0 && !isSearching ? Padding( padding: const EdgeInsets.symmetric(vertical: 10), child: Center( diff --git a/pubspec.lock b/pubspec.lock index adbc47f..1a560fd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -25,6 +25,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + carousel_slider: + dependency: "direct main" + description: + name: carousel_slider + sha256: "9c695cc963bf1d04a47bd6021f68befce8970bcd61d24938e1fb0918cf5d9c42" + url: "https://pub.dev" + source: hosted + version: "4.2.1" characters: dependency: transitive description: @@ -69,10 +77,10 @@ packages: dependency: "direct main" description: name: cupertino_icons - sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 url: "https://pub.dev" source: hosted - version: "1.0.6" + version: "1.0.8" fake_async: dependency: transitive description: @@ -118,6 +126,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.1" + flutter_svg: + dependency: "direct main" + description: + name: flutter_svg + sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2" + url: "https://pub.dev" + source: hosted + version: "2.0.10+1" flutter_test: dependency: "direct dev" description: flutter @@ -152,6 +168,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + lazy_load_scrollview: + dependency: "direct main" + description: + name: lazy_load_scrollview + sha256: "230c827d6f7ec5e461f0674ef332daae2f78190bf1e4cd84977e51de04b231e3" + url: "https://pub.dev" + source: hosted + version: "1.3.0" leak_tracker: dependency: transitive description: @@ -232,6 +256,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.0" + path_parsing: + dependency: transitive + description: + name: path_parsing + sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf + url: "https://pub.dev" + source: hosted + version: "1.0.1" path_provider_linux: dependency: transitive description: @@ -256,6 +288,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.1" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + url: "https://pub.dev" + source: hosted + version: "6.0.2" platform: dependency: transitive description: @@ -477,6 +517,30 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.1" + vector_graphics: + dependency: transitive + description: + name: vector_graphics + sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3" + url: "https://pub.dev" + source: hosted + version: "1.1.11+1" + vector_graphics_codec: + dependency: transitive + description: + name: vector_graphics_codec + sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da + url: "https://pub.dev" + source: hosted + version: "1.1.11+1" + vector_graphics_compiler: + dependency: transitive + description: + name: vector_graphics_compiler + sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81" + url: "https://pub.dev" + source: hosted + version: "1.1.11+1" vector_math: dependency: transitive description: @@ -517,6 +581,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + xml: + dependency: transitive + description: + name: xml + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://pub.dev" + source: hosted + version: "6.5.0" sdks: dart: ">=3.3.3 <4.0.0" flutter: ">=3.19.0"