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