add emoji overlay

This commit is contained in:
Henry Hiles 2026-09-16 16:52:58 -04:00
commit 163947fc90
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
5 changed files with 89 additions and 46 deletions

View file

@ -55,10 +55,10 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend.
- [x] Per message profiles
- [x] Attachments
- [ ] Commands with [MSC4391](https://github.com/matrix-org/matrix-spec-proposals/pull/4391)
- [x] Mentions
- [x] Tags
- [x] Users
- [x] Rooms
- [ ] Inline emoji picker (Putting this here since it'll be implemented the same way as mentions)
- [x] Emojis
- [ ] Custom emojis/stickers
- [ ] GIFs using Gomuks' GIF proxies
- [x] Receiving

View file

@ -0,0 +1,44 @@
import "package:collection/collection.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:material_emoji_picker/material_emoji_picker.dart";
import "package:material_ui/material_ui.dart";
import "package:nexus/helpers/extensions/better_when.dart";
class const EmojiOverlay(
final String query, {
required final String roomId,
required final void Function({required String id, required String name})
addTag,
super.key,
}) extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) => ref
.watch(EmojiController.provider)
.betterWhen(
data: (emojis) => ListView(
children: emojis
.map((element) => element.emojis)
.flattened
.where(
(emoji) =>
emoji.aliases.join().contains(query) ||
emoji.description.contains(query) ||
emoji.tags.join().contains(query),
)
.map(
(emoji) => ListTile(
leading: emoji.widget,
title: Text(emoji.aliases.first),
subtitle: Text(emoji.description),
onTap: () => addTag(
id: Uri.tryParse(emoji.value)?.scheme == "mxc"
? "" // TODO: Handle custom emotes
: emoji.value,
name: emoji.aliases.first,
),
),
)
.toList(),
),
);
}

View file

@ -28,9 +28,7 @@ class const RoomOverlay(
room.metadata?.canonicalAlias ??
room.metadata?.id ??
"Unknown Room";
return Material(
color: Colors.transparent,
child: ListTile(
return ListTile(
leading: AvatarOrHash(
room.metadata?.avatar,
name,
@ -52,7 +50,6 @@ class const RoomOverlay(
"",
);
},
),
);
})
.toList(),

View file

@ -2,6 +2,7 @@ import "package:material_ui/material_ui.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:nexus/widgets/composer/overlays/room_overlay.dart";
import "package:nexus/widgets/composer/overlays/user_overlay.dart";
import "package:nexus/widgets/composer/overlays/emoji_overlay.dart";
import "package:nexus/widgets/loading.dart";
class const TaggerOverlay(
@ -21,14 +22,18 @@ class const TaggerOverlay(
child: Container(
color: Theme.of(context).colorScheme.surfaceContainerHigh,
padding: .all(8),
child: Material(
color: Colors.transparent,
child: switch (triggerCharacter) {
"@" => UserOverlay(query, roomId: roomId, addTag: addTag),
"#" => RoomOverlay(query, addTag: addTag),
":" => EmojiOverlay(query, roomId: roomId, addTag: addTag),
_ => Loading(),
},
),
),
),
);
}
}

View file

@ -41,9 +41,7 @@ class const UserOverlay(
.map(
(member) => switch (member.content) {
MembershipContent(:final displayName, :final avatarUrl) =>
Material(
color: Colors.transparent,
child: ListTile(
ListTile(
leading: AvatarOrHash(
avatarUrl,
displayName ?? member.stateKey!.localpart,
@ -57,7 +55,6 @@ class const UserOverlay(
name: member.stateKey!.localpart,
),
),
),
_ => SizedBox.shrink(),
},
)