mirror of
				https://gitlab.com/famedly/fluffychat.git
				synced 2025-11-04 06:17:26 +01:00 
			
		
		
		
	refactor: Widget file structure and MVC user bottom sheet
This commit is contained in:
		
							parent
							
								
									69deae3dc1
								
							
						
					
					
						commit
						bd53745f35
					
				@ -14,7 +14,7 @@ import 'package:fluffychat/views/chat_encryption_settings.dart';
 | 
			
		||||
import 'package:fluffychat/views/chat_list.dart';
 | 
			
		||||
import 'package:fluffychat/views/chat_permissions_settings.dart';
 | 
			
		||||
import 'package:fluffychat/views/ui/empty_page_ui.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/loading_view.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/loading_view.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/log_view.dart';
 | 
			
		||||
import 'package:fluffychat/views/ui/login_ui.dart';
 | 
			
		||||
import 'package:fluffychat/views/new_group.dart';
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@ import 'package:famedlysdk/famedlysdk.dart';
 | 
			
		||||
import 'package:fluffychat/config/routes.dart';
 | 
			
		||||
import 'package:fluffychat/utils/platform_infos.dart';
 | 
			
		||||
import 'package:fluffychat/utils/sentry_controller.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/lock_screen.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/lock_screen.dart';
 | 
			
		||||
import 'package:flutter/cupertino.dart';
 | 
			
		||||
import 'package:flutter/foundation.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@ import 'package:famedlysdk/famedlysdk.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/views/widgets/chat_settings_popup_menu.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/content_banner.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/list_items/participant_list_item.dart';
 | 
			
		||||
import 'package:fluffychat/utils/matrix_locals.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@ import 'package:famedlysdk/famedlysdk.dart';
 | 
			
		||||
import 'package:fluffychat/views/chat_encryption_settings.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/avatar.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/matrix.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/max_width_body.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
import '../../utils/device_extension.dart';
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import 'package:fluffychat/views/chat_permissions_settings.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/list_items/permission_list_tile.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/matrix.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ import 'package:fluffychat/views/widgets/encryption_button.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/list_items/message.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/matrix.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/reply_content.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/user_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/views/user_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/config/app_emojis.dart';
 | 
			
		||||
import 'package:fluffychat/utils/matrix_locals.dart';
 | 
			
		||||
import 'package:fluffychat/utils/platform_infos.dart';
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import 'package:fluffychat/views/device_settings.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/max_width_body.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@ import '../homeserver_picker.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/default_app_bar_search_field.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/fluffy_banner.dart';
 | 
			
		||||
import 'package:fluffychat/config/app_config.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/one_page_card.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/one_page_card.dart';
 | 
			
		||||
import 'package:fluffychat/utils/platform_infos.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/foundation.dart';
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import 'package:fluffychat/views/widgets/default_app_bar_search_field.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:famedlysdk/famedlysdk.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/avatar.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/matrix.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import 'dart:async';
 | 
			
		||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
 | 
			
		||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
 | 
			
		||||
import 'package:famedlysdk/famedlysdk.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/one_page_card.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/one_page_card.dart';
 | 
			
		||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/matrix.dart';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import 'package:fluffychat/views/new_group.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/max_width_body.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@ import 'package:adaptive_page_layout/adaptive_page_layout.dart';
 | 
			
		||||
import 'package:fluffychat/views/new_private_chat.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/avatar.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/contacts_list.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/matrix.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import 'package:famedlysdk/famedlysdk.dart';
 | 
			
		||||
import 'package:fluffychat/views/settings_3pid.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/matrix.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import 'package:cached_network_image/cached_network_image.dart';
 | 
			
		||||
import 'package:famedlysdk/famedlysdk.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/max_width_body.dart';
 | 
			
		||||
import 'package:flutter/foundation.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import 'package:famedlysdk/famedlysdk.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/avatar.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/max_width_body.dart';
 | 
			
		||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import 'dart:io';
 | 
			
		||||
 | 
			
		||||
import 'package:famedlysdk/famedlysdk.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/max_width_body.dart';
 | 
			
		||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
 | 
			
		||||
import 'package:flutter/foundation.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import 'package:adaptive_theme/adaptive_theme.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/max_width_body.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import 'package:fluffychat/views/sign_up_password.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/views/widgets/one_page_card.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/one_page_card.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import 'package:fluffychat/views/sign_up.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/fluffy_banner.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/views/widgets/matrix.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/one_page_card.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/layouts/one_page_card.dart';
 | 
			
		||||
import 'package:flutter/cupertino.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										156
									
								
								lib/views/ui/user_bottom_sheet_ui.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								lib/views/ui/user_bottom_sheet_ui.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,156 @@
 | 
			
		||||
import 'dart:math';
 | 
			
		||||
 | 
			
		||||
import 'package:famedlysdk/famedlysdk.dart';
 | 
			
		||||
import 'package:fluffychat/config/themes.dart';
 | 
			
		||||
import 'package:fluffychat/utils/fluffy_share.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import '../widgets/content_banner.dart';
 | 
			
		||||
import '../user_bottom_sheet.dart';
 | 
			
		||||
import '../../utils/presence_extension.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
class UserBottomSheetUI extends StatelessWidget {
 | 
			
		||||
  final UserBottomSheetController controller;
 | 
			
		||||
 | 
			
		||||
  const UserBottomSheetUI(this.controller, {Key key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final user = controller.widget.user;
 | 
			
		||||
    final client = user.room.client;
 | 
			
		||||
    final presence = client.presences[user.id];
 | 
			
		||||
    return Center(
 | 
			
		||||
      child: Container(
 | 
			
		||||
        width: min(
 | 
			
		||||
            MediaQuery.of(context).size.width, FluffyThemes.columnWidth * 1.5),
 | 
			
		||||
        child: Material(
 | 
			
		||||
          elevation: 4,
 | 
			
		||||
          child: SafeArea(
 | 
			
		||||
            child: Scaffold(
 | 
			
		||||
              extendBodyBehindAppBar: true,
 | 
			
		||||
              appBar: AppBar(
 | 
			
		||||
                elevation: 0,
 | 
			
		||||
                backgroundColor:
 | 
			
		||||
                    Theme.of(context).scaffoldBackgroundColor.withOpacity(0.5),
 | 
			
		||||
                leading: IconButton(
 | 
			
		||||
                  icon: Icon(Icons.arrow_downward_outlined),
 | 
			
		||||
                  onPressed: Navigator.of(context, rootNavigator: false).pop,
 | 
			
		||||
                  tooltip: L10n.of(context).close,
 | 
			
		||||
                ),
 | 
			
		||||
                title: Text(user.calcDisplayname()),
 | 
			
		||||
                actions: [
 | 
			
		||||
                  if (user.id != user.room.client.userID)
 | 
			
		||||
                    PopupMenuButton(
 | 
			
		||||
                      itemBuilder: (_) => [
 | 
			
		||||
                        if (controller.widget.onMention != null)
 | 
			
		||||
                          PopupMenuItem(
 | 
			
		||||
                            value: 'mention',
 | 
			
		||||
                            child: _TextWithIcon(
 | 
			
		||||
                              L10n.of(context).mention,
 | 
			
		||||
                              Icons.alternate_email_outlined,
 | 
			
		||||
                            ),
 | 
			
		||||
                          ),
 | 
			
		||||
                        if (user.id != user.room.client.userID &&
 | 
			
		||||
                            !user.room.isDirectChat)
 | 
			
		||||
                          PopupMenuItem(
 | 
			
		||||
                            value: 'message',
 | 
			
		||||
                            child: _TextWithIcon(
 | 
			
		||||
                              L10n.of(context).sendAMessage,
 | 
			
		||||
                              Icons.send_outlined,
 | 
			
		||||
                            ),
 | 
			
		||||
                          ),
 | 
			
		||||
                        if (user.canChangePowerLevel)
 | 
			
		||||
                          PopupMenuItem(
 | 
			
		||||
                            value: 'permission',
 | 
			
		||||
                            child: _TextWithIcon(
 | 
			
		||||
                              L10n.of(context).setPermissionsLevel,
 | 
			
		||||
                              Icons.edit_attributes_outlined,
 | 
			
		||||
                            ),
 | 
			
		||||
                          ),
 | 
			
		||||
                        if (user.canKick)
 | 
			
		||||
                          PopupMenuItem(
 | 
			
		||||
                            value: 'kick',
 | 
			
		||||
                            child: _TextWithIcon(
 | 
			
		||||
                              L10n.of(context).kickFromChat,
 | 
			
		||||
                              Icons.exit_to_app_outlined,
 | 
			
		||||
                            ),
 | 
			
		||||
                          ),
 | 
			
		||||
                        if (user.canBan && user.membership != Membership.ban)
 | 
			
		||||
                          PopupMenuItem(
 | 
			
		||||
                            value: 'ban',
 | 
			
		||||
                            child: _TextWithIcon(
 | 
			
		||||
                              L10n.of(context).banFromChat,
 | 
			
		||||
                              Icons.warning_sharp,
 | 
			
		||||
                            ),
 | 
			
		||||
                          )
 | 
			
		||||
                        else if (user.canBan &&
 | 
			
		||||
                            user.membership == Membership.ban)
 | 
			
		||||
                          PopupMenuItem(
 | 
			
		||||
                            value: 'unban',
 | 
			
		||||
                            child: _TextWithIcon(
 | 
			
		||||
                              L10n.of(context).removeExile,
 | 
			
		||||
                              Icons.warning_outlined,
 | 
			
		||||
                            ),
 | 
			
		||||
                          ),
 | 
			
		||||
                      ],
 | 
			
		||||
                      onSelected: controller.participantAction,
 | 
			
		||||
                    ),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
              body: Column(
 | 
			
		||||
                children: [
 | 
			
		||||
                  Expanded(
 | 
			
		||||
                    child: ContentBanner(
 | 
			
		||||
                      user.avatarUrl,
 | 
			
		||||
                      defaultIcon: Icons.person_outline,
 | 
			
		||||
                      client: user.room.client,
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
                  ListTile(
 | 
			
		||||
                    title: Text(L10n.of(context).username),
 | 
			
		||||
                    subtitle: Text(user.id),
 | 
			
		||||
                    trailing: Icon(Icons.share_outlined),
 | 
			
		||||
                    onTap: () => FluffyShare.share(user.id, context),
 | 
			
		||||
                  ),
 | 
			
		||||
                  if (presence != null)
 | 
			
		||||
                    ListTile(
 | 
			
		||||
                      title: Text(presence.getLocalizedStatusMessage(context)),
 | 
			
		||||
                      subtitle:
 | 
			
		||||
                          Text(presence.getLocalizedLastActiveAgo(context)),
 | 
			
		||||
                      trailing: Icon(Icons.circle,
 | 
			
		||||
                          color: presence.presence.currentlyActive ?? false
 | 
			
		||||
                              ? Colors.green
 | 
			
		||||
                              : Colors.grey),
 | 
			
		||||
                    ),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _TextWithIcon extends StatelessWidget {
 | 
			
		||||
  final String text;
 | 
			
		||||
  final IconData iconData;
 | 
			
		||||
 | 
			
		||||
  const _TextWithIcon(
 | 
			
		||||
    this.text,
 | 
			
		||||
    this.iconData, {
 | 
			
		||||
    Key key,
 | 
			
		||||
  }) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Row(
 | 
			
		||||
      mainAxisSize: MainAxisSize.min,
 | 
			
		||||
      children: [
 | 
			
		||||
        Icon(iconData),
 | 
			
		||||
        SizedBox(width: 16),
 | 
			
		||||
        Text(text),
 | 
			
		||||
      ],
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										92
									
								
								lib/views/user_bottom_sheet.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								lib/views/user_bottom_sheet.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,92 @@
 | 
			
		||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
 | 
			
		||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
 | 
			
		||||
import 'package:famedlysdk/famedlysdk.dart';
 | 
			
		||||
import 'package:fluffychat/views/permission_slider_dialog.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
 | 
			
		||||
 | 
			
		||||
import 'ui/user_bottom_sheet_ui.dart';
 | 
			
		||||
 | 
			
		||||
class UserBottomSheet extends StatefulWidget {
 | 
			
		||||
  final User user;
 | 
			
		||||
  final Function onMention;
 | 
			
		||||
 | 
			
		||||
  const UserBottomSheet({
 | 
			
		||||
    Key key,
 | 
			
		||||
    @required this.user,
 | 
			
		||||
    this.onMention,
 | 
			
		||||
  }) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  UserBottomSheetController createState() => UserBottomSheetController();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class UserBottomSheetController extends State<UserBottomSheet> {
 | 
			
		||||
  void participantAction(String action) async {
 | 
			
		||||
    final Function _askConfirmation =
 | 
			
		||||
        () async => (await showOkCancelAlertDialog(
 | 
			
		||||
              context: context,
 | 
			
		||||
              useRootNavigator: false,
 | 
			
		||||
              title: L10n.of(context).areYouSure,
 | 
			
		||||
              okLabel: L10n.of(context).yes,
 | 
			
		||||
              cancelLabel: L10n.of(context).no,
 | 
			
		||||
            ) ==
 | 
			
		||||
            OkCancelResult.ok);
 | 
			
		||||
    switch (action) {
 | 
			
		||||
      case 'mention':
 | 
			
		||||
        Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        widget.onMention();
 | 
			
		||||
        break;
 | 
			
		||||
      case 'ban':
 | 
			
		||||
        if (await _askConfirmation()) {
 | 
			
		||||
          await showFutureLoadingDialog(
 | 
			
		||||
            context: context,
 | 
			
		||||
            future: () => widget.user.ban(),
 | 
			
		||||
          );
 | 
			
		||||
          Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case 'unban':
 | 
			
		||||
        if (await _askConfirmation()) {
 | 
			
		||||
          await showFutureLoadingDialog(
 | 
			
		||||
            context: context,
 | 
			
		||||
            future: () => widget.user.unban(),
 | 
			
		||||
          );
 | 
			
		||||
          Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case 'kick':
 | 
			
		||||
        if (await _askConfirmation()) {
 | 
			
		||||
          await showFutureLoadingDialog(
 | 
			
		||||
            context: context,
 | 
			
		||||
            future: () => widget.user.kick(),
 | 
			
		||||
          );
 | 
			
		||||
          Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case 'permission':
 | 
			
		||||
        final newPermission = await PermissionSliderDialog(
 | 
			
		||||
                initialPermission: widget.user.powerLevel)
 | 
			
		||||
            .show(context);
 | 
			
		||||
        if (newPermission != null) {
 | 
			
		||||
          if (newPermission == 100 && await _askConfirmation() == false) break;
 | 
			
		||||
          await showFutureLoadingDialog(
 | 
			
		||||
            context: context,
 | 
			
		||||
            future: () => widget.user.setPower(newPermission),
 | 
			
		||||
          );
 | 
			
		||||
          Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case 'message':
 | 
			
		||||
        final roomId = await widget.user.startDirectChat();
 | 
			
		||||
        await AdaptivePageLayout.of(context)
 | 
			
		||||
            .pushNamedAndRemoveUntilIsFirst('/rooms/$roomId');
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) => UserBottomSheetUI(this);
 | 
			
		||||
}
 | 
			
		||||
@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
import '../avatar.dart';
 | 
			
		||||
import '../user_bottom_sheet.dart';
 | 
			
		||||
import '../../user_bottom_sheet.dart';
 | 
			
		||||
 | 
			
		||||
class ParticipantListItem extends StatelessWidget {
 | 
			
		||||
  final User user;
 | 
			
		||||
 | 
			
		||||
@ -1,244 +0,0 @@
 | 
			
		||||
import 'dart:math';
 | 
			
		||||
 | 
			
		||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
 | 
			
		||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
 | 
			
		||||
import 'package:famedlysdk/famedlysdk.dart';
 | 
			
		||||
import 'package:fluffychat/views/permission_slider_dialog.dart';
 | 
			
		||||
import 'package:fluffychat/config/themes.dart';
 | 
			
		||||
import 'package:fluffychat/utils/fluffy_share.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'content_banner.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
import '../../utils/presence_extension.dart';
 | 
			
		||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
 | 
			
		||||
 | 
			
		||||
class UserBottomSheet extends StatelessWidget {
 | 
			
		||||
  final User user;
 | 
			
		||||
  final Function onMention;
 | 
			
		||||
 | 
			
		||||
  const UserBottomSheet({
 | 
			
		||||
    Key key,
 | 
			
		||||
    @required this.user,
 | 
			
		||||
    this.onMention,
 | 
			
		||||
  }) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  void participantAction(BuildContext context, String action) async {
 | 
			
		||||
    final Function _askConfirmation =
 | 
			
		||||
        () async => (await showOkCancelAlertDialog(
 | 
			
		||||
              context: context,
 | 
			
		||||
              useRootNavigator: false,
 | 
			
		||||
              title: L10n.of(context).areYouSure,
 | 
			
		||||
              okLabel: L10n.of(context).yes,
 | 
			
		||||
              cancelLabel: L10n.of(context).no,
 | 
			
		||||
            ) ==
 | 
			
		||||
            OkCancelResult.ok);
 | 
			
		||||
    switch (action) {
 | 
			
		||||
      case 'mention':
 | 
			
		||||
        Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        onMention();
 | 
			
		||||
        break;
 | 
			
		||||
      case 'ban':
 | 
			
		||||
        if (await _askConfirmation()) {
 | 
			
		||||
          await showFutureLoadingDialog(
 | 
			
		||||
            context: context,
 | 
			
		||||
            future: () => user.ban(),
 | 
			
		||||
          );
 | 
			
		||||
          Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case 'unban':
 | 
			
		||||
        if (await _askConfirmation()) {
 | 
			
		||||
          await showFutureLoadingDialog(
 | 
			
		||||
            context: context,
 | 
			
		||||
            future: () => user.unban(),
 | 
			
		||||
          );
 | 
			
		||||
          Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case 'kick':
 | 
			
		||||
        if (await _askConfirmation()) {
 | 
			
		||||
          await showFutureLoadingDialog(
 | 
			
		||||
            context: context,
 | 
			
		||||
            future: () => user.kick(),
 | 
			
		||||
          );
 | 
			
		||||
          Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case 'permission':
 | 
			
		||||
        final newPermission =
 | 
			
		||||
            await PermissionSliderDialog(initialPermission: user.powerLevel)
 | 
			
		||||
                .show(context);
 | 
			
		||||
        if (newPermission != null) {
 | 
			
		||||
          if (newPermission == 100 && await _askConfirmation() == false) break;
 | 
			
		||||
          await showFutureLoadingDialog(
 | 
			
		||||
            context: context,
 | 
			
		||||
            future: () => user.setPower(newPermission),
 | 
			
		||||
          );
 | 
			
		||||
          Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case 'message':
 | 
			
		||||
        final roomId = await user.startDirectChat();
 | 
			
		||||
        await AdaptivePageLayout.of(context)
 | 
			
		||||
            .pushNamedAndRemoveUntilIsFirst('/rooms/$roomId');
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final client = user.room.client;
 | 
			
		||||
    final presence = client.presences[user.id];
 | 
			
		||||
    final items = <PopupMenuEntry<String>>[];
 | 
			
		||||
 | 
			
		||||
    if (onMention != null) {
 | 
			
		||||
      items.add(
 | 
			
		||||
        PopupMenuItem(
 | 
			
		||||
          value: 'mention',
 | 
			
		||||
          child: _TextWithIcon(
 | 
			
		||||
            L10n.of(context).mention,
 | 
			
		||||
            Icons.alternate_email_outlined,
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    if (user.id != user.room.client.userID && !user.room.isDirectChat) {
 | 
			
		||||
      items.add(
 | 
			
		||||
        PopupMenuItem(
 | 
			
		||||
          value: 'message',
 | 
			
		||||
          child: _TextWithIcon(
 | 
			
		||||
            L10n.of(context).sendAMessage,
 | 
			
		||||
            Icons.send_outlined,
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    if (user.canChangePowerLevel) {
 | 
			
		||||
      items.add(
 | 
			
		||||
        PopupMenuItem(
 | 
			
		||||
          value: 'permission',
 | 
			
		||||
          child: _TextWithIcon(
 | 
			
		||||
            L10n.of(context).setPermissionsLevel,
 | 
			
		||||
            Icons.edit_attributes_outlined,
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    if (user.canKick) {
 | 
			
		||||
      items.add(
 | 
			
		||||
        PopupMenuItem(
 | 
			
		||||
          value: 'kick',
 | 
			
		||||
          child: _TextWithIcon(
 | 
			
		||||
            L10n.of(context).kickFromChat,
 | 
			
		||||
            Icons.exit_to_app_outlined,
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    if (user.canBan && user.membership != Membership.ban) {
 | 
			
		||||
      items.add(
 | 
			
		||||
        PopupMenuItem(
 | 
			
		||||
          value: 'ban',
 | 
			
		||||
          child: _TextWithIcon(
 | 
			
		||||
            L10n.of(context).banFromChat,
 | 
			
		||||
            Icons.warning_sharp,
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    } else if (user.canBan && user.membership == Membership.ban) {
 | 
			
		||||
      items.add(
 | 
			
		||||
        PopupMenuItem(
 | 
			
		||||
          value: 'unban',
 | 
			
		||||
          child: _TextWithIcon(
 | 
			
		||||
            L10n.of(context).removeExile,
 | 
			
		||||
            Icons.warning_outlined,
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    return Center(
 | 
			
		||||
      child: Container(
 | 
			
		||||
        width: min(
 | 
			
		||||
            MediaQuery.of(context).size.width, FluffyThemes.columnWidth * 1.5),
 | 
			
		||||
        child: Material(
 | 
			
		||||
          elevation: 4,
 | 
			
		||||
          child: SafeArea(
 | 
			
		||||
            child: Scaffold(
 | 
			
		||||
              extendBodyBehindAppBar: true,
 | 
			
		||||
              appBar: AppBar(
 | 
			
		||||
                elevation: 0,
 | 
			
		||||
                backgroundColor:
 | 
			
		||||
                    Theme.of(context).scaffoldBackgroundColor.withOpacity(0.5),
 | 
			
		||||
                leading: IconButton(
 | 
			
		||||
                  icon: Icon(Icons.arrow_downward_outlined),
 | 
			
		||||
                  onPressed: Navigator.of(context, rootNavigator: false).pop,
 | 
			
		||||
                  tooltip: L10n.of(context).close,
 | 
			
		||||
                ),
 | 
			
		||||
                title: Text(user.calcDisplayname()),
 | 
			
		||||
                actions: [
 | 
			
		||||
                  if (user.id != user.room.client.userID)
 | 
			
		||||
                    PopupMenuButton(
 | 
			
		||||
                      itemBuilder: (_) => items,
 | 
			
		||||
                      onSelected: (action) =>
 | 
			
		||||
                          participantAction(context, action),
 | 
			
		||||
                    ),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
              body: Column(
 | 
			
		||||
                children: [
 | 
			
		||||
                  Expanded(
 | 
			
		||||
                    child: ContentBanner(
 | 
			
		||||
                      user.avatarUrl,
 | 
			
		||||
                      defaultIcon: Icons.person_outline,
 | 
			
		||||
                      client: user.room.client,
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
                  ListTile(
 | 
			
		||||
                    title: Text(L10n.of(context).username),
 | 
			
		||||
                    subtitle: Text(user.id),
 | 
			
		||||
                    trailing: Icon(Icons.share_outlined),
 | 
			
		||||
                    onTap: () => FluffyShare.share(user.id, context),
 | 
			
		||||
                  ),
 | 
			
		||||
                  if (presence != null)
 | 
			
		||||
                    ListTile(
 | 
			
		||||
                      title: Text(presence.getLocalizedStatusMessage(context)),
 | 
			
		||||
                      subtitle:
 | 
			
		||||
                          Text(presence.getLocalizedLastActiveAgo(context)),
 | 
			
		||||
                      trailing: Icon(Icons.circle,
 | 
			
		||||
                          color: presence.presence.currentlyActive ?? false
 | 
			
		||||
                              ? Colors.green
 | 
			
		||||
                              : Colors.grey),
 | 
			
		||||
                    ),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _TextWithIcon extends StatelessWidget {
 | 
			
		||||
  final String text;
 | 
			
		||||
  final IconData iconData;
 | 
			
		||||
 | 
			
		||||
  const _TextWithIcon(
 | 
			
		||||
    this.text,
 | 
			
		||||
    this.iconData, {
 | 
			
		||||
    Key key,
 | 
			
		||||
  }) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Row(
 | 
			
		||||
      mainAxisSize: MainAxisSize.min,
 | 
			
		||||
      children: [
 | 
			
		||||
        Icon(iconData),
 | 
			
		||||
        SizedBox(width: 16),
 | 
			
		||||
        Text(text),
 | 
			
		||||
      ],
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user