parent
5304f22456
commit
a220e27877
13 changed files with 193 additions and 143 deletions
|
|
@ -1,43 +1,34 @@
|
|||
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||
import "package:material_ui/material_ui.dart";
|
||||
import "package:nexus/helpers/hooks/chat_scroll.dart";
|
||||
import "package:nexus/models/content/message.dart";
|
||||
import "package:nexus/models/event.dart";
|
||||
import "package:nexus/widgets/renderers/event.dart";
|
||||
import "package:nexus/widgets/highlight_wrapper.dart";
|
||||
import "package:super_sliver_list/super_sliver_list.dart";
|
||||
|
||||
class const ChatTimeline({
|
||||
required final String roomId,
|
||||
required final ChatScroll scroll,
|
||||
required final Future<void> Function(String) jumpToId,
|
||||
required final Future<void> Function(Event event) jumpToEvent,
|
||||
required final IList<PopupMenuEntry> Function(Event) getEventOptions,
|
||||
required final String? highlightedEvent,
|
||||
required final int? highlightedEvent,
|
||||
required final double composerHeight,
|
||||
super.key,
|
||||
}) extends StatelessWidget {
|
||||
bool isGrouped(Event event, Event? previousEvent) =>
|
||||
previousEvent?.content is MessageContent &&
|
||||
previousEvent?.redactedBy == null &&
|
||||
previousEvent?.relationType != "m.replace" &&
|
||||
event.sender == previousEvent?.sender &&
|
||||
event.pmp?.id == previousEvent?.pmp?.id;
|
||||
|
||||
Widget eventRow(
|
||||
Event event,
|
||||
Event? previousEvent, {
|
||||
required Future<void> Function(String) jumpToId,
|
||||
required IList<PopupMenuEntry> Function(Event) getEventOptions,
|
||||
required String? highlightedEvent,
|
||||
int eventRowId,
|
||||
int? previousEventRowId, {
|
||||
required Key key,
|
||||
}) => HighlightWrapper(
|
||||
EventRenderer(
|
||||
event,
|
||||
onTapReply: () => jumpToId(event.replyTo!),
|
||||
eventRowId,
|
||||
previousEventRowId: previousEventRowId,
|
||||
roomId: roomId,
|
||||
jumpToEvent: jumpToEvent,
|
||||
getEventOptions: getEventOptions,
|
||||
isGrouped: isGrouped(event, previousEvent),
|
||||
),
|
||||
key: key,
|
||||
isHighlighted: highlightedEvent == event.eventId,
|
||||
isHighlighted: highlightedEvent == eventRowId,
|
||||
);
|
||||
|
||||
@override
|
||||
|
|
@ -50,29 +41,23 @@ class const ChatTimeline({
|
|||
SliverToBoxAdapter(child: SizedBox(height: composerHeight)),
|
||||
|
||||
SuperSliverList.builder(
|
||||
itemCount: scroll.liveItems.length,
|
||||
itemCount: scroll.liveRows.length,
|
||||
itemBuilder: (_, index) => eventRow(
|
||||
scroll.liveItems[index],
|
||||
scroll.liveRows[index],
|
||||
index > 0
|
||||
? scroll.liveItems.getOrNull(index - 1)
|
||||
: scroll.historyItems.firstOrNull,
|
||||
jumpToId: jumpToId,
|
||||
getEventOptions: getEventOptions,
|
||||
highlightedEvent: highlightedEvent,
|
||||
key: scroll.keyFor(scroll.liveItems[index].eventId),
|
||||
? scroll.liveRows.getOrNull(index - 1)
|
||||
: scroll.historyRows.firstOrNull,
|
||||
key: scroll.keyFor(scroll.liveRows[index]),
|
||||
),
|
||||
),
|
||||
|
||||
SuperSliverList.builder(
|
||||
key: scroll.centerKey,
|
||||
itemCount: scroll.historyItems.length,
|
||||
itemCount: scroll.historyRows.length,
|
||||
itemBuilder: (_, index) => eventRow(
|
||||
scroll.historyItems[index],
|
||||
scroll.historyItems.getOrNull(index + 1),
|
||||
jumpToId: jumpToId,
|
||||
getEventOptions: getEventOptions,
|
||||
highlightedEvent: highlightedEvent,
|
||||
key: scroll.keyFor(scroll.historyItems[index].eventId),
|
||||
scroll.historyRows[index],
|
||||
scroll.historyRows.getOrNull(index + 1),
|
||||
key: scroll.keyFor(scroll.historyRows[index]),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -24,15 +24,15 @@ final class const RoomChat({
|
|||
required final String? roomId,
|
||||
required final bool isDesktop,
|
||||
required final bool showMembersByDefault,
|
||||
final String? initialHighlightedEvent,
|
||||
final Event? initialHighlightedEvent,
|
||||
super.key,
|
||||
}) extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final relatedEvent = useState<Event?>(null);
|
||||
final relationType = useState(RelationType.reply);
|
||||
final contextualEvent = useState<String?>(initialHighlightedEvent);
|
||||
final highlightedEvent = useState<String?>(null);
|
||||
final contextualEvent = useState<Event?>(initialHighlightedEvent);
|
||||
final highlightedEvent = useState<int?>(null);
|
||||
|
||||
final composerSize = useState<double>(64);
|
||||
|
||||
|
|
@ -63,7 +63,9 @@ final class const RoomChat({
|
|||
|
||||
final controllerProvider = RoomChatController.provider((
|
||||
roomId,
|
||||
contextualEvent.value,
|
||||
contextualEvent.value == null
|
||||
? null
|
||||
: (contextualEvent.value!.rowId, contextualEvent.value!.eventId),
|
||||
));
|
||||
final notifier = ref.watch(controllerProvider.notifier);
|
||||
|
||||
|
|
@ -97,12 +99,14 @@ final class const RoomChat({
|
|||
},
|
||||
);
|
||||
|
||||
Future<void> jumpToId(String eventId) async {
|
||||
highlightedEvent.value = eventId;
|
||||
Future<void> jumpToEvent(Event event) async {
|
||||
highlightedEvent.value = event.rowId;
|
||||
|
||||
await scroll.jumpToId(eventId);
|
||||
await scroll.jumpToEvent(event);
|
||||
await Future.delayed(.new(milliseconds: 700), () {
|
||||
if (highlightedEvent.value == eventId) highlightedEvent.value = null;
|
||||
if (highlightedEvent.value == event.rowId) {
|
||||
highlightedEvent.value = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -113,7 +117,7 @@ final class const RoomChat({
|
|||
if (!context.mounted) return;
|
||||
|
||||
if (scroll.scrollController.hasClients) {
|
||||
jumpToId(initialHighlightedEvent!);
|
||||
jumpToEvent(initialHighlightedEvent!);
|
||||
} else {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => check());
|
||||
}
|
||||
|
|
@ -141,7 +145,7 @@ final class const RoomChat({
|
|||
endDrawer: PinnedEventsDrawer(
|
||||
roomId,
|
||||
getEventOptions: getEventOptions,
|
||||
jumpToId: jumpToId,
|
||||
jumpToEvent: jumpToEvent,
|
||||
),
|
||||
body: Builder(
|
||||
builder: (middleContext) => Scaffold(
|
||||
|
|
@ -168,7 +172,8 @@ final class const RoomChat({
|
|||
padding: .symmetric(horizontal: 4),
|
||||
child: ChatTimeline(
|
||||
scroll: scroll,
|
||||
jumpToId: jumpToId,
|
||||
roomId: roomId,
|
||||
jumpToEvent: jumpToEvent,
|
||||
getEventOptions: getEventOptions,
|
||||
highlightedEvent: highlightedEvent.value,
|
||||
composerHeight: composerSize.value,
|
||||
|
|
|
|||
Loading…
Reference in a new issue