Add room tag support

This commit is contained in:
Christian Pauly 2020-06-24 09:22:08 +00:00
parent edd30460e7
commit 13b3c0df4d
5 changed files with 71 additions and 3 deletions

View file

@ -20,7 +20,7 @@ class Tag {
double order;
Tag.fromJson(Map<String, dynamic> json) {
order = json['order'];
order = json['order']?.toDouble();
}
Map<String, dynamic> toJson() {
@ -31,3 +31,12 @@ class Tag {
return data;
}
}
abstract class TagType {
static const String Favourite = 'm.favourite';
static const String LowPriority = 'm.lowpriority';
static const String ServerNotice = 'm.server_notice';
static bool isValid(String tag) => tag.startsWith('m.')
? [Favourite, LowPriority, ServerNotice].contains(tag)
: true;
}

View file

@ -1074,8 +1074,10 @@ class Client {
/// The compare function how the rooms should be sorted internally. By default
/// rooms are sorted by timestamp of the last m.room.message event or the last
/// event if there is no known message.
RoomSorter sortRoomsBy = (a, b) => b.timeCreated.millisecondsSinceEpoch
.compareTo(a.timeCreated.millisecondsSinceEpoch);
RoomSorter sortRoomsBy = (a, b) => (a.isFavourite != b.isFavourite)
? (a.isFavourite ? -1 : 1)
: b.timeCreated.millisecondsSinceEpoch
.compareTo(a.timeCreated.millisecondsSinceEpoch);
void _sortRooms() {
if (prevBatch == null || _sortLock || rooms.length < 2) return;

View file

@ -361,6 +361,40 @@ class Room {
{'topic': newName},
);
/// Add a tag to the room.
Future<void> addTag(String tag, {double order}) => client.api.addRoomTag(
client.userID,
id,
tag,
order: order,
);
/// Removes a tag from the room.
Future<void> removeTag(String tag) => client.api.removeRoomTag(
client.userID,
id,
tag,
);
/// Returns all tags for this room.
Map<String, Tag> get tags {
if (roomAccountData['m.tag'] == null ||
!(roomAccountData['m.tag'].content['tags'] is Map)) {
return {};
}
final tags = (roomAccountData['m.tag'].content['tags'] as Map)
.map((k, v) => MapEntry<String, Tag>(k, Tag.fromJson(v)));
tags.removeWhere((k, v) => !TagType.isValid(k));
return tags;
}
/// Returns true if this room has a m.favourite tag.
bool get isFavourite => tags[TagType.Favourite] != null;
/// Sets the m.favourite tag for this room.
Future<void> setFavourite(bool favourite) =>
favourite ? addTag(TagType.Favourite) : removeTag(TagType.Favourite);
/// Call the Matrix API to change the pinned events of this room.
Future<String> setPinnedEvents(List<String> pinnedEventIds) =>
client.api.sendState(

View file

@ -1791,6 +1791,8 @@ class FakeMatrixApi extends MockClient {
(var reqI) => {
'event_id': '\$event${FakeMatrixApi.eventCounter++}',
},
'/client/r0/user/%40test%3AfakeServer.notExisting/rooms/%21localpart%3Aserver.abc/tags/m.favourite':
(var req) => {},
'/client/r0/user/%40alice%3Aexample.com/rooms/%21localpart%3Aexample.com/tags/testtag':
(var req) => {},
'/client/r0/user/%40alice%3Aexample.com/account_data/test.account.data':
@ -1839,6 +1841,8 @@ class FakeMatrixApi extends MockClient {
'/client/r0/pushrules/global/content/nocake': (var req) => {},
'/client/r0/pushrules/global/override/!localpart%3Aserver.abc':
(var req) => {},
'/client/r0/user/%40test%3AfakeServer.notExisting/rooms/%21localpart%3Aserver.abc/tags/m.favourite':
(var req) => {},
'/client/r0/user/%40alice%3Aexample.com/rooms/%21localpart%3Aexample.com/tags/testtag':
(var req) => {},
},

View file

@ -409,6 +409,25 @@ void main() {
await room.sendCallCandidates('1234', [], txid: '1234');
});
test('Test tag methods', () async {
await room.addTag(TagType.Favourite, order: 0.1);
await room.removeTag(TagType.Favourite);
expect(room.isFavourite, false);
room.roomAccountData['m.tag'] = BasicRoomEvent.fromJson({
'content': {
'tags': {
'm.favourite': {'order': 0.1},
'm.wrong': {'order': 0.2},
}
},
'type': 'm.tag'
});
expect(room.tags.length, 1);
expect(room.tags[TagType.Favourite].order, 0.1);
expect(room.isFavourite, true);
await room.setFavourite(false);
});
test('joinRules', () async {
expect(room.canChangeJoinRules, false);
expect(room.joinRules, JoinRules.public);