Add progress indicators to search

This commit is contained in:
Tommy Chow 2022-01-05 09:38:05 -05:00
parent 58bb1d49d3
commit 25cf38eeaa
5 changed files with 227 additions and 178 deletions

View file

@ -1,6 +1,5 @@
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:frosty/screens/home/search/search_results_categories.dart';
import 'package:frosty/screens/home/search/search_results_channels.dart';
import 'package:frosty/screens/home/search/stores/search_store.dart';
@ -16,6 +15,8 @@ class Search extends StatefulWidget {
}
class _SearchState extends State<Search> {
final textEditingController = TextEditingController();
@override
Widget build(BuildContext context) {
const headerPadding = EdgeInsets.fromLTRB(15.0, 20.0, 15.0, 10.0);
@ -26,7 +27,7 @@ class _SearchState extends State<Search> {
Padding(
padding: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 10.0),
child: TextField(
controller: searchStore.textController,
controller: textEditingController,
autocorrect: false,
decoration: InputDecoration(
isDense: true,
@ -36,55 +37,62 @@ class _SearchState extends State<Search> {
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
suffixIcon: IconButton(
onPressed: searchStore.clearSearch,
onPressed: () {
setState(() {
textEditingController.clear();
});
FocusManager.instance.primaryFocus?.unfocus();
},
icon: const Icon(Icons.clear),
),
),
onSubmitted: searchStore.handleQuery,
onSubmitted: (query) => setState(() {
searchStore.handleQuery(query);
}),
),
),
Expanded(
child: RefreshIndicator(
onRefresh: () => searchStore.handleQuery(searchStore.textController.text),
child: GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Observer(
builder: (_) {
if (searchStore.textController.text.isEmpty) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (searchStore.searchHistory.isNotEmpty)
const Padding(
padding: EdgeInsets.all(15.0),
child: Text(
'HISTORY',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Expanded(
child: ListView(
children: searchStore.searchHistory
.mapIndexed((index, searchTerm) => ListTile(
leading: const Icon(Icons.history),
title: Text(searchTerm),
trailing: IconButton(
icon: const Icon(Icons.cancel),
onPressed: () => searchStore.searchHistory.removeAt(index),
),
onTap: () {
searchStore.textController.text = searchTerm;
searchStore.handleQuery(searchTerm);
},
))
.toList(),
child: GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: textEditingController.text.isEmpty
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (searchStore.searchHistory.isNotEmpty)
const Padding(
padding: EdgeInsets.all(15.0),
child: Text(
'HISTORY',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
],
);
}
return CustomScrollView(
Expanded(
child: ListView(
children: searchStore.searchHistory
.mapIndexed(
(index, searchTerm) => ListTile(
leading: const Icon(Icons.history),
title: Text(searchTerm),
trailing: IconButton(
icon: const Icon(Icons.cancel),
onPressed: () => setState(() {
searchStore.searchHistory.removeAt(index);
}),
),
onTap: () {
setState(() {
textEditingController.text = searchTerm;
searchStore.handleQuery(searchTerm);
});
},
),
)
.toList(),
),
),
],
)
: CustomScrollView(
slivers: [
const SliverToBoxAdapter(
child: SectionHeader(
@ -92,21 +100,19 @@ class _SearchState extends State<Search> {
padding: headerPadding,
),
),
SearchResultsChannels(searchStore: searchStore),
if (searchStore.categorySearchResults.isNotEmpty) ...[
const SliverToBoxAdapter(
child: SectionHeader(
'Categories',
padding: headerPadding,
),
SearchResultsChannels(
searchStore: searchStore,
query: textEditingController.text,
),
const SliverToBoxAdapter(
child: SectionHeader(
'Categories',
padding: headerPadding,
),
SearchResultsCategories(categories: searchStore.categorySearchResults),
]
),
SearchResultsCategories(searchStore: searchStore),
],
);
},
),
),
),
),
),
],
@ -115,7 +121,7 @@ class _SearchState extends State<Search> {
@override
void dispose() {
widget.searchStore.dispose();
textEditingController.dispose();
super.dispose();
}
}