Change search to only filter friends

This commit is contained in:
Nutcake 2023-05-03 18:43:06 +02:00
parent 9b26b92d9d
commit 3a4c7be758
4 changed files with 28 additions and 62 deletions

View file

@ -65,6 +65,17 @@ enum OnlineStatus {
orElse: () => OnlineStatus.unknown, orElse: () => OnlineStatus.unknown,
); );
} }
int compareTo(OnlineStatus other) {
if (this == other) return 0;
if (this == OnlineStatus.online) return -1;
if (other == OnlineStatus.online) return 1;
if (this == OnlineStatus.away) return -1;
if (other == OnlineStatus.away) return 1;
if (this == OnlineStatus.busy) return -1;
if (other == OnlineStatus.busy) return 1;
return 0;
}
} }
class UserStatus { class UserStatus {

View file

@ -142,7 +142,6 @@ class MessageCache {
Future<void> loadInitialMessages() async { Future<void> loadInitialMessages() async {
final messages = await MessageApi.getUserMessages(_apiClient, userId: _userId); final messages = await MessageApi.getUserMessages(_apiClient, userId: _userId);
_messages.clear();
_messages.addAll(messages); _messages.addAll(messages);
_ensureIntegrity(); _ensureIntegrity();
} }

View file

@ -34,7 +34,7 @@ class _ExpandingInputFabState extends State<ExpandingInputFab> {
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
color: Theme.of(context).colorScheme.secondaryContainer, color: Theme.of(context).colorScheme.secondaryContainer,
), ),
padding: const EdgeInsets.all(6), padding: const EdgeInsets.all(4),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -66,6 +66,7 @@ class _ExpandingInputFabState extends State<ExpandingInputFab> {
widget.onExpansionChanged?.call(_isExtended); widget.onExpansionChanged?.call(_isExtended);
}, },
splashRadius: 16, splashRadius: 16,
iconSize: 28,
icon: _isExtended ? const Icon(Icons.close) : const Icon(Icons.search), icon: _isExtended ? const Icon(Icons.close) : const Icon(Icons.search),
), ),
) )

View file

