mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-11-04 04:04:18 +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 conversationsPolicy = response["conversations_policy"];
 | 
			
		||||
    final accountInformationPolicy = response["account_info_policy"];
 | 
			
		||||
    final reportPolicy = response["report_policy"];
 | 
			
		||||
 | 
			
		||||
    _config = ServerConfig(
 | 
			
		||||
      minSupportedMobileVersion:
 | 
			
		||||
          Version.parse(response["min_supported_mobile_version"]),
 | 
			
		||||
      termsURL: response["terms_url"],
 | 
			
		||||
      privacyPolicyURL: response["privacy_policy_url"],
 | 
			
		||||
      contactEmail: response["contact_email"],
 | 
			
		||||
      playStoreURL: response["play_store_url"],
 | 
			
		||||
      androidDirectDownloadURL: response["android_direct_download_url"],
 | 
			
		||||
      banner: banner == null
 | 
			
		||||
          ? null
 | 
			
		||||
          : Banner(
 | 
			
		||||
              enabled: banner["enabled"],
 | 
			
		||||
              expire: banner["expire"],
 | 
			
		||||
              nature: BannerNatureExt.fromStr(banner["nature"]),
 | 
			
		||||
              message: Map<String, dynamic>.from(banner["message"])
 | 
			
		||||
                  .map((key, value) => MapEntry(key, value.toString())),
 | 
			
		||||
              link: banner["link"]),
 | 
			
		||||
      notificationsPolicy: NotificationsPolicy(
 | 
			
		||||
        hasFirebase: pushNotificationsPolicy["has_firebase"],
 | 
			
		||||
        hasIndependent: pushNotificationsPolicy["has_independent"],
 | 
			
		||||
      ),
 | 
			
		||||
      passwordPolicy: PasswordPolicy(
 | 
			
		||||
        allowMailInPassword: passwordPolicy["allow_email_in_password"],
 | 
			
		||||
        allowNameInPassword: passwordPolicy["allow_name_in_password"],
 | 
			
		||||
        minPasswordLength: passwordPolicy["min_password_length"],
 | 
			
		||||
        minNumberUpperCaseLetters:
 | 
			
		||||
            passwordPolicy["min_number_upper_case_letters"],
 | 
			
		||||
        minNumberLowerCaseLetters:
 | 
			
		||||
            passwordPolicy["min_number_lower_case_letters"],
 | 
			
		||||
        minNumberDigits: passwordPolicy["min_number_digits"],
 | 
			
		||||
        minNumberSpecialCharacters:
 | 
			
		||||
            passwordPolicy["min_number_special_characters"],
 | 
			
		||||
        minCategoriesPresence: passwordPolicy["min_categories_presence"],
 | 
			
		||||
      ),
 | 
			
		||||
      dataConservationPolicy: ServerDataConservationPolicy(
 | 
			
		||||
        minInactiveAccountLifetime:
 | 
			
		||||
            dataConservationPolicy["min_inactive_account_lifetime"],
 | 
			
		||||
        minNotificationLifetime:
 | 
			
		||||
            dataConservationPolicy["min_notification_lifetime"],
 | 
			
		||||
        minCommentsLifetime: dataConservationPolicy["min_comments_lifetime"],
 | 
			
		||||
        minPostsLifetime: dataConservationPolicy["min_posts_lifetime"],
 | 
			
		||||
        minConversationMessagesLifetime:
 | 
			
		||||
            dataConservationPolicy["min_conversation_messages_lifetime"],
 | 
			
		||||
        minLikesLifetime: dataConservationPolicy["min_likes_lifetime"],
 | 
			
		||||
      ),
 | 
			
		||||
      conversationsPolicy: ConversationsPolicy(
 | 
			
		||||
        maxConversationNameLen:
 | 
			
		||||
            conversationsPolicy["max_conversation_name_len"],
 | 
			
		||||
        minMessageLen: conversationsPolicy["min_message_len"],
 | 
			
		||||
        maxMessageLen: conversationsPolicy["max_message_len"],
 | 
			
		||||
        allowedFilesType:
 | 
			
		||||
            conversationsPolicy["allowed_files_type"].cast<String>(),
 | 
			
		||||
        filesMaxSize: conversationsPolicy["files_max_size"],
 | 
			
		||||
        writingEventInterval: conversationsPolicy["writing_event_interval"],
 | 
			
		||||
        writingEventLifetime: conversationsPolicy["writing_event_lifetime"],
 | 
			
		||||
        maxMessageImageWidth: conversationsPolicy["max_message_image_width"],
 | 
			
		||||
        maxMessageImageHeight: conversationsPolicy["max_message_image_height"],
 | 
			
		||||
        maxThumbnailWidth: conversationsPolicy["max_thumbnail_width"],
 | 
			
		||||
        maxThumbnailHeight: conversationsPolicy["max_thumbnail_height"],
 | 
			
		||||
        maxLogoWidth: conversationsPolicy["max_logo_width"],
 | 
			
		||||
        maxLogoHeight: conversationsPolicy["max_logo_height"],
 | 
			
		||||
      ),
 | 
			
		||||
      accountInformationPolicy: AccountInformationPolicy(
 | 
			
		||||
        minFirstNameLength: accountInformationPolicy["min_first_name_length"],
 | 
			
		||||
        maxFirstNameLength: accountInformationPolicy["max_first_name_length"],
 | 
			
		||||
        minLastNameLength: accountInformationPolicy["min_last_name_length"],
 | 
			
		||||
        maxLastNameLength: accountInformationPolicy["max_last_name_length"],
 | 
			
		||||
        maxLocationLength: accountInformationPolicy["max_location_length"],
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
        minSupportedMobileVersion:
 | 
			
		||||
            Version.parse(response["min_supported_mobile_version"]),
 | 
			
		||||
        termsURL: response["terms_url"],
 | 
			
		||||
        privacyPolicyURL: response["privacy_policy_url"],
 | 
			
		||||
        contactEmail: response["contact_email"],
 | 
			
		||||
        playStoreURL: response["play_store_url"],
 | 
			
		||||
        androidDirectDownloadURL: response["android_direct_download_url"],
 | 
			
		||||
        banner: banner == null
 | 
			
		||||
            ? null
 | 
			
		||||
            : Banner(
 | 
			
		||||
                enabled: banner["enabled"],
 | 
			
		||||
                expire: banner["expire"],
 | 
			
		||||
                nature: BannerNatureExt.fromStr(banner["nature"]),
 | 
			
		||||
                message: Map<String, dynamic>.from(banner["message"])
 | 
			
		||||
                    .map((key, value) => MapEntry(key, value.toString())),
 | 
			
		||||
                link: banner["link"]),
 | 
			
		||||
        notificationsPolicy: NotificationsPolicy(
 | 
			
		||||
          hasFirebase: pushNotificationsPolicy["has_firebase"],
 | 
			
		||||
          hasIndependent: pushNotificationsPolicy["has_independent"],
 | 
			
		||||
        ),
 | 
			
		||||
        passwordPolicy: PasswordPolicy(
 | 
			
		||||
          allowMailInPassword: passwordPolicy["allow_email_in_password"],
 | 
			
		||||
          allowNameInPassword: passwordPolicy["allow_name_in_password"],
 | 
			
		||||
          minPasswordLength: passwordPolicy["min_password_length"],
 | 
			
		||||
          minNumberUpperCaseLetters:
 | 
			
		||||
              passwordPolicy["min_number_upper_case_letters"],
 | 
			
		||||
          minNumberLowerCaseLetters:
 | 
			
		||||
              passwordPolicy["min_number_lower_case_letters"],
 | 
			
		||||
          minNumberDigits: passwordPolicy["min_number_digits"],
 | 
			
		||||
          minNumberSpecialCharacters:
 | 
			
		||||
              passwordPolicy["min_number_special_characters"],
 | 
			
		||||
          minCategoriesPresence: passwordPolicy["min_categories_presence"],
 | 
			
		||||
        ),
 | 
			
		||||
        dataConservationPolicy: ServerDataConservationPolicy(
 | 
			
		||||
          minInactiveAccountLifetime:
 | 
			
		||||
              dataConservationPolicy["min_inactive_account_lifetime"],
 | 
			
		||||
          minNotificationLifetime:
 | 
			
		||||
              dataConservationPolicy["min_notification_lifetime"],
 | 
			
		||||
          minCommentsLifetime: dataConservationPolicy["min_comments_lifetime"],
 | 
			
		||||
          minPostsLifetime: dataConservationPolicy["min_posts_lifetime"],
 | 
			
		||||
          minConversationMessagesLifetime:
 | 
			
		||||
              dataConservationPolicy["min_conversation_messages_lifetime"],
 | 
			
		||||
          minLikesLifetime: dataConservationPolicy["min_likes_lifetime"],
 | 
			
		||||
        ),
 | 
			
		||||
        conversationsPolicy: ConversationsPolicy(
 | 
			
		||||
          maxConversationNameLen:
 | 
			
		||||
              conversationsPolicy["max_conversation_name_len"],
 | 
			
		||||
          minMessageLen: conversationsPolicy["min_message_len"],
 | 
			
		||||
          maxMessageLen: conversationsPolicy["max_message_len"],
 | 
			
		||||
          allowedFilesType:
 | 
			
		||||
              conversationsPolicy["allowed_files_type"].cast<String>(),
 | 
			
		||||
          filesMaxSize: conversationsPolicy["files_max_size"],
 | 
			
		||||
          writingEventInterval: conversationsPolicy["writing_event_interval"],
 | 
			
		||||
          writingEventLifetime: conversationsPolicy["writing_event_lifetime"],
 | 
			
		||||
          maxMessageImageWidth: conversationsPolicy["max_message_image_width"],
 | 
			
		||||
          maxMessageImageHeight:
 | 
			
		||||
              conversationsPolicy["max_message_image_height"],
 | 
			
		||||
          maxThumbnailWidth: conversationsPolicy["max_thumbnail_width"],
 | 
			
		||||
          maxThumbnailHeight: conversationsPolicy["max_thumbnail_height"],
 | 
			
		||||
          maxLogoWidth: conversationsPolicy["max_logo_width"],
 | 
			
		||||
          maxLogoHeight: conversationsPolicy["max_logo_height"],
 | 
			
		||||
        ),
 | 
			
		||||
        accountInformationPolicy: AccountInformationPolicy(
 | 
			
		||||
          minFirstNameLength: accountInformationPolicy["min_first_name_length"],
 | 
			
		||||
          maxFirstNameLength: accountInformationPolicy["max_first_name_length"],
 | 
			
		||||
          minLastNameLength: accountInformationPolicy["min_last_name_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
 | 
			
		||||
@@ -109,4 +120,4 @@ class ServerConfigurationHelper {
 | 
			
		||||
/// Shortcut for server configuration
 | 
			
		||||
ServerConfig? get srvConfig => ServerConfigurationHelper.config;
 | 
			
		||||
 | 
			
		||||
bool get showBanner => srvConfig!.banner != null && srvConfig!.banner!.visible;
 | 
			
		||||
bool get showBanner => srvConfig!.banner != null && srvConfig!.banner!.visible;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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/intl_utils.dart';
 | 
			
		||||
import 'package:version/version.dart';
 | 
			
		||||
 | 
			
		||||
/// Server static configuration
 | 
			
		||||
@@ -137,6 +138,23 @@ class Banner {
 | 
			
		||||
  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 {
 | 
			
		||||
  final Version minSupportedMobileVersion;
 | 
			
		||||
  final String termsURL;
 | 
			
		||||
@@ -150,6 +168,7 @@ class ServerConfig {
 | 
			
		||||
  final ServerDataConservationPolicy dataConservationPolicy;
 | 
			
		||||
  final ConversationsPolicy conversationsPolicy;
 | 
			
		||||
  final AccountInformationPolicy accountInformationPolicy;
 | 
			
		||||
  final ReportPolicy? reportPolicy;
 | 
			
		||||
 | 
			
		||||
  const ServerConfig({
 | 
			
		||||
    required this.minSupportedMobileVersion,
 | 
			
		||||
@@ -164,5 +183,8 @@ class ServerConfig {
 | 
			
		||||
    required this.dataConservationPolicy,
 | 
			
		||||
    required this.conversationsPolicy,
 | 
			
		||||
    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 'package:comunic/enums/report_target_type.dart';
 | 
			
		||||
import 'package:comunic/helpers/friends_helper.dart';
 | 
			
		||||
import 'package:comunic/helpers/users_helper.dart';
 | 
			
		||||
import 'package:comunic/lists/friends_list.dart';
 | 
			
		||||
import 'package:comunic/lists/users_list.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/pending_friend_tile.dart';
 | 
			
		||||
import 'package:comunic/ui/widgets/safe_state.dart';
 | 
			
		||||
@@ -151,11 +154,13 @@ class _FriendsListScreenState extends SafeState<FriendsListScreen> {
 | 
			
		||||
                          onOpenPrivateConversation: _openPrivateConversation,
 | 
			
		||||
                          onSetFollowing: _setFollowingFriend,
 | 
			
		||||
                          onRequestDelete: _deleteFriend,
 | 
			
		||||
                          onReportFriend: _reportFriend,
 | 
			
		||||
                        )
 | 
			
		||||
                      : PendingFriendTile(
 | 
			
		||||
                          friend: _friendsList![i],
 | 
			
		||||
                          user: _usersInfo.getUser(_friendsList![i].id),
 | 
			
		||||
                          onRespond: _respondRequest,
 | 
			
		||||
                          onReport: _reportFriend,
 | 
			
		||||
                        );
 | 
			
		||||
                }),
 | 
			
		||||
          ),
 | 
			
		||||
@@ -216,6 +221,10 @@ class _FriendsListScreenState extends SafeState<FriendsListScreen> {
 | 
			
		||||
    _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]
 | 
			
		||||
  Future<void> _openPrivateConversation(Friend friend) async {
 | 
			
		||||
    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/user.dart';
 | 
			
		||||
import 'package:comunic/ui/widgets/account_image_widget.dart';
 | 
			
		||||
@@ -10,11 +11,17 @@ import 'package:flutter/material.dart';
 | 
			
		||||
///
 | 
			
		||||
/// @author Pierre HUBERT
 | 
			
		||||
 | 
			
		||||
enum _FriendMenuChoices { REMOVE, TOGGLE_FOLLOWING, PRIVATE_CONVERSATION }
 | 
			
		||||
enum _FriendMenuChoices {
 | 
			
		||||
  REMOVE,
 | 
			
		||||
  TOGGLE_FOLLOWING,
 | 
			
		||||
  PRIVATE_CONVERSATION,
 | 
			
		||||
  REPORT
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef OnRequestDeleteFriend = void Function(Friend);
 | 
			
		||||
typedef OnSetFollowing = void Function(Friend, bool);
 | 
			
		||||
typedef OnOpenPrivateConversation = void Function(Friend);
 | 
			
		||||
typedef OnReportFriend = void Function(Friend);
 | 
			
		||||
 | 
			
		||||
class AcceptedFriendTile extends StatelessWidget {
 | 
			
		||||
  final Friend friend;
 | 
			
		||||
@@ -22,6 +29,7 @@ class AcceptedFriendTile extends StatelessWidget {
 | 
			
		||||
  final OnRequestDeleteFriend onRequestDelete;
 | 
			
		||||
  final OnSetFollowing onSetFollowing;
 | 
			
		||||
  final OnOpenPrivateConversation onOpenPrivateConversation;
 | 
			
		||||
  final OnReportFriend onReportFriend;
 | 
			
		||||
 | 
			
		||||
  const AcceptedFriendTile({
 | 
			
		||||
    Key? key,
 | 
			
		||||
@@ -30,6 +38,7 @@ class AcceptedFriendTile extends StatelessWidget {
 | 
			
		||||
    required this.onRequestDelete,
 | 
			
		||||
    required this.onSetFollowing,
 | 
			
		||||
    required this.onOpenPrivateConversation,
 | 
			
		||||
    required this.onReportFriend,
 | 
			
		||||
  }) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
@@ -75,7 +84,15 @@ class AcceptedFriendTile extends StatelessWidget {
 | 
			
		||||
            child: Text(tr("Remove")!),
 | 
			
		||||
            value: _FriendMenuChoices.REMOVE,
 | 
			
		||||
          ),
 | 
			
		||||
        ],
 | 
			
		||||
        ]..addAll(srvConfig!.isReportingEnabled
 | 
			
		||||
            ? [
 | 
			
		||||
                // Report user
 | 
			
		||||
                PopupMenuItem(
 | 
			
		||||
                  child: Text(tr("Report abuse")!),
 | 
			
		||||
                  value: _FriendMenuChoices.REPORT,
 | 
			
		||||
                ),
 | 
			
		||||
              ]
 | 
			
		||||
            : []),
 | 
			
		||||
        onSelected: _selectedMenuOption,
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
@@ -97,6 +114,10 @@ class AcceptedFriendTile extends StatelessWidget {
 | 
			
		||||
      case _FriendMenuChoices.REMOVE:
 | 
			
		||||
        onRequestDelete(friend);
 | 
			
		||||
        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/user.dart';
 | 
			
		||||
import 'package:comunic/ui/tiles/accepted_friend_tile.dart';
 | 
			
		||||
import 'package:comunic/ui/widgets/account_image_widget.dart';
 | 
			
		||||
import 'package:comunic/utils/intl_utils.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
@@ -14,13 +16,15 @@ class PendingFriendTile extends StatelessWidget {
 | 
			
		||||
  final Friend friend;
 | 
			
		||||
  final User user;
 | 
			
		||||
  final RespondFriendshipRequestCallback onRespond;
 | 
			
		||||
  final OnReportFriend onReport;
 | 
			
		||||
 | 
			
		||||
  const PendingFriendTile(
 | 
			
		||||
      {Key? key,
 | 
			
		||||
      required this.friend,
 | 
			
		||||
      required this.user,
 | 
			
		||||
      required this.onRespond})
 | 
			
		||||
      : super(key: key);
 | 
			
		||||
  const PendingFriendTile({
 | 
			
		||||
    Key? key,
 | 
			
		||||
    required this.friend,
 | 
			
		||||
    required this.user,
 | 
			
		||||
    required this.onRespond,
 | 
			
		||||
    required this.onReport,
 | 
			
		||||
  }) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
@@ -56,7 +60,19 @@ class PendingFriendTile extends StatelessWidget {
 | 
			
		||||
              style: ButtonStyle(
 | 
			
		||||
                  backgroundColor: MaterialStateProperty.all(Colors.red)),
 | 
			
		||||
              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