1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2025-06-19 08:15:16 +00:00

Start conversation upgrade

This commit is contained in:
2021-03-10 17:54:41 +01:00
parent b094361f5a
commit dacccf57b5
35 changed files with 818 additions and 520 deletions

View File

@ -4,6 +4,7 @@ import 'package:comunic/ui/routes/main_route/main_route.dart';
import 'package:comunic/ui/routes/update_conversation_route.dart';
import 'package:comunic/ui/screens/conversation_screen.dart';
import 'package:comunic/ui/widgets/comunic_back_button_widget.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';
@ -25,7 +26,7 @@ class ConversationRoute extends StatefulWidget {
State<StatefulWidget> createState() => _ConversationRouteState();
}
class _ConversationRouteState extends State<ConversationRoute> {
class _ConversationRouteState extends SafeState<ConversationRoute> {
final ConversationsHelper _conversationsHelper = ConversationsHelper();
Conversation _conversation;
String _conversationName;
@ -42,21 +43,22 @@ class _ConversationRouteState extends State<ConversationRoute> {
Future<void> _loadConversation() async {
setError(false);
_conversation = await _conversationsHelper.getSingle(widget.conversationID,
force: true);
try {
_conversation = await _conversationsHelper
.getSingle(widget.conversationID, force: true);
if (_conversation == null) return setError(true);
if (_conversation == null) return setError(true);
final conversationName =
await ConversationsHelper.getConversationNameAsync(_conversation);
final conversationName =
await ConversationsHelper.getConversationNameAsync(_conversation);
if (!this.mounted) return null;
if (!this.mounted) return null;
if (conversationName == null) return setError(true);
setState(() {
_conversationName = conversationName;
});
setState(() => _conversationName = conversationName);
} catch (e, s) {
print("Failed to get conversation name! $e => $s");
setError(true);
}
}
void _openSettings() {

View File

@ -42,19 +42,18 @@ class _UpdateConversationRoute extends State<UpdateConversationRoute> {
Future<void> _loadConversation() async {
setError(false);
final conversation = await ConversationsHelper()
.getSingle(widget.conversationID, force: true);
try {
final conversation = await ConversationsHelper()
.getSingle(widget.conversationID, force: true);
if (conversation == null) return setError(true);
//Load information about the members of the conversation
_membersInfo = await UsersHelper().getList(conversation.membersID);
//Load information about the members of the conversation
_membersInfo = await UsersHelper().getUsersInfo(conversation.members);
if (_membersInfo == null) return setError(true);
setState(() {
_conversation = conversation;
});
setState(() => _conversation = conversation);
} catch (e, s) {
print("Failed to load conversation information! $e=>$s");
setError(true);
}
}
/// Build the body of this widget

View File

@ -110,7 +110,7 @@ class _CallScreenState extends SafeState<CallScreen> {
// First, load information about the conversation
_conversation =
await ConversationsHelper().getSingleOrThrow(convID, force: true);
await ConversationsHelper().getSingle(convID, force: true);
_convName =
await ConversationsHelper.getConversationNameAsync(_conversation);
assert(_convName != null);

View File

@ -32,8 +32,7 @@ class _ConversationMembersScreenState extends State<ConversationMembersScreen> {
Future<void> _refresh() async {
_conversation =
await ConversationsHelper().getSingle(widget.convID, force: true);
_members =
await UsersHelper().getListWithThrow(_conversation.members.toSet());
_members = await UsersHelper().getListWithThrow(_conversation.membersID);
}
@override
@ -55,12 +54,12 @@ class _ConversationMembersScreenState extends State<ConversationMembersScreen> {
);
Widget _buildItem(BuildContext context, int index) {
final user = _members.getUser(_conversation.members[index]);
final member = _conversation.members[index];
final user = _members.getUser(member.userID);
return ListTile(
leading: AccountImageWidget(user: user),
title: Text(user.displayName),
subtitle:
Text(_conversation.ownerID == user.id ? tr("Owner") : tr("Member")),
subtitle: Text(member.isAdmin ? tr("Admin") : tr("Member")),
);
}
}

View File

@ -70,9 +70,8 @@ class _ConversationScreenState extends SafeState<ConversationScreen> {
});
/// Method called when an error occurred while loading messages
void _errorLoading() {
_setError(_messages == null ? ErrorLevel.MAJOR : ErrorLevel.MINOR);
}
void _errorLoading() =>
_setError(_messages == null ? ErrorLevel.MAJOR : ErrorLevel.MINOR);
/// Load the first conversations
Future<void> _init() async {
@ -86,22 +85,27 @@ class _ConversationScreenState extends SafeState<ConversationScreen> {
.registerConversationEvents(widget.conversationID);
this.listen<NewConversationMessageEvent>((ev) async {
if (ev.msg.conversationID == widget.conversationID) {
await _conversationsHelper.saveMessage(ev.msg);
await _applyNewMessages(ConversationMessagesList()..add(ev.msg));
if (ev.msg.convID == widget.conversationID) {
try {
await _conversationsHelper.saveMessage(ev.msg);
await _applyNewMessages(ConversationMessagesList()..add(ev.msg));
} catch (e, s) {
print("Failed to show new message! $e => $s");
_errorLoading();
}
}
});
this.listen<UpdatedConversationMessageEvent>((ev) async {
if (ev.msg.conversationID == widget.conversationID) {
if (ev.msg.convID == widget.conversationID) {
await _conversationsHelper.saveMessage(ev.msg);
setState(() => _messages.replace(ev.msg));
}
});
this.listen<DeletedConversationMessageEvent>((ev) async {
if (ev.msg.conversationID == widget.conversationID) {
await _conversationsHelper.removeMessage(ev.msg.id);
if (ev.msg.convID == widget.conversationID) {
await _conversationsHelper.removeMessage(ev.msg);
setState(() => _messages.removeMsg(ev.msg.id));
}
});
@ -116,19 +120,23 @@ class _ConversationScreenState extends SafeState<ConversationScreen> {
Future<void> _loadMessages(bool online) async {
if (!mounted) return;
//First, get the messages
final messages = await _conversationsHelper.getNewMessages(
try {
//First, get the messages
final messages = await _conversationsHelper.getNewMessages(
conversationID: widget.conversationID,
lastMessageID: _messages == null ? 0 : _messages.lastMessageID,
online: online);
online: online,
);
if (messages == null) return _errorLoading();
// In case we are offline and we did not get any message we do not do
// anything (we wait for the online request)
if (messages.length == 0 && !online) return;
// In case we are offline and we did not get any message we do not do
// anything (we wait for the online request)
if (messages.length == 0 && !online) return;
await _applyNewMessages(messages);
await _applyNewMessages(messages);
} catch (e, s) {
print("Failed to load messages! $e => $s");
_errorLoading();
}
}
/// Get older messages
@ -136,45 +144,43 @@ class _ConversationScreenState extends SafeState<ConversationScreen> {
if (_loadingOlderMessages != _OlderMessagesLevel.NONE ||
_messages == null ||
_messages.length == 0) return;
try {
// Let's start to load older messages
_setLoadingOlderMessagesState(_OlderMessagesLevel.LOADING);
// Let's start to load older messages
_setLoadingOlderMessagesState(_OlderMessagesLevel.LOADING);
final messages = await _conversationsHelper.getOlderMessages(
conversationID: widget.conversationID,
oldestMessagesID: _messages.firstMessageID);
final messages = await _conversationsHelper.getOlderMessages(
conversationID: widget.conversationID,
oldestMessagesID: _messages.firstMessageID);
// Mark as not loading anymore
_setLoadingOlderMessagesState(_OlderMessagesLevel.NONE);
// Mark as not loading anymore
_setLoadingOlderMessagesState(_OlderMessagesLevel.NONE);
// Check if there is no more unread messages
if (messages.length == 0) {
_setLoadingOlderMessagesState(_OlderMessagesLevel.NO_MORE_AVAILABLE);
return;
}
// Check for errors
if (messages == null) {
// Apply the messages
_applyNewMessages(messages);
} catch (e, s) {
print("Failed to load older messages! $e => $s");
_errorLoading();
return;
}
// Check if there is no more unread messages
if (messages.length == 0) {
_setLoadingOlderMessagesState(_OlderMessagesLevel.NO_MORE_AVAILABLE);
return;
}
// Apply the messages
_applyNewMessages(messages);
}
/// Apply new messages [messages] must not be null
///
/// Throws in case of failure
Future<void> _applyNewMessages(ConversationMessagesList messages) async {
// We ignore new messages once the area is no longer visible
if (!this.mounted) return;
//Then get information about users
final usersToGet =
findMissingFromList(_usersInfo.usersID, messages.getUsersID());
findMissingFromList(_usersInfo.usersID, messages.getUsersID()).toSet();
final users = await _usersHelper.getUsersInfo(usersToGet);
if (users == null) _errorLoading();
final users = await _usersHelper.getList(usersToGet);
// Save the new list of messages
setState(() {

View File

@ -62,32 +62,24 @@ class _ConversationScreenState extends SafeState<ConversationsListScreen> {
await _loadConversationsList(false);
}
void _gotLoadingError() {
setError(_list == null ? LoadErrorLevel.MAJOR : LoadErrorLevel.MINOR);
}
/// Load the list of conversations
Future<void> _loadConversationsList(bool cached) async {
setError(LoadErrorLevel.NONE);
//Get the list of conversations
var list;
if (cached)
list = await _conversationsHelper.getCachedList();
else
list = await _conversationsHelper.downloadList();
try {
ConversationsList list = cached
? await _conversationsHelper.getCachedList()
: await _conversationsHelper.downloadList();
assert(list != null);
if (list == null) return _gotLoadingError();
//Get information about the members of the conversations
list.users = await _usersHelper.getList(list.allUsersID);
//Get information about the members of the conversations
list.users = await _usersHelper.getUsersInfo(list.allUsersID);
if (list.users == null) return _gotLoadingError();
//Save list
setState(() {
_list = list;
});
setState(() => _list = list);
} catch (e, s) {
debugPrint("Failed to get conversations list! $e => $s", wrapWidth: 1024);
setError(_list == null ? LoadErrorLevel.MAJOR : LoadErrorLevel.MINOR);
}
}
/// Build an error card
@ -159,9 +151,13 @@ class _ConversationScreenState extends SafeState<ConversationsListScreen> {
if (result == null || !result) return;
// Request the conversation to be deleted now
if (!await _conversationsHelper.deleteConversation(conversation.id))
try {
await _conversationsHelper.deleteConversation(conversation.id);
} catch (e, s) {
print("Failed to delete conversation! $e => $s");
Scaffold.of(context).showSnackBar(
SnackBar(content: Text(tr("Could not delete the conversation!"))));
}
// Reload the list of conversations
_loadConversationsList(false);

View File

@ -3,11 +3,8 @@ import 'package:comunic/helpers/events_helper.dart';
import 'package:comunic/helpers/users_helper.dart';
import 'package:comunic/lists/unread_conversations_list.dart';
import 'package:comunic/lists/users_list.dart';
import 'package:comunic/ui/routes/main_route/main_route.dart';
import 'package:comunic/ui/widgets/account_image_widget.dart';
import 'package:comunic/ui/widgets/async_screen_widget.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
import 'package:comunic/utils/date_utils.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:flutter/material.dart';
@ -70,7 +67,7 @@ class _UnreadConversationsScreenState
}
Widget _tileBuilder(BuildContext context, int index) {
final conv = _list[index];
/*final conv = _list[index];
final user = _users.getUser(conv.userID);
return ListTile(
leading: AccountImageWidget(user: user),
@ -83,9 +80,12 @@ class _UnreadConversationsScreenState
style: TextStyle(fontStyle: FontStyle.italic),
),
]),
),
)
trailing: Text(diffTimeFromNowToStr(conv.lastActive)),
onTap: () => MainController.of(context).openConversation(conv.id),
);
);*/
// TODO : reimplement
throw new Exception("unimplemented");
}
}

View File

@ -1,8 +1,6 @@
import 'package:comunic/helpers/conversations_helper.dart';
import 'package:comunic/lists/users_list.dart';
import 'package:comunic/models/conversation.dart';
import 'package:comunic/models/user.dart';
import 'package:comunic/ui/routes/main_route/main_route.dart';
import 'package:comunic/ui/tiles/simple_user_tile.dart';
import 'package:comunic/ui/widgets/pick_user_widget.dart';
import 'package:comunic/utils/intl_utils.dart';
@ -36,11 +34,11 @@ class _UpdateConversationScreen extends State<UpdateConversationScreen> {
get isUpdating => widget.initialSettings != null;
get isOwner => !isUpdating || widget.initialSettings.isOwner;
get isAdmin => !isUpdating || widget.initialSettings.isAdmin;
Conversation get _initialSettings => widget.initialSettings;
bool get _canAddMembers => isOwner || _initialSettings.canEveryoneAddMembers;
bool get _canAddMembers => isAdmin || _initialSettings.canEveryoneAddMembers;
@override
void initState() {
@ -68,7 +66,7 @@ class _UpdateConversationScreen extends State<UpdateConversationScreen> {
decoration: InputDecoration(
labelText: tr("Conversation name (optionnal)"),
alignLabelWithHint: true,
enabled: isOwner,
enabled: isAdmin,
),
),
@ -90,7 +88,7 @@ class _UpdateConversationScreen extends State<UpdateConversationScreen> {
children: <Widget>[
Switch.adaptive(
value: _canEveryoneAddMembers,
onChanged: isOwner
onChanged: isAdmin
? (b) => setState(() {
_canEveryoneAddMembers = b;
})
@ -126,7 +124,7 @@ class _UpdateConversationScreen extends State<UpdateConversationScreen> {
PopupMenuItem(
child: Text(tr("Remove")),
value: _MembersMenuChoices.REMOVE,
enabled: isOwner ||
enabled: isAdmin ||
(_canEveryoneAddMembers &&
!_initialSettings.members
.contains(f.id)),
@ -163,7 +161,8 @@ class _UpdateConversationScreen extends State<UpdateConversationScreen> {
/// Submit the conversation
Future<void> _submitForm() async {
final settings = Conversation(
// TODO : reimplement
/* final settings = Conversation(
id: isUpdating ? widget.initialSettings.id : 0,
ownerID: isUpdating ? widget.initialSettings.ownerID : 0,
name: _nameController.text,
@ -198,6 +197,6 @@ class _UpdateConversationScreen extends State<UpdateConversationScreen> {
MainController.of(context).popPage();
if (!isUpdating)
MainController.of(context).openConversation(conversationID);
MainController.of(context).openConversation(conversationID);*/
}
}

View File

@ -1,7 +1,6 @@
import 'package:comunic/models/conversation_message.dart';
import 'package:comunic/models/user.dart';
import 'package:comunic/ui/widgets/account_image_widget.dart';
import 'package:comunic/ui/widgets/network_image_widget.dart';
import 'package:comunic/ui/widgets/text_widget.dart';
import 'package:comunic/utils/date_utils.dart';
import 'package:comunic/utils/intl_utils.dart';
@ -72,7 +71,9 @@ class ConversationMessageTile extends StatelessWidget {
/// Build widget image
Widget _buildMessageImage(BuildContext context) {
return Container(
return Text("");
// TODO : fix file
/*return Container(
margin: EdgeInsets.only(bottom: 2),
child: NetworkImageWidget(
url: message.imageURL,
@ -80,7 +81,7 @@ class ConversationMessageTile extends StatelessWidget {
width: 200,
height: 200,
),
);
);*/
}
/// Build message date

View File

@ -80,7 +80,7 @@ class ConversationTile extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
_buildSubInformation(
Icons.access_time, diffTimeFromNowToStr(conversation.lastActive)),
Icons.access_time, diffTimeFromNowToStr(conversation.lastActivity)),
_buildSubInformation(
Icons.group,
conversation.members.length == 1

View File

@ -119,33 +119,36 @@ class PostsListWidgetState extends SafeState<PostsListWidget> {
_loading = true;
final list = !getOlder
? await widget.getPostsList()
: await widget.getOlder(_list.oldestID);
try {
final list = !getOlder
? await widget.getPostsList()
: await widget.getOlder(_list.oldestID);
if (list == null) return _loadError();
if (list == null) return _loadError();
final users = await _usersHelper.getList(list.usersID);
final users = await _usersHelper.getList(list.usersID);
if (users == null) return _loadError();
final groups = await _groupsHelper.getList(list.groupsID);
final groups = await _groupsHelper.getList(list.groupsID);
if (groups == null) return _loadError();
if (groups == null) return _loadError();
if (!mounted) return;
if (!mounted) return;
setState(() {
if (!getOlder) {
_list = list;
_users = users;
_groups = groups;
} else {
_list.addAll(list);
_users.addAll(users);
_groups.addAll(groups);
}
});
setState(() {
if (!getOlder) {
_list = list;
_users = users;
_groups = groups;
} else {
_list.addAll(list);
_users.addAll(users);
_groups.addAll(groups);
}
});
} catch (e, s) {
print("Failed to load post information ! $e => $s");
_loadError();
}
_loading = false;
}

View File

@ -81,7 +81,7 @@ class _ConversationWindowState extends SafeState<ConversationWindow> {
_refresh();
listen<NewConversationMessageEvent>((e) {
if (e.msg.conversationID == _convID &&
if (e.msg.convID == _convID &&
_collapsed &&
e.msg.userID != userID()) setState(() => _hasNewMessages = true);
});