@ -2,13 +2,10 @@ import 'dart:async';
import 'package:contacts_plus_plus/api_client.dart'; import 'package:contacts_plus_plus/api_client.dart';
import 'package:contacts_plus_plus/apis/friend_api.dart'; import 'package:contacts_plus_plus/apis/friend_api.dart';
import 'package:contacts_plus_plus/apis/user_api.dart';
import 'package:contacts_plus_plus/models/friend.dart'; import 'package:contacts_plus_plus/models/friend.dart';
import 'package:contacts_plus_plus/models/user.dart';
import 'package:contacts_plus_plus/widgets/expanding_input_fab.dart'; import 'package:contacts_plus_plus/widgets/expanding_input_fab.dart';
import 'package:contacts_plus_plus/widgets/friend_list_tile.dart'; import 'package:contacts_plus_plus/widgets/friend_list_tile.dart';
import 'package:contacts_plus_plus/widgets/settings_page.dart'; import 'package:contacts_plus_plus/widgets/settings_page.dart';
import 'package:contacts_plus_plus/widgets/user_list_tile.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class FriendsList extends StatefulWidget { class FriendsList extends StatefulWidget {
@ -19,11 +16,10 @@ class FriendsList extends StatefulWidget {
} }
class _FriendsListState extends State<FriendsList> { class _FriendsListState extends State<FriendsList> {
Future<List>? _listFuture; Future<List<Friend>>? _friendsFuture;
Future<List>? _friendFuture;
ClientHolder? _clientHolder; ClientHolder? _clientHolder;
Timer? _debouncer; Timer? _debouncer;
bool _searchIsLoading = false; String _searchFilter = "";
@override @override
void dispose() { void dispose() {
@ -42,36 +38,17 @@ class _FriendsListState extends State<FriendsList> {
} }
void _refreshFriendsList() { void _refreshFriendsList() {
_searchIsLoading = true; _friendsFuture = FriendApi.getFriendsList(_clientHolder!.client).then((Iterable<Friend> value) =>
_listFuture = FriendApi.getFriendsList(_clientHolder!.client).then((Iterable<Friend> value) =>
value.toList() value.toList()
..sort((a, b) { ..sort((a, b) {
if (a.userStatus.onlineStatus == b.userStatus.onlineStatus) { if (a.userStatus.onlineStatus == b.userStatus.onlineStatus) {
return a.userStatus.lastStatusChange.compareTo(b.userStatus.lastStatusChange); return a.userStatus.lastStatusChange.compareTo(b.userStatus.lastStatusChange);
} else { } else {
if (a.userStatus.onlineStatus == OnlineStatus.online) { return a.userStatus.onlineStatus.compareTo(b.userStatus.onlineStatus);
return -1;
} else {
return 1;
}
} }
}, },
), ),
).whenComplete(() => setState((){ _searchIsLoading = false; })); );
_friendFuture = _listFuture;
}
void _searchForUsers(String needle) {
_listFuture = UserApi.searchUsers(_clientHolder!.client, needle: needle).then((value) =>
value.toList()
..sort((a, b) {
return a.username.length.compareTo(b.username.length);
},)
).whenComplete(() => setState((){ _searchIsLoading = false; }));
}
void _restoreFriendsList() {
_listFuture = _friendFuture;
} }
@override @override
@ -93,24 +70,20 @@ class _FriendsListState extends State<FriendsList> {
RefreshIndicator( RefreshIndicator(
onRefresh: () async { onRefresh: () async {
_refreshFriendsList(); _refreshFriendsList();
await _listFuture; await _friendsFuture;
}, },
child: FutureBuilder( child: FutureBuilder(
future: _listFuture, future: _friendsFuture,
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasData) { if (snapshot.hasData) {
final data = snapshot.data as Iterable; var data = (snapshot.data as List<Friend>);
if (_searchFilter.isNotEmpty) {
data = data.where((element) => element.username.contains(_searchFilter)).toList();
data.sort((a, b) => a.username.length.compareTo(b.username.length));
}
return ListView.builder( return ListView.builder(
itemCount: data.length, itemCount: data.length,
itemBuilder: (context, index) { itemBuilder: (context, index) => FriendListTile(friend: data[index]),
final entry = data.elementAt(index);
if (entry is Friend) {
return FriendListTile(friend: entry);
} else if (entry is User) {
return UserListTile(user: entry);
}
return null;
},
); );
} else if (snapshot.hasError) { } else if (snapshot.hasError) {
FlutterError.reportError(FlutterErrorDetails(exception: snapshot.error!, stack: snapshot.stackTrace)); FlutterError.reportError(FlutterErrorDetails(exception: snapshot.error!, stack: snapshot.stackTrace));
@ -137,38 +110,20 @@ class _FriendsListState extends State<FriendsList> {
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
child: ExpandingInputFab( child: ExpandingInputFab(
onInputChanged: (String text) { onInputChanged: (String text) {
if (_debouncer?.isActive ?? false) _debouncer?.cancel();
if (text.isEmpty) {
setState(() { setState(() {
_searchIsLoading = false; _searchFilter = text;
_restoreFriendsList();
});
return;
}
setState(() {
_searchIsLoading = true;
});
_debouncer = Timer(const Duration(milliseconds: 500), () {
setState(() {
if(text.isNotEmpty) {
_searchForUsers(text);
} else {
_searchIsLoading = false;
}
});
}); });
}, },
onExpansionChanged: (expanded) { onExpansionChanged: (expanded) {
if (_debouncer?.isActive ?? false) _debouncer?.cancel(); if (_debouncer?.isActive ?? false) _debouncer?.cancel();
if (!expanded) { if (!expanded) {
setState(() { setState(() {
_restoreFriendsList(); _searchFilter = "";
}); });
} }
}, },
), ),
), ),
if (_searchIsLoading) const Align(alignment: Alignment.topCenter, child: LinearProgressIndicator(),)
], ],
), ),
); );