1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-29 16:26:27 +00:00
comunicmobile/lib/ui/screens/friends_list_screen.dart

233 lines
7.2 KiB
Dart
Raw Normal View History

import 'dart:math';
2022-03-18 16:54:19 +00:00
import 'package:comunic/enums/report_target_type.dart';
import 'package:comunic/helpers/friends_helper.dart';
import 'package:comunic/helpers/users_helper.dart';
import 'package:comunic/lists/friends_list.dart';
import 'package:comunic/lists/users_list.dart';
2019-05-01 16:01:20 +00:00
import 'package:comunic/models/friend.dart';
2022-03-18 16:54:19 +00:00
import 'package:comunic/models/report_target.dart';
import 'package:comunic/ui/dialogs/report_dialog.dart';
import 'package:comunic/ui/tiles/accepted_friend_tile.dart';
import 'package:comunic/ui/tiles/pending_friend_tile.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
import 'package:comunic/utils/conversations_utils.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';
/// Friends list screen
///
/// Display the list of friends of the current user
///
/// @author Pierre HUBERT
enum _ErrorsLevel { NONE, MINOR, MAJOR }
class FriendsListScreen extends StatefulWidget {
2021-03-17 16:14:53 +00:00
final bool showAppBar;
const FriendsListScreen({Key? key, this.showAppBar = true}) : super(key: key);
2021-03-17 16:14:53 +00:00
@override
State<StatefulWidget> createState() => _FriendsListScreenState();
}
class _FriendsListScreenState extends SafeState<FriendsListScreen> {
/// Helpers
final _friendsHelper = FriendsHelper();
final _usersHelper = UsersHelper();
/// Widget members
_ErrorsLevel _error = _ErrorsLevel.NONE;
FriendsList? _friendsList;
late UsersList _usersInfo;
2022-03-12 08:42:07 +00:00
final _refreshIndicatorKey = GlobalKey<RefreshIndicatorState>();
/// Useful setters
set error(_ErrorsLevel err) => setState(() => _error = err);
void _gotError() {
error = _friendsList == null ? _ErrorsLevel.MAJOR : _ErrorsLevel.MINOR;
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
2019-05-04 17:35:03 +00:00
_getList();
}
/// Initialize list retrieving
Future<void> _getList() async {
await _loadList(false);
await _loadList(true);
}
2019-05-04 07:37:53 +00:00
/// Refresh the list of friends
Future<void> _refreshList() async {
2022-03-12 08:42:07 +00:00
if (_refreshIndicatorKey.currentState != null)
await _refreshIndicatorKey.currentState!.show();
else
await _getList();
2019-05-04 07:37:53 +00:00
}
/// Load the list of friends
2019-05-04 17:35:03 +00:00
Future<void> _loadList(bool online) async {
error = _ErrorsLevel.NONE;
// Get the list of friends
2019-05-04 17:35:03 +00:00
final list = await _friendsHelper.getList(online: online);
// Check if there is no cache yet
if (!online && list!.isEmpty) return;
// Check for errors
if (list == null) return _gotError();
// Get information about related users
final users = await _usersHelper.getUsersInfo(list.usersId);
// Check for errors
if (users == null) return _gotError();
// Apply new information
setState(() {
2019-05-04 17:35:03 +00:00
_friendsList = list..sort();
_usersInfo = users;
});
error = _ErrorsLevel.NONE;
}
/// Build and return loading error
2019-05-01 16:01:20 +00:00
Widget _buildError() => buildErrorCard(
tr("Could not load your list of friends!"),
actions: [
2021-03-13 14:28:34 +00:00
TextButton(
2019-05-04 07:37:53 +00:00
onPressed: _refreshList,
child: Text(
tr("Retry")!.toUpperCase(),
style: TextStyle(color: Colors.white),
),
),
],
);
@override
2020-05-16 15:36:52 +00:00
Widget build(BuildContext context) => Scaffold(
2021-03-17 16:14:53 +00:00
appBar: widget.showAppBar
? AppBar(
title: Text(tr("Your friends list")!),
2021-03-17 16:14:53 +00:00
)
: null,
2020-05-16 15:36:52 +00:00
body: _buildBody(),
);
Widget _buildBody() {
if (_error == _ErrorsLevel.MAJOR) return _buildError();
if (_friendsList == null) return buildCenteredProgressBar();
2019-05-04 07:37:53 +00:00
return Column(
children: <Widget>[
2019-05-04 07:37:53 +00:00
// Check for errors
Container(child: _error != _ErrorsLevel.NONE ? _buildError() : null),
// List of friends
Expanded(
child: RefreshIndicator(
key: _refreshIndicatorKey,
2019-05-04 17:35:03 +00:00
onRefresh: () => _loadList(true),
2019-05-04 07:37:53 +00:00
child: ListView.builder(
physics: AlwaysScrollableScrollPhysics(),
itemCount: max(_friendsList!.length, 1),
itemBuilder: (c, i) {
if (_friendsList!.isEmpty)
return Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Text(tr("You do not have any friend yet!")!)),
);
return _friendsList![i].accepted
? AcceptedFriendTile(
friend: _friendsList![i],
user: _usersInfo.getUser(_friendsList![i].id),
onOpenPrivateConversation: _openPrivateConversation,
onSetFollowing: _setFollowingFriend,
onRequestDelete: _deleteFriend,
2022-03-18 16:54:19 +00:00
onReportFriend: _reportFriend,
)
: PendingFriendTile(
friend: _friendsList![i],
user: _usersInfo.getUser(_friendsList![i].id),
onRespond: _respondRequest,
2022-03-18 16:54:19 +00:00
onReport: _reportFriend,
);
}),
2019-05-04 07:37:53 +00:00
),
),
],
);
}
2019-05-01 16:01:20 +00:00
/// Respond to friendship request
Future<void> _respondRequest(Friend f, bool accept) async {
if (!await _friendsHelper.respondRequest(f.id, accept))
showSimpleSnack(context, tr("Could not respond to friendship request!")!);
2019-05-01 16:01:20 +00:00
// Load the list of friends again
2019-05-04 07:37:53 +00:00
_refreshList();
2019-05-01 16:01:20 +00:00
}
2019-05-01 17:46:13 +00:00
/// Update following status of a friend
Future<void> _setFollowingFriend(Friend friend, bool follow) async {
if (!await _friendsHelper.setFollowing(friend.id, follow))
showSimpleSnack(context, tr("Could not update following status!")!);
2019-05-01 17:46:13 +00:00
2019-05-04 07:37:53 +00:00
_refreshList();
2019-05-01 17:46:13 +00:00
}
/// Handles deletion request of a friend
Future<void> _deleteFriend(Friend f) async {
final choice = await showDialog<bool>(
context: context,
builder: (b) => AlertDialog(
title: Text(tr("Delete friend")!),
2020-05-16 15:36:52 +00:00
content: Text(tr(
"Are you sure do you want to remove this friend from your list of friends ? A friendship request will have to be sent to get this user back to your list!")!),
2020-05-16 15:36:52 +00:00
actions: <Widget>[
2021-03-13 14:28:34 +00:00
TextButton(
2020-05-16 15:36:52 +00:00
onPressed: () => Navigator.pop(context, false),
child: Text(tr("Cancel")!.toUpperCase()),
),
2021-03-13 14:28:34 +00:00
TextButton(
2020-05-16 15:36:52 +00:00
onPressed: () => Navigator.pop(context, true),
child: Text(
tr("Confirm")!.toUpperCase(),
2020-05-16 15:36:52 +00:00
style: TextStyle(color: Colors.red),
),
),
],
),
);
if (choice == null || !choice) return;
// Forward the request to the server
if (!await _friendsHelper.removeFriend(f.id))
showSimpleSnack(
context, tr("Could not delete this person from your friends list!")!);
// Refresh list
2019-05-04 07:37:53 +00:00
_refreshList();
}
2022-03-18 16:54:19 +00:00
/// Report a friend
Future<void> _reportFriend(Friend friend) async => await showReportDialog(
ctx: context, target: ReportTarget(ReportTargetType.User, friend.id));
/// Open a private conversation for a given [friend]
Future<void> _openPrivateConversation(Friend friend) async {
await openPrivateConversation(context, friend.id);
}
}