Merge branch 'soru/user-slider-on-pill-tap' into 'main'

feat: Open user bottom sheet on tapping user pills

See merge request famedly/fluffychat!529
This commit is contained in:
Sorunome 2021-09-22 13:16:51 +00:00
commit b079e786c7
3 changed files with 57 additions and 32 deletions

View File

@ -9,15 +9,18 @@ import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:vrouter/vrouter.dart'; import 'package:vrouter/vrouter.dart';
import 'views/user_bottom_sheet_view.dart'; import 'views/user_bottom_sheet_view.dart';
import '../widgets/matrix.dart';
class UserBottomSheet extends StatefulWidget { class UserBottomSheet extends StatefulWidget {
final User user; final User user;
final Profile profile;
final Function onMention; final Function onMention;
final BuildContext outerContext; final BuildContext outerContext;
const UserBottomSheet({ const UserBottomSheet({
Key key, Key key,
@required this.user, this.user,
this.profile,
@required this.outerContext, @required this.outerContext,
this.onMention, this.onMention,
}) : super(key: key); }) : super(key: key);
@ -83,14 +86,28 @@ class UserBottomSheetController extends State<UserBottomSheet> {
} }
break; break;
case 'message': case 'message':
final roomIdResult = await showFutureLoadingDialog( if (widget.user != null) {
context: context, final roomIdResult = await showFutureLoadingDialog(
future: () => widget.user.startDirectChat(), context: context,
); future: () => widget.user.startDirectChat(),
if (roomIdResult.error != null) return; );
VRouter.of(widget.outerContext) if (roomIdResult.error != null) return;
.toSegments(['rooms', roomIdResult.result]); VRouter.of(widget.outerContext)
Navigator.of(context, rootNavigator: false).pop(); .toSegments(['rooms', roomIdResult.result]);
Navigator.of(context, rootNavigator: false).pop();
} else {
final result = await showFutureLoadingDialog<String>(
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; break;
} }
} }

View File

@ -5,6 +5,7 @@ import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/utils/fluffy_share.dart'; import 'package:fluffychat/utils/fluffy_share.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../widgets/content_banner.dart'; import '../../widgets/content_banner.dart';
import '../../widgets/matrix.dart';
import '../user_bottom_sheet.dart'; import '../user_bottom_sheet.dart';
import '../../utils/matrix_sdk_extensions.dart/presence_extension.dart'; import '../../utils/matrix_sdk_extensions.dart/presence_extension.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
@ -17,8 +18,12 @@ class UserBottomSheetView extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final user = controller.widget.user; final user = controller.widget.user;
final client = user.room.client; final client = user?.room?.client ?? Matrix.of(context).client;
final presence = client.presences[user.id]; 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( return Center(
child: Container( child: Container(
width: min( width: min(
@ -37,12 +42,12 @@ class UserBottomSheetView extends StatelessWidget {
onPressed: Navigator.of(context, rootNavigator: false).pop, onPressed: Navigator.of(context, rootNavigator: false).pop,
tooltip: L10n.of(context).close, tooltip: L10n.of(context).close,
), ),
title: Text(user.calcDisplayname()), title: Text(displayname),
actions: [ actions: [
if (user.id != user.room.client.userID) if (mxid != client.userID)
PopupMenuButton( PopupMenuButton(
itemBuilder: (_) => [ itemBuilder: (_) => [
if (controller.widget.onMention != null) if (user != null && controller.widget.onMention != null)
PopupMenuItem( PopupMenuItem(
value: 'mention', value: 'mention',
child: _TextWithIcon( child: _TextWithIcon(
@ -50,8 +55,8 @@ class UserBottomSheetView extends StatelessWidget {
Icons.alternate_email_outlined, Icons.alternate_email_outlined,
), ),
), ),
if (user.id != user.room.client.userID && if (mxid != client.userID &&
!user.room.isDirectChat) (user == null || !user.room.isDirectChat))
PopupMenuItem( PopupMenuItem(
value: 'message', value: 'message',
child: _TextWithIcon( child: _TextWithIcon(
@ -59,7 +64,7 @@ class UserBottomSheetView extends StatelessWidget {
Icons.send_outlined, Icons.send_outlined,
), ),
), ),
if (user.canChangePowerLevel) if (user != null && user.canChangePowerLevel)
PopupMenuItem( PopupMenuItem(
value: 'permission', value: 'permission',
child: _TextWithIcon( child: _TextWithIcon(
@ -67,7 +72,7 @@ class UserBottomSheetView extends StatelessWidget {
Icons.edit_attributes_outlined, Icons.edit_attributes_outlined,
), ),
), ),
if (user.canKick) if (user != null && user.canKick)
PopupMenuItem( PopupMenuItem(
value: 'kick', value: 'kick',
child: _TextWithIcon( child: _TextWithIcon(
@ -75,7 +80,9 @@ class UserBottomSheetView extends StatelessWidget {
Icons.exit_to_app_outlined, Icons.exit_to_app_outlined,
), ),
), ),
if (user.canBan && user.membership != Membership.ban) if (user != null &&
user.canBan &&
user.membership != Membership.ban)
PopupMenuItem( PopupMenuItem(
value: 'ban', value: 'ban',
child: _TextWithIcon( child: _TextWithIcon(
@ -83,7 +90,8 @@ class UserBottomSheetView extends StatelessWidget {
Icons.warning_sharp, Icons.warning_sharp,
), ),
) )
else if (user.canBan && else if (user != null &&
user.canBan &&
user.membership == Membership.ban) user.membership == Membership.ban)
PopupMenuItem( PopupMenuItem(
value: 'unban', value: 'unban',
@ -101,17 +109,17 @@ class UserBottomSheetView extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
child: ContentBanner( child: ContentBanner(
user.avatarUrl, avatarUrl,
defaultIcon: Icons.person_outline, defaultIcon: Icons.person_outline,
client: user.room.client, client: client,
), ),
), ),
ListTile( ListTile(
title: Text(L10n.of(context).username), title: Text(L10n.of(context).username),
subtitle: Text(user.id), subtitle: Text(mxid),
trailing: Icon(Icons.share_outlined), trailing: Icon(Icons.share_outlined),
onTap: () => FluffyShare.share( onTap: () =>
user.id, controller.widget.outerContext), FluffyShare.share(mxid, controller.widget.outerContext),
), ),
if (presence != null) if (presence != null)
ListTile( ListTile(

View File

@ -11,6 +11,7 @@ import 'package:punycode/punycode.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'platform_infos.dart'; import 'platform_infos.dart';
import '../pages/user_bottom_sheet.dart';
class UrlLauncher { class UrlLauncher {
final String url; final String url;
@ -166,16 +167,15 @@ class UrlLauncher {
}); });
} }
} else if (identityParts.primaryIdentifier.sigil == '@') { } else if (identityParts.primaryIdentifier.sigil == '@') {
final result = await showFutureLoadingDialog<String>( final profile = await matrix.client
.getProfileFromUserId(identityParts.primaryIdentifier);
await showModalBottomSheet(
context: context, context: context,
future: () => matrix.client.startDirectChat( builder: (c) => UserBottomSheet(
identityParts.primaryIdentifier, profile: profile,
outerContext: context,
), ),
); );
if (result.error == null) {
VRouter.of(context).toSegments(['rooms', result.result]);
return;
}
} }
} }
} }