From 5cd789bf3a1decaf4fb3300703766fa96898631f Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Mon, 1 May 2023 22:31:36 +0200 Subject: [PATCH] Changed clients search --- lib/providers/servers_provider.dart | 52 ++++++++++++++++ lib/screens/clients/clients.dart | 60 +++++++++++++++--- lib/screens/clients/clients_desktop_view.dart | 61 ++++++++++++++++--- 3 files changed, 154 insertions(+), 19 deletions(-) diff --git a/lib/providers/servers_provider.dart b/lib/providers/servers_provider.dart index fd0bd58..e59d8ae 100644 --- a/lib/providers/servers_provider.dart +++ b/lib/providers/servers_provider.dart @@ -34,6 +34,9 @@ class ServersProvider with ChangeNotifier { loadStatus: LoadStatus.loading, data: null ); + String? _searchTermClients; + List _filteredActiveClients = []; + List _filteredAddedClients = []; final Filtering _filtering = Filtering( loadStatus: LoadStatus.loading, @@ -87,6 +90,18 @@ class ServersProvider with ChangeNotifier { return _clients; } + String? get searchTermClients { + return _searchTermClients; + } + + List get filteredActiveClients { + return _filteredActiveClients; + } + + List get filteredAddedClients { + return _filteredAddedClients; + } + FilteringStatus? get filteringStatus { return _filteringStatus; } @@ -148,6 +163,43 @@ class ServersProvider with ChangeNotifier { void setClientsData(ClientsData data) { _clients.data = data; + if (_searchTermClients != null && _searchTermClients != '') { + _filteredActiveClients = _clients.data!.autoClientsData.where( + (client) => client.ip.contains(_searchTermClients!.toLowerCase()) || (client.name != null ? client.name!.contains(_searchTermClients!.toLowerCase()) : false) + ).toList(); + _filteredAddedClients = _clients.data!.clients.where( + (client) { + isContained(String value) => value.contains(value.toLowerCase()); + return client.ids.any(isContained); + } + ).toList(); + } + else { + _filteredActiveClients = data.autoClientsData; + _filteredAddedClients = data.clients; + } + notifyListeners(); + } + + void setSearchTermClients(String? value) { + _searchTermClients = value; + if (value != null && value != '') { + if (_clients.data != null) { + _filteredActiveClients = _clients.data!.autoClientsData.where( + (client) => client.ip.contains(value.toLowerCase()) || (client.name != null ? client.name!.contains(value.toLowerCase()) : false) + ).toList(); + _filteredAddedClients = _clients.data!.clients.where( + (client) { + isContained(String value) => value.contains(value.toLowerCase()); + return client.ids.any(isContained); + } + ).toList(); + } + } + else { + if (_clients.data != null) _filteredActiveClients = _clients.data!.autoClientsData; + if (_clients.data != null) _filteredAddedClients = _clients.data!.clients; + } notifyListeners(); } diff --git a/lib/screens/clients/clients.dart b/lib/screens/clients/clients.dart index 3b52760..91d7dd1 100644 --- a/lib/screens/clients/clients.dart +++ b/lib/screens/clients/clients.dart @@ -61,6 +61,9 @@ class _ClientsWidgetState extends State with TickerProviderStateM late TabController tabController; final ScrollController scrollController = ScrollController(); + bool searchMode = false; + final TextEditingController searchController = TextEditingController(); + Future fetchClients() async { widget.setLoadingStatus(LoadStatus.loading, false); final result = await getClients(widget.server); @@ -136,7 +139,7 @@ class _ClientsWidgetState extends State with TickerProviderStateM scrollController: scrollController, loadStatus: serversProvider.clients.loadStatus, data: serversProvider.clients.loadStatus == LoadStatus.loaded - ? serversProvider.clients.data!.autoClientsData : [], + ? serversProvider.filteredActiveClients : [], fetchClients: fetchClients, onClientSelected: (client) => Navigator.push(context, MaterialPageRoute( builder: (context) => LogsListClient( @@ -151,7 +154,7 @@ class _ClientsWidgetState extends State with TickerProviderStateM scrollController: scrollController, loadStatus: serversProvider.clients.loadStatus, data: serversProvider.clients.loadStatus == LoadStatus.loaded - ? serversProvider.clients.data!.clients : [], + ? serversProvider.filteredAddedClients : [], fetchClients: fetchClients, onClientSelected: (client) => Navigator.push(context, MaterialPageRoute( builder: (context) => LogsListClient( @@ -216,19 +219,58 @@ class _ClientsWidgetState extends State with TickerProviderStateM SliverOverlapAbsorber( handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), sliver: SliverAppBar( - title: Text(AppLocalizations.of(context)!.clients), + title: searchMode == true + ? Row( + children: [ + IconButton( + onPressed: () { + setState(() { + searchMode = false; + searchController.text = ""; + serversProvider.setSearchTermClients(null); + }); + }, + icon: const Icon(Icons.arrow_back_rounded) + ), + const SizedBox(width: 16), + Expanded( + child: TextField( + controller: searchController, + onChanged: (value) => serversProvider.setSearchTermClients(value), + decoration: InputDecoration( + suffixIcon: IconButton( + onPressed: () { + setState(() { + searchController.text = ""; + serversProvider.setSearchTermClients(null); + }); + }, + icon: const Icon(Icons.clear_rounded) + ), + hintText: AppLocalizations.of(context)!.search, + hintStyle: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 18 + ), + border: InputBorder.none, + ), + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 18 + ), + ), + ) + ], + ) + : Text(AppLocalizations.of(context)!.clients), pinned: true, floating: true, centerTitle: false, forceElevated: innerBoxIsScrolled, actions: [ - if (serversProvider.clients.loadStatus == LoadStatus.loaded) ...[ + if (serversProvider.clients.loadStatus == LoadStatus.loaded && searchMode == false) ...[ IconButton( - onPressed: () => { - Navigator.push(context, MaterialPageRoute( - builder: (context) => const SearchClients() - )) - }, + onPressed: () => setState(() => searchMode = true), icon: const Icon(Icons.search), tooltip: AppLocalizations.of(context)!.searchClients, ), diff --git a/lib/screens/clients/clients_desktop_view.dart b/lib/screens/clients/clients_desktop_view.dart index 8f0f772..19e6254 100644 --- a/lib/screens/clients/clients_desktop_view.dart +++ b/lib/screens/clients/clients_desktop_view.dart @@ -11,7 +11,6 @@ import 'package:adguard_home_manager/providers/app_config_provider.dart'; import 'package:adguard_home_manager/constants/enums.dart'; import 'package:adguard_home_manager/models/clients.dart'; import 'package:adguard_home_manager/providers/servers_provider.dart'; -import 'package:adguard_home_manager/screens/clients/search_clients.dart'; class ClientsDesktopView extends StatefulWidget { @@ -36,6 +35,9 @@ class _ClientsDesktopViewState extends State with TickerPro AutoClient? selectedActiveClient; Client? selectedAddedClient; + + bool searchMode = false; + final TextEditingController searchController = TextEditingController(); @override void initState() { @@ -90,7 +92,7 @@ class _ClientsDesktopViewState extends State with TickerPro scrollController: scrollController, loadStatus: serversProvider.clients.loadStatus, data: serversProvider.clients.loadStatus == LoadStatus.loaded - ? serversProvider.clients.data!.autoClientsData : [], + ? serversProvider.filteredActiveClients : [], fetchClients: widget.fetchClients, onClientSelected: (client) => setState(() { selectedAddedClient = null; @@ -111,7 +113,7 @@ class _ClientsDesktopViewState extends State with TickerPro scrollController: scrollController, loadStatus: serversProvider.clients.loadStatus, data: serversProvider.clients.loadStatus == LoadStatus.loaded - ? serversProvider.clients.data!.clients : [], + ? serversProvider.filteredAddedClients : [], fetchClients: widget.fetchClients, onClientSelected: (client) => setState(() { selectedActiveClient = null; @@ -136,16 +138,55 @@ class _ClientsDesktopViewState extends State with TickerPro length: 2, child: Scaffold( appBar: AppBar( - title: Text(AppLocalizations.of(context)!.clients), + title: searchMode == true + ? Row( + children: [ + IconButton( + onPressed: () { + setState(() { + searchMode = false; + searchController.text = ""; + serversProvider.setSearchTermClients(null); + }); + }, + icon: const Icon(Icons.arrow_back_rounded) + ), + const SizedBox(width: 16), + Expanded( + child: TextField( + controller: searchController, + onChanged: (value) => serversProvider.setSearchTermClients(value), + decoration: InputDecoration( + suffixIcon: IconButton( + onPressed: () { + setState(() { + searchController.text = ""; + serversProvider.setSearchTermClients(null); + }); + }, + icon: const Icon(Icons.clear_rounded) + ), + hintText: AppLocalizations.of(context)!.search, + hintStyle: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 18 + ), + border: InputBorder.none, + ), + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 18 + ), + ), + ) + ], + ) + : Text(AppLocalizations.of(context)!.clients), centerTitle: false, actions: [ - if (serversProvider.clients.loadStatus == LoadStatus.loaded) ...[ + if (serversProvider.clients.loadStatus == LoadStatus.loaded && searchMode == false) ...[ IconButton( - onPressed: () => { - Navigator.push(context, MaterialPageRoute( - builder: (context) => const SearchClients() - )) - }, + onPressed: () => setState(() => searchMode = true), icon: const Icon(Icons.search), tooltip: AppLocalizations.of(context)!.searchClients, ),