invite-related fixups
This commit is contained in:
parent
485383e99c
commit
ba258c2fcd
6 changed files with 66 additions and 32 deletions
|
|
@ -59,8 +59,13 @@ class InvitesController extends Notifier<IList<RoomSummary>> {
|
|||
summary.copyWith(
|
||||
worldReadable: historyVisibility == .worldReadable,
|
||||
),
|
||||
MembershipContent(:final isDirect) when event.stateKey == userId =>
|
||||
summary.copyWith(invitedBy: event.sender, isDirect: isDirect),
|
||||
MembershipContent(:final isDirect, :final reason)
|
||||
when event.stateKey == userId =>
|
||||
summary.copyWith(
|
||||
invitedBy: event.sender,
|
||||
inviteReason: reason,
|
||||
isDirect: isDirect,
|
||||
),
|
||||
_ => summary,
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@ class const RoomSummary({
|
|||
/// Who invited the current user, for invites.
|
||||
@JsonKey(includeFromJson: false) final String? invitedBy,
|
||||
|
||||
/// The reason given for the invite, if any.
|
||||
@JsonKey(includeFromJson: false) final String? inviteReason,
|
||||
|
||||
/// The inviter's membership, for their display name and avatar.
|
||||
@JsonKey(includeFromJson: false) final MembershipContent? inviterProfile,
|
||||
|
||||
|
|
|
|||
|
|
@ -124,7 +124,6 @@ class const InviteCard(final RoomSummary invite, {super.key})
|
|||
[
|
||||
if (inviterName != null)
|
||||
"${invite.isDirect ? "Direct message from" : "Invited by"} $inviterName",
|
||||
?invite.topic,
|
||||
].join("\n"),
|
||||
maxLines: 2,
|
||||
overflow: .ellipsis,
|
||||
|
|
|
|||
|
|
@ -10,14 +10,17 @@ final class const LinkifiedText(
|
|||
super.key,
|
||||
}) extends ConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) => Linkify(
|
||||
text: text,
|
||||
maxLines: maxLines,
|
||||
style: style,
|
||||
options: .new(humanize: false),
|
||||
onOpen: (link) =>
|
||||
ref.read(LaunchHelper.provider).launchUrl(.parse(link.url)),
|
||||
linkStyle: .new(color: Theme.of(context).colorScheme.primary),
|
||||
overflow: maxLines == null ? null : .ellipsis,
|
||||
);
|
||||
Widget build(BuildContext context, WidgetRef ref) =>
|
||||
MaterialUiCompatibilityBridge(
|
||||
child: Linkify(
|
||||
text: text,
|
||||
maxLines: maxLines,
|
||||
style: style,
|
||||
options: .new(humanize: false),
|
||||
onOpen: (link) =>
|
||||
ref.read(LaunchHelper.provider).launchUrl(.parse(link.url)),
|
||||
linkStyle: .new(color: Theme.of(context).colorScheme.primary),
|
||||
overflow: maxLines == null ? null : .ellipsis,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,18 +55,21 @@ final class const RoomMenuButton(
|
|||
builder: (context) => HookBuilder(
|
||||
builder: (context) {
|
||||
final userIdController = useTextEditingController();
|
||||
final reasonController = useTextEditingController();
|
||||
final text = useValueListenable(userIdController).text.trim();
|
||||
final valid = RegExp(r"^@[^:\s]+:[^\s]+$").hasMatch(text);
|
||||
|
||||
void submit() {
|
||||
if (!valid) return;
|
||||
Navigator.of(context).pop();
|
||||
final reason = reasonController.text.trim();
|
||||
client
|
||||
.setMembership(
|
||||
.new(
|
||||
userId: text,
|
||||
roomId: room!.metadata!.id,
|
||||
action: .invite,
|
||||
reason: reason.isEmpty ? null : reason,
|
||||
),
|
||||
)
|
||||
.onError(showError);
|
||||
|
|
@ -74,18 +77,32 @@ final class const RoomMenuButton(
|
|||
|
||||
return AlertDialog(
|
||||
title: Text("Invite User"),
|
||||
content: TextField(
|
||||
controller: userIdController,
|
||||
autofocus: true,
|
||||
keyboardType: .emailAddress,
|
||||
onSubmitted: (_) => submit(),
|
||||
decoration: .new(
|
||||
labelText: "User ID",
|
||||
hintText: "@user:example.com",
|
||||
errorText: text.isEmpty || valid
|
||||
? null
|
||||
: "Enter a valid user ID",
|
||||
),
|
||||
content: Column(
|
||||
mainAxisSize: .min,
|
||||
spacing: 12,
|
||||
children: [
|
||||
TextField(
|
||||
controller: userIdController,
|
||||
autofocus: true,
|
||||
keyboardType: .emailAddress,
|
||||
onSubmitted: (_) => submit(),
|
||||
decoration: .new(
|
||||
labelText: "User ID",
|
||||
hintText: "@user:example.com",
|
||||
errorText: text.isEmpty || valid
|
||||
? null
|
||||
: "Enter a valid user ID",
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
controller: reasonController,
|
||||
textCapitalization: .sentences,
|
||||
onSubmitted: (_) => submit(),
|
||||
decoration: const .new(
|
||||
labelText: "Invite reason (optional)",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
|
|
|
|||
|
|
@ -61,6 +61,13 @@ class const RoomSummaryDialog(
|
|||
),
|
||||
subtitle: SelectableText(invitedBy),
|
||||
),
|
||||
if (summary.inviteReason case final reason?)
|
||||
ListTile(
|
||||
titleAlignment: ListTileTitleAlignment.titleHeight,
|
||||
leading: const Icon(Icons.format_quote),
|
||||
title: const Text("Invite reason"),
|
||||
subtitle: SelectableText(reason),
|
||||
),
|
||||
// Invite state never includes the member count
|
||||
if (summary.joinedMembers != null || !isInvite)
|
||||
ListTile(
|
||||
|
|
@ -70,23 +77,23 @@ class const RoomSummaryDialog(
|
|||
leading: Icon(Icons.people),
|
||||
),
|
||||
ListTile(
|
||||
title: SelectableText(summary.canonicalAlias ?? summary.roomId),
|
||||
title: Text(
|
||||
summary.canonicalAlias == null ? "Room ID" : "Canonical Alias",
|
||||
),
|
||||
subtitle: SelectableText(summary.canonicalAlias ?? summary.roomId),
|
||||
leading: Icon(Icons.numbers),
|
||||
),
|
||||
if (summary.topic != null)
|
||||
ListTile(
|
||||
titleAlignment: ListTileTitleAlignment.titleHeight,
|
||||
title: LinkifiedText(
|
||||
summary.topic!,
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
title: Text("Topic"),
|
||||
subtitle: LinkifiedText(summary.topic!),
|
||||
leading: Icon(Icons.info),
|
||||
),
|
||||
if (summary.encryption != null)
|
||||
ListTile(title: Text("Encrypted"), leading: Icon(Icons.lock)),
|
||||
if (summary.worldReadable == true)
|
||||
ListTile(
|
||||
title: Text("Anyone can read the history"),
|
||||
title: Text("Anyone can read room history"),
|
||||
leading: Icon(Icons.public),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
Loading…
Reference in a new issue