make user bottom sheet scrollable
This commit is contained in:
parent
ec30adc0e3
commit
a61cac130b
2 changed files with 148 additions and 156 deletions
|
|
@ -7,6 +7,7 @@ import "package:m3e_card_list/m3e_card_list.dart";
|
|||
import "package:nexus/controllers/members_by_status.dart";
|
||||
import "package:nexus/controllers/members_grouped.dart";
|
||||
import "package:nexus/helpers/extensions/get_localpart.dart";
|
||||
import "package:nexus/helpers/extensions/show_user_popover.dart";
|
||||
import "package:nexus/helpers/extensions/string_to_color.dart";
|
||||
import "package:nexus/models/content/membership.dart";
|
||||
import "package:nexus/models/membership_status.dart";
|
||||
|
|
@ -14,7 +15,6 @@ import "package:nexus/widgets/avatar_or_hash.dart";
|
|||
import "package:nexus/widgets/divider_text.dart";
|
||||
import "package:nexus/widgets/error_dialog.dart";
|
||||
import "package:nexus/widgets/loading.dart";
|
||||
import "package:nexus/widgets/user_bottom_sheet.dart";
|
||||
|
||||
class const MemberList(final String roomId, {super.key})
|
||||
extends HookConsumerWidget {
|
||||
|
|
@ -140,20 +140,10 @@ class const MemberList(final String roomId, {super.key})
|
|||
final member = members[index];
|
||||
if (member.content
|
||||
case MembershipContent content) {
|
||||
showModalBottomSheet(
|
||||
constraints: .loose(
|
||||
.new(
|
||||
500,
|
||||
(context.size?.height ?? 1000) - 80,
|
||||
),
|
||||
),
|
||||
isScrollControlled: true,
|
||||
context: context,
|
||||
builder: (context) => UserBottomSheet(
|
||||
content,
|
||||
member.stateKey!,
|
||||
roomId: roomId,
|
||||
),
|
||||
context.showUserPopover(
|
||||
content,
|
||||
member.stateKey!,
|
||||
roomId: roomId,
|
||||
);
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -79,176 +79,178 @@ final class const UserBottomSheet(
|
|||
|
||||
return Padding(
|
||||
padding: .all(42),
|
||||
child: Column(
|
||||
spacing: 4,
|
||||
mainAxisSize: .min,
|
||||
crossAxisAlignment: .center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: .end,
|
||||
children: [
|
||||
M3EButton(
|
||||
onPressed: Navigator.of(context).pop,
|
||||
child: Icon(Icons.close),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 18),
|
||||
|
||||
ExpandableImage(
|
||||
member.avatarUrl == null ? null : .new(mxc: member.avatarUrl!),
|
||||
child: AvatarOrHash(
|
||||
member.avatarUrl,
|
||||
member.displayName ?? userId.localpart,
|
||||
height: 200,
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 8),
|
||||
|
||||
SelectableText(
|
||||
member.displayName ?? userId.localpart,
|
||||
style: textTheme.headlineLarge,
|
||||
textAlign: .center,
|
||||
),
|
||||
SelectableText(
|
||||
userId,
|
||||
textAlign: .center,
|
||||
style: textTheme.titleSmall?.copyWith(
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
|
||||
ref
|
||||
.watch(ProfileController.provider(userId))
|
||||
.betterWhen(
|
||||
loading: () => Text(""),
|
||||
data: (profileResponse) => Column(
|
||||
children: [
|
||||
if (profileResponse.profile.timezone == null &&
|
||||
profileResponse.profile.pronouns.isEmpty)
|
||||
Text(""),
|
||||
Wrap(
|
||||
crossAxisAlignment: .center,
|
||||
alignment: .center,
|
||||
spacing: 4,
|
||||
runSpacing: 4,
|
||||
children: [
|
||||
...profileResponse.profile.pronouns
|
||||
.where(
|
||||
// TODO: Check system language (l10n)
|
||||
(pronoun) => pronoun.language == "en",
|
||||
)
|
||||
.mapIndexed(
|
||||
(index, pronoun) => [
|
||||
if (index != 0)
|
||||
Icon(
|
||||
Icons.circle,
|
||||
size: 4,
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
Text(
|
||||
pronoun.summary,
|
||||
textAlign: .center,
|
||||
style: textTheme.titleSmall?.copyWith(
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
.flattened,
|
||||
|
||||
if (profileResponse.profile.timezone != null) ...[
|
||||
if (profileResponse.profile.pronouns.isNotEmpty)
|
||||
SizedBox(
|
||||
height: 16,
|
||||
child: VerticalDivider(
|
||||
thickness: 1.5,
|
||||
width: 4,
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
profileResponse.profile.timezone!,
|
||||
textAlign: .center,
|
||||
style: textTheme.titleSmall?.copyWith(
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 8),
|
||||
if (userId != ref.watch(ClientStateController.provider)?.userId &&
|
||||
roomId != null) ...[
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
spacing: 4,
|
||||
mainAxisSize: .min,
|
||||
crossAxisAlignment: .center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: .end,
|
||||
children: [
|
||||
Expanded(
|
||||
child: M3EButton.icon(
|
||||
onPressed: null,
|
||||
shape: .square,
|
||||
style: .tonal,
|
||||
icon: Icon(Icons.message),
|
||||
label: Text("Message"),
|
||||
),
|
||||
M3EButton(
|
||||
onPressed: Navigator.of(context).pop,
|
||||
child: Icon(Icons.close),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 18),
|
||||
|
||||
if (ref.watch(
|
||||
PowerLevelController.provider(
|
||||
.membershipAction(
|
||||
action: .kick,
|
||||
roomId: roomId!,
|
||||
targetUser: userId,
|
||||
),
|
||||
ExpandableImage(
|
||||
member.avatarUrl == null ? null : .new(mxc: member.avatarUrl!),
|
||||
child: AvatarOrHash(
|
||||
member.avatarUrl,
|
||||
member.displayName ?? userId.localpart,
|
||||
height: 200,
|
||||
),
|
||||
))
|
||||
Padding(
|
||||
padding: .only(top: 4),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
spacing: 8,
|
||||
children: [
|
||||
if (member.status == .join || member.status == .invite)
|
||||
),
|
||||
|
||||
SizedBox(height: 8),
|
||||
|
||||
SelectableText(
|
||||
member.displayName ?? userId.localpart,
|
||||
style: textTheme.headlineLarge,
|
||||
textAlign: .center,
|
||||
),
|
||||
SelectableText(
|
||||
userId,
|
||||
textAlign: .center,
|
||||
style: textTheme.titleSmall?.copyWith(
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
|
||||
ref
|
||||
.watch(ProfileController.provider(userId))
|
||||
.betterWhen(
|
||||
loading: () => Text(""),
|
||||
data: (profileResponse) => Column(
|
||||
children: [
|
||||
if (profileResponse.profile.timezone == null &&
|
||||
profileResponse.profile.pronouns.isEmpty)
|
||||
Text(""),
|
||||
Wrap(
|
||||
crossAxisAlignment: .center,
|
||||
alignment: .center,
|
||||
spacing: 4,
|
||||
runSpacing: 4,
|
||||
children: [
|
||||
...profileResponse.profile.pronouns
|
||||
.where(
|
||||
// TODO: Check system language (l10n)
|
||||
(pronoun) => pronoun.language == "en",
|
||||
)
|
||||
.mapIndexed(
|
||||
(index, pronoun) => [
|
||||
if (index != 0)
|
||||
Icon(
|
||||
Icons.circle,
|
||||
size: 4,
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
Text(
|
||||
pronoun.summary,
|
||||
textAlign: .center,
|
||||
style: textTheme.titleSmall?.copyWith(
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
.flattened,
|
||||
|
||||
if (profileResponse.profile.timezone != null) ...[
|
||||
if (profileResponse.profile.pronouns.isNotEmpty)
|
||||
SizedBox(
|
||||
height: 16,
|
||||
child: VerticalDivider(
|
||||
thickness: 1.5,
|
||||
width: 4,
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
profileResponse.profile.timezone!,
|
||||
textAlign: .center,
|
||||
style: textTheme.titleSmall?.copyWith(
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 8),
|
||||
if (userId != ref.watch(ClientStateController.provider)?.userId &&
|
||||
roomId != null) ...[
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: M3EButton.icon(
|
||||
onPressed: null,
|
||||
shape: .square,
|
||||
style: .tonal,
|
||||
icon: Icon(Icons.message),
|
||||
label: Text("Message"),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
if (ref.watch(
|
||||
PowerLevelController.provider(
|
||||
.membershipAction(
|
||||
action: .kick,
|
||||
roomId: roomId!,
|
||||
targetUser: userId,
|
||||
),
|
||||
),
|
||||
))
|
||||
Padding(
|
||||
padding: .only(top: 4),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
spacing: 8,
|
||||
children: [
|
||||
if (member.status == .join || member.status == .invite)
|
||||
M3EButton.icon(
|
||||
onPressed: () => showMembershipDialog(.kick),
|
||||
shape: .square,
|
||||
icon: Icon(Icons.sports_martial_arts),
|
||||
label: Text("Kick"),
|
||||
decoration: .new(
|
||||
backgroundColor: WidgetStatePropertyAll(
|
||||
theme.colorScheme.error,
|
||||
),
|
||||
foregroundColor: WidgetStatePropertyAll(
|
||||
theme.colorScheme.onError,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
M3EButton.icon(
|
||||
onPressed: () => showMembershipDialog(.kick),
|
||||
onPressed: () => showMembershipDialog(.ban),
|
||||
shape: .square,
|
||||
icon: Icon(Icons.sports_martial_arts),
|
||||
label: Text("Kick"),
|
||||
icon: Icon(Icons.gavel),
|
||||
label: Text("Ban"),
|
||||
decoration: .new(
|
||||
backgroundColor: WidgetStatePropertyAll(
|
||||
theme.colorScheme.error,
|
||||
theme.colorScheme.errorContainer,
|
||||
),
|
||||
foregroundColor: WidgetStatePropertyAll(
|
||||
theme.colorScheme.onError,
|
||||
theme.colorScheme.onErrorContainer,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
M3EButton.icon(
|
||||
onPressed: () => showMembershipDialog(.ban),
|
||||
shape: .square,
|
||||
icon: Icon(Icons.gavel),
|
||||
label: Text("Ban"),
|
||||
decoration: .new(
|
||||
backgroundColor: WidgetStatePropertyAll(
|
||||
theme.colorScheme.errorContainer,
|
||||
),
|
||||
foregroundColor: WidgetStatePropertyAll(
|
||||
theme.colorScheme.onErrorContainer,
|
||||
),
|
||||
),
|
||||
),
|
||||
].map((e) => Expanded(child: e)).toList(),
|
||||
].map((e) => Expanded(child: e)).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue