diff --git a/lib/enums/user_page_visibility.dart b/lib/enums/user_page_visibility.dart new file mode 100644 index 0000000..832951c --- /dev/null +++ b/lib/enums/user_page_visibility.dart @@ -0,0 +1,5 @@ +/// User page visibility +/// +/// @author Pierre HUBERT + +enum UserPageVisibility { PRIVATE, PUBLIC, OPEN } diff --git a/lib/helpers/conversations_helper.dart b/lib/helpers/conversations_helper.dart index 15b4916..1d798a8 100644 --- a/lib/helpers/conversations_helper.dart +++ b/lib/helpers/conversations_helper.dart @@ -1,3 +1,5 @@ +import 'package:comunic/lists/conversations_list.dart'; +import 'package:comunic/lists/users_list.dart'; import 'package:comunic/models/api_request.dart'; import 'package:comunic/models/conversation.dart'; @@ -7,16 +9,15 @@ import 'package:comunic/models/conversation.dart'; class ConversationsHelper { /// Download the list of conversations from the server - Future> downloadList() async { + Future downloadList() async { final response = await APIRequest(uri: "conversations/getList", needLogin: true).exec(); if (response.code != 200) return null; try { - List list = List(); - response.getArray().forEach((f) => - list.add(Conversation( + ConversationsList list = ConversationsList(); + response.getArray().forEach((f) => list.add(Conversation( id: f["ID"], ownerID: f["ID_owner"], lastActive: f["last_active"], @@ -27,10 +28,23 @@ class ConversationsHelper { ))); return list; - - } on Exception catch(e){ + } on Exception catch (e) { print(e.toString()); return null; } } + + /// Get the name of a [conversation]. This requires information about the + /// users of this conversation + static String getConversationName(Conversation conversation, UsersList users) { + if (conversation.has_name) return conversation.name; + + // TODO : exclude current user name + String name = ""; + for (int i = 0; i < 3 && i < conversation.members.length; i++) + name += + (i > 0 ? ", " : "") + users.getUser(conversation.members[i]).fullName; + + return name; + } } diff --git a/lib/helpers/users_helper.dart b/lib/helpers/users_helper.dart new file mode 100644 index 0000000..e4ebf3c --- /dev/null +++ b/lib/helpers/users_helper.dart @@ -0,0 +1,47 @@ +import 'package:comunic/enums/user_page_visibility.dart'; +import 'package:comunic/lists/users_list.dart'; +import 'package:comunic/models/api_request.dart'; +import 'package:comunic/models/user.dart'; + +/// User helper +/// +/// Helper used to get information about the users of Comunic +/// +/// @author Pierre HUBERT + +class UsersHelper { + /// Download information about some given users ID + /// + /// Return the list of users information in case of success, null in case of + /// failure + Future downloadInfo(List users) async { + // Execute the request + final response = await APIRequest( + uri: "user/getInfoMultiple", args: {"usersID": users.join(",")}).exec(); + + // Check if the request did not execute correctly + if (response.code != 200) return null; + + final list = UsersList(); + response.getObject().forEach( + (k, v) => list.add( + User( + id: v["userID"], + firstName: v["firstName"], + lastName: v["lastName"], + pageVisibility: v["publicPage"] == "false" + ? UserPageVisibility.PRIVATE + : (v["openPage"] == "false" + ? UserPageVisibility.PRIVATE + : UserPageVisibility.OPEN), + virtualDirectory: v["virtualDirectory"] == "" + ? null + : v["virtualDirectory"], + accountImageURL: v["accountImage"], + ), + ), + ); + + return list; + } +} diff --git a/lib/lists/conversations_list.dart b/lib/lists/conversations_list.dart new file mode 100644 index 0000000..0b47bce --- /dev/null +++ b/lib/lists/conversations_list.dart @@ -0,0 +1,33 @@ +import 'dart:collection'; + +import 'package:comunic/lists/users_list.dart'; +import 'package:comunic/models/conversation.dart'; + +/// Conversations list +/// +/// @author Pierre HUBERT + +class ConversationsList extends ListBase { + + final List _list = List(); + UsersList users; + + set length(l) => _list.length = l; + int get length => _list.length; + + @override + Conversation operator [](int index) => _list[index]; + + @override + void operator []=(int index, Conversation value) => _list[index] = value; + + /// Get the entire lists of users ID in this list + List get allUsersID { + final List list = List(); + forEach((c) => c.members.forEach((id){ + if(!list.contains(id)) + list.add(id); + })); + return list; + } +} diff --git a/lib/lists/users_list.dart b/lib/lists/users_list.dart new file mode 100644 index 0000000..12dd5e4 --- /dev/null +++ b/lib/lists/users_list.dart @@ -0,0 +1,34 @@ +import 'dart:collection'; + +import 'package:comunic/models/user.dart'; + +/// Users list +/// +/// @author Pierre HUBERT + +class UsersList extends ListBase { + + List _list = List(); + + int get length => _list.length; + set length(l) => _list.length = l; + + @override + User operator [](int index) { + return _list[index]; + } + + @override + void operator []=(int index, User value) { + _list[index] = value; + } + + /// Find a user with a specific ID + User getUser(int userID){ + for(int i = 0; i < this.length; i++) + if(this[i].id == userID) + return this[i]; + + throw "User not found in the list!"; + } +} \ No newline at end of file diff --git a/lib/models/conversation.dart b/lib/models/conversation.dart index 245393f..992191c 100644 --- a/lib/models/conversation.dart +++ b/lib/models/conversation.dart @@ -27,4 +27,7 @@ class Conversation { assert(following != null), assert(sawLastMessage != null), assert(members != null); + + /// Check out whether a conversation has a fixed name or not + bool get has_name => this.name != null; } diff --git a/lib/models/user.dart b/lib/models/user.dart new file mode 100644 index 0000000..a397d49 --- /dev/null +++ b/lib/models/user.dart @@ -0,0 +1,31 @@ +import 'package:comunic/enums/user_page_visibility.dart'; +import 'package:meta/meta.dart'; + +/// Single user information +/// +/// @author Pierre HUBERT + +class User { + final int id; + final String firstName; + final String lastName; + final UserPageVisibility pageVisibility; + final String virtualDirectory; + final String accountImageURL; + + const User({ + @required this.id, + @required this.firstName, + @required this.lastName, + @required this.pageVisibility, + @required this.virtualDirectory, + @required this.accountImageURL, + }) : assert(id != null), + assert(firstName != null), + assert(lastName != null), + assert(pageVisibility != null), + assert(accountImageURL != null); + + /// Get user full name + String get fullName => firstName + " " + lastName; +} diff --git a/lib/ui/screens/conversations_screen.dart b/lib/ui/screens/conversations_screen.dart index 056fe59..8e8d1e9 100644 --- a/lib/ui/screens/conversations_screen.dart +++ b/lib/ui/screens/conversations_screen.dart @@ -1,6 +1,7 @@ import 'package:comunic/enums/load_error_level.dart'; import 'package:comunic/helpers/conversations_helper.dart'; -import 'package:comunic/models/conversation.dart'; +import 'package:comunic/helpers/users_helper.dart'; +import 'package:comunic/lists/conversations_list.dart'; import 'package:comunic/ui/tiles/conversation_tile.dart'; import 'package:comunic/utils/intl_utils.dart'; import 'package:comunic/utils/ui_utils.dart'; @@ -17,7 +18,8 @@ class ConversationsScreen extends StatefulWidget { class _ConversationScreenState extends State { final ConversationsHelper _conversationsHelper = ConversationsHelper(); - List _list; + final UsersHelper _usersHelper = UsersHelper(); + ConversationsList _list; LoadErrorLevel _error = LoadErrorLevel.NONE; bool _loading = true; @@ -31,7 +33,7 @@ class _ConversationScreenState extends State { void setLoading(bool loading) => setState(() => _loading = loading); - void gotLoadingError() { + void _gotLoadingError() { setLoading(false); setError(_list == null ? LoadErrorLevel.MAJOR : LoadErrorLevel.MINOR); } @@ -41,12 +43,18 @@ class _ConversationScreenState extends State { setError(LoadErrorLevel.NONE); setLoading(true); + //Process the list of conversations final list = await _conversationsHelper.downloadList(); + if (list == null) return _gotLoadingError(); - if (list == null) return gotLoadingError(); + //Get information about the members of the conversations + list.users = await _usersHelper.downloadInfo(list.allUsersID); + if(list.users == null) return _gotLoadingError(); //Save list - _list = list; + setState(() { + _list = list; + }); setLoading(false); } @@ -79,6 +87,7 @@ class _ConversationScreenState extends State { itemBuilder: (context, index) { return ConversationTile( conversation: _list.elementAt(index), + usersList: _list.users, ); }, itemCount: _list.length, diff --git a/lib/ui/tiles/conversation_tile.dart b/lib/ui/tiles/conversation_tile.dart index 2098ec2..40c09d3 100644 --- a/lib/ui/tiles/conversation_tile.dart +++ b/lib/ui/tiles/conversation_tile.dart @@ -1,3 +1,5 @@ +import 'package:comunic/helpers/conversations_helper.dart'; +import 'package:comunic/lists/users_list.dart'; import 'package:comunic/models/conversation.dart'; import 'package:comunic/utils/date_utils.dart'; import 'package:comunic/utils/intl_utils.dart'; @@ -9,8 +11,13 @@ import 'package:flutter/material.dart'; class ConversationTile extends StatelessWidget { final Conversation conversation; + final UsersList usersList; - const ConversationTile({Key key, this.conversation}) : super(key: key); + const ConversationTile( + {Key key, @required this.conversation, @required this.usersList}) + : assert(conversation != null), + assert(usersList != null), + super(key: key); _buildSubInformation(IconData icon, String content) { return Row( @@ -28,7 +35,10 @@ class ConversationTile extends StatelessWidget { @override Widget build(BuildContext context) { return ListTile( - title: Text(conversation.name == null ? "Unknown" : conversation.name), + title: Text(ConversationsHelper.getConversationName( + conversation, + usersList, + )), leading: Icon( conversation.sawLastMessage ? Icons.check_circle : Icons.lens, color: conversation.sawLastMessage ? null : Colors.blue,