refactor: Enhance logic when to mark room as read

This commit is contained in:
krille-chan 2024-02-29 18:06:06 +01:00
commit 0cf6a1d74a
No known key found for this signature in database
2 changed files with 229 additions and 225 deletions

View file

@ -252,6 +252,7 @@ class ChatController extends State<ChatPageWithRoom>
setState(() => _scrolledUp = true);
} else if (scrollController.position.pixels <= 0 && _scrolledUp == true) {
setState(() => _scrolledUp = false);
setReadMarker();
}
if (scrollController.position.pixels == 0 ||
@ -275,6 +276,7 @@ class ChatController extends State<ChatPageWithRoom>
_loadDraft();
super.initState();
sendingClient = Matrix.of(context).client;
WidgetsBinding.instance.addObserver(this);
_tryLoadTimeline();
}
@ -286,7 +288,6 @@ class ChatController extends State<ChatPageWithRoom>
if (fullyRead.isEmpty) return;
if (timeline!.events.any((event) => event.eventId == fullyRead)) {
Logs().v('Scroll up to visible event', fullyRead);
setReadMarker();
return;
}
if (!mounted) return;
@ -317,6 +318,11 @@ class ChatController extends State<ChatPageWithRoom>
int? animateInEventIndex;
void onInsert(int i) {
if (timeline?.events[i].status == EventStatus.synced) {
final index = timeline!.events.firstIndexWhereNotError;
if (i == index) setReadMarker(eventId: timeline?.events[i].eventId);
}
// setState will be called by updateView() anyway
animateInEventIndex = i;
}
@ -350,6 +356,7 @@ class ChatController extends State<ChatPageWithRoom>
}
timeline!.requestKeys(onlineKeyBackupOnly: false);
if (room.markedUnread) room.markUnread(false);
setReadMarker();
// 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
@ -371,7 +378,6 @@ class ChatController extends State<ChatPageWithRoom>
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state != AppLifecycleState.resumed) return;
if (!_scrolledUp) return;
setReadMarker();
}
@ -379,13 +385,19 @@ class ChatController extends State<ChatPageWithRoom>
void setReadMarker({String? eventId}) {
if (_setReadMarkerFuture != null) return;
if (_scrolledUp) return;
if (scrollUpBannerEventId != null) return;
if (eventId == null &&
!room.hasNewMessages &&
room.notificationCount == 0) {
return;
}
if (!Matrix.of(context).webHasFocus) return;
// Do not send read markers when app is not in foreground
if (!Matrix.of(context).webHasFocus ||
WidgetsBinding.instance.lifecycleState != AppLifecycleState.resumed) {
return;
}
final timeline = this.timeline;
if (timeline == null || timeline.events.isEmpty) return;
@ -932,7 +944,6 @@ class ChatController extends State<ChatPageWithRoom>
);
});
await loadTimelineFuture;
setReadMarker();
}
scrollController.jumpTo(0);
}
@ -1174,7 +1185,6 @@ class ChatController extends State<ChatPageWithRoom>
void onInputBarChanged(String text) {
if (_inputTextIsEmpty != text.isEmpty) {
setReadMarker();
setState(() {
_inputTextIsEmpty = text.isEmpty;
});
@ -1300,3 +1310,12 @@ class ChatController extends State<ChatPageWithRoom>
}
enum EmojiPickerType { reaction, keyboard }
extension on List<Event> {
int get firstIndexWhereNotError {
if (isEmpty) return 0;
final index = indexWhere((event) => !event.status.isError);
if (index == -1) return length;
return index;
}
}