mirror of
				https://gitlab.com/famedly/fluffychat.git
				synced 2025-11-04 06:17:26 +01:00 
			
		
		
		
	Merge branch 'krille/nicer-modal-bottom-sheet' into 'main'
style: New modal bottom sheets See merge request famedly/fluffychat!1071
This commit is contained in:
		
						commit
						8f9e1a9142
					
				@ -61,12 +61,14 @@ void main() {
 | 
			
		||||
          await tester.pumpAndSettle();
 | 
			
		||||
 | 
			
		||||
          await tester.scrollUntilVisible(
 | 
			
		||||
            find.text('Chats'),
 | 
			
		||||
            find.text('Chats').first,
 | 
			
		||||
            500,
 | 
			
		||||
            scrollable: find.descendant(
 | 
			
		||||
            scrollable: find
 | 
			
		||||
                .descendant(
 | 
			
		||||
                  of: find.byType(ChatListViewBody),
 | 
			
		||||
                  matching: find.byType(Scrollable),
 | 
			
		||||
            ),
 | 
			
		||||
                )
 | 
			
		||||
                .first,
 | 
			
		||||
          );
 | 
			
		||||
          await tester.pumpAndSettle();
 | 
			
		||||
          await tester.tap(find.text('Chats'));
 | 
			
		||||
@ -77,10 +79,12 @@ void main() {
 | 
			
		||||
          await tester.scrollUntilVisible(
 | 
			
		||||
            find.text(Users.user2.name).first,
 | 
			
		||||
            500,
 | 
			
		||||
            scrollable: find.descendant(
 | 
			
		||||
            scrollable: find
 | 
			
		||||
                .descendant(
 | 
			
		||||
                  of: find.byType(ChatListViewBody),
 | 
			
		||||
                  matching: find.byType(Scrollable),
 | 
			
		||||
            ),
 | 
			
		||||
                )
 | 
			
		||||
                .first,
 | 
			
		||||
          );
 | 
			
		||||
          await tester.pumpAndSettle();
 | 
			
		||||
          await tester.tap(find.text(Users.user2.name).first);
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,7 @@ import 'package:vrouter/vrouter.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat/chat_view.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat/event_info_dialog.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat/recording_dialog.dart';
 | 
			
		||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
 | 
			
		||||
import 'package:fluffychat/utils/matrix_sdk_extensions/ios_badge_client_extension.dart';
 | 
			
		||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
 | 
			
		||||
@ -422,9 +423,8 @@ class ChatController extends State<Chat> {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void sendStickerAction() async {
 | 
			
		||||
    final sticker = await showModalBottomSheet<ImagePackImageContent>(
 | 
			
		||||
    final sticker = await showAdaptiveBottomSheet<ImagePackImageContent>(
 | 
			
		||||
      context: context,
 | 
			
		||||
      useRootNavigator: false,
 | 
			
		||||
      builder: (c) => StickerPickerDialog(room: room!),
 | 
			
		||||
    );
 | 
			
		||||
    if (sticker == null) return;
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@ import 'package:vrouter/vrouter.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/pages/chat/chat.dart';
 | 
			
		||||
import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/avatar.dart';
 | 
			
		||||
 | 
			
		||||
@ -26,7 +27,7 @@ class ChatAppBarTitle extends StatelessWidget {
 | 
			
		||||
      splashColor: Colors.transparent,
 | 
			
		||||
      highlightColor: Colors.transparent,
 | 
			
		||||
      onTap: directChatMatrixID != null
 | 
			
		||||
          ? () => showModalBottomSheet(
 | 
			
		||||
          ? () => showAdaptiveBottomSheet(
 | 
			
		||||
                context: context,
 | 
			
		||||
                builder: (c) => UserBottomSheet(
 | 
			
		||||
                  user: room
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ import 'package:fluffychat/pages/chat/events/message.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat/seen_by_row.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat/typing_indicators.dart';
 | 
			
		||||
import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/utils/matrix_sdk_extensions/filtered_timeline_extension.dart';
 | 
			
		||||
import 'package:fluffychat/utils/platform_infos.dart';
 | 
			
		||||
 | 
			
		||||
@ -89,7 +90,7 @@ class ChatEventList extends StatelessWidget {
 | 
			
		||||
                    onSwipe: (direction) =>
 | 
			
		||||
                        controller.replyAction(replyTo: event),
 | 
			
		||||
                    onInfoTab: controller.showEventInfo,
 | 
			
		||||
                    onAvatarTab: (Event event) => showModalBottomSheet(
 | 
			
		||||
                    onAvatarTab: (Event event) => showAdaptiveBottomSheet(
 | 
			
		||||
                          context: context,
 | 
			
		||||
                          builder: (c) => UserBottomSheet(
 | 
			
		||||
                            user: event.senderFromMemoryOrFallback,
 | 
			
		||||
 | 
			
		||||
@ -6,11 +6,12 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
import 'package:matrix/matrix.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/config/app_config.dart';
 | 
			
		||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/utils/date_time_extension.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/avatar.dart';
 | 
			
		||||
 | 
			
		||||
extension EventInfoDialogExtension on Event {
 | 
			
		||||
  void showInfoDialog(BuildContext context) => showModalBottomSheet(
 | 
			
		||||
  void showInfoDialog(BuildContext context) => showAdaptiveBottomSheet(
 | 
			
		||||
        context: context,
 | 
			
		||||
        builder: (context) =>
 | 
			
		||||
            EventInfoDialog(l10n: L10n.of(context)!, event: this),
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@ import 'package:matrix/matrix.dart';
 | 
			
		||||
import 'package:matrix_link_text/link_text.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/pages/chat/events/video_player.dart';
 | 
			
		||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/utils/date_time_extension.dart';
 | 
			
		||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/avatar.dart';
 | 
			
		||||
@ -52,7 +53,7 @@ class MessageContent extends StatelessWidget {
 | 
			
		||||
    }
 | 
			
		||||
    event.requestKey();
 | 
			
		||||
    final sender = event.senderFromMemoryOrFallback;
 | 
			
		||||
    await showModalBottomSheet(
 | 
			
		||||
    await showAdaptiveBottomSheet(
 | 
			
		||||
      context: context,
 | 
			
		||||
      builder: (context) => Scaffold(
 | 
			
		||||
        appBar: AppBar(
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
import 'package:matrix/matrix.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
 | 
			
		||||
import '../../widgets/avatar.dart';
 | 
			
		||||
import '../user_bottom_sheet/user_bottom_sheet.dart';
 | 
			
		||||
 | 
			
		||||
@ -28,7 +29,7 @@ class ParticipantListItem extends StatelessWidget {
 | 
			
		||||
    return Opacity(
 | 
			
		||||
      opacity: user.membership == Membership.join ? 1 : 0.5,
 | 
			
		||||
      child: ListTile(
 | 
			
		||||
        onTap: () => showModalBottomSheet(
 | 
			
		||||
        onTap: () => showAdaptiveBottomSheet(
 | 
			
		||||
          context: context,
 | 
			
		||||
          builder: (c) => UserBottomSheet(
 | 
			
		||||
            user: user,
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,7 @@ import 'package:fluffychat/pages/chat_list/chat_list_item.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat_list/search_title.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat_list/space_view.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat_list/stories_header.dart';
 | 
			
		||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/utils/matrix_sdk_extensions/client_stories_extension.dart';
 | 
			
		||||
import 'package:fluffychat/utils/stream_extension.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/avatar.dart';
 | 
			
		||||
@ -101,7 +102,7 @@ class ChatListViewBody extends StatelessWidget {
 | 
			
		||||
                                          L10n.of(context)!.group,
 | 
			
		||||
                                      avatar:
 | 
			
		||||
                                          roomSearchResult.chunk[i].avatarUrl,
 | 
			
		||||
                                      onPressed: () => showModalBottomSheet(
 | 
			
		||||
                                      onPressed: () => showAdaptiveBottomSheet(
 | 
			
		||||
                                        context: context,
 | 
			
		||||
                                        builder: (c) => PublicRoomBottomSheet(
 | 
			
		||||
                                          roomAlias: roomSearchResult
 | 
			
		||||
@ -140,7 +141,7 @@ class ChatListViewBody extends StatelessWidget {
 | 
			
		||||
                                          L10n.of(context)!.unknownDevice,
 | 
			
		||||
                                      avatar:
 | 
			
		||||
                                          userSearchResult.results[i].avatarUrl,
 | 
			
		||||
                                      onPressed: () => showModalBottomSheet(
 | 
			
		||||
                                      onPressed: () => showAdaptiveBottomSheet(
 | 
			
		||||
                                        context: context,
 | 
			
		||||
                                        builder: (c) => ProfileBottomSheet(
 | 
			
		||||
                                          userId: userSearchResult
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,7 @@ import 'package:vrouter/vrouter.dart';
 | 
			
		||||
import 'package:fluffychat/config/app_config.dart';
 | 
			
		||||
import 'package:fluffychat/pages/homeserver_picker/homeserver_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/pages/homeserver_picker/homeserver_picker_view.dart';
 | 
			
		||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/matrix.dart';
 | 
			
		||||
import '../../utils/localized_exception_extension.dart';
 | 
			
		||||
 | 
			
		||||
@ -71,7 +72,8 @@ class HomeserverPickerController extends State<HomeserverPicker> {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void showServerInfo(HomeserverBenchmarkResult server) => showModalBottomSheet(
 | 
			
		||||
  void showServerInfo(HomeserverBenchmarkResult server) =>
 | 
			
		||||
      showAdaptiveBottomSheet(
 | 
			
		||||
        context: context,
 | 
			
		||||
        builder: (_) => HomeserverBottomSheet(
 | 
			
		||||
          homeserver: server,
 | 
			
		||||
 | 
			
		||||
@ -10,13 +10,13 @@ import 'package:future_loading_dialog/future_loading_dialog.dart';
 | 
			
		||||
import 'package:matrix/encryption.dart';
 | 
			
		||||
import 'package:matrix/matrix.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/avatar.dart';
 | 
			
		||||
 | 
			
		||||
class KeyVerificationDialog extends StatefulWidget {
 | 
			
		||||
  Future<void> show(BuildContext context) => showModalBottomSheet(
 | 
			
		||||
  Future<void> show(BuildContext context) => showAdaptiveBottomSheet(
 | 
			
		||||
        context: context,
 | 
			
		||||
        builder: (context) => this,
 | 
			
		||||
        useRootNavigator: false,
 | 
			
		||||
        isDismissible: false,
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@ import 'package:matrix/matrix.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/pages/new_private_chat/new_private_chat_view.dart';
 | 
			
		||||
import 'package:fluffychat/pages/new_private_chat/qr_scanner_modal.dart';
 | 
			
		||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/utils/fluffy_share.dart';
 | 
			
		||||
import 'package:fluffychat/utils/platform_infos.dart';
 | 
			
		||||
import 'package:fluffychat/utils/url_launcher.dart';
 | 
			
		||||
@ -75,10 +76,8 @@ class NewPrivateChatController extends State<NewPrivateChat> {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    await showModalBottomSheet(
 | 
			
		||||
    await showAdaptiveBottomSheet(
 | 
			
		||||
      context: context,
 | 
			
		||||
      useRootNavigator: false,
 | 
			
		||||
      //useSafeArea: false,
 | 
			
		||||
      builder: (_) => const QrScannerModal(),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,7 @@ import 'package:video_player/video_player.dart';
 | 
			
		||||
import 'package:vrouter/vrouter.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/pages/story/story_view.dart';
 | 
			
		||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/utils/date_time_extension.dart';
 | 
			
		||||
import 'package:fluffychat/utils/localized_exception_extension.dart';
 | 
			
		||||
import 'package:fluffychat/utils/matrix_sdk_extensions/client_stories_extension.dart';
 | 
			
		||||
@ -58,7 +59,7 @@ class StoryPageController extends State<StoryPage> {
 | 
			
		||||
  void replyEmojiAction() async {
 | 
			
		||||
    if (replyLoading) return;
 | 
			
		||||
    _modalOpened = true;
 | 
			
		||||
    await showModalBottomSheet(
 | 
			
		||||
    await showAdaptiveBottomSheet(
 | 
			
		||||
      context: context,
 | 
			
		||||
      builder: (context) => EmojiPicker(
 | 
			
		||||
        onEmojiSelected: (c, e) {
 | 
			
		||||
@ -123,7 +124,7 @@ class StoryPageController extends State<StoryPage> {
 | 
			
		||||
 | 
			
		||||
  void displaySeenByUsers() async {
 | 
			
		||||
    _modalOpened = true;
 | 
			
		||||
    await showModalBottomSheet(
 | 
			
		||||
    await showAdaptiveBottomSheet(
 | 
			
		||||
      context: context,
 | 
			
		||||
      builder: (context) => Scaffold(
 | 
			
		||||
        appBar: AppBar(
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,17 @@ import 'package:fluffychat/widgets/permission_slider_dialog.dart';
 | 
			
		||||
import '../../widgets/matrix.dart';
 | 
			
		||||
import 'user_bottom_sheet_view.dart';
 | 
			
		||||
 | 
			
		||||
enum UserBottomSheetAction {
 | 
			
		||||
  report,
 | 
			
		||||
  mention,
 | 
			
		||||
  ban,
 | 
			
		||||
  kick,
 | 
			
		||||
  unban,
 | 
			
		||||
  permission,
 | 
			
		||||
  message,
 | 
			
		||||
  ignore,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class UserBottomSheet extends StatefulWidget {
 | 
			
		||||
  final User user;
 | 
			
		||||
  final Function? onMention;
 | 
			
		||||
@ -27,7 +38,7 @@ class UserBottomSheet extends StatefulWidget {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class UserBottomSheetController extends State<UserBottomSheet> {
 | 
			
		||||
  void participantAction(String action) async {
 | 
			
		||||
  void participantAction(UserBottomSheetAction action) async {
 | 
			
		||||
    // ignore: prefer_function_declarations_over_variables
 | 
			
		||||
    final Function askConfirmation = () async => (await showOkCancelAlertDialog(
 | 
			
		||||
          useRootNavigator: false,
 | 
			
		||||
@ -38,7 +49,7 @@ class UserBottomSheetController extends State<UserBottomSheet> {
 | 
			
		||||
        ) ==
 | 
			
		||||
        OkCancelResult.ok);
 | 
			
		||||
    switch (action) {
 | 
			
		||||
      case 'report':
 | 
			
		||||
      case UserBottomSheetAction.report:
 | 
			
		||||
        final event = widget.user;
 | 
			
		||||
        final score = await showConfirmationDialog<int>(
 | 
			
		||||
            context: context,
 | 
			
		||||
@ -82,11 +93,11 @@ class UserBottomSheetController extends State<UserBottomSheet> {
 | 
			
		||||
        ScaffoldMessenger.of(context).showSnackBar(
 | 
			
		||||
            SnackBar(content: Text(L10n.of(context)!.contentHasBeenReported)));
 | 
			
		||||
        break;
 | 
			
		||||
      case 'mention':
 | 
			
		||||
      case UserBottomSheetAction.mention:
 | 
			
		||||
        Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        widget.onMention!();
 | 
			
		||||
        break;
 | 
			
		||||
      case 'ban':
 | 
			
		||||
      case UserBottomSheetAction.ban:
 | 
			
		||||
        if (await askConfirmation()) {
 | 
			
		||||
          await showFutureLoadingDialog(
 | 
			
		||||
            context: context,
 | 
			
		||||
@ -95,7 +106,7 @@ class UserBottomSheetController extends State<UserBottomSheet> {
 | 
			
		||||
          Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case 'unban':
 | 
			
		||||
      case UserBottomSheetAction.unban:
 | 
			
		||||
        if (await askConfirmation()) {
 | 
			
		||||
          await showFutureLoadingDialog(
 | 
			
		||||
            context: context,
 | 
			
		||||
@ -104,7 +115,7 @@ class UserBottomSheetController extends State<UserBottomSheet> {
 | 
			
		||||
          Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case 'kick':
 | 
			
		||||
      case UserBottomSheetAction.kick:
 | 
			
		||||
        if (await askConfirmation()) {
 | 
			
		||||
          await showFutureLoadingDialog(
 | 
			
		||||
            context: context,
 | 
			
		||||
@ -113,7 +124,7 @@ class UserBottomSheetController extends State<UserBottomSheet> {
 | 
			
		||||
          Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case 'permission':
 | 
			
		||||
      case UserBottomSheetAction.permission:
 | 
			
		||||
        final newPermission = await showPermissionChooser(
 | 
			
		||||
          context,
 | 
			
		||||
          currentLevel: widget.user.powerLevel,
 | 
			
		||||
@ -127,7 +138,7 @@ class UserBottomSheetController extends State<UserBottomSheet> {
 | 
			
		||||
          Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case 'message':
 | 
			
		||||
      case UserBottomSheetAction.message:
 | 
			
		||||
        final roomIdResult = await showFutureLoadingDialog(
 | 
			
		||||
          context: context,
 | 
			
		||||
          future: () => widget.user.startDirectChat(),
 | 
			
		||||
@ -137,7 +148,7 @@ class UserBottomSheetController extends State<UserBottomSheet> {
 | 
			
		||||
            .toSegments(['rooms', roomIdResult.result!]);
 | 
			
		||||
        Navigator.of(context, rootNavigator: false).pop();
 | 
			
		||||
        break;
 | 
			
		||||
      case 'ignore':
 | 
			
		||||
      case UserBottomSheetAction.ignore:
 | 
			
		||||
        if (await askConfirmation()) {
 | 
			
		||||
          await showFutureLoadingDialog(
 | 
			
		||||
              context: context,
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,11 @@
 | 
			
		||||
import 'dart:math';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
import 'package:matrix/matrix.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/config/themes.dart';
 | 
			
		||||
import 'package:fluffychat/utils/fluffy_share.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/avatar.dart';
 | 
			
		||||
import '../../utils/matrix_sdk_extensions/presence_extension.dart';
 | 
			
		||||
import '../../widgets/content_banner.dart';
 | 
			
		||||
import '../../widgets/m2_popup_menu_button.dart';
 | 
			
		||||
import '../../widgets/matrix.dart';
 | 
			
		||||
import 'user_bottom_sheet.dart';
 | 
			
		||||
 | 
			
		||||
@ -23,155 +19,114 @@ class UserBottomSheetView extends StatelessWidget {
 | 
			
		||||
    final user = controller.widget.user;
 | 
			
		||||
    final client = Matrix.of(context).client;
 | 
			
		||||
    final presence = client.presences[user.id];
 | 
			
		||||
    return Center(
 | 
			
		||||
      child: SizedBox(
 | 
			
		||||
        width: min(
 | 
			
		||||
            MediaQuery.of(context).size.width, FluffyThemes.columnWidth * 1.5),
 | 
			
		||||
        child: Material(
 | 
			
		||||
          elevation: 4,
 | 
			
		||||
          child: SafeArea(
 | 
			
		||||
    return SafeArea(
 | 
			
		||||
      child: Scaffold(
 | 
			
		||||
              extendBodyBehindAppBar: true,
 | 
			
		||||
        appBar: AppBar(
 | 
			
		||||
                elevation: 0,
 | 
			
		||||
                backgroundColor:
 | 
			
		||||
                    Theme.of(context).scaffoldBackgroundColor.withOpacity(0.5),
 | 
			
		||||
                leading: IconButton(
 | 
			
		||||
                  icon: const Icon(Icons.arrow_downward_outlined),
 | 
			
		||||
          leading: CloseButton(
 | 
			
		||||
            onPressed: Navigator.of(context, rootNavigator: false).pop,
 | 
			
		||||
                  tooltip: L10n.of(context)!.close,
 | 
			
		||||
          ),
 | 
			
		||||
          title: Text(user.calcDisplayname()),
 | 
			
		||||
          actions: [
 | 
			
		||||
            if (user.id != client.userID)
 | 
			
		||||
                    M2PopupMenuButton(
 | 
			
		||||
                      itemBuilder: (_) => [
 | 
			
		||||
                        if (controller.widget.onMention != null)
 | 
			
		||||
                          PopupMenuItem(
 | 
			
		||||
                            value: 'mention',
 | 
			
		||||
                            child: _TextWithIcon(
 | 
			
		||||
                              L10n.of(context)!.mention,
 | 
			
		||||
                              Icons.alternate_email_outlined,
 | 
			
		||||
                            ),
 | 
			
		||||
                          ),
 | 
			
		||||
                        if (user.id != 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)!.unbanFromChat,
 | 
			
		||||
                              Icons.warning_outlined,
 | 
			
		||||
                            ),
 | 
			
		||||
                          ),
 | 
			
		||||
                        if (!client.ignoredUsers.contains(user.id))
 | 
			
		||||
                          PopupMenuItem(
 | 
			
		||||
                            value: 'ignore',
 | 
			
		||||
                            child: _TextWithIcon(
 | 
			
		||||
                              L10n.of(context)!.ignore,
 | 
			
		||||
                              Icons.block,
 | 
			
		||||
                            ),
 | 
			
		||||
                          ),
 | 
			
		||||
                        PopupMenuItem(
 | 
			
		||||
                          value: 'report',
 | 
			
		||||
                          child: _TextWithIcon(
 | 
			
		||||
                            L10n.of(context)!.reportUser,
 | 
			
		||||
                            Icons.shield_outlined,
 | 
			
		||||
              Padding(
 | 
			
		||||
                padding: const EdgeInsets.all(8.0),
 | 
			
		||||
                child: OutlinedButton.icon(
 | 
			
		||||
                  onPressed: () => controller
 | 
			
		||||
                      .participantAction(UserBottomSheetAction.message),
 | 
			
		||||
                  icon: const Icon(Icons.chat_outlined),
 | 
			
		||||
                  label: Text(L10n.of(context)!.newChat),
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
          ],
 | 
			
		||||
                      onSelected: controller.participantAction,
 | 
			
		||||
        ),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
              body: Column(
 | 
			
		||||
        body: ListView(
 | 
			
		||||
          children: [
 | 
			
		||||
                  Expanded(
 | 
			
		||||
                    child: ContentBanner(
 | 
			
		||||
            Row(
 | 
			
		||||
              children: [
 | 
			
		||||
                Padding(
 | 
			
		||||
                  padding: const EdgeInsets.all(16.0),
 | 
			
		||||
                  child: Avatar(
 | 
			
		||||
                    mxContent: user.avatarUrl,
 | 
			
		||||
                      defaultIcon: Icons.account_circle_outlined,
 | 
			
		||||
                      client: client,
 | 
			
		||||
                    name: user.calcDisplayname(),
 | 
			
		||||
                    size: Avatar.defaultSize * 2,
 | 
			
		||||
                    fontSize: 24,
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
                  ListTile(
 | 
			
		||||
                    title: Text(L10n.of(context)!.username),
 | 
			
		||||
                    subtitle: Text(user.id),
 | 
			
		||||
                    trailing: Icon(Icons.adaptive.share_outlined),
 | 
			
		||||
                    onTap: () => FluffyShare.share(
 | 
			
		||||
                Expanded(
 | 
			
		||||
                  child: ListTile(
 | 
			
		||||
                    contentPadding: const EdgeInsets.only(right: 16.0),
 | 
			
		||||
                    title: Text(user.id),
 | 
			
		||||
                    subtitle: presence == null
 | 
			
		||||
                        ? null
 | 
			
		||||
                        : Text(presence.getLocalizedLastActiveAgo(context)),
 | 
			
		||||
                    trailing: IconButton(
 | 
			
		||||
                      icon: Icon(Icons.adaptive.share),
 | 
			
		||||
                      onPressed: () => FluffyShare.share(
 | 
			
		||||
                        user.id,
 | 
			
		||||
                        context,
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                  if (presence != null)
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
            if (controller.widget.onMention != null)
 | 
			
		||||
              ListTile(
 | 
			
		||||
                      title: Text(presence.getLocalizedStatusMessage(context)),
 | 
			
		||||
                      subtitle:
 | 
			
		||||
                          Text(presence.getLocalizedLastActiveAgo(context)),
 | 
			
		||||
                      trailing: Icon(Icons.circle,
 | 
			
		||||
                          color: presence.presence == PresenceType.online
 | 
			
		||||
                              ? Colors.green
 | 
			
		||||
                              : Colors.grey),
 | 
			
		||||
                trailing: const Icon(Icons.alternate_email_outlined),
 | 
			
		||||
                title: Text(L10n.of(context)!.mention),
 | 
			
		||||
                onTap: () =>
 | 
			
		||||
                    controller.participantAction(UserBottomSheetAction.mention),
 | 
			
		||||
              ),
 | 
			
		||||
            if (user.canChangePowerLevel)
 | 
			
		||||
              ListTile(
 | 
			
		||||
                title: Text(L10n.of(context)!.setPermissionsLevel),
 | 
			
		||||
                trailing: const Icon(Icons.edit_attributes_outlined),
 | 
			
		||||
                onTap: () => controller
 | 
			
		||||
                    .participantAction(UserBottomSheetAction.permission),
 | 
			
		||||
              ),
 | 
			
		||||
            if (user.canKick)
 | 
			
		||||
              ListTile(
 | 
			
		||||
                title: Text(L10n.of(context)!.kickFromChat),
 | 
			
		||||
                trailing: const Icon(Icons.exit_to_app_outlined),
 | 
			
		||||
                onTap: () =>
 | 
			
		||||
                    controller.participantAction(UserBottomSheetAction.kick),
 | 
			
		||||
              ),
 | 
			
		||||
            if (user.canBan && user.membership != Membership.ban)
 | 
			
		||||
              ListTile(
 | 
			
		||||
                title: Text(L10n.of(context)!.banFromChat),
 | 
			
		||||
                trailing: const Icon(Icons.warning_sharp),
 | 
			
		||||
                onTap: () =>
 | 
			
		||||
                    controller.participantAction(UserBottomSheetAction.ban),
 | 
			
		||||
              )
 | 
			
		||||
            else if (user.canBan && user.membership == Membership.ban)
 | 
			
		||||
              ListTile(
 | 
			
		||||
                title: Text(L10n.of(context)!.unbanFromChat),
 | 
			
		||||
                trailing: const Icon(Icons.warning_outlined),
 | 
			
		||||
                onTap: () =>
 | 
			
		||||
                    controller.participantAction(UserBottomSheetAction.unban),
 | 
			
		||||
              ),
 | 
			
		||||
            if (user.id != client.userID &&
 | 
			
		||||
                !client.ignoredUsers.contains(user.id))
 | 
			
		||||
              ListTile(
 | 
			
		||||
                textColor: Theme.of(context).colorScheme.onErrorContainer,
 | 
			
		||||
                iconColor: Theme.of(context).colorScheme.onErrorContainer,
 | 
			
		||||
                title: Text(L10n.of(context)!.ignore),
 | 
			
		||||
                trailing: const Icon(Icons.block),
 | 
			
		||||
                onTap: () =>
 | 
			
		||||
                    controller.participantAction(UserBottomSheetAction.ignore),
 | 
			
		||||
              ),
 | 
			
		||||
            if (user.id != client.userID)
 | 
			
		||||
              ListTile(
 | 
			
		||||
                textColor: Theme.of(context).colorScheme.error,
 | 
			
		||||
                iconColor: Theme.of(context).colorScheme.error,
 | 
			
		||||
                title: Text(L10n.of(context)!.reportUser),
 | 
			
		||||
                trailing: const Icon(Icons.shield_outlined),
 | 
			
		||||
                onTap: () =>
 | 
			
		||||
                    controller.participantAction(UserBottomSheetAction.report),
 | 
			
		||||
              ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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),
 | 
			
		||||
        const SizedBox(width: 16),
 | 
			
		||||
        Text(text),
 | 
			
		||||
      ],
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										28
									
								
								lib/utils/adaptive_bottom_sheet.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								lib/utils/adaptive_bottom_sheet.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/config/app_config.dart';
 | 
			
		||||
import 'package:fluffychat/config/themes.dart';
 | 
			
		||||
import 'package:fluffychat/utils/platform_infos.dart';
 | 
			
		||||
 | 
			
		||||
Future<T?> showAdaptiveBottomSheet<T>({
 | 
			
		||||
  required BuildContext context,
 | 
			
		||||
  required Widget Function(BuildContext) builder,
 | 
			
		||||
  bool isDismissible = true,
 | 
			
		||||
}) =>
 | 
			
		||||
    showModalBottomSheet(
 | 
			
		||||
      context: context,
 | 
			
		||||
      builder: builder,
 | 
			
		||||
      useRootNavigator: !PlatformInfos.isMobile,
 | 
			
		||||
      isDismissible: isDismissible,
 | 
			
		||||
      constraints: BoxConstraints(
 | 
			
		||||
        maxHeight: MediaQuery.of(context).size.height - 128,
 | 
			
		||||
        maxWidth: FluffyThemes.columnWidth * 1.5,
 | 
			
		||||
      ),
 | 
			
		||||
      clipBehavior: Clip.hardEdge,
 | 
			
		||||
      shape: const RoundedRectangleBorder(
 | 
			
		||||
        borderRadius: BorderRadius.only(
 | 
			
		||||
          topLeft: Radius.circular(AppConfig.borderRadius),
 | 
			
		||||
          topRight: Radius.circular(AppConfig.borderRadius),
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
@ -10,6 +10,7 @@ import 'package:url_launcher/url_launcher.dart';
 | 
			
		||||
import 'package:vrouter/vrouter.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/config/app_config.dart';
 | 
			
		||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/matrix.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/profile_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/public_room_bottom_sheet.dart';
 | 
			
		||||
@ -145,7 +146,7 @@ class UrlLauncher {
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
      } else {
 | 
			
		||||
        await showModalBottomSheet(
 | 
			
		||||
        await showAdaptiveBottomSheet(
 | 
			
		||||
          context: context,
 | 
			
		||||
          builder: (c) => PublicRoomBottomSheet(
 | 
			
		||||
            roomAlias: identityParts.primaryIdentifier,
 | 
			
		||||
@ -182,7 +183,7 @@ class UrlLauncher {
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } else if (identityParts.primaryIdentifier.sigil == '@') {
 | 
			
		||||
      await showModalBottomSheet(
 | 
			
		||||
      await showAdaptiveBottomSheet(
 | 
			
		||||
        context: context,
 | 
			
		||||
        builder: (c) => ProfileBottomSheet(
 | 
			
		||||
          userId: identityParts.primaryIdentifier,
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@ import 'package:vrouter/vrouter.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat/cupertino_widgets_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat/edit_widgets_dialog.dart';
 | 
			
		||||
import 'package:fluffychat/pages/chat/widgets_bottom_sheet.dart';
 | 
			
		||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
 | 
			
		||||
import 'm2_popup_menu_button.dart';
 | 
			
		||||
import 'matrix.dart';
 | 
			
		||||
 | 
			
		||||
@ -185,7 +186,7 @@ class ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
 | 
			
		||||
          context: context,
 | 
			
		||||
          builder: (context) => CupertinoWidgetsBottomSheet(room: widget.room),
 | 
			
		||||
        )
 | 
			
		||||
      : showModalBottomSheet(
 | 
			
		||||
      : showAdaptiveBottomSheet(
 | 
			
		||||
          context: context,
 | 
			
		||||
          builder: (context) => WidgetsBottomSheet(room: widget.room),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,3 @@
 | 
			
		||||
import 'dart:math';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
@ -7,10 +5,8 @@ import 'package:future_loading_dialog/future_loading_dialog.dart';
 | 
			
		||||
import 'package:matrix/matrix.dart';
 | 
			
		||||
import 'package:vrouter/vrouter.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/config/themes.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/content_banner.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/avatar.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/matrix.dart';
 | 
			
		||||
import '../utils/localized_exception_extension.dart';
 | 
			
		||||
 | 
			
		||||
class ProfileBottomSheet extends StatelessWidget {
 | 
			
		||||
  final String userId;
 | 
			
		||||
@ -37,67 +33,55 @@ class ProfileBottomSheet extends StatelessWidget {
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Center(
 | 
			
		||||
      child: SizedBox(
 | 
			
		||||
        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: const Icon(Icons.arrow_downward_outlined),
 | 
			
		||||
                  onPressed: Navigator.of(context, rootNavigator: false).pop,
 | 
			
		||||
                  tooltip: L10n.of(context)!.close,
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
              body: FutureBuilder<Profile>(
 | 
			
		||||
                  future:
 | 
			
		||||
                      Matrix.of(context).client.getProfileFromUserId(userId),
 | 
			
		||||
    return SafeArea(
 | 
			
		||||
      child: FutureBuilder<Profile>(
 | 
			
		||||
        future: Matrix.of(context).client.getProfileFromUserId(userId),
 | 
			
		||||
        builder: (context, snapshot) {
 | 
			
		||||
          final profile = snapshot.data;
 | 
			
		||||
 | 
			
		||||
                    return Column(
 | 
			
		||||
                      children: [
 | 
			
		||||
                        Expanded(
 | 
			
		||||
                          child: profile == null
 | 
			
		||||
                              ? Container(
 | 
			
		||||
                                  alignment: Alignment.center,
 | 
			
		||||
                                  color: Theme.of(context).secondaryHeaderColor,
 | 
			
		||||
                                  child: snapshot.hasError
 | 
			
		||||
                                      ? Text(snapshot.error!
 | 
			
		||||
                                          .toLocalizedString(context))
 | 
			
		||||
                                      : const CircularProgressIndicator
 | 
			
		||||
                                          .adaptive(strokeWidth: 2),
 | 
			
		||||
                                )
 | 
			
		||||
                              : ContentBanner(
 | 
			
		||||
                                  mxContent: profile.avatarUrl,
 | 
			
		||||
                                  defaultIcon: Icons.account_circle_outlined,
 | 
			
		||||
                                  client: Matrix.of(context).client,
 | 
			
		||||
                                  placeholder: (context) => Center(
 | 
			
		||||
                                    child: Text(
 | 
			
		||||
                                      userId.localpart ?? userId,
 | 
			
		||||
                                      style:
 | 
			
		||||
                                          Theme.of(context).textTheme.headline3,
 | 
			
		||||
          return Scaffold(
 | 
			
		||||
            appBar: AppBar(
 | 
			
		||||
              leading: CloseButton(
 | 
			
		||||
                onPressed: Navigator.of(context, rootNavigator: false).pop,
 | 
			
		||||
              ),
 | 
			
		||||
                                  ),
 | 
			
		||||
                                ),
 | 
			
		||||
                        ),
 | 
			
		||||
                        ListTile(
 | 
			
		||||
              title: ListTile(
 | 
			
		||||
                contentPadding: const EdgeInsets.only(right: 16.0),
 | 
			
		||||
                title: Text(
 | 
			
		||||
                              profile?.displayName ?? userId.localpart ?? ''),
 | 
			
		||||
                          subtitle: Text(userId),
 | 
			
		||||
                          trailing: const Icon(Icons.account_box_outlined),
 | 
			
		||||
                  profile?.displayName ?? userId.localpart ?? userId,
 | 
			
		||||
                  style: const TextStyle(fontSize: 18),
 | 
			
		||||
                ),
 | 
			
		||||
                subtitle: Text(
 | 
			
		||||
                  userId,
 | 
			
		||||
                  style: const TextStyle(fontSize: 12),
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
              actions: [
 | 
			
		||||
                Padding(
 | 
			
		||||
                  padding: const EdgeInsets.all(8.0),
 | 
			
		||||
                  child: OutlinedButton.icon(
 | 
			
		||||
                    onPressed: () => _startDirectChat(context),
 | 
			
		||||
                    icon: Icon(Icons.adaptive.share_outlined),
 | 
			
		||||
                    label: Text(L10n.of(context)!.share),
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
            body: ListView(
 | 
			
		||||
              children: [
 | 
			
		||||
                Center(
 | 
			
		||||
                  child: Padding(
 | 
			
		||||
                    padding: const EdgeInsets.all(16.0),
 | 
			
		||||
                    child: Avatar(
 | 
			
		||||
                      mxContent: profile?.avatarUrl,
 | 
			
		||||
                      name: profile?.displayName ?? userId,
 | 
			
		||||
                      size: Avatar.defaultSize * 3,
 | 
			
		||||
                      fontSize: 36,
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
                Container(
 | 
			
		||||
                  width: double.infinity,
 | 
			
		||||
                  padding: const EdgeInsets.all(12),
 | 
			
		||||
                          child: ElevatedButton.icon(
 | 
			
		||||
                  child: FloatingActionButton.extended(
 | 
			
		||||
                    onPressed: () => _startDirectChat(context),
 | 
			
		||||
                    label: Text(L10n.of(context)!.newChat),
 | 
			
		||||
                    icon: const Icon(Icons.send_outlined),
 | 
			
		||||
@ -105,11 +89,9 @@ class ProfileBottomSheet extends StatelessWidget {
 | 
			
		||||
                ),
 | 
			
		||||
                const SizedBox(height: 8),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          );
 | 
			
		||||
                  }),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
        },
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,3 @@
 | 
			
		||||
import 'dart:math';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
@ -8,7 +6,6 @@ import 'package:matrix/matrix.dart';
 | 
			
		||||
import 'package:matrix_link_text/link_text.dart';
 | 
			
		||||
import 'package:vrouter/vrouter.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/config/themes.dart';
 | 
			
		||||
import 'package:fluffychat/utils/url_launcher.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/content_banner.dart';
 | 
			
		||||
import 'package:fluffychat/widgets/matrix.dart';
 | 
			
		||||
@ -72,13 +69,7 @@ class PublicRoomBottomSheet extends StatelessWidget {
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final roomAlias = this.roomAlias;
 | 
			
		||||
    return Center(
 | 
			
		||||
      child: SizedBox(
 | 
			
		||||
        width: min(
 | 
			
		||||
            MediaQuery.of(context).size.width, FluffyThemes.columnWidth * 1.5),
 | 
			
		||||
        child: Material(
 | 
			
		||||
          elevation: 4,
 | 
			
		||||
          child: SafeArea(
 | 
			
		||||
    return SafeArea(
 | 
			
		||||
      child: Scaffold(
 | 
			
		||||
        extendBodyBehindAppBar: true,
 | 
			
		||||
        appBar: AppBar(
 | 
			
		||||
@ -116,8 +107,7 @@ class PublicRoomBottomSheet extends StatelessWidget {
 | 
			
		||||
                      alignment: Alignment.center,
 | 
			
		||||
                      color: Theme.of(context).secondaryHeaderColor,
 | 
			
		||||
                      child: snapshot.hasError
 | 
			
		||||
                                ? Text(
 | 
			
		||||
                                    snapshot.error!.toLocalizedString(context))
 | 
			
		||||
                          ? Text(snapshot.error!.toLocalizedString(context))
 | 
			
		||||
                          : const CircularProgressIndicator.adaptive(
 | 
			
		||||
                              strokeWidth: 2),
 | 
			
		||||
                    )
 | 
			
		||||
@ -148,14 +138,10 @@ class PublicRoomBottomSheet extends StatelessWidget {
 | 
			
		||||
                      ),
 | 
			
		||||
                      subtitle: LinkText(
 | 
			
		||||
                        text: profile!.topic!,
 | 
			
		||||
                              linkStyle:
 | 
			
		||||
                                  const TextStyle(color: Colors.blueAccent),
 | 
			
		||||
                        linkStyle: const TextStyle(color: Colors.blueAccent),
 | 
			
		||||
                        textStyle: TextStyle(
 | 
			
		||||
                          fontSize: 14,
 | 
			
		||||
                                color: Theme.of(context)
 | 
			
		||||
                                    .textTheme
 | 
			
		||||
                                    .bodyText2!
 | 
			
		||||
                                    .color,
 | 
			
		||||
                          color: Theme.of(context).textTheme.bodyText2!.color,
 | 
			
		||||
                        ),
 | 
			
		||||
                        onLinkTap: (url) =>
 | 
			
		||||
                            UrlLauncher(context, url).launchUrl(),
 | 
			
		||||
@ -165,9 +151,6 @@ class PublicRoomBottomSheet extends StatelessWidget {
 | 
			
		||||
              );
 | 
			
		||||
            }),
 | 
			
		||||
      ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user