1
0
Fork 0
forked from Nexus/nexus

fix some power level checks, fixes #19

This commit is contained in:
Henry Hiles 2026-05-04 12:53:04 -04:00
commit e310f0f60e
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
2 changed files with 136 additions and 115 deletions

View file

@ -91,81 +91,92 @@ class ChatBox extends HookConsumerWidget {
padding: EdgeInsets.symmetric(horizontal: 8), padding: EdgeInsets.symmetric(horizontal: 8),
child: Row( child: Row(
spacing: 8, spacing: 8,
children: [ mainAxisAlignment: MainAxisAlignment.center,
EmojiPickerButton( children: canSendMessages
context: context, ? [
onSelection: (_) => node?.requestFocus(), EmojiPickerButton(
controller: controller.value, context: context,
), onSelection: (_) => node?.requestFocus(),
PopupMenuButton( controller: controller.value,
tooltip: "Add media",
enabled: canSendMessages,
itemBuilder: (context) => [
PopupMenuItem(
child: ListTile(
title: Text("Camera"),
leading: Icon(Icons.add_a_photo),
), ),
), PopupMenuButton(
PopupMenuItem( tooltip: "Add media",
child: ListTile( enabled: canSendMessages,
title: Text("Gallery"), itemBuilder: (context) => [
leading: Icon(Icons.add_photo_alternate), PopupMenuItem(
child: ListTile(
title: Text("Camera"),
leading: Icon(Icons.add_a_photo),
),
),
PopupMenuItem(
child: ListTile(
title: Text("Gallery"),
leading: Icon(Icons.add_photo_alternate),
),
),
PopupMenuItem(
child: ListTile(
title: Text("Files"),
leading: Icon(Icons.attachment),
),
),
],
icon: Icon(Icons.add),
), ),
), Expanded(
PopupMenuItem( child: FlutterTagger(
child: ListTile( triggerStrategy: TriggerStrategy.eager,
title: Text("Files"), overlay: MentionOverlay(
leading: Icon(Icons.attachment), query: query.value,
triggerCharacter: triggerCharacter.value,
addTag: ({required id, required name}) {
controller.value.addTag(id: id, name: name);
node?.requestFocus();
},
),
controller: controller.value,
onSearch: (newQuery, newTriggerCharacter) {
triggerCharacter.value = newTriggerCharacter;
query.value = newQuery;
},
triggerCharacterAndStyles: {
"@": style,
"#": style,
},
builder: (context, key) => TextFormField(
enabled: canSendMessages,
maxLines: 12,
minLines: 1,
autofocus: true,
decoration: InputDecoration(
hintText: "Your message here...",
border: InputBorder.none,
),
controller: controller.value,
key: key,
onFieldSubmitted: (_) => send(),
// Don't defocus on submit
onEditingComplete: () {},
textInputAction: TextInputAction.done,
focusNode: node,
),
),
), ),
), IconButton(
], onPressed: !canSendMessages ? null : send,
icon: Icon(Icons.add), icon: Icon(Icons.send),
), tooltip: "Send message",
Expanded(
child: FlutterTagger(
triggerStrategy: TriggerStrategy.eager,
overlay: MentionOverlay(
query: query.value,
triggerCharacter: triggerCharacter.value,
addTag: ({required id, required name}) {
controller.value.addTag(id: id, name: name);
node?.requestFocus();
},
),
controller: controller.value,
onSearch: (newQuery, newTriggerCharacter) {
triggerCharacter.value = newTriggerCharacter;
query.value = newQuery;
},
triggerCharacterAndStyles: {"@": style, "#": style},
builder: (context, key) => TextFormField(
enabled: canSendMessages,
maxLines: 12,
minLines: 1,
autofocus: true,
decoration: InputDecoration(
hintText: canSendMessages
? "Your message here..."
: "You don't have permission to send messages in this room...",
border: InputBorder.none,
), ),
controller: controller.value, ]
key: key, : [
onFieldSubmitted: (_) => send(), Padding(
// Don't defocus on submit padding: EdgeInsetsGeometry.all(8),
onEditingComplete: () {}, child: Text(
textInputAction: TextInputAction.done, "You don't have permission to send messages in this room...",
focusNode: node, ),
), ),
), ],
),
IconButton(
onPressed: !canSendMessages ? null : send,
icon: Icon(Icons.send),
tooltip: "Send message",
),
],
), ),
), ),
], ],

View file

@ -87,53 +87,63 @@ class RoomChat extends HookConsumerWidget {
List<PopupMenuEntry> getMessageOptions(Message message) { List<PopupMenuEntry> getMessageOptions(Message message) {
final isSentByMe = message.authorId == userId; final isSentByMe = message.authorId == userId;
return [ return [
PopupMenuItem( if (ref.watch(
child: Row( PowerLevelController.provider(
children: [ PowerLevelConfig(eventType: "m.reaction"),
...{ ),
...ref.watch( ))
AccountDataController.provider.select( PopupMenuItem(
(value) => IList( child: Row(
value["m.recent_emoji"]?.content["recent_emoji"] ?? children: [
[], ...{
).map((entry) => entry["emoji"]), ...ref.watch(
AccountDataController.provider.select(
(value) => IList(
value["m.recent_emoji"]?.content["recent_emoji"] ??
[],
).map((entry) => entry["emoji"]),
),
),
"👍",
"🤣",
"😭",
"🤔",
}
.toIList()
.sublist(0, 4)
.map(
(emoji) => IconButton(
onPressed: () async {
Navigator.of(context).pop();
await notifier
.sendReaction(emoji, message)
.onError(showError);
},
icon: Text(emoji),
), ),
), ),
"👍", EmojiPickerButton(
"🤣", context: context,
"😭", onPressed: Navigator.of(context).pop,
"🤔", onSelection: (emoji) =>
} notifier.sendReaction(emoji, message).onError(showError),
.toIList() ),
.sublist(0, 4) ],
.map( ),
(emoji) => IconButton( ),
onPressed: () async { if (ref.watch(
Navigator.of(context).pop(); PowerLevelController.provider(
await notifier PowerLevelConfig(eventType: "m.room.message"),
.sendReaction(emoji, message) ),
.onError(showError); ))
}, PopupMenuItem(
icon: Text(emoji), onTap: () {
), relatedMessage.value = message;
), relationType.value = RelationType.reply;
EmojiPickerButton( composerNode.requestFocus();
context: context, },
onPressed: Navigator.of(context).pop, child: ListTile(leading: Icon(Icons.reply), title: Text("Reply")),
onSelection: (emoji) =>
notifier.sendReaction(emoji, message).onError(showError),
),
],
), ),
),
PopupMenuItem(
onTap: () {
relatedMessage.value = message;
relationType.value = RelationType.reply;
composerNode.requestFocus();
},
child: ListTile(leading: Icon(Icons.reply), title: Text("Reply")),
),
if (message is TextMessage && isSentByMe) if (message is TextMessage && isSentByMe)
PopupMenuItem( PopupMenuItem(
onTap: () { onTap: () {