refactor: Move setreadmarker functionality to timeline
Apps had a hard time to just set the marker for the last event. The lastEvent in the Room may not be the actual last event because we ignore several event types there. Therefore it makes sense to refactor the setUnread method. Now the timeline class has an easy method to set the read marker to the last synced event, which can only be known by the timeline if we want to avoid another DB access.
This commit is contained in:
parent
0e2542b172
commit
e313426dd9
|
|
@ -506,10 +506,14 @@ class Room {
|
|||
/// Returns true if this room is unread
|
||||
bool get isUnread => notificationCount > 0 || markedUnread;
|
||||
|
||||
/// Sets an unread flag manually for this room. Similar to the setUnreadMarker
|
||||
/// this changes the local account data model before syncing it to make sure
|
||||
/// this works if there is no connection to the homeserver.
|
||||
Future<void> setUnread(bool unread) async {
|
||||
@Deprecated('Use [markUnread] instead')
|
||||
Future<void> setUnread(bool unread) => markUnread(unread);
|
||||
|
||||
/// Sets an unread flag manually for this room. This changes the local account
|
||||
/// data model before syncing it to make sure
|
||||
/// this works if there is no connection to the homeserver. This does **not**
|
||||
/// set a read marker!
|
||||
Future<void> markUnread(bool unread) async {
|
||||
final content = MarkedUnread(unread).toJson();
|
||||
await _handleFakeSync(SyncUpdate(nextBatch: '')
|
||||
..rooms = (RoomsUpdate()
|
||||
|
|
@ -527,13 +531,6 @@ class Room {
|
|||
EventType.markedUnread,
|
||||
content,
|
||||
);
|
||||
final lastEvent = this.lastEvent;
|
||||
if (!unread && lastEvent != null) {
|
||||
await setReadMarker(
|
||||
lastEvent.eventId,
|
||||
mRead: lastEvent.eventId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if this room has a m.favourite tag.
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:collection/src/iterable_extensions.dart';
|
||||
|
||||
import '../matrix.dart';
|
||||
import 'event.dart';
|
||||
import 'event_status.dart';
|
||||
|
|
@ -172,6 +174,14 @@ class Timeline {
|
|||
}
|
||||
}
|
||||
|
||||
/// Set the read marker to the last synced event in this timeline.
|
||||
Future<void> setReadMarker([String? eventId]) async {
|
||||
eventId ??=
|
||||
events.firstWhereOrNull((event) => event.status.isSynced)?.eventId;
|
||||
if (eventId == null) return;
|
||||
return room.setReadMarker(eventId, mRead: eventId);
|
||||
}
|
||||
|
||||
int _findEvent({String? event_id, String? unsigned_txid}) {
|
||||
// we want to find any existing event where either the passed event_id or the passed unsigned_txid
|
||||
// matches either the event_id or transaction_id of the existing event.
|
||||
|
|
|
|||
|
|
@ -1779,6 +1779,7 @@ class FakeMatrixApi extends MockClient {
|
|||
'/client/r0/rooms/!localpart%3Aexample.com/receipt/m.read/%241234%3Aexample.com':
|
||||
(var req) => {},
|
||||
'/client/r0/rooms/!localpart%3Aexample.com/read_markers': (var req) => {},
|
||||
'/client/r0/rooms/!1234%3Aexample.com/read_markers': (var req) => {},
|
||||
'/client/r0/user/${Uri.encodeComponent('@othertest:fakeServer.notExisting')}/filter':
|
||||
(var req) => {'filter_id': '1234'},
|
||||
'/client/r0/user/${Uri.encodeComponent('@test:fakeServer.notExisting')}/filter':
|
||||
|
|
|
|||
|
|
@ -743,15 +743,15 @@ void main() {
|
|||
});
|
||||
|
||||
test('Test marked unread room', () async {
|
||||
await room.setUnread(true);
|
||||
await room.setUnread(false);
|
||||
expect(room.isUnread, false);
|
||||
await room.markUnread(true);
|
||||
await room.markUnread(false);
|
||||
expect(room.markedUnread, false);
|
||||
room.roomAccountData['com.famedly.marked_unread'] =
|
||||
BasicRoomEvent.fromJson({
|
||||
'content': {'unread': true},
|
||||
'type': 'com.famedly.marked_unread'
|
||||
});
|
||||
expect(room.isUnread, true);
|
||||
expect(room.markedUnread, true);
|
||||
});
|
||||
|
||||
test('joinRules', () async {
|
||||
|
|
|
|||
|
|
@ -372,6 +372,24 @@ void main() {
|
|||
expect(timeline.events[0].status, EventStatus.error);
|
||||
expect(timeline.events.length, 1);
|
||||
});
|
||||
test('setReadMarker', () async {
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': EventStatus.synced.intValue,
|
||||
'event_id': 'will-work',
|
||||
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
room.notificationCount = 1;
|
||||
await timeline.setReadMarker();
|
||||
expect(room.notificationCount, 0);
|
||||
});
|
||||
test('sending an event and the http request finishes first, 0 -> 1 -> 2',
|
||||
() async {
|
||||
timeline.events.clear();
|
||||
|
|
|
|||
Loading…
Reference in New Issue