Add progress indicators to search
This commit is contained in:
parent
58bb1d49d3
commit
25cf38eeaa
5 changed files with 227 additions and 178 deletions
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue