diff --git a/lib/pages/user_bottom_sheet.dart b/lib/pages/user_bottom_sheet.dart index 8e048fb9..61e7c45a 100644 --- a/lib/pages/user_bottom_sheet.dart +++ b/lib/pages/user_bottom_sheet.dart @@ -9,15 +9,18 @@ import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:vrouter/vrouter.dart'; import 'views/user_bottom_sheet_view.dart'; +import '../widgets/matrix.dart'; class UserBottomSheet extends StatefulWidget { final User user; + final Profile profile; final Function onMention; final BuildContext outerContext; const UserBottomSheet({ Key key, - @required this.user, + this.user, + this.profile, @required this.outerContext, this.onMention, }) : super(key: key); @@ -83,14 +86,28 @@ class UserBottomSheetController extends State { } break; case 'message': - final roomIdResult = await showFutureLoadingDialog( - context: context, - future: () => widget.user.startDirectChat(), - ); - if (roomIdResult.error != null) return; - VRouter.of(widget.outerContext) - .toSegments(['rooms', roomIdResult.result]); - Navigator.of(context, rootNavigator: false).pop(); + if (widget.user != null) { + final roomIdResult = await showFutureLoadingDialog( + context: context, + future: () => widget.user.startDirectChat(), + ); + if (roomIdResult.error != null) return; + VRouter.of(widget.outerContext) + .toSegments(['rooms', roomIdResult.result]); + Navigator.of(context, rootNavigator: false).pop(); + } else { + final result = await showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context).client.startDirectChat( + widget.profile.userId, + ), + ); + if (result.error == null) { + VRouter.of(context).toSegments(['rooms', result.result]); + Navigator.of(context, rootNavigator: false).pop(); + return; + } + } break; } } diff --git a/lib/pages/views/user_bottom_sheet_view.dart b/lib/pages/views/user_bottom_sheet_view.dart index 47ec2828..edf52118 100644 --- a/lib/pages/views/user_bottom_sheet_view.dart +++ b/lib/pages/views/user_bottom_sheet_view.dart @@ -5,6 +5,7 @@ import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/utils/fluffy_share.dart'; import 'package:flutter/material.dart'; import '../../widgets/content_banner.dart'; +import '../../widgets/matrix.dart'; import '../user_bottom_sheet.dart'; import '../../utils/matrix_sdk_extensions.dart/presence_extension.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -17,8 +18,12 @@ class UserBottomSheetView extends StatelessWidget { @override Widget build(BuildContext context) { final user = controller.widget.user; - final client = user.room.client; - final presence = client.presences[user.id]; + final client = user?.room?.client ?? Matrix.of(context).client; + final mxid = user?.id ?? controller.widget.profile?.userId ?? ''; + final presence = client.presences[mxid]; + final displayname = + user?.calcDisplayname() ?? controller.widget.profile?.displayName ?? ''; + final avatarUrl = user?.avatarUrl ?? controller.widget.profile?.avatarUrl; return Center( child: Container( width: min( @@ -37,12 +42,12 @@ class UserBottomSheetView extends StatelessWidget { onPressed: Navigator.of(context, rootNavigator: false).pop, tooltip: L10n.of(context).close, ), - title: Text(user.calcDisplayname()), + title: Text(displayname), actions: [ - if (user.id != user.room.client.userID) + if (mxid != client.userID) PopupMenuButton( itemBuilder: (_) => [ - if (controller.widget.onMention != null) + if (user != null && controller.widget.onMention != null) PopupMenuItem( value: 'mention', child: _TextWithIcon( @@ -50,8 +55,8 @@ class UserBottomSheetView extends StatelessWidget { Icons.alternate_email_outlined, ), ), - if (user.id != user.room.client.userID && - !user.room.isDirectChat) + if (mxid != client.userID && + (user == null || !user.room.isDirectChat)) PopupMenuItem( value: 'message', child: _TextWithIcon( @@ -59,7 +64,7 @@ class UserBottomSheetView extends StatelessWidget { Icons.send_outlined, ), ), - if (user.canChangePowerLevel) + if (user != null && user.canChangePowerLevel) PopupMenuItem( value: 'permission', child: _TextWithIcon( @@ -67,7 +72,7 @@ class UserBottomSheetView extends StatelessWidget { Icons.edit_attributes_outlined, ), ), - if (user.canKick) + if (user != null && user.canKick) PopupMenuItem( value: 'kick', child: _TextWithIcon( @@ -75,7 +80,9 @@ class UserBottomSheetView extends StatelessWidget { Icons.exit_to_app_outlined, ), ), - if (user.canBan && user.membership != Membership.ban) + if (user != null && + user.canBan && + user.membership != Membership.ban) PopupMenuItem( value: 'ban', child: _TextWithIcon( @@ -83,7 +90,8 @@ class UserBottomSheetView extends StatelessWidget { Icons.warning_sharp, ), ) - else if (user.canBan && + else if (user != null && + user.canBan && user.membership == Membership.ban) PopupMenuItem( value: 'unban', @@ -101,17 +109,17 @@ class UserBottomSheetView extends StatelessWidget { children: [ Expanded( child: ContentBanner( - user.avatarUrl, + avatarUrl, defaultIcon: Icons.person_outline, - client: user.room.client, + client: client, ), ), ListTile( title: Text(L10n.of(context).username), - subtitle: Text(user.id), + subtitle: Text(mxid), trailing: Icon(Icons.share_outlined), - onTap: () => FluffyShare.share( - user.id, controller.widget.outerContext), + onTap: () => + FluffyShare.share(mxid, controller.widget.outerContext), ), if (presence != null) ListTile( diff --git a/lib/utils/url_launcher.dart b/lib/utils/url_launcher.dart index d76806c5..fe40bd91 100644 --- a/lib/utils/url_launcher.dart +++ b/lib/utils/url_launcher.dart @@ -11,6 +11,7 @@ import 'package:punycode/punycode.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'platform_infos.dart'; +import '../pages/user_bottom_sheet.dart'; class UrlLauncher { final String url; @@ -166,16 +167,15 @@ class UrlLauncher { }); } } else if (identityParts.primaryIdentifier.sigil == '@') { - final result = await showFutureLoadingDialog( + final profile = await matrix.client + .getProfileFromUserId(identityParts.primaryIdentifier); + await showModalBottomSheet( context: context, - future: () => matrix.client.startDirectChat( - identityParts.primaryIdentifier, + builder: (c) => UserBottomSheet( + profile: profile, + outerContext: context, ), ); - if (result.error == null) { - VRouter.of(context).toSegments(['rooms', result.result]); - return; - } } } }