1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-26 06:49:22 +00:00

Added conversation message statistics

This commit is contained in:
Pierre HUBERT 2021-03-11 17:27:20 +01:00
parent 217111e3fd
commit c8ca80f6e7
4 changed files with 134 additions and 2 deletions

View File

@ -0,0 +1,95 @@
import 'package:comunic/helpers/users_helper.dart';
import 'package:comunic/lists/users_list.dart';
import 'package:comunic/models/conversation.dart';
import 'package:comunic/models/conversation_message.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/utils/date_utils.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:flutter/material.dart';
/// Conversation message statistics route
///
/// @author Pierre Hubert
class ConversationMessageStatsRoute extends StatefulWidget {
final Conversation conv;
final ConversationMessage message;
const ConversationMessageStatsRoute({
Key key,
@required this.conv,
@required this.message,
}) : assert(conv != null),
assert(message != null),
super(key: key);
@override
_ConversationMessageStatsRouteState createState() =>
_ConversationMessageStatsRouteState();
}
class _ConversationMessageStatsRouteState
extends State<ConversationMessageStatsRoute> {
UsersList _users;
Future<void> _init() async {
_users = await UsersHelper()
.getList(widget.conv.membersID..add(widget.message.userID));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(tr("Message statistics")),
leading: IconButton(
icon: Icon(Icons.close),
onPressed: () => MainController.of(context).popPage(),
),
),
body: AsyncScreenWidget(
onReload: _init,
onBuild: _buildScreen,
errorMessage: tr("Failed to load message information!")),
);
}
List<Widget> get _firstItems => [
ListTile(
leading: Icon(Icons.access_time_rounded),
title: Text(tr("Created on")),
subtitle: Text(dateTimeToString(widget.message.date)),
),
ListTile(
leading: AccountImageWidget(
user: _users.getUser(widget.message.userID),
),
title: Text(_users.getUser(widget.message.userID).fullName),
subtitle: Text(tr("Creator")),
),
];
Widget _buildScreen() => ListView.builder(
itemCount: _firstItems.length + widget.conv.members.length,
itemBuilder: (c, i) {
final firstItems = _firstItems;
if (i < firstItems.length) return firstItems[i];
final convMember = widget.conv.members[i - firstItems.length];
if (convMember.userID == widget.message.userID) return Container();
return ListTile(
leading: AccountImageWidget(
user: _users.getUser(convMember.userID),
),
title: Text(_users.getUser(convMember.userID).fullName),
subtitle: Text(convMember.lastMessageSeen < widget.message.id
? tr("Message not seen yet")
: tr("Message seen")),
);
},
);
}

View File

@ -1,4 +1,7 @@
import 'package:comunic/helpers/account_helper.dart'; import 'package:comunic/helpers/account_helper.dart';
import 'package:comunic/models/conversation.dart';
import 'package:comunic/models/conversation_message.dart';
import 'package:comunic/ui/routes/conversation_message_stats_route.dart';
import 'package:comunic/ui/routes/conversation_route.dart'; import 'package:comunic/ui/routes/conversation_route.dart';
import 'package:comunic/ui/routes/main_route/page_info.dart'; import 'package:comunic/ui/routes/main_route/page_info.dart';
import 'package:comunic/ui/routes/settings/account_settings_route.dart'; import 'package:comunic/ui/routes/settings/account_settings_route.dart';
@ -151,6 +154,18 @@ abstract class MainController extends State<MainRoute> {
hideNavBar: true, hideNavBar: true,
)); ));
/// Open a conversation message statistics page
void openConversationMessageStats(
Conversation conv, ConversationMessage message) =>
pushPage(PageInfo(
child: ConversationMessageStatsRoute(
conv: conv,
message: message,
),
hideNavBar: true,
canShowAsDialog: true,
));
/// Start a call for a given conversation /// Start a call for a given conversation
void startCall(int convID) => void startCall(int convID) =>
pushPage(PageInfo(child: CallScreen(convID: convID), hideNavBar: true)); pushPage(PageInfo(child: CallScreen(convID: convID), hideNavBar: true));

View File

@ -8,6 +8,7 @@ import 'package:comunic/lists/users_list.dart';
import 'package:comunic/models/conversation.dart'; import 'package:comunic/models/conversation.dart';
import 'package:comunic/models/conversation_message.dart'; import 'package:comunic/models/conversation_message.dart';
import 'package:comunic/models/new_conversation_message.dart'; import 'package:comunic/models/new_conversation_message.dart';
import 'package:comunic/ui/routes/main_route/main_route.dart';
import 'package:comunic/ui/tiles/conversation_message_tile.dart'; import 'package:comunic/ui/tiles/conversation_message_tile.dart';
import 'package:comunic/ui/tiles/server_conversation_message_tile.dart'; import 'package:comunic/ui/tiles/server_conversation_message_tile.dart';
import 'package:comunic/ui/widgets/safe_state.dart'; import 'package:comunic/ui/widgets/safe_state.dart';
@ -331,6 +332,7 @@ class _ConversationScreenState extends SafeState<ConversationScreen> {
userInfo: _usersInfo.getUser(_messages[i].userID), userInfo: _usersInfo.getUser(_messages[i].userID),
isLastMessage: _isLastMessage(i), isLastMessage: _isLastMessage(i),
isFirstMessage: _isFirstMessage(i), isFirstMessage: _isFirstMessage(i),
onRequestMessageStats: _requestMessageStats,
onRequestMessageUpdate: _updateMessage, onRequestMessageUpdate: _updateMessage,
onRequestMessageDelete: _deleteMessage, onRequestMessageDelete: _deleteMessage,
); );
@ -425,6 +427,12 @@ class _ConversationScreenState extends SafeState<ConversationScreen> {
); );
} }
/// Request message statistics
void _requestMessageStats(ConversationMessage message) async {
MainController.of(context)
.openConversationMessageStats(_conversation, message);
}
/// Request message content update /// Request message content update
Future<void> _updateMessage(ConversationMessage message) async { Future<void> _updateMessage(ConversationMessage message) async {
final newContent = await askUserString( final newContent = await askUserString(

View File

@ -18,9 +18,11 @@ enum _MenuChoices {
COPY_URL, COPY_URL,
COPY_MESSAGE, COPY_MESSAGE,
DELETE, DELETE,
REQUEST_UPDATE_CONTENT REQUEST_UPDATE_CONTENT,
GET_STATS,
} }
typedef OnRequestMessageStats = void Function(ConversationMessage);
typedef OnRequestMessageUpdate = void Function(ConversationMessage); typedef OnRequestMessageUpdate = void Function(ConversationMessage);
typedef OnRequestMessageDelete = void Function(ConversationMessage); typedef OnRequestMessageDelete = void Function(ConversationMessage);
@ -30,6 +32,7 @@ class ConversationMessageTile extends StatelessWidget {
final User userInfo; final User userInfo;
final bool isLastMessage; final bool isLastMessage;
final bool isFirstMessage; final bool isFirstMessage;
final OnRequestMessageStats onRequestMessageStats;
final OnRequestMessageUpdate onRequestMessageUpdate; final OnRequestMessageUpdate onRequestMessageUpdate;
final OnRequestMessageDelete onRequestMessageDelete; final OnRequestMessageDelete onRequestMessageDelete;
@ -40,12 +43,14 @@ class ConversationMessageTile extends StatelessWidget {
@required this.userInfo, @required this.userInfo,
@required this.isLastMessage, @required this.isLastMessage,
@required this.isFirstMessage, @required this.isFirstMessage,
@required this.onRequestMessageStats,
@required this.onRequestMessageUpdate, @required this.onRequestMessageUpdate,
@required this.onRequestMessageDelete, @required this.onRequestMessageDelete,
}) : assert(message != null), }) : assert(message != null),
assert(userInfo != null), assert(userInfo != null),
assert(isLastMessage != null), assert(isLastMessage != null),
assert(isFirstMessage != null), assert(isFirstMessage != null),
assert(onRequestMessageStats != null),
assert(onRequestMessageUpdate != null), assert(onRequestMessageUpdate != null),
assert(onRequestMessageDelete != null), assert(onRequestMessageDelete != null),
super(key: key); super(key: key);
@ -66,7 +71,6 @@ class ConversationMessageTile extends StatelessWidget {
width: 35.0, width: 35.0,
), ),
itemBuilder: (c) => [ itemBuilder: (c) => [
PopupMenuItem( PopupMenuItem(
enabled: (message.message?.content ?? "") != "", enabled: (message.message?.content ?? "") != "",
value: _MenuChoices.COPY_MESSAGE, value: _MenuChoices.COPY_MESSAGE,
@ -78,6 +82,12 @@ class ConversationMessageTile extends StatelessWidget {
value: _MenuChoices.COPY_URL, value: _MenuChoices.COPY_URL,
child: Text(tr("Copy URL")), child: Text(tr("Copy URL")),
), ),
PopupMenuItem(
value: _MenuChoices.GET_STATS,
child: Text(tr("Statistics")),
),
// Update message content // Update message content
PopupMenuItem( PopupMenuItem(
enabled: message.isOwner, enabled: message.isOwner,
@ -275,6 +285,10 @@ class ConversationMessageTile extends StatelessWidget {
FlutterClipboard.copy(message.file.url); FlutterClipboard.copy(message.file.url);
break; break;
case _MenuChoices.GET_STATS:
onRequestMessageStats(message);
break;
case _MenuChoices.REQUEST_UPDATE_CONTENT: case _MenuChoices.REQUEST_UPDATE_CONTENT:
onRequestMessageUpdate(message); onRequestMessageUpdate(message);
break; break;