From e310f0f60ead18c77b8da2259c8cffe7b617cffb Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 4 May 2026 12:53:04 -0400 Subject: [PATCH] fix some power level checks, fixes #19 --- lib/widgets/chat_page/composer/chat_box.dart | 153 ++++++++++--------- lib/widgets/chat_page/room_chat.dart | 98 ++++++------ 2 files changed, 136 insertions(+), 115 deletions(-) diff --git a/lib/widgets/chat_page/composer/chat_box.dart b/lib/widgets/chat_page/composer/chat_box.dart index 478974e..dee52e1 100644 --- a/lib/widgets/chat_page/composer/chat_box.dart +++ b/lib/widgets/chat_page/composer/chat_box.dart @@ -91,81 +91,92 @@ class ChatBox extends HookConsumerWidget { padding: EdgeInsets.symmetric(horizontal: 8), child: Row( spacing: 8, - children: [ - EmojiPickerButton( - context: context, - onSelection: (_) => node?.requestFocus(), - controller: controller.value, - ), - PopupMenuButton( - tooltip: "Add media", - enabled: canSendMessages, - itemBuilder: (context) => [ - PopupMenuItem( - child: ListTile( - title: Text("Camera"), - leading: Icon(Icons.add_a_photo), + mainAxisAlignment: MainAxisAlignment.center, + children: canSendMessages + ? [ + EmojiPickerButton( + context: context, + onSelection: (_) => node?.requestFocus(), + controller: controller.value, ), - ), - PopupMenuItem( - child: ListTile( - title: Text("Gallery"), - leading: Icon(Icons.add_photo_alternate), + PopupMenuButton( + tooltip: "Add media", + enabled: canSendMessages, + itemBuilder: (context) => [ + 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), ), - ), - PopupMenuItem( - child: ListTile( - title: Text("Files"), - leading: Icon(Icons.attachment), + 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: "Your message here...", + border: InputBorder.none, + ), + controller: controller.value, + key: key, + onFieldSubmitted: (_) => send(), + // Don't defocus on submit + onEditingComplete: () {}, + textInputAction: TextInputAction.done, + focusNode: node, + ), + ), ), - ), - ], - icon: Icon(Icons.add), - ), - 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, + IconButton( + onPressed: !canSendMessages ? null : send, + icon: Icon(Icons.send), + tooltip: "Send message", ), - 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.send), - tooltip: "Send message", - ), - ], + ] + : [ + Padding( + padding: EdgeInsetsGeometry.all(8), + child: Text( + "You don't have permission to send messages in this room...", + ), + ), + ], ), ), ], diff --git a/lib/widgets/chat_page/room_chat.dart b/lib/widgets/chat_page/room_chat.dart index 5166d87..7fb3f8f 100644 --- a/lib/widgets/chat_page/room_chat.dart +++ b/lib/widgets/chat_page/room_chat.dart @@ -87,53 +87,63 @@ class RoomChat extends HookConsumerWidget { List getMessageOptions(Message message) { final isSentByMe = message.authorId == userId; return [ - PopupMenuItem( - child: Row( - children: [ - ...{ - ...ref.watch( - AccountDataController.provider.select( - (value) => IList( - value["m.recent_emoji"]?.content["recent_emoji"] ?? - [], - ).map((entry) => entry["emoji"]), + if (ref.watch( + PowerLevelController.provider( + PowerLevelConfig(eventType: "m.reaction"), + ), + )) + PopupMenuItem( + child: Row( + children: [ + ...{ + ...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), ), ), - "👍", - "🤣", - "😭", - "🤔", - } - .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), - ), - ], + EmojiPickerButton( + context: context, + onPressed: Navigator.of(context).pop, + onSelection: (emoji) => + notifier.sendReaction(emoji, message).onError(showError), + ), + ], + ), + ), + if (ref.watch( + PowerLevelController.provider( + PowerLevelConfig(eventType: "m.room.message"), + ), + )) + PopupMenuItem( + onTap: () { + relatedMessage.value = message; + relationType.value = RelationType.reply; + composerNode.requestFocus(); + }, + child: ListTile(leading: Icon(Icons.reply), title: Text("Reply")), ), - ), - 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) PopupMenuItem( onTap: () {