diff --git a/lib/src/room.dart b/lib/src/room.dart index cef98d89..cac0f74f 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -2149,6 +2149,63 @@ class Room { return; } + /// Generates a matrix.to link with appropriate routing info to share the room + Future matrixToInviteLink() async { + if (canonicalAlias.isNotEmpty) { + return Uri.parse( + 'https://matrix.to/#/${Uri.encodeComponent(canonicalAlias)}'); + } + final List queryParameters = []; + final users = await requestParticipants(); + final currentPowerLevelsMap = getState(EventTypes.RoomPowerLevels)?.content; + + final temp = List.from(users); + temp.removeWhere((user) => user.powerLevel < 50); + if (currentPowerLevelsMap != null) { + // just for weird rooms + temp.removeWhere((user) => + user.powerLevel < getDefaultPowerLevel(currentPowerLevelsMap)); + } + + if (temp.isNotEmpty) { + temp.sort((a, b) => a.powerLevel.compareTo(b.powerLevel)); + if (temp.last.id.domain != null) { + queryParameters.add(temp.last.id.domain!); + } + } + + final Map servers = {}; + users.forEach((user) { + if (user.id.domain != null) { + if (servers.containsKey(user.id.domain!)) { + servers[user.id.domain!] = servers[user.id.domain!]! + 1; + } else { + servers[user.id.domain!] = 1; + } + } + }); + final sortedServers = Map.fromEntries(servers.entries.toList() + ..sort((e1, e2) => e1.value.compareTo(e2.value))); + for (var i = 0; i <= 2; i++) { + if (!queryParameters.contains(sortedServers.keys.last)) { + queryParameters.add(sortedServers.keys.last); + } + sortedServers.remove(sortedServers.keys.last); + } + + var queryString = '?'; + for (var i = 0; + i <= (queryParameters.length > 2 ? 2 : queryParameters.length); + i++) { + if (i != 0) { + queryString += '&'; + } + queryString += 'via=${queryParameters[i]}'; + } + return Uri.parse( + 'https://matrix.to/#/${Uri.encodeComponent(id)}$queryString'); + } + /// Remove a child from this space by setting the `via` to an empty list. Future removeSpaceChild(String roomId) => !isSpace ? throw Exception('Room is not a space!') diff --git a/test/room_test.dart b/test/room_test.dart index a51a15e6..f3dcfb82 100644 --- a/test/room_test.dart +++ b/test/room_test.dart @@ -1341,7 +1341,24 @@ void main() { expect(room.getMention('@[Alice Margatroid]'), '@alice:example.org'); expect(room.getMention('@[Alice Margatroid]#1754'), '@alice:example.org'); }); - + test('inviteLink', () async { + var matrixToLink = await room.matrixToInviteLink(); + expect(matrixToLink.toString(), + 'https://matrix.to/#/%23testalias%3Aexample.com'); + room.setState( + Event( + senderId: '@test:example.com', + type: 'm.room.canonical_alias', + room: room, + eventId: '123', + content: {'alias': ''}, + originServerTs: DateTime.now(), + stateKey: ''), + ); + matrixToLink = await room.matrixToInviteLink(); + expect(matrixToLink.toString(), + 'https://matrix.to/#/!localpart%3Aserver.abc?via=example.org&via=example.com&via=test.abc'); + }); test('logout', () async { await matrix.logout(); });