working reply rendering
This commit is contained in:
parent
7761ca73fd
commit
a72d696f49
3 changed files with 81 additions and 35 deletions
|
|
@ -31,6 +31,7 @@ abstract class Event with _$Event {
|
|||
String? redactedBy,
|
||||
String? relatesTo,
|
||||
String? relationType,
|
||||
String? replyTo,
|
||||
String? decryptionError,
|
||||
String? sendError,
|
||||
@Default(IMap.empty()) IMap<String, int> reactions,
|
||||
|
|
@ -43,6 +44,10 @@ abstract class Event with _$Event {
|
|||
|
||||
factory Event.fromJson(Map<String, dynamic> json) =>
|
||||
_$EventFromJson(json).copyWith(
|
||||
replyTo:
|
||||
((json["decrypted"] ?? json["content"])["m.new_content"] ??
|
||||
json["decrypted"] ??
|
||||
json["content"])?["m.relates_to"]?["m.in_reply_to"]?["event_id"],
|
||||
content: Content.fromEventJson(
|
||||
(json["decrypted"] ?? json["content"])["m.new_content"] ??
|
||||
json["decrypted"] ??
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import "package:nexus/models/event.dart";
|
|||
import "package:nexus/models/requests/get_event_request.dart";
|
||||
import "package:nexus/widgets/expandable_image.dart";
|
||||
import "package:nexus/widgets/html/html.dart";
|
||||
import "package:nexus/widgets/html/quoted.dart";
|
||||
import "package:nexus/widgets/lazy_loading/message_avatar.dart";
|
||||
import "package:nexus/widgets/lazy_loading/message_displayname.dart";
|
||||
import "package:nexus/widgets/link_preview.dart";
|
||||
|
|
@ -110,8 +109,9 @@ class EventRenderer extends ConsumerWidget {
|
|||
],
|
||||
),
|
||||
Card(
|
||||
color:
|
||||
ref.watch(
|
||||
color: textOnly
|
||||
? Colors.transparent
|
||||
: ref.watch(
|
||||
ClientStateController.provider.select(
|
||||
(value) => value?.userId,
|
||||
),
|
||||
|
|
@ -121,38 +121,63 @@ class EventRenderer extends ConsumerWidget {
|
|||
? colorScheme.onPrimary
|
||||
: colorScheme.primaryContainer)
|
||||
: colorScheme.surfaceContainer,
|
||||
elevation: textOnly ? 0 : null,
|
||||
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(12),
|
||||
padding: textOnly
|
||||
? EdgeInsets.zero
|
||||
: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (event.relationType == "m.in_reply_to" &&
|
||||
event.relatesTo != null)
|
||||
Quoted(
|
||||
ref
|
||||
.watch(
|
||||
if (event.replyTo != null)
|
||||
Card(
|
||||
margin: EdgeInsets.only(bottom: 8),
|
||||
color: theme.colorScheme.surfaceContainer,
|
||||
child: InkWell(
|
||||
onTap: onTapReply,
|
||||
child: Padding(
|
||||
padding: EdgeInsetsGeometry.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 12,
|
||||
),
|
||||
child: switch (ref.watch(
|
||||
EventController.provider(
|
||||
GetEventRequest(
|
||||
roomId: event.roomId,
|
||||
eventId: event.relatesTo!,
|
||||
eventId: event.replyTo!,
|
||||
),
|
||||
),
|
||||
)
|
||||
.when(
|
||||
data: (replyEvent) => replyEvent == null
|
||||
? SizedBox.shrink()
|
||||
: EventRenderer(
|
||||
replyEvent,
|
||||
)) {
|
||||
AsyncData(:final value?) ||
|
||||
AsyncLoading(:final value?) => Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
MessageAvatar(event, height: 24),
|
||||
MessageDisplayname(
|
||||
event,
|
||||
style: TextStyle(
|
||||
color:
|
||||
theme.colorScheme.primary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: EventRenderer(
|
||||
value,
|
||||
textOnly: true,
|
||||
maxLines: 1,
|
||||
),
|
||||
error: (_, _) => Text(
|
||||
),
|
||||
],
|
||||
),
|
||||
AsyncError _ => Text(
|
||||
"An error occurred while fetching the reply",
|
||||
style: errorStyle,
|
||||
),
|
||||
loading: () =>
|
||||
Text("Fetching event..."),
|
||||
_ => Text("Fetching event..."),
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
switch (event.content) {
|
||||
|
|
@ -408,6 +433,8 @@ class EventRenderer extends ConsumerWidget {
|
|||
? textOnly
|
||||
? Text("Unknown event type", style: errorStyle)
|
||||
: SizedBox.shrink()
|
||||
: textOnly
|
||||
? child
|
||||
: GestureDetector(
|
||||
onSecondaryTapUp: contextMenuCallback,
|
||||
onLongPressStart: contextMenuCallback,
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ class RoomChat extends HookConsumerWidget {
|
|||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final relatedEvent = useState<Event?>(null);
|
||||
final relationType = useState(RelationType.reply);
|
||||
final flashingEvent = useState<String?>(null);
|
||||
|
||||
final memberListOpened = useState<bool>(showMembersByDefault);
|
||||
|
||||
|
|
@ -329,21 +330,34 @@ class RoomChat extends HookConsumerWidget {
|
|||
value[index],
|
||||
EventRenderer(
|
||||
value[index],
|
||||
onTapReply: () =>
|
||||
onTapReply: () async {
|
||||
final replyId = value[index].replyTo;
|
||||
listController.value.animateToItem(
|
||||
index: index,
|
||||
index: value.indexWhere(
|
||||
(element) => element.eventId == replyId,
|
||||
),
|
||||
scrollController: scrollController,
|
||||
alignment: 0.5,
|
||||
duration: (_) =>
|
||||
Duration(milliseconds: 250),
|
||||
curve: (_) => Curves.easeInOut,
|
||||
),
|
||||
);
|
||||
flashingEvent.value = replyId;
|
||||
await Future.delayed(
|
||||
Duration(seconds: 1),
|
||||
() {
|
||||
if (flashingEvent.value == replyId) {
|
||||
flashingEvent.value = null;
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
getEventOptions: getEventOptions,
|
||||
// TODO: Reimplement grouping
|
||||
isGrouped: false,
|
||||
),
|
||||
// TODO: Reimplement flashing
|
||||
isFlashing: false,
|
||||
isFlashing:
|
||||
flashingEvent.value == value[index].eventId,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue