mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-11-04 04:04:18 +00:00 
			
		
		
		
	Added conversation message statistics
This commit is contained in:
		
							
								
								
									
										95
									
								
								lib/ui/routes/conversation_message_stats_route.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								lib/ui/routes/conversation_message_stats_route.dart
									
									
									
									
									
										Normal 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")),
 | 
			
		||||
          );
 | 
			
		||||
        },
 | 
			
		||||
      );
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,7 @@
 | 
			
		||||
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/main_route/page_info.dart';
 | 
			
		||||
import 'package:comunic/ui/routes/settings/account_settings_route.dart';
 | 
			
		||||
@@ -151,6 +154,18 @@ abstract class MainController extends State<MainRoute> {
 | 
			
		||||
        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
 | 
			
		||||
  void startCall(int convID) =>
 | 
			
		||||
      pushPage(PageInfo(child: CallScreen(convID: convID), hideNavBar: true));
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ import 'package:comunic/lists/users_list.dart';
 | 
			
		||||
import 'package:comunic/models/conversation.dart';
 | 
			
		||||
import 'package:comunic/models/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/server_conversation_message_tile.dart';
 | 
			
		||||
import 'package:comunic/ui/widgets/safe_state.dart';
 | 
			
		||||
@@ -331,6 +332,7 @@ class _ConversationScreenState extends SafeState<ConversationScreen> {
 | 
			
		||||
                    userInfo: _usersInfo.getUser(_messages[i].userID),
 | 
			
		||||
                    isLastMessage: _isLastMessage(i),
 | 
			
		||||
                    isFirstMessage: _isFirstMessage(i),
 | 
			
		||||
                    onRequestMessageStats: _requestMessageStats,
 | 
			
		||||
                    onRequestMessageUpdate: _updateMessage,
 | 
			
		||||
                    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
 | 
			
		||||
  Future<void> _updateMessage(ConversationMessage message) async {
 | 
			
		||||
    final newContent = await askUserString(
 | 
			
		||||
 
 | 
			
		||||
@@ -18,9 +18,11 @@ enum _MenuChoices {
 | 
			
		||||
  COPY_URL,
 | 
			
		||||
  COPY_MESSAGE,
 | 
			
		||||
  DELETE,
 | 
			
		||||
  REQUEST_UPDATE_CONTENT
 | 
			
		||||
  REQUEST_UPDATE_CONTENT,
 | 
			
		||||
  GET_STATS,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef OnRequestMessageStats = void Function(ConversationMessage);
 | 
			
		||||
typedef OnRequestMessageUpdate = void Function(ConversationMessage);
 | 
			
		||||
typedef OnRequestMessageDelete = void Function(ConversationMessage);
 | 
			
		||||
 | 
			
		||||
@@ -30,6 +32,7 @@ class ConversationMessageTile extends StatelessWidget {
 | 
			
		||||
  final User userInfo;
 | 
			
		||||
  final bool isLastMessage;
 | 
			
		||||
  final bool isFirstMessage;
 | 
			
		||||
  final OnRequestMessageStats onRequestMessageStats;
 | 
			
		||||
  final OnRequestMessageUpdate onRequestMessageUpdate;
 | 
			
		||||
  final OnRequestMessageDelete onRequestMessageDelete;
 | 
			
		||||
 | 
			
		||||
@@ -40,12 +43,14 @@ class ConversationMessageTile extends StatelessWidget {
 | 
			
		||||
    @required this.userInfo,
 | 
			
		||||
    @required this.isLastMessage,
 | 
			
		||||
    @required this.isFirstMessage,
 | 
			
		||||
    @required this.onRequestMessageStats,
 | 
			
		||||
    @required this.onRequestMessageUpdate,
 | 
			
		||||
    @required this.onRequestMessageDelete,
 | 
			
		||||
  })  : assert(message != null),
 | 
			
		||||
        assert(userInfo != null),
 | 
			
		||||
        assert(isLastMessage != null),
 | 
			
		||||
        assert(isFirstMessage != null),
 | 
			
		||||
        assert(onRequestMessageStats != null),
 | 
			
		||||
        assert(onRequestMessageUpdate != null),
 | 
			
		||||
        assert(onRequestMessageDelete != null),
 | 
			
		||||
        super(key: key);
 | 
			
		||||
@@ -66,7 +71,6 @@ class ConversationMessageTile extends StatelessWidget {
 | 
			
		||||
          width: 35.0,
 | 
			
		||||
        ),
 | 
			
		||||
        itemBuilder: (c) => [
 | 
			
		||||
 | 
			
		||||
          PopupMenuItem(
 | 
			
		||||
            enabled: (message.message?.content ?? "") != "",
 | 
			
		||||
            value: _MenuChoices.COPY_MESSAGE,
 | 
			
		||||
@@ -78,6 +82,12 @@ class ConversationMessageTile extends StatelessWidget {
 | 
			
		||||
            value: _MenuChoices.COPY_URL,
 | 
			
		||||
            child: Text(tr("Copy URL")),
 | 
			
		||||
          ),
 | 
			
		||||
 | 
			
		||||
          PopupMenuItem(
 | 
			
		||||
            value: _MenuChoices.GET_STATS,
 | 
			
		||||
            child: Text(tr("Statistics")),
 | 
			
		||||
          ),
 | 
			
		||||
 | 
			
		||||
          // Update message content
 | 
			
		||||
          PopupMenuItem(
 | 
			
		||||
            enabled: message.isOwner,
 | 
			
		||||
@@ -275,6 +285,10 @@ class ConversationMessageTile extends StatelessWidget {
 | 
			
		||||
        FlutterClipboard.copy(message.file.url);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case _MenuChoices.GET_STATS:
 | 
			
		||||
        onRequestMessageStats(message);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case _MenuChoices.REQUEST_UPDATE_CONTENT:
 | 
			
		||||
        onRequestMessageUpdate(message);
 | 
			
		||||
        break;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user