mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-11-04 12:14:11 +00:00 
			
		
		
		
	Start to build report dialog
This commit is contained in:
		
							
								
								
									
										28
									
								
								lib/enums/report_target_type.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								lib/enums/report_target_type.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					/// What kind of content that can be reported
 | 
				
			||||||
 | 
					enum ReportTargetType {
 | 
				
			||||||
 | 
					  Post,
 | 
				
			||||||
 | 
					  Comment,
 | 
				
			||||||
 | 
					  Conversation,
 | 
				
			||||||
 | 
					  ConversationMessage,
 | 
				
			||||||
 | 
					  User,
 | 
				
			||||||
 | 
					  Group
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extension ReportTargetExt on ReportTargetType {
 | 
				
			||||||
 | 
					  String get apiId {
 | 
				
			||||||
 | 
					    switch (this) {
 | 
				
			||||||
 | 
					      case ReportTargetType.Post:
 | 
				
			||||||
 | 
					        return "post";
 | 
				
			||||||
 | 
					      case ReportTargetType.Comment:
 | 
				
			||||||
 | 
					        return "comment";
 | 
				
			||||||
 | 
					      case ReportTargetType.Conversation:
 | 
				
			||||||
 | 
					        return "conversation";
 | 
				
			||||||
 | 
					      case ReportTargetType.ConversationMessage:
 | 
				
			||||||
 | 
					        return "conversation_message";
 | 
				
			||||||
 | 
					      case ReportTargetType.User:
 | 
				
			||||||
 | 
					        return "user";
 | 
				
			||||||
 | 
					      case ReportTargetType.Group:
 | 
				
			||||||
 | 
					        return "group";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -23,77 +23,88 @@ class ServerConfigurationHelper {
 | 
				
			|||||||
    final dataConservationPolicy = response["data_conservation_policy"];
 | 
					    final dataConservationPolicy = response["data_conservation_policy"];
 | 
				
			||||||
    final conversationsPolicy = response["conversations_policy"];
 | 
					    final conversationsPolicy = response["conversations_policy"];
 | 
				
			||||||
    final accountInformationPolicy = response["account_info_policy"];
 | 
					    final accountInformationPolicy = response["account_info_policy"];
 | 
				
			||||||
 | 
					    final reportPolicy = response["report_policy"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _config = ServerConfig(
 | 
					    _config = ServerConfig(
 | 
				
			||||||
      minSupportedMobileVersion:
 | 
					        minSupportedMobileVersion:
 | 
				
			||||||
          Version.parse(response["min_supported_mobile_version"]),
 | 
					            Version.parse(response["min_supported_mobile_version"]),
 | 
				
			||||||
      termsURL: response["terms_url"],
 | 
					        termsURL: response["terms_url"],
 | 
				
			||||||
      privacyPolicyURL: response["privacy_policy_url"],
 | 
					        privacyPolicyURL: response["privacy_policy_url"],
 | 
				
			||||||
      contactEmail: response["contact_email"],
 | 
					        contactEmail: response["contact_email"],
 | 
				
			||||||
      playStoreURL: response["play_store_url"],
 | 
					        playStoreURL: response["play_store_url"],
 | 
				
			||||||
      androidDirectDownloadURL: response["android_direct_download_url"],
 | 
					        androidDirectDownloadURL: response["android_direct_download_url"],
 | 
				
			||||||
      banner: banner == null
 | 
					        banner: banner == null
 | 
				
			||||||
          ? null
 | 
					            ? null
 | 
				
			||||||
          : Banner(
 | 
					            : Banner(
 | 
				
			||||||
              enabled: banner["enabled"],
 | 
					                enabled: banner["enabled"],
 | 
				
			||||||
              expire: banner["expire"],
 | 
					                expire: banner["expire"],
 | 
				
			||||||
              nature: BannerNatureExt.fromStr(banner["nature"]),
 | 
					                nature: BannerNatureExt.fromStr(banner["nature"]),
 | 
				
			||||||
              message: Map<String, dynamic>.from(banner["message"])
 | 
					                message: Map<String, dynamic>.from(banner["message"])
 | 
				
			||||||
                  .map((key, value) => MapEntry(key, value.toString())),
 | 
					                    .map((key, value) => MapEntry(key, value.toString())),
 | 
				
			||||||
              link: banner["link"]),
 | 
					                link: banner["link"]),
 | 
				
			||||||
      notificationsPolicy: NotificationsPolicy(
 | 
					        notificationsPolicy: NotificationsPolicy(
 | 
				
			||||||
        hasFirebase: pushNotificationsPolicy["has_firebase"],
 | 
					          hasFirebase: pushNotificationsPolicy["has_firebase"],
 | 
				
			||||||
        hasIndependent: pushNotificationsPolicy["has_independent"],
 | 
					          hasIndependent: pushNotificationsPolicy["has_independent"],
 | 
				
			||||||
      ),
 | 
					        ),
 | 
				
			||||||
      passwordPolicy: PasswordPolicy(
 | 
					        passwordPolicy: PasswordPolicy(
 | 
				
			||||||
        allowMailInPassword: passwordPolicy["allow_email_in_password"],
 | 
					          allowMailInPassword: passwordPolicy["allow_email_in_password"],
 | 
				
			||||||
        allowNameInPassword: passwordPolicy["allow_name_in_password"],
 | 
					          allowNameInPassword: passwordPolicy["allow_name_in_password"],
 | 
				
			||||||
        minPasswordLength: passwordPolicy["min_password_length"],
 | 
					          minPasswordLength: passwordPolicy["min_password_length"],
 | 
				
			||||||
        minNumberUpperCaseLetters:
 | 
					          minNumberUpperCaseLetters:
 | 
				
			||||||
            passwordPolicy["min_number_upper_case_letters"],
 | 
					              passwordPolicy["min_number_upper_case_letters"],
 | 
				
			||||||
        minNumberLowerCaseLetters:
 | 
					          minNumberLowerCaseLetters:
 | 
				
			||||||
            passwordPolicy["min_number_lower_case_letters"],
 | 
					              passwordPolicy["min_number_lower_case_letters"],
 | 
				
			||||||
        minNumberDigits: passwordPolicy["min_number_digits"],
 | 
					          minNumberDigits: passwordPolicy["min_number_digits"],
 | 
				
			||||||
        minNumberSpecialCharacters:
 | 
					          minNumberSpecialCharacters:
 | 
				
			||||||
            passwordPolicy["min_number_special_characters"],
 | 
					              passwordPolicy["min_number_special_characters"],
 | 
				
			||||||
        minCategoriesPresence: passwordPolicy["min_categories_presence"],
 | 
					          minCategoriesPresence: passwordPolicy["min_categories_presence"],
 | 
				
			||||||
      ),
 | 
					        ),
 | 
				
			||||||
      dataConservationPolicy: ServerDataConservationPolicy(
 | 
					        dataConservationPolicy: ServerDataConservationPolicy(
 | 
				
			||||||
        minInactiveAccountLifetime:
 | 
					          minInactiveAccountLifetime:
 | 
				
			||||||
            dataConservationPolicy["min_inactive_account_lifetime"],
 | 
					              dataConservationPolicy["min_inactive_account_lifetime"],
 | 
				
			||||||
        minNotificationLifetime:
 | 
					          minNotificationLifetime:
 | 
				
			||||||
            dataConservationPolicy["min_notification_lifetime"],
 | 
					              dataConservationPolicy["min_notification_lifetime"],
 | 
				
			||||||
        minCommentsLifetime: dataConservationPolicy["min_comments_lifetime"],
 | 
					          minCommentsLifetime: dataConservationPolicy["min_comments_lifetime"],
 | 
				
			||||||
        minPostsLifetime: dataConservationPolicy["min_posts_lifetime"],
 | 
					          minPostsLifetime: dataConservationPolicy["min_posts_lifetime"],
 | 
				
			||||||
        minConversationMessagesLifetime:
 | 
					          minConversationMessagesLifetime:
 | 
				
			||||||
            dataConservationPolicy["min_conversation_messages_lifetime"],
 | 
					              dataConservationPolicy["min_conversation_messages_lifetime"],
 | 
				
			||||||
        minLikesLifetime: dataConservationPolicy["min_likes_lifetime"],
 | 
					          minLikesLifetime: dataConservationPolicy["min_likes_lifetime"],
 | 
				
			||||||
      ),
 | 
					        ),
 | 
				
			||||||
      conversationsPolicy: ConversationsPolicy(
 | 
					        conversationsPolicy: ConversationsPolicy(
 | 
				
			||||||
        maxConversationNameLen:
 | 
					          maxConversationNameLen:
 | 
				
			||||||
            conversationsPolicy["max_conversation_name_len"],
 | 
					              conversationsPolicy["max_conversation_name_len"],
 | 
				
			||||||
        minMessageLen: conversationsPolicy["min_message_len"],
 | 
					          minMessageLen: conversationsPolicy["min_message_len"],
 | 
				
			||||||
        maxMessageLen: conversationsPolicy["max_message_len"],
 | 
					          maxMessageLen: conversationsPolicy["max_message_len"],
 | 
				
			||||||
        allowedFilesType:
 | 
					          allowedFilesType:
 | 
				
			||||||
            conversationsPolicy["allowed_files_type"].cast<String>(),
 | 
					              conversationsPolicy["allowed_files_type"].cast<String>(),
 | 
				
			||||||
        filesMaxSize: conversationsPolicy["files_max_size"],
 | 
					          filesMaxSize: conversationsPolicy["files_max_size"],
 | 
				
			||||||
        writingEventInterval: conversationsPolicy["writing_event_interval"],
 | 
					          writingEventInterval: conversationsPolicy["writing_event_interval"],
 | 
				
			||||||
        writingEventLifetime: conversationsPolicy["writing_event_lifetime"],
 | 
					          writingEventLifetime: conversationsPolicy["writing_event_lifetime"],
 | 
				
			||||||
        maxMessageImageWidth: conversationsPolicy["max_message_image_width"],
 | 
					          maxMessageImageWidth: conversationsPolicy["max_message_image_width"],
 | 
				
			||||||
        maxMessageImageHeight: conversationsPolicy["max_message_image_height"],
 | 
					          maxMessageImageHeight:
 | 
				
			||||||
        maxThumbnailWidth: conversationsPolicy["max_thumbnail_width"],
 | 
					              conversationsPolicy["max_message_image_height"],
 | 
				
			||||||
        maxThumbnailHeight: conversationsPolicy["max_thumbnail_height"],
 | 
					          maxThumbnailWidth: conversationsPolicy["max_thumbnail_width"],
 | 
				
			||||||
        maxLogoWidth: conversationsPolicy["max_logo_width"],
 | 
					          maxThumbnailHeight: conversationsPolicy["max_thumbnail_height"],
 | 
				
			||||||
        maxLogoHeight: conversationsPolicy["max_logo_height"],
 | 
					          maxLogoWidth: conversationsPolicy["max_logo_width"],
 | 
				
			||||||
      ),
 | 
					          maxLogoHeight: conversationsPolicy["max_logo_height"],
 | 
				
			||||||
      accountInformationPolicy: AccountInformationPolicy(
 | 
					        ),
 | 
				
			||||||
        minFirstNameLength: accountInformationPolicy["min_first_name_length"],
 | 
					        accountInformationPolicy: AccountInformationPolicy(
 | 
				
			||||||
        maxFirstNameLength: accountInformationPolicy["max_first_name_length"],
 | 
					          minFirstNameLength: accountInformationPolicy["min_first_name_length"],
 | 
				
			||||||
        minLastNameLength: accountInformationPolicy["min_last_name_length"],
 | 
					          maxFirstNameLength: accountInformationPolicy["max_first_name_length"],
 | 
				
			||||||
        maxLastNameLength: accountInformationPolicy["max_last_name_length"],
 | 
					          minLastNameLength: accountInformationPolicy["min_last_name_length"],
 | 
				
			||||||
        maxLocationLength: accountInformationPolicy["max_location_length"],
 | 
					          maxLastNameLength: accountInformationPolicy["max_last_name_length"],
 | 
				
			||||||
      ),
 | 
					          maxLocationLength: accountInformationPolicy["max_location_length"],
 | 
				
			||||||
    );
 | 
					        ),
 | 
				
			||||||
 | 
					        reportPolicy: reportPolicy == null
 | 
				
			||||||
 | 
					            ? null
 | 
				
			||||||
 | 
					            : ReportPolicy(
 | 
				
			||||||
 | 
					                causes: List.from(reportPolicy["causes"]
 | 
				
			||||||
 | 
					                    .map((cause) => ReportCause(
 | 
				
			||||||
 | 
					                        id: cause["id"],
 | 
				
			||||||
 | 
					                        label: new Map<String, String>.from(cause["label"])))
 | 
				
			||||||
 | 
					                    .toList()),
 | 
				
			||||||
 | 
					                maxCommentLength: reportPolicy["max_comment_length"],
 | 
				
			||||||
 | 
					              ));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Get current server configuration, throwing if it is not loaded yet
 | 
					  /// Get current server configuration, throwing if it is not loaded yet
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								lib/models/report_target.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								lib/models/report_target.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/enums/report_target_type.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ReportTarget {
 | 
				
			||||||
 | 
					  final ReportTargetType type;
 | 
				
			||||||
 | 
					  final int targetId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const ReportTarget(this.type, this.targetId);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
import 'package:comunic/utils/date_utils.dart';
 | 
					import 'package:comunic/utils/date_utils.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/utils/intl_utils.dart';
 | 
				
			||||||
import 'package:version/version.dart';
 | 
					import 'package:version/version.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Server static configuration
 | 
					/// Server static configuration
 | 
				
			||||||
@@ -137,6 +138,23 @@ class Banner {
 | 
				
			|||||||
  bool get visible => enabled && (expire == null || expire! > time());
 | 
					  bool get visible => enabled && (expire == null || expire! > time());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ReportCause {
 | 
				
			||||||
 | 
					  final String id;
 | 
				
			||||||
 | 
					  final Map<String, String> label;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const ReportCause({required this.id, required this.label});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String get localeLabel =>
 | 
				
			||||||
 | 
					      label.containsKey(shortLang) ? label[shortLang]! : label["en"]!;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ReportPolicy {
 | 
				
			||||||
 | 
					  final List<ReportCause> causes;
 | 
				
			||||||
 | 
					  final int maxCommentLength;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const ReportPolicy({required this.causes, required this.maxCommentLength});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ServerConfig {
 | 
					class ServerConfig {
 | 
				
			||||||
  final Version minSupportedMobileVersion;
 | 
					  final Version minSupportedMobileVersion;
 | 
				
			||||||
  final String termsURL;
 | 
					  final String termsURL;
 | 
				
			||||||
@@ -150,6 +168,7 @@ class ServerConfig {
 | 
				
			|||||||
  final ServerDataConservationPolicy dataConservationPolicy;
 | 
					  final ServerDataConservationPolicy dataConservationPolicy;
 | 
				
			||||||
  final ConversationsPolicy conversationsPolicy;
 | 
					  final ConversationsPolicy conversationsPolicy;
 | 
				
			||||||
  final AccountInformationPolicy accountInformationPolicy;
 | 
					  final AccountInformationPolicy accountInformationPolicy;
 | 
				
			||||||
 | 
					  final ReportPolicy? reportPolicy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const ServerConfig({
 | 
					  const ServerConfig({
 | 
				
			||||||
    required this.minSupportedMobileVersion,
 | 
					    required this.minSupportedMobileVersion,
 | 
				
			||||||
@@ -164,5 +183,8 @@ class ServerConfig {
 | 
				
			|||||||
    required this.dataConservationPolicy,
 | 
					    required this.dataConservationPolicy,
 | 
				
			||||||
    required this.conversationsPolicy,
 | 
					    required this.conversationsPolicy,
 | 
				
			||||||
    required this.accountInformationPolicy,
 | 
					    required this.accountInformationPolicy,
 | 
				
			||||||
 | 
					    required this.reportPolicy,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool get isReportingEnabled => this.reportPolicy != null;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										80
									
								
								lib/ui/dialogs/report_dialog.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								lib/ui/dialogs/report_dialog.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/helpers/server_config_helper.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/models/report_target.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/models/server_config.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/ui/widgets/dialogs/cancel_dialog_button.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/utils/intl_utils.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum _Status { ChooseCause, GiveComment, Sending }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Show a dialog to report some content
 | 
				
			||||||
 | 
					Future<void> showReportDialog({
 | 
				
			||||||
 | 
					  required BuildContext ctx,
 | 
				
			||||||
 | 
					  required ReportTarget target,
 | 
				
			||||||
 | 
					}) async {
 | 
				
			||||||
 | 
					  await showDialog(
 | 
				
			||||||
 | 
					      context: ctx,
 | 
				
			||||||
 | 
					      builder: (ctx) => _ReportDialog(
 | 
				
			||||||
 | 
					            target: target,
 | 
				
			||||||
 | 
					          ));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _ReportDialog extends StatefulWidget {
 | 
				
			||||||
 | 
					  final ReportTarget target;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const _ReportDialog({Key? key, required this.target}) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  State<_ReportDialog> createState() => _ReportDialogState();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _ReportDialogState extends State<_ReportDialog> {
 | 
				
			||||||
 | 
					  var _cause = srvConfig!.reportPolicy!.causes.length - 1;
 | 
				
			||||||
 | 
					  var _status = _Status.ChooseCause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  List<ReportCause> get _causes => srvConfig!.reportPolicy!.causes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return AlertDialog(
 | 
				
			||||||
 | 
					      title: Text(tr("Report abuse")!),
 | 
				
			||||||
 | 
					      content: Container(width: 100, height: 200, child: _buildContent()),
 | 
				
			||||||
 | 
					      actions: _status == _Status.Sending
 | 
				
			||||||
 | 
					          ? []
 | 
				
			||||||
 | 
					          : [
 | 
				
			||||||
 | 
					              CancelDialogButton(),
 | 
				
			||||||
 | 
					              MaterialButton(
 | 
				
			||||||
 | 
					                onPressed: null,
 | 
				
			||||||
 | 
					                child: Text(
 | 
				
			||||||
 | 
					                    (_status == _Status.ChooseCause ? tr("Next")! : tr("Send")!)
 | 
				
			||||||
 | 
					                        .toUpperCase()),
 | 
				
			||||||
 | 
					              )
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Widget _buildContent() {
 | 
				
			||||||
 | 
					    if (_status == _Status.Sending)
 | 
				
			||||||
 | 
					      return Center(child: CircularProgressIndicator());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_status == _Status.ChooseCause)
 | 
				
			||||||
 | 
					      return Column(
 | 
				
			||||||
 | 
					        children: [
 | 
				
			||||||
 | 
					          Text(tr("Please choose the reason of your report (you can scroll to access all reasons):")!),
 | 
				
			||||||
 | 
					          Expanded(
 | 
				
			||||||
 | 
					            child: ListView.builder(
 | 
				
			||||||
 | 
					              itemBuilder: (c, i) => RadioListTile(
 | 
				
			||||||
 | 
					                  dense: false,
 | 
				
			||||||
 | 
					                  title: Text(_causes[i].localeLabel),
 | 
				
			||||||
 | 
					                  value: i,
 | 
				
			||||||
 | 
					                  groupValue: _cause,
 | 
				
			||||||
 | 
					                  onChanged: (_i) => setState(() => _cause = i)),
 | 
				
			||||||
 | 
					              itemCount: _causes.length,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    throw Exception("todo");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,10 +1,13 @@
 | 
				
			|||||||
import 'dart:math';
 | 
					import 'dart:math';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'package:comunic/enums/report_target_type.dart';
 | 
				
			||||||
import 'package:comunic/helpers/friends_helper.dart';
 | 
					import 'package:comunic/helpers/friends_helper.dart';
 | 
				
			||||||
import 'package:comunic/helpers/users_helper.dart';
 | 
					import 'package:comunic/helpers/users_helper.dart';
 | 
				
			||||||
import 'package:comunic/lists/friends_list.dart';
 | 
					import 'package:comunic/lists/friends_list.dart';
 | 
				
			||||||
import 'package:comunic/lists/users_list.dart';
 | 
					import 'package:comunic/lists/users_list.dart';
 | 
				
			||||||
import 'package:comunic/models/friend.dart';
 | 
					import 'package:comunic/models/friend.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/models/report_target.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/ui/dialogs/report_dialog.dart';
 | 
				
			||||||
import 'package:comunic/ui/tiles/accepted_friend_tile.dart';
 | 
					import 'package:comunic/ui/tiles/accepted_friend_tile.dart';
 | 
				
			||||||
import 'package:comunic/ui/tiles/pending_friend_tile.dart';
 | 
					import 'package:comunic/ui/tiles/pending_friend_tile.dart';
 | 
				
			||||||
import 'package:comunic/ui/widgets/safe_state.dart';
 | 
					import 'package:comunic/ui/widgets/safe_state.dart';
 | 
				
			||||||
@@ -151,11 +154,13 @@ class _FriendsListScreenState extends SafeState<FriendsListScreen> {
 | 
				
			|||||||
                          onOpenPrivateConversation: _openPrivateConversation,
 | 
					                          onOpenPrivateConversation: _openPrivateConversation,
 | 
				
			||||||
                          onSetFollowing: _setFollowingFriend,
 | 
					                          onSetFollowing: _setFollowingFriend,
 | 
				
			||||||
                          onRequestDelete: _deleteFriend,
 | 
					                          onRequestDelete: _deleteFriend,
 | 
				
			||||||
 | 
					                          onReportFriend: _reportFriend,
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
                      : PendingFriendTile(
 | 
					                      : PendingFriendTile(
 | 
				
			||||||
                          friend: _friendsList![i],
 | 
					                          friend: _friendsList![i],
 | 
				
			||||||
                          user: _usersInfo.getUser(_friendsList![i].id),
 | 
					                          user: _usersInfo.getUser(_friendsList![i].id),
 | 
				
			||||||
                          onRespond: _respondRequest,
 | 
					                          onRespond: _respondRequest,
 | 
				
			||||||
 | 
					                          onReport: _reportFriend,
 | 
				
			||||||
                        );
 | 
					                        );
 | 
				
			||||||
                }),
 | 
					                }),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
@@ -216,6 +221,10 @@ class _FriendsListScreenState extends SafeState<FriendsListScreen> {
 | 
				
			|||||||
    _refreshList();
 | 
					    _refreshList();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Report a friend
 | 
				
			||||||
 | 
					  Future<void> _reportFriend(Friend friend) async => await showReportDialog(
 | 
				
			||||||
 | 
					      ctx: context, target: ReportTarget(ReportTargetType.User, friend.id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Open a private conversation for a given [friend]
 | 
					  /// Open a private conversation for a given [friend]
 | 
				
			||||||
  Future<void> _openPrivateConversation(Friend friend) async {
 | 
					  Future<void> _openPrivateConversation(Friend friend) async {
 | 
				
			||||||
    await openPrivateConversation(context, friend.id);
 | 
					    await openPrivateConversation(context, friend.id);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/helpers/server_config_helper.dart';
 | 
				
			||||||
import 'package:comunic/models/friend.dart';
 | 
					import 'package:comunic/models/friend.dart';
 | 
				
			||||||
import 'package:comunic/models/user.dart';
 | 
					import 'package:comunic/models/user.dart';
 | 
				
			||||||
import 'package:comunic/ui/widgets/account_image_widget.dart';
 | 
					import 'package:comunic/ui/widgets/account_image_widget.dart';
 | 
				
			||||||
@@ -10,11 +11,17 @@ import 'package:flutter/material.dart';
 | 
				
			|||||||
///
 | 
					///
 | 
				
			||||||
/// @author Pierre HUBERT
 | 
					/// @author Pierre HUBERT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum _FriendMenuChoices { REMOVE, TOGGLE_FOLLOWING, PRIVATE_CONVERSATION }
 | 
					enum _FriendMenuChoices {
 | 
				
			||||||
 | 
					  REMOVE,
 | 
				
			||||||
 | 
					  TOGGLE_FOLLOWING,
 | 
				
			||||||
 | 
					  PRIVATE_CONVERSATION,
 | 
				
			||||||
 | 
					  REPORT
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef OnRequestDeleteFriend = void Function(Friend);
 | 
					typedef OnRequestDeleteFriend = void Function(Friend);
 | 
				
			||||||
typedef OnSetFollowing = void Function(Friend, bool);
 | 
					typedef OnSetFollowing = void Function(Friend, bool);
 | 
				
			||||||
typedef OnOpenPrivateConversation = void Function(Friend);
 | 
					typedef OnOpenPrivateConversation = void Function(Friend);
 | 
				
			||||||
 | 
					typedef OnReportFriend = void Function(Friend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AcceptedFriendTile extends StatelessWidget {
 | 
					class AcceptedFriendTile extends StatelessWidget {
 | 
				
			||||||
  final Friend friend;
 | 
					  final Friend friend;
 | 
				
			||||||
@@ -22,6 +29,7 @@ class AcceptedFriendTile extends StatelessWidget {
 | 
				
			|||||||
  final OnRequestDeleteFriend onRequestDelete;
 | 
					  final OnRequestDeleteFriend onRequestDelete;
 | 
				
			||||||
  final OnSetFollowing onSetFollowing;
 | 
					  final OnSetFollowing onSetFollowing;
 | 
				
			||||||
  final OnOpenPrivateConversation onOpenPrivateConversation;
 | 
					  final OnOpenPrivateConversation onOpenPrivateConversation;
 | 
				
			||||||
 | 
					  final OnReportFriend onReportFriend;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const AcceptedFriendTile({
 | 
					  const AcceptedFriendTile({
 | 
				
			||||||
    Key? key,
 | 
					    Key? key,
 | 
				
			||||||
@@ -30,6 +38,7 @@ class AcceptedFriendTile extends StatelessWidget {
 | 
				
			|||||||
    required this.onRequestDelete,
 | 
					    required this.onRequestDelete,
 | 
				
			||||||
    required this.onSetFollowing,
 | 
					    required this.onSetFollowing,
 | 
				
			||||||
    required this.onOpenPrivateConversation,
 | 
					    required this.onOpenPrivateConversation,
 | 
				
			||||||
 | 
					    required this.onReportFriend,
 | 
				
			||||||
  }) : super(key: key);
 | 
					  }) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
@@ -75,7 +84,15 @@ class AcceptedFriendTile extends StatelessWidget {
 | 
				
			|||||||
            child: Text(tr("Remove")!),
 | 
					            child: Text(tr("Remove")!),
 | 
				
			||||||
            value: _FriendMenuChoices.REMOVE,
 | 
					            value: _FriendMenuChoices.REMOVE,
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
        ],
 | 
					        ]..addAll(srvConfig!.isReportingEnabled
 | 
				
			||||||
 | 
					            ? [
 | 
				
			||||||
 | 
					                // Report user
 | 
				
			||||||
 | 
					                PopupMenuItem(
 | 
				
			||||||
 | 
					                  child: Text(tr("Report abuse")!),
 | 
				
			||||||
 | 
					                  value: _FriendMenuChoices.REPORT,
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					              ]
 | 
				
			||||||
 | 
					            : []),
 | 
				
			||||||
        onSelected: _selectedMenuOption,
 | 
					        onSelected: _selectedMenuOption,
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
@@ -97,6 +114,10 @@ class AcceptedFriendTile extends StatelessWidget {
 | 
				
			|||||||
      case _FriendMenuChoices.REMOVE:
 | 
					      case _FriendMenuChoices.REMOVE:
 | 
				
			||||||
        onRequestDelete(friend);
 | 
					        onRequestDelete(friend);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      case _FriendMenuChoices.REPORT:
 | 
				
			||||||
 | 
					        onReportFriend(friend);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/helpers/server_config_helper.dart';
 | 
				
			||||||
import 'package:comunic/models/friend.dart';
 | 
					import 'package:comunic/models/friend.dart';
 | 
				
			||||||
import 'package:comunic/models/user.dart';
 | 
					import 'package:comunic/models/user.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/ui/tiles/accepted_friend_tile.dart';
 | 
				
			||||||
import 'package:comunic/ui/widgets/account_image_widget.dart';
 | 
					import 'package:comunic/ui/widgets/account_image_widget.dart';
 | 
				
			||||||
import 'package:comunic/utils/intl_utils.dart';
 | 
					import 'package:comunic/utils/intl_utils.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
@@ -14,13 +16,15 @@ class PendingFriendTile extends StatelessWidget {
 | 
				
			|||||||
  final Friend friend;
 | 
					  final Friend friend;
 | 
				
			||||||
  final User user;
 | 
					  final User user;
 | 
				
			||||||
  final RespondFriendshipRequestCallback onRespond;
 | 
					  final RespondFriendshipRequestCallback onRespond;
 | 
				
			||||||
 | 
					  final OnReportFriend onReport;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const PendingFriendTile(
 | 
					  const PendingFriendTile({
 | 
				
			||||||
      {Key? key,
 | 
					    Key? key,
 | 
				
			||||||
      required this.friend,
 | 
					    required this.friend,
 | 
				
			||||||
      required this.user,
 | 
					    required this.user,
 | 
				
			||||||
      required this.onRespond})
 | 
					    required this.onRespond,
 | 
				
			||||||
      : super(key: key);
 | 
					    required this.onReport,
 | 
				
			||||||
 | 
					  }) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
@@ -56,7 +60,19 @@ class PendingFriendTile extends StatelessWidget {
 | 
				
			|||||||
              style: ButtonStyle(
 | 
					              style: ButtonStyle(
 | 
				
			||||||
                  backgroundColor: MaterialStateProperty.all(Colors.red)),
 | 
					                  backgroundColor: MaterialStateProperty.all(Colors.red)),
 | 
				
			||||||
              onPressed: () => onRespond(friend, false),
 | 
					              onPressed: () => onRespond(friend, false),
 | 
				
			||||||
            )
 | 
					            ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Report button
 | 
				
			||||||
 | 
					            srvConfig!.isReportingEnabled
 | 
				
			||||||
 | 
					                ? IconButton(
 | 
				
			||||||
 | 
					                    visualDensity: VisualDensity.compact,
 | 
				
			||||||
 | 
					                    onPressed: () => onReport(friend),
 | 
				
			||||||
 | 
					                    icon: Icon(
 | 
				
			||||||
 | 
					                      Icons.flag,
 | 
				
			||||||
 | 
					                      size: 15.0,
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                  )
 | 
				
			||||||
 | 
					                : Container()
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user