Merge branch 'krille/timeline-set-read-marker' into 'main'

refactor: Move setreadmarker functionality to timeline

See merge request famedly/company/frontend/famedlysdk!879
This commit is contained in:
Nicolas Werner 2021-11-09 14:14:43 +00:00
commit c443b239b4
5 changed files with 41 additions and 15 deletions

View File

@ -506,10 +506,14 @@ class Room {
/// Returns true if this room is unread /// Returns true if this room is unread
bool get isUnread => notificationCount > 0 || markedUnread; bool get isUnread => notificationCount > 0 || markedUnread;
/// Sets an unread flag manually for this room. Similar to the setUnreadMarker @Deprecated('Use [markUnread] instead')
/// this changes the local account data model before syncing it to make sure Future<void> setUnread(bool unread) => markUnread(unread);
/// this works if there is no connection to the homeserver.
Future<void> setUnread(bool unread) async { /// 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(); final content = MarkedUnread(unread).toJson();
await _handleFakeSync(SyncUpdate(nextBatch: '') await _handleFakeSync(SyncUpdate(nextBatch: '')
..rooms = (RoomsUpdate() ..rooms = (RoomsUpdate()
@ -527,13 +531,6 @@ class Room {
EventType.markedUnread, EventType.markedUnread,
content, 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. /// Returns true if this room has a m.favourite tag.

View File

@ -18,6 +18,8 @@
import 'dart:async'; import 'dart:async';
import 'package:collection/src/iterable_extensions.dart';
import '../matrix.dart'; import '../matrix.dart';
import 'event.dart'; import 'event.dart';
import 'event_status.dart'; import 'event_status.dart';
@ -185,6 +187,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}) { 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 // 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. // matches either the event_id or transaction_id of the existing event.

View File

@ -1779,6 +1779,7 @@ class FakeMatrixApi extends MockClient {
'/client/r0/rooms/!localpart%3Aexample.com/receipt/m.read/%241234%3Aexample.com': '/client/r0/rooms/!localpart%3Aexample.com/receipt/m.read/%241234%3Aexample.com':
(var req) => {}, (var req) => {},
'/client/r0/rooms/!localpart%3Aexample.com/read_markers': (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': '/client/r0/user/${Uri.encodeComponent('@othertest:fakeServer.notExisting')}/filter':
(var req) => {'filter_id': '1234'}, (var req) => {'filter_id': '1234'},
'/client/r0/user/${Uri.encodeComponent('@test:fakeServer.notExisting')}/filter': '/client/r0/user/${Uri.encodeComponent('@test:fakeServer.notExisting')}/filter':

View File

@ -743,15 +743,15 @@ void main() {
}); });
test('Test marked unread room', () async { test('Test marked unread room', () async {
await room.setUnread(true); await room.markUnread(true);
await room.setUnread(false); await room.markUnread(false);
expect(room.isUnread, false); expect(room.markedUnread, false);
room.roomAccountData['com.famedly.marked_unread'] = room.roomAccountData['com.famedly.marked_unread'] =
BasicRoomEvent.fromJson({ BasicRoomEvent.fromJson({
'content': {'unread': true}, 'content': {'unread': true},
'type': 'com.famedly.marked_unread' 'type': 'com.famedly.marked_unread'
}); });
expect(room.isUnread, true); expect(room.markedUnread, true);
}); });
test('joinRules', () async { test('joinRules', () async {

View File

@ -386,6 +386,24 @@ void main() {
expect(timeline.events[0].status, EventStatus.error); expect(timeline.events[0].status, EventStatus.error);
expect(timeline.events.length, 1); 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', test('sending an event and the http request finishes first, 0 -> 1 -> 2',
() async { () async {
timeline.events.clear(); timeline.events.clear();