fix: accurate loading indicator for search, add button to clear search

main
daniel-michel 2024-01-09 12:47:42 +01:00
parent d5861bdb78
commit a0e4edb508
3 changed files with 43 additions and 21 deletions

View File

@ -41,6 +41,7 @@ class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
late AnimationController _controller; late AnimationController _controller;
late LiveSearch liveSearch; late LiveSearch liveSearch;
late TextEditingController _searchController;
@override @override
void initState() { void initState() {
@ -49,12 +50,14 @@ class _HomePageState extends State<HomePage>
vsync: this, // the SingleTickerProviderStateMixin vsync: this, // the SingleTickerProviderStateMixin
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
); );
_searchController = TextEditingController();
liveSearch = LiveSearch(widget.manager); liveSearch = LiveSearch(widget.manager);
} }
@override @override
void dispose() { void dispose() {
_controller.dispose(); _controller.dispose();
_searchController.dispose();
super.dispose(); super.dispose();
} }
@ -62,7 +65,11 @@ class _HomePageState extends State<HomePage>
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: TextField( title: Row(
children: [
Expanded(
child: TextField(
controller: _searchController,
decoration: const InputDecoration( decoration: const InputDecoration(
hintText: "Search", hintText: "Search",
border: InputBorder.none, border: InputBorder.none,
@ -78,6 +85,23 @@ class _HomePageState extends State<HomePage>
}); });
}, },
), ),
),
AnimatedBuilder(
animation: _controller,
builder: (context, child) {
if (liveSearch.searchTerm.isEmpty) return Container();
return IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
_searchController.clear();
liveSearch.updateSearch("");
_controller.reverse();
},
);
},
),
],
),
actions: [HamburgerMenu(widget.manager)], actions: [HamburgerMenu(widget.manager)],
), ),
body: SwipeTransition( body: SwipeTransition(

View File

@ -7,6 +7,8 @@ class DelayedFunctionCaller {
DelayedFunctionCaller(this.function, this.duration); DelayedFunctionCaller(this.function, this.duration);
get scheduled => _timer != null && _timer!.isActive;
void call() { void call() {
// If a timer is already active, return. // If a timer is already active, return.
if (_timer != null && _timer!.isActive) { if (_timer != null && _timer!.isActive) {

View File

@ -9,32 +9,29 @@ class LiveSearch extends ChangeNotifier {
Duration minTimeBetweenRequests = const Duration(milliseconds: 200); Duration minTimeBetweenRequests = const Duration(milliseconds: 200);
late final DelayedFunctionCaller _searchCaller; late final DelayedFunctionCaller _searchCaller;
final MovieManager manager; final MovieManager manager;
bool loading = false;
bool searchingOnline = false; bool searchingOnline = false;
LiveSearch(this.manager) { LiveSearch(this.manager) {
_searchCaller = DelayedFunctionCaller(searchOnline, minTimeBetweenRequests); _searchCaller = DelayedFunctionCaller(searchOnline, minTimeBetweenRequests);
} }
get loading => searchingOnline || _searchCaller.scheduled;
void updateSearch(String search) { void updateSearch(String search) {
searchTerm = search; searchTerm = search;
if (searchTerm.isEmpty) { if (searchTerm.isEmpty) {
return; return;
} }
searchResults = manager.localSearch(search); searchResults = manager.localSearch(search);
loading = true;
_searchCaller.call(); _searchCaller.call();
notifyListeners(); notifyListeners();
} }
void searchOnline() async { void searchOnline() async {
if (searchTerm.isEmpty) { if (searchTerm.isEmpty) {
loading = false;
notifyListeners();
return; return;
} }
if (searchingOnline) { if (searchingOnline) {
loading = true;
_searchCaller.call(); _searchCaller.call();
notifyListeners(); notifyListeners();
return; return;
@ -55,7 +52,6 @@ class LiveSearch extends ChangeNotifier {
notifyListeners(); notifyListeners();
} finally { } finally {
searchingOnline = false; searchingOnline = false;
loading = false;
notifyListeners(); notifyListeners();
} }
} }