mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-11-25 22:39:22 +00:00
Made search live
This commit is contained in:
parent
af079cc4b0
commit
33eb0c5aed
@ -1,4 +1,14 @@
|
||||
import 'package:comunic/helpers/groups_helper.dart';
|
||||
import 'package:comunic/helpers/search_helper.dart';
|
||||
import 'package:comunic/helpers/users_helper.dart';
|
||||
import 'package:comunic/lists/groups_list.dart';
|
||||
import 'package:comunic/lists/search_results_list.dart';
|
||||
import 'package:comunic/lists/users_list.dart';
|
||||
import 'package:comunic/models/search_result.dart';
|
||||
import 'package:comunic/ui/widgets/account_image_widget.dart';
|
||||
import 'package:comunic/ui/widgets/group_icon_widget.dart';
|
||||
import 'package:comunic/utils/intl_utils.dart';
|
||||
import 'package:comunic/utils/ui_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Global search field
|
||||
@ -7,12 +17,37 @@ import 'package:flutter/material.dart';
|
||||
|
||||
const _MainSearchColor = Color(0xFF999990);
|
||||
|
||||
class _SearchResults {
|
||||
final SearchResultsList list;
|
||||
final UsersList users;
|
||||
final GroupsList groups;
|
||||
|
||||
_SearchResults(this.list, this.users, this.groups);
|
||||
}
|
||||
|
||||
class GlobalSearchField extends StatefulWidget {
|
||||
@override
|
||||
_GlobalSearchFieldState createState() => _GlobalSearchFieldState();
|
||||
}
|
||||
|
||||
class _GlobalSearchFieldState extends State<GlobalSearchField> {
|
||||
final _focusNode = FocusNode();
|
||||
|
||||
final _controller = TextEditingController();
|
||||
|
||||
_SearchResults _searchResultsList;
|
||||
|
||||
OverlayEntry _overlayEntry;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_focusNode.addListener(() {
|
||||
if (!_focusNode.hasFocus) _removeOverlay();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
@ -23,7 +58,10 @@ class _GlobalSearchFieldState extends State<GlobalSearchField> {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
child: TextField(
|
||||
controller: _controller,
|
||||
focusNode: _focusNode,
|
||||
textAlignVertical: TextAlignVertical.center,
|
||||
onChanged: (s) => _refreshSearch(),
|
||||
decoration: InputDecoration(
|
||||
hintText: tr("Search..."),
|
||||
hintStyle: TextStyle(color: _MainSearchColor),
|
||||
@ -40,4 +78,94 @@ class _GlobalSearchFieldState extends State<GlobalSearchField> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _refreshSearch() async {
|
||||
if (_controller.text.length < 1) {
|
||||
_removeOverlay();
|
||||
return;
|
||||
}
|
||||
|
||||
_showOverlay();
|
||||
|
||||
try {
|
||||
final results = await SearchHelper().globalSearch(_controller.text);
|
||||
final users = await UsersHelper().getListWithThrow(results.usersId);
|
||||
final groups = await GroupsHelper().getListOrThrow(results.groupsId);
|
||||
|
||||
_searchResultsList = _SearchResults(results, users, groups);
|
||||
|
||||
if (_overlayEntry != null) _overlayEntry.markNeedsBuild();
|
||||
} catch (e, s) {
|
||||
print("Could not perform search! $e\n$s");
|
||||
showSimpleSnack(context, tr("Could not perform search!"));
|
||||
}
|
||||
}
|
||||
|
||||
void _showOverlay() {
|
||||
if (_overlayEntry == null) {
|
||||
_overlayEntry = _createOverlayEntry();
|
||||
Overlay.of(context).insert(_overlayEntry);
|
||||
}
|
||||
}
|
||||
|
||||
void _removeOverlay() {
|
||||
if (_overlayEntry != null) {
|
||||
_overlayEntry.remove();
|
||||
_overlayEntry = null;
|
||||
}
|
||||
}
|
||||
|
||||
OverlayEntry _createOverlayEntry() {
|
||||
RenderBox renderBox = context.findRenderObject();
|
||||
var size = renderBox.size;
|
||||
var offset = renderBox.localToGlobal(Offset.zero);
|
||||
|
||||
return OverlayEntry(
|
||||
builder: (context) => Positioned(
|
||||
left: offset.dx,
|
||||
top: offset.dy + size.height + 5.0,
|
||||
width: size.width,
|
||||
height: 300,
|
||||
child: Material(
|
||||
elevation: 4.0,
|
||||
child: _SearchResultsWidget(results: _searchResultsList),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
class _SearchResultsWidget extends StatelessWidget {
|
||||
final _SearchResults results;
|
||||
|
||||
const _SearchResultsWidget({Key key, this.results}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (results == null) return Container();
|
||||
return ListView.builder(
|
||||
itemBuilder: _builder,
|
||||
itemCount: results.list.length,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _builder(BuildContext context, int index) {
|
||||
final res = results.list[index];
|
||||
|
||||
switch (res.kind) {
|
||||
case SearchResultKind.USER:
|
||||
final user = results.users.getUser(res.id);
|
||||
return ListTile(
|
||||
leading: AccountImageWidget(user: user),
|
||||
title: Text(user.displayName),
|
||||
);
|
||||
|
||||
case SearchResultKind.GROUP:
|
||||
final group = results.groups.getGroup(res.id);
|
||||
return ListTile(
|
||||
leading: GroupIcon(group: group),
|
||||
title: Text(group.displayName),
|
||||
);
|
||||
}
|
||||
throw Exception("Unreachable statement!");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user