mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-11-04 12:14:11 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			199 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			199 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			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';
 | 
						|
import 'package:comunic/models/friend.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 {
 | 
						|
  @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;
 | 
						|
  UsersList _usersInfo;
 | 
						|
  GlobalKey<RefreshIndicatorState> _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();
 | 
						|
    _getList();
 | 
						|
  }
 | 
						|
 | 
						|
  /// Initialize list retrieving
 | 
						|
  Future<void> _getList() async {
 | 
						|
    await _loadList(false);
 | 
						|
    await _loadList(true);
 | 
						|
  }
 | 
						|
 | 
						|
  /// Refresh the list of friends
 | 
						|
  Future<void> _refreshList() async {
 | 
						|
    await _refreshIndicatorKey.currentState.show();
 | 
						|
  }
 | 
						|
 | 
						|
  /// Load the list of friends
 | 
						|
  Future<void> _loadList(bool online) async {
 | 
						|
    error = _ErrorsLevel.NONE;
 | 
						|
 | 
						|
    // Get the list of friends
 | 
						|
    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(() {
 | 
						|
      _friendsList = list..sort();
 | 
						|
      _usersInfo = users;
 | 
						|
    });
 | 
						|
    error = _ErrorsLevel.NONE;
 | 
						|
  }
 | 
						|
 | 
						|
  /// Build and return loading error
 | 
						|
  Widget _buildError() => buildErrorCard(
 | 
						|
        tr("Could not load your list of friends!"),
 | 
						|
        actions: [
 | 
						|
          FlatButton(
 | 
						|
            onPressed: _refreshList,
 | 
						|
            child: Text(
 | 
						|
              tr("Retry").toUpperCase(),
 | 
						|
              style: TextStyle(color: Colors.white),
 | 
						|
            ),
 | 
						|
          ),
 | 
						|
        ],
 | 
						|
      );
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    if (_error == _ErrorsLevel.MAJOR) return _buildError();
 | 
						|
    if (_friendsList == null) return buildCenteredProgressBar();
 | 
						|
 | 
						|
    return Column(
 | 
						|
      children: <Widget>[
 | 
						|
        // Check for errors
 | 
						|
        Container(child: _error != _ErrorsLevel.NONE ? _buildError() : null),
 | 
						|
 | 
						|
        // List of friends
 | 
						|
        Expanded(
 | 
						|
          child: RefreshIndicator(
 | 
						|
            key: _refreshIndicatorKey,
 | 
						|
            onRefresh: () => _loadList(true),
 | 
						|
            child: ListView.builder(
 | 
						|
                physics: AlwaysScrollableScrollPhysics(),
 | 
						|
                itemCount: _friendsList.length,
 | 
						|
                itemBuilder: (c, i) => _friendsList[i].accepted
 | 
						|
                    ? AcceptedFriendTile(
 | 
						|
                        friend: _friendsList[i],
 | 
						|
                        user: _usersInfo.getUser(_friendsList[i].id),
 | 
						|
                        onOpenPrivateConversation: _openPrivateConversation,
 | 
						|
                        onSetFollowing: _setFollowingFriend,
 | 
						|
                        onRequestDelete: _deleteFriend,
 | 
						|
                      )
 | 
						|
                    : PendingFriendTile(
 | 
						|
                        friend: _friendsList[i],
 | 
						|
                        user: _usersInfo.getUser(_friendsList[i].id),
 | 
						|
                        onRespond: _respondRequest,
 | 
						|
                      )),
 | 
						|
          ),
 | 
						|
        ),
 | 
						|
      ],
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  /// 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!"));
 | 
						|
 | 
						|
    // Load the list of friends again
 | 
						|
    _refreshList();
 | 
						|
  }
 | 
						|
 | 
						|
  /// 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!"));
 | 
						|
 | 
						|
    _refreshList();
 | 
						|
  }
 | 
						|
 | 
						|
  /// 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")),
 | 
						|
            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!")),
 | 
						|
            actions: <Widget>[
 | 
						|
              FlatButton(
 | 
						|
                onPressed: () => Navigator.pop(context, false),
 | 
						|
                child: Text(tr("Cancel").toUpperCase()),
 | 
						|
              ),
 | 
						|
              FlatButton(
 | 
						|
                onPressed: () => Navigator.pop(context, true),
 | 
						|
                child: Text(
 | 
						|
                  tr("Confirm").toUpperCase(),
 | 
						|
                  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
 | 
						|
    _refreshList();
 | 
						|
  }
 | 
						|
 | 
						|
  /// Open a private conversation for a given [friend]
 | 
						|
  Future<void> _openPrivateConversation(Friend friend) async {
 | 
						|
    await openPrivateConversation(context, friend.id);
 | 
						|
  }
 | 
						|
}
 |