forked from Nexus/nexus
parent
d7ea233b18
commit
05bc9034d1
4 changed files with 141 additions and 127 deletions
|
|
@ -63,126 +63,118 @@ class ChatBox extends HookConsumerWidget {
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
);
|
);
|
||||||
|
|
||||||
return Positioned(
|
return Padding(
|
||||||
bottom: 0,
|
padding: EdgeInsetsGeometry.all(12),
|
||||||
left: 0,
|
child: ClipRRect(
|
||||||
right: 0,
|
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||||
child: Padding(
|
child: Column(
|
||||||
padding: EdgeInsetsGeometry.all(12),
|
children: [
|
||||||
child: ClipRRect(
|
RelationPreview(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
relatedEvent,
|
||||||
child: Column(
|
shouldMention: shouldMention.value,
|
||||||
children: [
|
toggleShouldMention: () =>
|
||||||
RelationPreview(
|
shouldMention.value = !shouldMention.value,
|
||||||
relatedEvent,
|
relationType: relationType,
|
||||||
shouldMention: shouldMention.value,
|
onDismiss: onDismiss,
|
||||||
toggleShouldMention: () =>
|
),
|
||||||
shouldMention.value = !shouldMention.value,
|
Container(
|
||||||
relationType: relationType,
|
color: theme.colorScheme.surfaceContainerHighest,
|
||||||
onDismiss: onDismiss,
|
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||||
),
|
child: Row(
|
||||||
Container(
|
spacing: 8,
|
||||||
color: theme.colorScheme.surfaceContainerHighest,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
children:
|
||||||
child: Row(
|
ref.watch(
|
||||||
spacing: 8,
|
PowerLevelController.provider(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
PowerLevelConfig(
|
||||||
children:
|
eventType: EventType.message,
|
||||||
ref.watch(
|
roomId: roomId,
|
||||||
PowerLevelController.provider(
|
|
||||||
PowerLevelConfig(
|
|
||||||
eventType: EventType.message,
|
|
||||||
roomId: roomId,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
? [
|
)
|
||||||
EmojiPickerButton(
|
? [
|
||||||
context: context,
|
EmojiPickerButton(
|
||||||
onSelection: (_) => node?.requestFocus(),
|
context: context,
|
||||||
|
onSelection: (_) => node?.requestFocus(),
|
||||||
|
controller: controller.value,
|
||||||
|
),
|
||||||
|
PopupMenuButton(
|
||||||
|
tooltip: "Add media",
|
||||||
|
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),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: FlutterTagger(
|
||||||
|
triggerStrategy: TriggerStrategy.eager,
|
||||||
|
overlay: MentionOverlay(
|
||||||
|
roomId,
|
||||||
|
query: query.value,
|
||||||
|
triggerCharacter: triggerCharacter.value,
|
||||||
|
addTag: ({required id, required name}) {
|
||||||
|
controller.value.addTag(id: id, name: name);
|
||||||
|
node?.requestFocus();
|
||||||
|
},
|
||||||
|
),
|
||||||
controller: controller.value,
|
controller: controller.value,
|
||||||
),
|
onSearch: (newQuery, newTriggerCharacter) {
|
||||||
PopupMenuButton(
|
triggerCharacter.value = newTriggerCharacter;
|
||||||
tooltip: "Add media",
|
query.value = newQuery;
|
||||||
itemBuilder: (context) => [
|
},
|
||||||
PopupMenuItem(
|
triggerCharacterAndStyles: {"@": style, "#": style},
|
||||||
child: ListTile(
|
builder: (context, key) => TextFormField(
|
||||||
title: Text("Camera"),
|
maxLines: 12,
|
||||||
leading: Icon(Icons.add_a_photo),
|
minLines: 1,
|
||||||
),
|
autofocus: true,
|
||||||
),
|
decoration: InputDecoration(
|
||||||
PopupMenuItem(
|
hintText: "Your message here...",
|
||||||
child: ListTile(
|
border: InputBorder.none,
|
||||||
title: Text("Gallery"),
|
|
||||||
leading: Icon(Icons.add_photo_alternate),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PopupMenuItem(
|
|
||||||
child: ListTile(
|
|
||||||
title: Text("Files"),
|
|
||||||
leading: Icon(Icons.attachment),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
icon: Icon(Icons.add),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: FlutterTagger(
|
|
||||||
triggerStrategy: TriggerStrategy.eager,
|
|
||||||
overlay: MentionOverlay(
|
|
||||||
roomId,
|
|
||||||
query: query.value,
|
|
||||||
triggerCharacter: triggerCharacter.value,
|
|
||||||
addTag: ({required id, required name}) {
|
|
||||||
controller.value.addTag(id: id, name: name);
|
|
||||||
node?.requestFocus();
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
controller: controller.value,
|
controller: controller.value,
|
||||||
onSearch: (newQuery, newTriggerCharacter) {
|
key: key,
|
||||||
triggerCharacter.value = newTriggerCharacter;
|
onFieldSubmitted: (_) => send(),
|
||||||
query.value = newQuery;
|
// Don't defocus on submit
|
||||||
},
|
onEditingComplete: () {},
|
||||||
triggerCharacterAndStyles: {
|
textInputAction: TextInputAction.done,
|
||||||
"@": style,
|
focusNode: node,
|
||||||
"#": style,
|
|
||||||
},
|
|
||||||
builder: (context, key) => TextFormField(
|
|
||||||
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: send,
|
IconButton(
|
||||||
icon: Icon(Icons.send),
|
onPressed: send,
|
||||||
tooltip: "Send message",
|
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...",
|
||||||
),
|
),
|
||||||
]
|
),
|
||||||
: [
|
],
|
||||||
Padding(
|
|
||||||
padding: EdgeInsetsGeometry.all(8),
|
|
||||||
child: Text(
|
|
||||||
"You don't have permission to send messages in this room...",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import "package:flutter/material.dart";
|
||||||
import "package:flutter/services.dart";
|
import "package:flutter/services.dart";
|
||||||
import "package:flutter_hooks/flutter_hooks.dart";
|
import "package:flutter_hooks/flutter_hooks.dart";
|
||||||
import "package:hooks_riverpod/hooks_riverpod.dart";
|
import "package:hooks_riverpod/hooks_riverpod.dart";
|
||||||
|
import "package:measure_size/measure_size.dart";
|
||||||
import "package:nexus/controllers/account_data_controller.dart";
|
import "package:nexus/controllers/account_data_controller.dart";
|
||||||
import "package:nexus/controllers/client_controller.dart";
|
import "package:nexus/controllers/client_controller.dart";
|
||||||
import "package:nexus/controllers/client_state_controller.dart";
|
import "package:nexus/controllers/client_state_controller.dart";
|
||||||
|
|
@ -45,6 +46,8 @@ class RoomChat extends HookConsumerWidget {
|
||||||
final relationType = useState(RelationType.reply);
|
final relationType = useState(RelationType.reply);
|
||||||
final flashingEvent = useState<String?>(null);
|
final flashingEvent = useState<String?>(null);
|
||||||
|
|
||||||
|
final composerSize = useState<double>(64);
|
||||||
|
|
||||||
final memberListOpened = useState<bool>(showMembersByDefault);
|
final memberListOpened = useState<bool>(showMembersByDefault);
|
||||||
|
|
||||||
final userId = ref.watch(ClientStateController.provider)?.userId;
|
final userId = ref.watch(ClientStateController.provider)?.userId;
|
||||||
|
|
@ -346,7 +349,9 @@ class RoomChat extends HookConsumerWidget {
|
||||||
controller: scrollController,
|
controller: scrollController,
|
||||||
slivers: [
|
slivers: [
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding: EdgeInsetsGeometry.only(bottom: 64),
|
padding: EdgeInsetsGeometry.only(
|
||||||
|
bottom: composerSize.value,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
SuperSliverList.builder(
|
SuperSliverList.builder(
|
||||||
|
|
@ -416,22 +421,30 @@ class RoomChat extends HookConsumerWidget {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ChatBox(
|
Positioned(
|
||||||
roomId,
|
bottom: 0,
|
||||||
node: composerNode,
|
left: 0,
|
||||||
onSend: (text, {required shouldMention, required tags}) =>
|
right: 0,
|
||||||
notifier
|
child: MeasureSize(
|
||||||
.send(
|
onChange: (size) => composerSize.value = size.height,
|
||||||
text,
|
child: ChatBox(
|
||||||
tags: tags,
|
roomId,
|
||||||
relationType: relationType.value,
|
node: composerNode,
|
||||||
shouldMention: shouldMention,
|
onSend: (text, {required shouldMention, required tags}) =>
|
||||||
relation: relatedEvent.value,
|
notifier
|
||||||
)
|
.send(
|
||||||
.onError(showError),
|
text,
|
||||||
relationType: relationType.value,
|
tags: tags,
|
||||||
relatedEvent: relatedEvent.value,
|
relationType: relationType.value,
|
||||||
onDismiss: () => relatedEvent.value = null,
|
shouldMention: shouldMention,
|
||||||
|
relation: relatedEvent.value,
|
||||||
|
)
|
||||||
|
.onError(showError),
|
||||||
|
relationType: relationType.value,
|
||||||
|
relatedEvent: relatedEvent.value,
|
||||||
|
onDismiss: () => relatedEvent.value = null,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -760,6 +760,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.13.0"
|
version: "0.13.0"
|
||||||
|
measure_size:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: measure_size
|
||||||
|
sha256: "4b2de7b29567501434902a2f4080cf12a8bc7038b2eb97dfae91b71791620b68"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.2"
|
||||||
media_kit:
|
media_kit:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ dependencies:
|
||||||
media_kit: 1.2.6
|
media_kit: 1.2.6
|
||||||
media_kit_video: 2.0.1
|
media_kit_video: 2.0.1
|
||||||
media_kit_libs_video: 1.0.7
|
media_kit_libs_video: 1.0.7
|
||||||
|
measure_size: ^5.0.2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: 2.15.0
|
build_runner: 2.15.0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue