OpenContacts/lib/widgets/home_screen.dart

168 lines
5.4 KiB
Dart
Raw Normal View History

2023-04-30 09:43:59 -04:00
import 'dart:async';
2023-04-29 15:26:12 -04:00
import 'package:contacts_plus/apis/friend_api.dart';
2023-04-30 09:43:59 -04:00
import 'package:contacts_plus/apis/user_api.dart';
2023-04-29 15:26:12 -04:00
import 'package:contacts_plus/main.dart';
import 'package:contacts_plus/models/friend.dart';
2023-04-30 09:43:59 -04:00
import 'package:contacts_plus/models/user.dart';
import 'package:contacts_plus/widgets/expanding_input_fab.dart';
import 'package:contacts_plus/widgets/friend_list_tile.dart';
import 'package:contacts_plus/widgets/user_list_tile.dart';
2023-04-29 13:18:46 -04:00
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
2023-04-30 09:43:59 -04:00
Future<List>? _listFuture;
Future<List>? _friendFuture;
2023-04-30 07:39:09 -04:00
ClientHolder? _clientHolder;
2023-04-30 09:43:59 -04:00
Timer? _debouncer;
2023-04-30 17:14:29 -04:00
bool _searchIsLoading = false;
2023-04-30 09:43:59 -04:00
@override
void dispose() {
_debouncer?.cancel();
super.dispose();
}
2023-04-29 15:26:12 -04:00
@override
2023-04-30 07:39:09 -04:00
void didChangeDependencies() {
super.didChangeDependencies();
final clientHolder = ClientHolder.of(context);
if (_clientHolder != clientHolder) {
_clientHolder = clientHolder;
_refreshFriendsList();
}
2023-04-29 15:26:12 -04:00
}
void _refreshFriendsList() {
2023-04-30 17:14:29 -04:00
_searchIsLoading = true;
2023-04-30 09:43:59 -04:00
_listFuture = FriendApi.getFriendsList(_clientHolder!.client).then((Iterable<Friend> value) =>
2023-04-29 15:26:12 -04:00
value.toList()
..sort((a, b) {
if (a.userStatus.onlineStatus == b.userStatus.onlineStatus) {
return a.userStatus.lastStatusChange.compareTo(b.userStatus.lastStatusChange);
} else {
if (a.userStatus.onlineStatus == OnlineStatus.online) {
return -1;
} else {
return 1;
}
}
},
),
2023-04-30 17:14:29 -04:00
).whenComplete(() => setState((){ _searchIsLoading = false; }));
2023-04-30 09:43:59 -04:00
_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);
},)
2023-04-30 17:14:29 -04:00
).whenComplete(() => setState((){ _searchIsLoading = false; }));
2023-04-30 09:43:59 -04:00
}
void _restoreFriendsList() {
_listFuture = _friendFuture;
2023-04-29 15:26:12 -04:00
}
2023-04-29 13:18:46 -04:00
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
2023-04-30 09:43:59 -04:00
title: const Text("Contacts++"),
2023-04-29 13:18:46 -04:00
),
2023-04-30 09:43:59 -04:00
body: Stack(
children: [
RefreshIndicator(
onRefresh: () async {
_refreshFriendsList();
await _listFuture;
},
child: FutureBuilder(
future: _listFuture,
builder: (context, snapshot) {
if (snapshot.hasData) {
final data = snapshot.data as Iterable;
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, 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) {
2023-04-30 17:14:29 -04:00
FlutterError.reportError(FlutterErrorDetails(exception: snapshot.error!, stack: snapshot.stackTrace));
2023-04-30 09:43:59 -04:00
return Center(
child: Padding(
padding: const EdgeInsets.all(64),
child: Text(
"Something went wrong: ${snapshot.error}",
softWrap: true,
style: Theme
.of(context)
.textTheme
.labelMedium,
2023-04-30 07:39:09 -04:00
),
),
2023-04-29 15:26:12 -04:00
);
2023-04-30 09:43:59 -04:00
} else {
2023-04-30 17:14:29 -04:00
return const SizedBox.shrink();
2023-04-30 09:43:59 -04:00
}
}
),
),
Align(
alignment: Alignment.bottomCenter,
child: ExpandingInputFab(
onInputChanged: (String text) {
if (_debouncer?.isActive ?? false) _debouncer?.cancel();
if (text.isEmpty) {
setState(() {
2023-04-30 17:14:29 -04:00
_searchIsLoading = false;
2023-04-30 09:43:59 -04:00
_restoreFriendsList();
});
2023-04-30 17:14:29 -04:00
return;
2023-04-30 09:43:59 -04:00
}
2023-04-30 17:14:29 -04:00
setState(() {
_searchIsLoading = true;
});
2023-04-30 09:43:59 -04:00
_debouncer = Timer(const Duration(milliseconds: 500), () {
2023-04-30 17:14:29 -04:00
setState(() {
if(text.isNotEmpty) {
_searchForUsers(text);
} else {
_searchIsLoading = false;
}
});
2023-04-30 09:43:59 -04:00
});
},
onExpansionChanged: (expanded) {
if (_debouncer?.isActive ?? false) _debouncer?.cancel();
if (!expanded) {
setState(() {
_restoreFriendsList();
});
}
},
),
),
2023-04-30 17:14:29 -04:00
if (_searchIsLoading) const Align(alignment: Alignment.topCenter, child: LinearProgressIndicator(),)
2023-04-30 09:43:59 -04:00
],
2023-04-29 13:18:46 -04:00
),
);
}
2023-04-30 09:43:59 -04:00
}