chore: Follow up jump to unread message

This commit is contained in:
Krille 2023-03-25 15:23:14 +01:00
parent 2acf49a12b
commit fc8fe60613
No known key found for this signature in database
4 changed files with 60 additions and 37 deletions

View File

@ -276,6 +276,8 @@ class ChatController extends State<ChatPageWithRoom> {
_loadDraft(); _loadDraft();
super.initState(); super.initState();
sendingClient = Matrix.of(context).client; sendingClient = Matrix.of(context).client;
readMarkerEventId = room.fullyRead;
loadTimelineFuture = _getTimeline();
} }
void updateView() { void updateView() {
@ -283,33 +285,34 @@ class ChatController extends State<ChatPageWithRoom> {
setState(() {}); setState(() {});
} }
Future<void> getTimeline([String? eventContextId]) async { Future<void>? loadTimelineFuture;
if (timeline == null) {
await Matrix.of(context).client.roomsLoading;
await Matrix.of(context).client.accountDataLoading;
timeline = await room.getTimeline(
onUpdate: updateView,
eventContextId: eventContextId,
);
if (timeline!.events.isNotEmpty) {
if (room.markedUnread) room.markUnread(false);
setReadMarker();
}
// when the scroll controller is attached we want to scroll to an event id, if specified Future<void> _getTimeline([String? eventContextId]) async {
// and update the scroll controller...which will trigger a request history, if the await Matrix.of(context).client.roomsLoading;
// "load more" button is visible on the screen await Matrix.of(context).client.accountDataLoading;
SchedulerBinding.instance.addPostFrameCallback((_) async { final timeline = this.timeline = await room.getTimeline(
if (mounted) { onUpdate: updateView,
final event = VRouter.of(context).queryParameters['event']; eventContextId: eventContextId,
if (event != null) { );
scrollToEventId(event); if (timeline.events.isNotEmpty) {
} if (room.markedUnread) room.markUnread(false);
_updateScrollController(); setReadMarker();
}
});
} }
timeline!.requestKeys(onlineKeyBackupOnly: false);
// when the scroll controller is attached we want to scroll to an event id, if specified
// and update the scroll controller...which will trigger a request history, if the
// "load more" button is visible on the screen
SchedulerBinding.instance.addPostFrameCallback((_) async {
if (mounted) {
final event = VRouter.of(context).queryParameters['event'];
if (event != null) {
scrollToEventId(event);
}
_updateScrollController();
}
});
timeline.requestKeys(onlineKeyBackupOnly: false);
return; return;
} }
@ -317,7 +320,8 @@ class ChatController extends State<ChatPageWithRoom> {
void setReadMarker({String? eventId}) { void setReadMarker({String? eventId}) {
if (_setReadMarkerFuture != null) return; if (_setReadMarkerFuture != null) return;
if (lastReadEventVisible && if (eventId == null &&
lastReadEventVisible &&
!room.hasNewMessages && !room.hasNewMessages &&
room.notificationCount == 0) { room.notificationCount == 0) {
return; return;
@ -784,8 +788,9 @@ class ChatController extends State<ChatPageWithRoom> {
if (eventIndex == -1) { if (eventIndex == -1) {
setState(() { setState(() {
timeline = null; timeline = null;
loadTimelineFuture = _getTimeline(eventId);
}); });
await getTimeline(eventId); await loadTimelineFuture;
eventIndex = timeline!.events.indexWhere((e) => e.eventId == eventId); eventIndex = timeline!.events.indexWhere((e) => e.eventId == eventId);
} }
if (!mounted) { if (!mounted) {
@ -802,8 +807,9 @@ class ChatController extends State<ChatPageWithRoom> {
if (!timeline!.allowNewEvent) { if (!timeline!.allowNewEvent) {
setState(() { setState(() {
timeline = null; timeline = null;
loadTimelineFuture = _getTimeline();
}); });
await getTimeline(); await loadTimelineFuture;
setReadMarker(eventId: timeline!.events.first.eventId); setReadMarker(eventId: timeline!.events.first.eventId);
} }
scrollController.jumpTo(0); scrollController.jumpTo(0);

View File

@ -124,7 +124,8 @@ class ChatEventList extends StatelessWidget {
.any((e) => e.eventId == event.eventId), .any((e) => e.eventId == event.eventId),
timeline: controller.timeline!, timeline: controller.timeline!,
displayReadMarker: displayReadMarker:
controller.readMarkerEventId == event.eventId, controller.readMarkerEventId == event.eventId &&
controller.timeline?.allowNewEvent == false,
nextEvent: i < controller.timeline!.events.length nextEvent: i < controller.timeline!.events.length
? controller.timeline!.events[i] ? controller.timeline!.events[i]
: null, : null,

View File

@ -139,8 +139,6 @@ class ChatView extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
controller.readMarkerEventId ??= controller.room.fullyRead;
if (controller.room.membership == Membership.invite) { if (controller.room.membership == Membership.invite) {
showFutureLoadingDialog( showFutureLoadingDialog(
context: context, context: context,
@ -167,7 +165,7 @@ class ChatView extends StatelessWidget {
stream: controller.room.onUpdate.stream stream: controller.room.onUpdate.stream
.rateLimit(const Duration(seconds: 1)), .rateLimit(const Duration(seconds: 1)),
builder: (context, snapshot) => FutureBuilder( builder: (context, snapshot) => FutureBuilder(
future: controller.getTimeline(), future: controller.loadTimelineFuture,
builder: (BuildContext context, snapshot) { builder: (BuildContext context, snapshot) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(

View File

@ -354,12 +354,30 @@ class Message extends StatelessWidget {
if (displayReadMarker) if (displayReadMarker)
Row( Row(
children: [ children: [
const Expanded(child: Divider()), Expanded(
Padding( child: Divider(color: Theme.of(context).colorScheme.primary),
padding: const EdgeInsets.all(8.0), ),
child: Text(L10n.of(context)!.readUpToHere), Container(
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).colorScheme.primary,
),
color: Theme.of(context).colorScheme.primaryContainer,
borderRadius: BorderRadius.circular(4),
),
margin: const EdgeInsets.all(8.0),
padding: const EdgeInsets.symmetric(
horizontal: 8,
),
child: Text(
L10n.of(context)!.readUpToHere,
style:
TextStyle(color: Theme.of(context).colorScheme.primary),
),
),
Expanded(
child: Divider(color: Theme.of(context).colorScheme.primary),
), ),
const Expanded(child: Divider()),
], ],
), ),
], ],