Fix sending permission thingy
This commit is contained in:
parent
f249f39972
commit
6215537f8e
2 changed files with 148 additions and 137 deletions
|
|
@ -7,6 +7,7 @@ import "package:nexus/controllers/avatar_controller.dart";
|
||||||
import "package:nexus/controllers/events_controller.dart";
|
import "package:nexus/controllers/events_controller.dart";
|
||||||
import "package:nexus/helpers/extensions/event_to_message.dart";
|
import "package:nexus/helpers/extensions/event_to_message.dart";
|
||||||
import "package:nexus/helpers/extensions/list_to_messages.dart";
|
import "package:nexus/helpers/extensions/list_to_messages.dart";
|
||||||
|
import "package:fluttertagger/fluttertagger.dart" as tagger;
|
||||||
|
|
||||||
class RoomChatController extends AsyncNotifier<ChatController> {
|
class RoomChatController extends AsyncNotifier<ChatController> {
|
||||||
final Room room;
|
final Room room;
|
||||||
|
|
@ -93,11 +94,27 @@ class RoomChatController extends AsyncNotifier<ChatController> {
|
||||||
Future<void> updateMessage(Message message, Message newMessage) async =>
|
Future<void> updateMessage(Message message, Message newMessage) async =>
|
||||||
(await future).updateMessage(message, newMessage);
|
(await future).updateMessage(message, newMessage);
|
||||||
|
|
||||||
Future<void> send(String message, {Message? replyTo}) async =>
|
Future<void> send(
|
||||||
room.sendTextEvent(
|
String message, {
|
||||||
message,
|
required Iterable<tagger.Tag> tags,
|
||||||
inReplyTo: replyTo == null ? null : await room.getEventById(replyTo.id),
|
Message? replyTo,
|
||||||
|
}) async {
|
||||||
|
var taggedMessage = message;
|
||||||
|
|
||||||
|
for (final tag in tags) {
|
||||||
|
final escaped = RegExp.escape(tag.id.substring(1));
|
||||||
|
final pattern = RegExp(r"@@(" + escaped + r")#[^#]*#");
|
||||||
|
taggedMessage = taggedMessage.replaceAllMapped(
|
||||||
|
pattern,
|
||||||
|
(m) => "@${m.group(1)}",
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await room.sendTextEvent(
|
||||||
|
taggedMessage,
|
||||||
|
inReplyTo: replyTo == null ? null : await room.getEventById(replyTo.id),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<chat.User> resolveUser(String id) async {
|
Future<chat.User> resolveUser(String id) async {
|
||||||
final user = await room.client.getUserProfile(id);
|
final user = await room.client.getUserProfile(id);
|
||||||
|
|
|
||||||
|
|
@ -33,19 +33,25 @@ class ChatBox extends HookConsumerWidget {
|
||||||
final triggerCharacter = useState("");
|
final triggerCharacter = useState("");
|
||||||
final query = useState("");
|
final query = useState("");
|
||||||
|
|
||||||
Future<void> send() => ref
|
void send() {
|
||||||
.watch(RoomChatController.provider(room).notifier)
|
ref
|
||||||
.send(controller.value.text, replyTo: replyToMessage);
|
.watch(RoomChatController.provider(room).notifier)
|
||||||
|
.send(
|
||||||
|
controller.value.formattedText,
|
||||||
|
replyTo: replyToMessage,
|
||||||
|
tags: controller.value.tags,
|
||||||
|
);
|
||||||
|
controller.value.text = "";
|
||||||
|
}
|
||||||
|
|
||||||
final node = useFocusNode(
|
final node = useFocusNode(
|
||||||
onKeyEvent: (_, event) {
|
onKeyEvent: (_, event) {
|
||||||
if (event is! KeyDownEvent || Platform.isAndroid || Platform.isIOS) {
|
if (event is KeyDownEvent && !Platform.isAndroid && !Platform.isIOS) {
|
||||||
if (event.logicalKey == LogicalKeyboardKey.enter &&
|
if (event.logicalKey == LogicalKeyboardKey.enter &&
|
||||||
!HardwareKeyboard.instance.isShiftPressed) {
|
!HardwareKeyboard.instance.isShiftPressed) {
|
||||||
send();
|
send();
|
||||||
return KeyEventResult.handled;
|
return KeyEventResult.handled;
|
||||||
}
|
} else if (event.logicalKey == LogicalKeyboardKey.escape) {
|
||||||
if (event.logicalKey == LogicalKeyboardKey.escape) {
|
|
||||||
onDismiss();
|
onDismiss();
|
||||||
return KeyEventResult.handled;
|
return KeyEventResult.handled;
|
||||||
}
|
}
|
||||||
|
|
@ -78,139 +84,127 @@ class ChatBox extends HookConsumerWidget {
|
||||||
Container(
|
Container(
|
||||||
color: theme.colorScheme.surfaceContainerHighest,
|
color: theme.colorScheme.surfaceContainerHighest,
|
||||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||||
child: room.canSendDefaultMessages
|
child: Row(
|
||||||
? Row(
|
spacing: 8,
|
||||||
spacing: 8,
|
children: [
|
||||||
children: [
|
PopupMenuButton(
|
||||||
PopupMenuButton(
|
itemBuilder: (context) => [],
|
||||||
itemBuilder: (context) => [],
|
icon: Icon(Icons.add),
|
||||||
icon: Icon(Icons.add),
|
enabled: room.canSendDefaultMessages,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: FlutterTagger(
|
child: FlutterTagger(
|
||||||
triggerStrategy: TriggerStrategy.eager,
|
triggerStrategy: TriggerStrategy.eager,
|
||||||
overlay: Padding(
|
overlay: Padding(
|
||||||
padding: EdgeInsets.all(8),
|
padding: EdgeInsets.all(8),
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.all(
|
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||||
Radius.circular(12),
|
child: Container(
|
||||||
),
|
color: theme.colorScheme.surfaceContainerHigh,
|
||||||
child: Container(
|
padding: EdgeInsets.all(8),
|
||||||
color:
|
child: switch (triggerCharacter.value) {
|
||||||
theme.colorScheme.surfaceContainerHigh,
|
"@" =>
|
||||||
padding: EdgeInsets.all(8),
|
ref
|
||||||
child: switch (triggerCharacter.value) {
|
.watch(MembersController.provider(room))
|
||||||
"@" =>
|
.betterWhen(
|
||||||
ref
|
data: (members) => ListView(
|
||||||
.watch(
|
children:
|
||||||
MembersController.provider(room),
|
(query.value.isEmpty
|
||||||
)
|
? members
|
||||||
.betterWhen(
|
: members.where(
|
||||||
data: (members) => ListView(
|
(member) =>
|
||||||
children:
|
member.senderId
|
||||||
(query.value.isEmpty
|
.contains(
|
||||||
? members
|
query.value,
|
||||||
: members.where(
|
) ||
|
||||||
(member) =>
|
(member.content["displayname"]
|
||||||
member
|
as String?)
|
||||||
.senderId
|
?.contains(
|
||||||
.contains(
|
query
|
||||||
query
|
.value,
|
||||||
.value,
|
) ==
|
||||||
) ||
|
true,
|
||||||
(member.content["displayname"]
|
))
|
||||||
as String?)
|
.map(
|
||||||
?.contains(
|
(member) => ListTile(
|
||||||
query.value,
|
leading: AvatarOrHash(
|
||||||
) ==
|
ref
|
||||||
true,
|
.watch(
|
||||||
))
|
AvatarController.provider(
|
||||||
.map(
|
member
|
||||||
(member) => ListTile(
|
.content["avatar_url"]
|
||||||
leading: AvatarOrHash(
|
.toString(),
|
||||||
ref
|
),
|
||||||
.watch(
|
)
|
||||||
AvatarController.provider(
|
.whenOrNull(
|
||||||
member
|
data: (data) =>
|
||||||
.content["avatar_url"]
|
data,
|
||||||
.toString(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.whenOrNull(
|
|
||||||
data:
|
|
||||||
(
|
|
||||||
data,
|
|
||||||
) =>
|
|
||||||
data,
|
|
||||||
),
|
|
||||||
member
|
|
||||||
.content["displayname"]
|
|
||||||
.toString(),
|
|
||||||
headers: room
|
|
||||||
.client
|
|
||||||
.headers,
|
|
||||||
),
|
),
|
||||||
title: Text(
|
member
|
||||||
member.content["displayname"]
|
.content["displayname"]
|
||||||
as String? ??
|
.toString(),
|
||||||
member
|
headers:
|
||||||
.senderId,
|
room.client.headers,
|
||||||
),
|
),
|
||||||
onTap: () => controller
|
title: Text(
|
||||||
.value
|
member.content["displayname"]
|
||||||
.addTag(
|
as String? ??
|
||||||
id: "member",
|
member.senderId,
|
||||||
name: member
|
),
|
||||||
.senderId
|
onTap: () => controller
|
||||||
.substring(
|
.value
|
||||||
1,
|
.addTag(
|
||||||
)
|
id: member.senderId,
|
||||||
.split(
|
name: member
|
||||||
":",
|
.senderId
|
||||||
)
|
.substring(1)
|
||||||
.first,
|
.split(":")
|
||||||
),
|
.first,
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
.toList(),
|
)
|
||||||
),
|
.toList(),
|
||||||
),
|
),
|
||||||
"#" => Text("Todo"),
|
),
|
||||||
_ => Loading(),
|
"#" => Text("Todo"),
|
||||||
},
|
_ => Loading(),
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
controller: controller.value,
|
|
||||||
onSearch: (newQuery, newTriggerCharacter) {
|
|
||||||
triggerCharacter.value = newTriggerCharacter;
|
|
||||||
query.value = newQuery;
|
|
||||||
},
|
},
|
||||||
triggerCharacterAndStyles: {
|
|
||||||
"@": style,
|
|
||||||
"#": style,
|
|
||||||
":": style,
|
|
||||||
},
|
|
||||||
builder: (context, key) => TextFormField(
|
|
||||||
maxLines: 12,
|
|
||||||
minLines: 1,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: "Your message here...",
|
|
||||||
border: InputBorder.none,
|
|
||||||
),
|
|
||||||
controller: controller.value,
|
|
||||||
key: key,
|
|
||||||
autofocus: true,
|
|
||||||
focusNode: node,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
IconButton(onPressed: send, icon: Icon(Icons.send)),
|
),
|
||||||
],
|
controller: controller.value,
|
||||||
)
|
onSearch: (newQuery, newTriggerCharacter) {
|
||||||
: Text(
|
triggerCharacter.value = newTriggerCharacter;
|
||||||
"You don't have permission to send messages here...",
|
query.value = newQuery;
|
||||||
|
},
|
||||||
|
triggerCharacterAndStyles: {
|
||||||
|
"@": style,
|
||||||
|
"#": style,
|
||||||
|
":": style,
|
||||||
|
},
|
||||||
|
builder: (context, key) => TextFormField(
|
||||||
|
enabled: room.canSendDefaultMessages,
|
||||||
|
maxLines: 12,
|
||||||
|
minLines: 1,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: room.canSendDefaultMessages
|
||||||
|
? "Your message here..."
|
||||||
|
: "You don't have permission to send messages in this room...",
|
||||||
|
border: InputBorder.none,
|
||||||
|
),
|
||||||
|
controller: controller.value,
|
||||||
|
key: key,
|
||||||
|
autofocus: true,
|
||||||
|
focusNode: node,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: room.canSendDefaultMessages ? send : null,
|
||||||
|
icon: Icon(Icons.send),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue