mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-11-25 22:39:22 +00:00
Create search page
This commit is contained in:
parent
ef9a2c7190
commit
0494a9058d
@ -1,6 +1,8 @@
|
|||||||
import 'package:comunic/helpers/users_helper.dart';
|
import 'package:comunic/helpers/users_helper.dart';
|
||||||
|
import 'package:comunic/lists/search_results_list.dart';
|
||||||
import 'package:comunic/lists/users_list.dart';
|
import 'package:comunic/lists/users_list.dart';
|
||||||
import 'package:comunic/models/api_request.dart';
|
import 'package:comunic/models/api_request.dart';
|
||||||
|
import 'package:comunic/models/search_result.dart';
|
||||||
import 'package:comunic/utils/api_utils.dart';
|
import 'package:comunic/utils/api_utils.dart';
|
||||||
|
|
||||||
/// Search helper
|
/// Search helper
|
||||||
@ -21,4 +23,25 @@ class SearchHelper {
|
|||||||
return await UsersHelper()
|
return await UsersHelper()
|
||||||
.getUsersInfo(response.getArray().map((f) => cast<int>(f)).toList());
|
.getUsersInfo(response.getArray().map((f) => cast<int>(f)).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Perform a global search
|
||||||
|
Future<SearchResultsList> globalSearch(String query) async {
|
||||||
|
final result = await APIRequest(
|
||||||
|
uri: "search/global", needLogin: true, args: {"query": query}).exec();
|
||||||
|
|
||||||
|
result.assertOk();
|
||||||
|
|
||||||
|
return SearchResultsList()..addAll(result.getArray().map((f) {
|
||||||
|
switch (f["kind"]) {
|
||||||
|
case "user":
|
||||||
|
return SearchResult(id: f["id"], kind: SearchResultKind.USER);
|
||||||
|
|
||||||
|
case "group":
|
||||||
|
return SearchResult(id: f["id"], kind: SearchResultKind.GROUP);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw Exception("Unkown search kind: ${f["kind"]}");
|
||||||
|
}
|
||||||
|
}).toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
20
lib/lists/search_results_list.dart
Normal file
20
lib/lists/search_results_list.dart
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import 'package:comunic/lists/abstract_list.dart';
|
||||||
|
import 'package:comunic/models/search_result.dart';
|
||||||
|
|
||||||
|
/// List of result of a global search on the database
|
||||||
|
///
|
||||||
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
|
class SearchResultsList extends AbstractList<SearchResult> {
|
||||||
|
/// Get the list of users included in this search result
|
||||||
|
Set<int> get usersId => this
|
||||||
|
.where((f) => f.kind == SearchResultKind.USER)
|
||||||
|
.map((f) => f.id)
|
||||||
|
.toSet();
|
||||||
|
|
||||||
|
/// Get the list of groups included in this search result
|
||||||
|
Set<int> get groupsId => this
|
||||||
|
.where((f) => f.kind == SearchResultKind.GROUP)
|
||||||
|
.map((f) => f.id)
|
||||||
|
.toSet();
|
||||||
|
}
|
18
lib/models/search_result.dart
Normal file
18
lib/models/search_result.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
||||||
|
/// Single search result
|
||||||
|
///
|
||||||
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
|
enum SearchResultKind { USER, GROUP }
|
||||||
|
|
||||||
|
class SearchResult {
|
||||||
|
final int id;
|
||||||
|
final SearchResultKind kind;
|
||||||
|
|
||||||
|
SearchResult({
|
||||||
|
@required this.id,
|
||||||
|
@required this.kind,
|
||||||
|
}) : assert(id != null),
|
||||||
|
assert(kind != null);
|
||||||
|
}
|
@ -9,6 +9,7 @@ import 'package:comunic/ui/screens/groups_list_screen.dart';
|
|||||||
import 'package:comunic/ui/screens/newest_posts.dart';
|
import 'package:comunic/ui/screens/newest_posts.dart';
|
||||||
import 'package:comunic/ui/screens/notifications_screen.dart';
|
import 'package:comunic/ui/screens/notifications_screen.dart';
|
||||||
import 'package:comunic/ui/screens/other_friends_lists_screen.dart';
|
import 'package:comunic/ui/screens/other_friends_lists_screen.dart';
|
||||||
|
import 'package:comunic/ui/screens/search_screen.dart';
|
||||||
import 'package:comunic/ui/screens/user_access_denied_screen.dart';
|
import 'package:comunic/ui/screens/user_access_denied_screen.dart';
|
||||||
import 'package:comunic/ui/screens/user_page_screen.dart';
|
import 'package:comunic/ui/screens/user_page_screen.dart';
|
||||||
import 'package:comunic/ui/widgets/navbar_widget.dart';
|
import 'package:comunic/ui/widgets/navbar_widget.dart';
|
||||||
@ -168,6 +169,9 @@ class _HomeRouteState extends HomeController {
|
|||||||
case BarCallbackActions.OPEN_USER_ACCESS_DENIED_PAGE:
|
case BarCallbackActions.OPEN_USER_ACCESS_DENIED_PAGE:
|
||||||
return UserAccessDeniedScreen(userID: _currTab.args["userID"]);
|
return UserAccessDeniedScreen(userID: _currTab.args["userID"]);
|
||||||
|
|
||||||
|
case BarCallbackActions.OPEN_SEARCH_PAGE:
|
||||||
|
return SearchScreen();
|
||||||
|
|
||||||
case BarCallbackActions.OPEN_GROUPS:
|
case BarCallbackActions.OPEN_GROUPS:
|
||||||
return GroupsListScreen();
|
return GroupsListScreen();
|
||||||
|
|
||||||
|
118
lib/ui/screens/search_screen.dart
Normal file
118
lib/ui/screens/search_screen.dart
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
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/group.dart';
|
||||||
|
import 'package:comunic/models/search_result.dart';
|
||||||
|
import 'package:comunic/models/user.dart';
|
||||||
|
import 'package:comunic/ui/routes/home_route.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';
|
||||||
|
|
||||||
|
/// Search screen
|
||||||
|
///
|
||||||
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
|
class SearchScreen extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_SearchScreenState createState() => _SearchScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SearchScreenState extends State<SearchScreen> {
|
||||||
|
SearchResultsList _searchResultsList;
|
||||||
|
UsersList _usersList;
|
||||||
|
GroupsList _groupsList;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
TextField(
|
||||||
|
onChanged: (s) => _newSearch(s),
|
||||||
|
),
|
||||||
|
_searchResultsList == null
|
||||||
|
? Container()
|
||||||
|
: Expanded(
|
||||||
|
child: ListView(
|
||||||
|
children: _searchResultsList
|
||||||
|
.map((f) => f.kind == SearchResultKind.USER
|
||||||
|
? _SearchResultUser(
|
||||||
|
user: _usersList.getUser(f.id),
|
||||||
|
)
|
||||||
|
: _SearchResultGroup(
|
||||||
|
group: _groupsList[f.id],
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Perform a new search
|
||||||
|
void _newSearch(String s) async {
|
||||||
|
try {
|
||||||
|
if (s.length < 2) return;
|
||||||
|
|
||||||
|
final list = await SearchHelper().globalSearch(s);
|
||||||
|
final users = await UsersHelper().getListWithThrow(list.usersId);
|
||||||
|
final groups = await GroupsHelper().getListOrThrow(list.groupsId);
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_searchResultsList = list;
|
||||||
|
_usersList = users;
|
||||||
|
_groupsList = groups;
|
||||||
|
});
|
||||||
|
} catch (e, stack) {
|
||||||
|
print(e);
|
||||||
|
print(stack);
|
||||||
|
|
||||||
|
showSimpleSnack(context, tr("Could not peform search!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SearchResultUser extends StatelessWidget {
|
||||||
|
final User user;
|
||||||
|
|
||||||
|
const _SearchResultUser({Key key, this.user})
|
||||||
|
: assert(user != null),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListTile(
|
||||||
|
leading: AccountImageWidget(
|
||||||
|
user: user,
|
||||||
|
),
|
||||||
|
title: Text(user.displayName),
|
||||||
|
onTap: () => HomeController.of(context).openUserPage(user.id),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SearchResultGroup extends StatelessWidget {
|
||||||
|
final Group group;
|
||||||
|
|
||||||
|
const _SearchResultGroup({Key key, this.group})
|
||||||
|
: assert(group != null),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListTile(
|
||||||
|
leading: GroupIcon(group: group),
|
||||||
|
title: Text(group.displayName),
|
||||||
|
subtitle: Text(tr("Group")),
|
||||||
|
onTap: () => HomeController.of(context).openGroup(group.id),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@ enum BarCallbackActions {
|
|||||||
OPEN_NEWEST_POSTS,
|
OPEN_NEWEST_POSTS,
|
||||||
OPEN_FRIENDS,
|
OPEN_FRIENDS,
|
||||||
OPEN_MY_PAGE,
|
OPEN_MY_PAGE,
|
||||||
|
OPEN_SEARCH_PAGE,
|
||||||
OPEN_GROUPS,
|
OPEN_GROUPS,
|
||||||
OPEN_GROUP_PAGE,
|
OPEN_GROUP_PAGE,
|
||||||
OPEN_USER_PAGE,
|
OPEN_USER_PAGE,
|
||||||
@ -91,7 +92,11 @@ final _menuActionsItem = <_ActionMenuItem>[
|
|||||||
_ActionMenuItem(
|
_ActionMenuItem(
|
||||||
label: tr("My Page"), action: BarCallbackActions.OPEN_MY_PAGE),
|
label: tr("My Page"), action: BarCallbackActions.OPEN_MY_PAGE),
|
||||||
_ActionMenuItem(label: tr("Groups"), action: BarCallbackActions.OPEN_GROUPS),
|
_ActionMenuItem(label: tr("Groups"), action: BarCallbackActions.OPEN_GROUPS),
|
||||||
_ActionMenuItem(label: tr("Account settings"), action: BarCallbackActions.OPEN_ACCOUNT_SETTINGS),
|
_ActionMenuItem(
|
||||||
|
label: tr("Search"), action: BarCallbackActions.OPEN_SEARCH_PAGE),
|
||||||
|
_ActionMenuItem(
|
||||||
|
label: tr("Account settings"),
|
||||||
|
action: BarCallbackActions.OPEN_ACCOUNT_SETTINGS),
|
||||||
_ActionMenuItem(
|
_ActionMenuItem(
|
||||||
label: tr("App settings"), action: BarCallbackActions.OPEN_APP_SETTINGS),
|
label: tr("App settings"), action: BarCallbackActions.OPEN_APP_SETTINGS),
|
||||||
_ActionMenuItem(
|
_ActionMenuItem(
|
||||||
|
Loading…
Reference in New Issue
Block a user