1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-22 21:09:21 +00:00
comunicmobile/lib/ui/screens/conversations_list_screen.dart

227 lines
7.3 KiB
Dart
Raw Normal View History

import 'dart:math';
2019-04-23 12:35:41 +00:00
import 'package:comunic/enums/load_error_level.dart';
import 'package:comunic/helpers/conversations_helper.dart';
import 'package:comunic/helpers/events_helper.dart';
2021-04-06 16:04:16 +00:00
import 'package:comunic/helpers/groups_helper.dart';
import 'package:comunic/helpers/users_helper.dart';
import 'package:comunic/lists/conversations_list.dart';
2021-04-06 16:04:16 +00:00
import 'package:comunic/lists/groups_list.dart';
import 'package:comunic/lists/users_list.dart';
import 'package:comunic/models/conversation.dart';
2020-05-05 11:21:37 +00:00
import 'package:comunic/ui/routes/main_route/main_route.dart';
import 'package:comunic/ui/screens/create_conversation_screen.dart';
2019-04-23 12:35:41 +00:00
import 'package:comunic/ui/tiles/conversation_tile.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
2019-04-23 12:35:41 +00:00
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';
/// Conversations screen
///
/// @author Pierre HUBERT
2019-04-24 15:46:25 +00:00
class ConversationsListScreen extends StatefulWidget {
2020-05-09 05:10:18 +00:00
final bool useSmallFAB;
final Function()? onOpen;
2020-05-09 05:10:18 +00:00
const ConversationsListScreen({
Key? key,
this.useSmallFAB = false,
this.onOpen,
2022-03-11 16:02:06 +00:00
}) : super(key: key);
2020-05-09 05:10:18 +00:00
2019-04-23 12:35:41 +00:00
@override
State<StatefulWidget> createState() => _ConversationScreenState();
}
class _ConversationScreenState extends SafeState<ConversationsListScreen> {
2019-04-23 12:35:41 +00:00
final ConversationsHelper _conversationsHelper = ConversationsHelper();
final UsersHelper _usersHelper = UsersHelper();
ConversationsList? _list;
late UsersList _users;
GroupsList? _groups;
2019-04-23 12:35:41 +00:00
LoadErrorLevel _error = LoadErrorLevel.NONE;
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
GlobalKey<RefreshIndicatorState>();
2019-04-23 12:35:41 +00:00
@override
void initState() {
super.initState();
this.listen<NewNumberUnreadConversations>(
(d) => _refreshIndicatorKey.currentState!.show());
2019-04-23 12:35:41 +00:00
}
2019-05-01 15:10:23 +00:00
@override
void didChangeDependencies() {
super.didChangeDependencies();
_loadConversations();
2019-05-01 15:10:23 +00:00
}
2019-04-23 12:35:41 +00:00
void setError(LoadErrorLevel err) => setState(() => _error = err);
/// Get the list of conversations, once from the cache, once from the server
Future<void> _loadConversations() async {
await _loadConversationsList(true);
await _loadConversationsList(false);
}
2019-04-23 12:35:41 +00:00
/// Load the list of conversations
Future<void> _loadConversationsList(bool cached) async {
2019-04-23 12:35:41 +00:00
setError(LoadErrorLevel.NONE);
2021-03-10 16:54:41 +00:00
try {
ConversationsList list = cached
? await _conversationsHelper.getCachedList()
: await _conversationsHelper.downloadList();
2019-05-01 15:10:23 +00:00
2021-04-06 16:04:16 +00:00
// Get information about the members of the conversations
_users = await _usersHelper.getList(list.allUsersID);
_groups = await GroupsHelper().getListOrThrow(list.allGroupsID);
2019-04-23 12:35:41 +00:00
2021-03-10 16:54:41 +00:00
setState(() => _list = list);
} catch (e, s) {
debugPrint("Failed to get conversations list! $e => $s", wrapWidth: 1024);
setError(_list == null ? LoadErrorLevel.MAJOR : LoadErrorLevel.MINOR);
}
2019-04-23 12:35:41 +00:00
}
/// Build an error card
Widget _buildErrorCard() {
return buildErrorCard(
tr("Could not retrieve the list of conversations!"),
actions: <Widget>[
2021-03-13 14:28:34 +00:00
TextButton(
onPressed: () => _refreshIndicatorKey.currentState!.show(),
2019-04-23 12:35:41 +00:00
child: Text(
tr("Retry")!.toUpperCase(),
2019-04-23 12:35:41 +00:00
style: TextStyle(
color: Colors.white,
),
),
)
],
);
}
2019-04-24 15:46:25 +00:00
/// Open a conversation
2021-04-06 16:22:45 +00:00
void _openConversation(Conversation conv) {
MainController.of(context)!.openConversation(conv);
if (widget.onOpen != null) widget.onOpen!();
2019-04-24 15:46:25 +00:00
}
2019-04-27 14:23:08 +00:00
/// Create a new conversation
void _createConversation() {
MainController.of(context)!.push(
2021-04-24 08:14:56 +00:00
CreateConversationScreen(),
canShowAsDialog: true,
hideNavBar: true,
);
if (widget.onOpen != null) widget.onOpen!();
2019-04-27 14:23:08 +00:00
}
/// Handle conversations updated requests
void _updateConversation(Conversation conversation) {
MainController.of(context)!.openConversationSettingsRoute(conversation);
}
/// Handle conversation deletion request
Future<void> _requestLeaveConversation(Conversation conversation) async {
2021-04-06 16:04:16 +00:00
if (conversation.isGroupConversation) {
showAlert(
context: context,
title: tr("Group conversation"),
message: tr(
"This conversation is managed by a group. You can not leave it this way. If you do not want to receive notifications from this conversation anymore, you can stop following it in the conversation settings"));
return;
}
final result = await showConfirmDialog(
context: context,
message: conversation.isLastAdmin
? tr(
"Do you really want to leave this conversation ? As you are its last admin, it will be completely deleted!")
: tr("Do you really want to leave this conversation ?"));
2022-03-11 16:02:06 +00:00
if (!result) return;
// Request the conversation to be deleted now
2021-03-10 16:54:41 +00:00
try {
await _conversationsHelper.deleteConversation(conversation.id);
} catch (e, s) {
print("Failed to leave conversation! $e => $s");
2021-03-13 14:28:34 +00:00
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(tr("Could not leave the conversation!")!)));
2021-03-10 16:54:41 +00:00
}
// Reload the list of conversations
_loadConversationsList(false);
}
2019-04-23 12:35:41 +00:00
@override
Widget build(BuildContext context) {
if (_error == LoadErrorLevel.MAJOR) return _buildErrorCard();
if (_list == null) return buildCenteredProgressBar();
// Show the list of conversations
return Stack(
children: <Widget>[
Column(
children: <Widget>[
Container(
child: _error == LoadErrorLevel.MINOR ? _buildErrorCard() : null,
),
Expanded(
child: RefreshIndicator(
onRefresh: () => _loadConversationsList(false),
key: _refreshIndicatorKey,
child: ListView.builder(
physics: AlwaysScrollableScrollPhysics(),
controller: ScrollController(),
itemBuilder: (context, index) {
if (_list!.isEmpty)
return Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Text(
tr("You do not have any conversation yet!")!)),
);
if (_list![index].isGroupConversation &&
!_list![index].following) return Container();
2021-04-06 16:04:16 +00:00
return ConversationTile(
conversation: _list!.elementAt(index),
2021-04-06 16:04:16 +00:00
usersList: _users,
groupsList: _groups,
onOpen: (c) {
2021-04-06 16:22:45 +00:00
_openConversation(c);
},
onRequestUpdate: _updateConversation,
onRequestLeave: _requestLeaveConversation,
);
},
itemCount: max(_list!.length, 1),
),
),
),
],
),
2019-04-27 14:23:08 +00:00
// Add conversation button
Positioned(
2020-05-09 05:10:18 +00:00
right: widget.useSmallFAB ? 5.0 : 20.0,
bottom: widget.useSmallFAB ? 5.0 : 20.0,
2019-04-27 14:23:08 +00:00
child: FloatingActionButton(
2020-05-09 05:10:18 +00:00
mini: widget.useSmallFAB,
onPressed: () => _createConversation(),
2019-04-27 14:23:08 +00:00
child: Icon(Icons.add),
),
),
],
2019-04-23 12:35:41 +00:00
);
}
}