chore: Load chat at last read marker

This commit is contained in:
Krille 2023-04-14 14:23:58 +02:00
parent 9ace2fe07b
commit 92072904e6
No known key found for this signature in database
3 changed files with 34 additions and 46 deletions

View File

@ -2528,5 +2528,6 @@
} }
}, },
"jumpToLastReadMessage": "Jump to last read message", "jumpToLastReadMessage": "Jump to last read message",
"readUpToHere": "Read up to here" "readUpToHere": "Read up to here",
"jump": "Jump"
} }

View File

@ -163,11 +163,6 @@ class ChatController extends State<ChatPageWithRoom> {
bool showEmojiPicker = false; bool showEmojiPicker = false;
bool get lastReadEventVisible =>
timeline == null ||
room.fullyRead.isEmpty ||
timeline!.events.any((event) => event.eventId == room.fullyRead);
void recreateChat() async { void recreateChat() async {
final room = this.room; final room = this.room;
final userId = room.directChatMatrixID; final userId = room.directChatMatrixID;
@ -287,14 +282,36 @@ class ChatController extends State<ChatPageWithRoom> {
Future<void>? loadTimelineFuture; Future<void>? loadTimelineFuture;
Future<void> _getTimeline([String? eventContextId]) async { Future<void> _getTimeline({
String? eventContextId,
Duration timeout = const Duration(seconds: 5),
}) async {
await Matrix.of(context).client.roomsLoading; await Matrix.of(context).client.roomsLoading;
await Matrix.of(context).client.accountDataLoading; await Matrix.of(context).client.accountDataLoading;
final timeline = this.timeline = await room.getTimeline( eventContextId ??= room.fullyRead;
onUpdate: updateView, try {
eventContextId: eventContextId, timeline = await room
); .getTimeline(
if (timeline.events.isNotEmpty) { onUpdate: updateView,
eventContextId: eventContextId,
)
.timeout(timeout);
} on TimeoutException catch (_) {
if (!mounted) return;
timeline = await room.getTimeline(onUpdate: updateView);
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(L10n.of(context)!.jumpToLastReadMessage),
action: SnackBarAction(
label: L10n.of(context)!.jump,
onPressed: () => scrollToEventId(eventContextId!),
),
),
);
}
timeline!.requestKeys(onlineKeyBackupOnly: false);
if (timeline!.events.isNotEmpty) {
if (room.markedUnread) room.markUnread(false); if (room.markedUnread) room.markUnread(false);
setReadMarker(); setReadMarker();
} }
@ -311,7 +328,6 @@ class ChatController extends State<ChatPageWithRoom> {
} }
}); });
timeline.requestKeys(onlineKeyBackupOnly: false);
return; return;
} }
@ -320,7 +336,6 @@ class ChatController extends State<ChatPageWithRoom> {
void setReadMarker({String? eventId}) { void setReadMarker({String? eventId}) {
if (_setReadMarkerFuture != null) return; if (_setReadMarkerFuture != null) return;
if (eventId == null && if (eventId == null &&
lastReadEventVisible &&
!room.hasNewMessages && !room.hasNewMessages &&
room.notificationCount == 0) { room.notificationCount == 0) {
return; return;
@ -330,10 +345,6 @@ class ChatController extends State<ChatPageWithRoom> {
final timeline = this.timeline; final timeline = this.timeline;
if (timeline == null || timeline.events.isEmpty) return; if (timeline == null || timeline.events.isEmpty) return;
if (eventId == null && !lastReadEventVisible) {
return;
}
eventId ??= timeline.events.first.eventId; eventId ??= timeline.events.first.eventId;
Logs().v('Set read marker...', eventId); Logs().v('Set read marker...', eventId);
// ignore: unawaited_futures // ignore: unawaited_futures
@ -787,7 +798,10 @@ class ChatController extends State<ChatPageWithRoom> {
if (eventIndex == -1) { if (eventIndex == -1) {
setState(() { setState(() {
timeline = null; timeline = null;
loadTimelineFuture = _getTimeline(eventId); loadTimelineFuture = _getTimeline(
eventContextId: eventId,
timeout: const Duration(seconds: 30),
);
}); });
await loadTimelineFuture; await loadTimelineFuture;
WidgetsBinding.instance.addPostFrameCallback((timeStamp) { WidgetsBinding.instance.addPostFrameCallback((timeStamp) {

View File

@ -336,33 +336,6 @@ class ChatView extends StatelessWidget {
], ],
), ),
), ),
if (!controller.lastReadEventVisible &&
controller.timeline!.allowNewEvent)
Positioned(
top: 16,
left: 0,
right: 0,
child: Center(
child: FloatingActionButton.extended(
icon: const Icon(Icons.arrow_upward_outlined),
onPressed: () => controller.scrollToEventId(
controller.room.fullyRead,
),
label: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(L10n.of(context)!.jumpToLastReadMessage),
IconButton(
onPressed: () => controller.setReadMarker(
eventId: controller.room.fullyRead,
),
icon: const Icon(Icons.close),
),
],
),
),
),
),
if (controller.dragging) if (controller.dragging)
Container( Container(
color: Theme.of(context) color: Theme.of(context)