mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-11-25 22:39:22 +00:00
Get conversation message
This commit is contained in:
parent
1ec197202c
commit
e2202a4794
@ -1,9 +1,11 @@
|
|||||||
import 'package:comunic/helpers/database/conversations_database_helper.dart';
|
import 'package:comunic/helpers/database/conversations_database_helper.dart';
|
||||||
import 'package:comunic/helpers/users_helper.dart';
|
import 'package:comunic/helpers/users_helper.dart';
|
||||||
|
import 'package:comunic/lists/conversation_messages_list.dart';
|
||||||
import 'package:comunic/lists/conversations_list.dart';
|
import 'package:comunic/lists/conversations_list.dart';
|
||||||
import 'package:comunic/lists/users_list.dart';
|
import 'package:comunic/lists/users_list.dart';
|
||||||
import 'package:comunic/models/api_request.dart';
|
import 'package:comunic/models/api_request.dart';
|
||||||
import 'package:comunic/models/conversation.dart';
|
import 'package:comunic/models/conversation.dart';
|
||||||
|
import 'package:comunic/models/conversation_message.dart';
|
||||||
import 'package:comunic/utils/account_utils.dart';
|
import 'package:comunic/utils/account_utils.dart';
|
||||||
|
|
||||||
/// Conversation helper
|
/// Conversation helper
|
||||||
@ -67,7 +69,7 @@ class ConversationsHelper {
|
|||||||
/// cached version of the conversation will be used, else it will always get
|
/// cached version of the conversation will be used, else it will always get
|
||||||
/// the information from the server
|
/// the information from the server
|
||||||
Future<Conversation> getSingle(int id, {bool force = false}) async {
|
Future<Conversation> getSingle(int id, {bool force = false}) async {
|
||||||
if(force || ! await _conversationsDatabaseHelper.has(id))
|
if (force || !await _conversationsDatabaseHelper.has(id))
|
||||||
return await _downloadSingle(id);
|
return await _downloadSingle(id);
|
||||||
else
|
else
|
||||||
return _conversationsDatabaseHelper.get(id);
|
return _conversationsDatabaseHelper.get(id);
|
||||||
@ -112,7 +114,7 @@ class ConversationsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Turn an API entry into a [Conversation] object
|
/// Turn an API entry into a [Conversation] object
|
||||||
Conversation _apiToConversation(Map<String, dynamic> map){
|
Conversation _apiToConversation(Map<String, dynamic> map) {
|
||||||
return Conversation(
|
return Conversation(
|
||||||
id: map["ID"],
|
id: map["ID"],
|
||||||
ownerID: map["ID_owner"],
|
ownerID: map["ID_owner"],
|
||||||
@ -123,4 +125,35 @@ class ConversationsHelper {
|
|||||||
members: map["members"].map<int>((f) => int.parse(f)).toList(),
|
members: map["members"].map<int>((f) => int.parse(f)).toList(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Refresh the list of messages of a conversation
|
||||||
|
///
|
||||||
|
/// Set [lastMessageID] to 0 to specify that we do not have any message of the
|
||||||
|
/// conversation yet or another value else
|
||||||
|
Future<ConversationMessagesList> downloadNewMessagesSingle(int conversationID,
|
||||||
|
{int lastMessageID = 0}) async {
|
||||||
|
// Execute the request on the server
|
||||||
|
final response = await APIRequest(
|
||||||
|
uri: "conversations/refresh_single",
|
||||||
|
needLogin: true,
|
||||||
|
args: {
|
||||||
|
"conversationID": conversationID.toString(),
|
||||||
|
"last_message_id": lastMessageID.toString()
|
||||||
|
}).exec();
|
||||||
|
|
||||||
|
if (response.code != 200) return null;
|
||||||
|
|
||||||
|
// Parse the response of the server
|
||||||
|
ConversationMessagesList list = ConversationMessagesList();
|
||||||
|
response.getArray().forEach((f) {
|
||||||
|
list.add(ConversationMessage(
|
||||||
|
id: f["ID"],
|
||||||
|
userID: f["ID_user"],
|
||||||
|
timeInsert: f["time_insert"],
|
||||||
|
message: f["message"],
|
||||||
|
imageURL: f["image_path"]));
|
||||||
|
});
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
35
lib/lists/conversation_messages_list.dart
Normal file
35
lib/lists/conversation_messages_list.dart
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import 'dart:collection';
|
||||||
|
|
||||||
|
import 'package:comunic/models/conversation_message.dart';
|
||||||
|
|
||||||
|
/// Conversations messages list
|
||||||
|
///
|
||||||
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
|
class ConversationMessagesList extends ListBase<ConversationMessage> {
|
||||||
|
final List<ConversationMessage> _list = List();
|
||||||
|
|
||||||
|
set length(int v) => _list.length = v;
|
||||||
|
|
||||||
|
int get length => _list.length;
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConversationMessage operator [](int index) {
|
||||||
|
return _list[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void operator []=(int index, ConversationMessage value) {
|
||||||
|
_list[index] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the list of the users ID who own a message in this list
|
||||||
|
List<int> getUsersID() {
|
||||||
|
final List<int> users = List();
|
||||||
|
|
||||||
|
for (ConversationMessage message in this)
|
||||||
|
if (!users.contains(message.userID)) users.add(message.userID);
|
||||||
|
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
}
|
@ -7,10 +7,10 @@ import 'package:comunic/models/user.dart';
|
|||||||
/// @author Pierre HUBERT
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
class UsersList extends ListBase<User> {
|
class UsersList extends ListBase<User> {
|
||||||
|
|
||||||
List<User> _list = List();
|
List<User> _list = List();
|
||||||
|
|
||||||
int get length => _list.length;
|
int get length => _list.length;
|
||||||
|
|
||||||
set length(l) => _list.length = l;
|
set length(l) => _list.length = l;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -24,11 +24,13 @@ class UsersList extends ListBase<User> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Find a user with a specific ID
|
/// Find a user with a specific ID
|
||||||
User getUser(int userID){
|
User getUser(int userID) {
|
||||||
for(int i = 0; i < this.length; i++)
|
for (int i = 0; i < this.length; i++)
|
||||||
if(this[i].id == userID)
|
if (this[i].id == userID) return this[i];
|
||||||
return this[i];
|
|
||||||
|
|
||||||
throw "User not found in the list!";
|
throw "User not found in the list!";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the list of users ID present in this list
|
||||||
|
List<int> get usersID => List.generate(length, (i) => this[i].id);
|
||||||
}
|
}
|
29
lib/models/conversation_message.dart
Normal file
29
lib/models/conversation_message.dart
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
|
/// Single conversation message
|
||||||
|
///
|
||||||
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
|
class ConversationMessage implements Comparable {
|
||||||
|
final int id;
|
||||||
|
final int userID;
|
||||||
|
final int timeInsert;
|
||||||
|
final String message;
|
||||||
|
final String imageURL;
|
||||||
|
|
||||||
|
const ConversationMessage({
|
||||||
|
@required this.id,
|
||||||
|
@required this.userID,
|
||||||
|
@required this.timeInsert,
|
||||||
|
@required this.message,
|
||||||
|
@required this.imageURL,
|
||||||
|
}) : assert(id != null),
|
||||||
|
assert(userID != null),
|
||||||
|
assert(timeInsert != null),
|
||||||
|
assert(message != null);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int compareTo(other) {
|
||||||
|
return id.compareTo(other.id);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:comunic/helpers/conversations_helper.dart';
|
import 'package:comunic/helpers/conversations_helper.dart';
|
||||||
import 'package:comunic/models/conversation.dart';
|
import 'package:comunic/models/conversation.dart';
|
||||||
|
import 'package:comunic/ui/screens/conversation_screen.dart';
|
||||||
import 'package:comunic/utils/intl_utils.dart';
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
import 'package:comunic/utils/ui_utils.dart';
|
import 'package:comunic/utils/ui_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -38,16 +39,14 @@ class _ConversationRouteState extends State<ConversationRoute> {
|
|||||||
Future<void> _loadConversation() async {
|
Future<void> _loadConversation() async {
|
||||||
setError(false);
|
setError(false);
|
||||||
|
|
||||||
_conversation =
|
_conversation = await _conversationsHelper.getSingle(widget.conversationID);
|
||||||
await _conversationsHelper.getSingle(widget.conversationID);
|
|
||||||
|
|
||||||
if (_conversation == null) return setError(true);
|
if (_conversation == null) return setError(true);
|
||||||
|
|
||||||
final conversationName =
|
final conversationName =
|
||||||
await ConversationsHelper.getConversationNameAsync(_conversation);
|
await ConversationsHelper.getConversationNameAsync(_conversation);
|
||||||
|
|
||||||
if(conversationName == null)
|
if (conversationName == null) return setError(true);
|
||||||
return setError(true);
|
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_conversationName = conversationName;
|
_conversationName = conversationName;
|
||||||
@ -72,8 +71,12 @@ class _ConversationRouteState extends State<ConversationRoute> {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
//if (_conversationName == null || _conversation == null)
|
if (_conversationName == null || _conversation == null)
|
||||||
return buildCenteredProgressBar();
|
return buildCenteredProgressBar();
|
||||||
|
|
||||||
|
return ConversationScreen(
|
||||||
|
conversationID: widget.conversationID,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
94
lib/ui/screens/conversation_screen.dart
Normal file
94
lib/ui/screens/conversation_screen.dart
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import 'package:comunic/helpers/conversations_helper.dart';
|
||||||
|
import 'package:comunic/helpers/users_helper.dart';
|
||||||
|
import 'package:comunic/lists/conversation_messages_list.dart';
|
||||||
|
import 'package:comunic/lists/users_list.dart';
|
||||||
|
import 'package:comunic/ui/tiles/conversation_message_tile.dart';
|
||||||
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
|
import 'package:comunic/utils/list_utils.dart';
|
||||||
|
import 'package:comunic/utils/ui_utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// Conversation screen
|
||||||
|
///
|
||||||
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
|
enum ErrorLevel { NONE, MINOR, MAJOR }
|
||||||
|
|
||||||
|
class ConversationScreen extends StatefulWidget {
|
||||||
|
final int conversationID;
|
||||||
|
|
||||||
|
const ConversationScreen({Key key, this.conversationID})
|
||||||
|
: assert(conversationID != null),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _ConversationScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ConversationScreenState extends State<ConversationScreen> {
|
||||||
|
final ConversationsHelper _conversationsHelper = ConversationsHelper();
|
||||||
|
final UsersHelper _usersHelper = UsersHelper();
|
||||||
|
ConversationMessagesList _messages;
|
||||||
|
UsersList _usersInfo = UsersList();
|
||||||
|
ErrorLevel _error = ErrorLevel.NONE;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
_loadMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setError(ErrorLevel err) => setState(() => _error = err);
|
||||||
|
|
||||||
|
/// Method called when an error occurred while loading messages
|
||||||
|
void _errorLoading() {
|
||||||
|
_setError(_messages == null ? ErrorLevel.MAJOR : ErrorLevel.MINOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a list of messages
|
||||||
|
Future<void> _loadMessages() async {
|
||||||
|
//First, get the messages
|
||||||
|
final messages = await _conversationsHelper
|
||||||
|
.downloadNewMessagesSingle(widget.conversationID);
|
||||||
|
|
||||||
|
if (messages == null) return _errorLoading();
|
||||||
|
|
||||||
|
//Then get information about users
|
||||||
|
final usersToGet =
|
||||||
|
findMissingFromList(_usersInfo.usersID, messages.getUsersID());
|
||||||
|
|
||||||
|
final users = await _usersHelper.getUsersInfo(usersToGet);
|
||||||
|
|
||||||
|
if (users == null) _errorLoading();
|
||||||
|
|
||||||
|
// Save the new list of messages
|
||||||
|
setState(() {
|
||||||
|
_usersInfo.addAll(users);
|
||||||
|
if (_messages == null)
|
||||||
|
_messages = messages;
|
||||||
|
else
|
||||||
|
_messages.addAll(messages);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Error handling
|
||||||
|
Widget _buildError() {
|
||||||
|
return buildErrorCard(tr("Could not load the list of messages!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (_error == ErrorLevel.MAJOR) return _buildError();
|
||||||
|
|
||||||
|
if (_messages == null) return buildCenteredProgressBar();
|
||||||
|
|
||||||
|
return ListView.builder(
|
||||||
|
itemCount: _messages.length,
|
||||||
|
itemBuilder: (c, i) {
|
||||||
|
return ConversationMessageTile(
|
||||||
|
message: _messages.elementAt(i),
|
||||||
|
userInfo: _usersInfo.getUser(_messages[i].userID),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
22
lib/ui/tiles/conversation_message_tile.dart
Normal file
22
lib/ui/tiles/conversation_message_tile.dart
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import 'package:comunic/models/conversation_message.dart';
|
||||||
|
import 'package:comunic/models/user.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// Conversation message tile
|
||||||
|
///
|
||||||
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
|
class ConversationMessageTile extends StatelessWidget {
|
||||||
|
final ConversationMessage message;
|
||||||
|
final User userInfo;
|
||||||
|
|
||||||
|
const ConversationMessageTile({Key key, this.message, this.userInfo})
|
||||||
|
: assert(message != null),
|
||||||
|
assert(userInfo != null),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Text(message.message);
|
||||||
|
}
|
||||||
|
}
|
@ -12,3 +12,16 @@ List<int> listToIntList(List<dynamic> srcList){
|
|||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Find the list of missing elements of a [testList] from a [srcList]
|
||||||
|
List<T> findMissingFromList<T>(List<T> srcList, List<T>testList) {
|
||||||
|
|
||||||
|
List<T> dest = List();
|
||||||
|
|
||||||
|
testList.forEach((f){
|
||||||
|
if(!srcList.contains(f) && !dest.contains(f))
|
||||||
|
dest.add(f);
|
||||||
|
});
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user