Merge branch 'krille/create-rooms-methods' into 'main'
feat: More advanced create chat methods See merge request famedly/company/frontend/famedlysdk!877
This commit is contained in:
commit
b350d5ab5b
|
|
@ -556,24 +556,102 @@ class Client extends MatrixApi {
|
|||
}
|
||||
|
||||
/// Returns an existing direct room ID with this user or creates a new one.
|
||||
/// Returns null on error.
|
||||
Future<String> startDirectChat(String mxid) async {
|
||||
/// By default encryption will be enabled if the client supports encryption
|
||||
/// and the other user has uploaded any encryption keys.
|
||||
Future<String> startDirectChat(
|
||||
String mxid, {
|
||||
bool? enableEncryption,
|
||||
List<StateEvent>? initialState,
|
||||
bool waitForSync = true,
|
||||
}) async {
|
||||
// Try to find an existing direct chat
|
||||
var roomId = getDirectChatFromUserId(mxid);
|
||||
if (roomId != null) return roomId;
|
||||
final directChatRoomId = getDirectChatFromUserId(mxid);
|
||||
if (directChatRoomId != null) return directChatRoomId;
|
||||
|
||||
enableEncryption ??= await userOwnsEncryptionKeys(mxid);
|
||||
if (enableEncryption) {
|
||||
initialState ??= [];
|
||||
if (!initialState.any((s) => s.type == EventTypes.Encryption)) {
|
||||
initialState.add(StateEvent(
|
||||
content: {
|
||||
'algorithm': supportedGroupEncryptionAlgorithms.first,
|
||||
},
|
||||
type: EventTypes.Encryption,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Start a new direct chat
|
||||
roomId = await createRoom(
|
||||
final roomId = await createRoom(
|
||||
invite: [mxid],
|
||||
isDirect: true,
|
||||
preset: CreateRoomPreset.trustedPrivateChat,
|
||||
initialState: initialState,
|
||||
);
|
||||
|
||||
if (waitForSync && getRoomById(roomId) == null) {
|
||||
// Wait for room actually appears in sync
|
||||
await onSync.stream
|
||||
.firstWhere((sync) => sync.rooms?.join?.containsKey(roomId) ?? false);
|
||||
}
|
||||
|
||||
await Room(id: roomId, client: this).addToDirectChat(mxid);
|
||||
|
||||
return roomId;
|
||||
}
|
||||
|
||||
/// Simplified method to create a new group chat. By default it is a private
|
||||
/// chat. The encryption is enabled if this client supports encryption and
|
||||
/// the preset is not a public chat.
|
||||
Future<String> createGroupChat({
|
||||
String? groupName,
|
||||
bool? enableEncryption,
|
||||
List<String>? invite,
|
||||
CreateRoomPreset preset = CreateRoomPreset.privateChat,
|
||||
List<StateEvent>? initialState,
|
||||
bool waitForSync = true,
|
||||
}) async {
|
||||
enableEncryption ??=
|
||||
encryptionEnabled && preset != CreateRoomPreset.publicChat;
|
||||
if (enableEncryption) {
|
||||
initialState ??= [];
|
||||
if (!initialState.any((s) => s.type == EventTypes.Encryption)) {
|
||||
initialState.add(StateEvent(
|
||||
content: {
|
||||
'algorithm': supportedGroupEncryptionAlgorithms.first,
|
||||
},
|
||||
type: EventTypes.Encryption,
|
||||
));
|
||||
}
|
||||
}
|
||||
final roomId = await createRoom(
|
||||
invite: invite,
|
||||
preset: preset,
|
||||
name: groupName,
|
||||
initialState: initialState,
|
||||
);
|
||||
|
||||
if (waitForSync) {
|
||||
if (getRoomById(roomId) == null) {
|
||||
// Wait for room actually appears in sync
|
||||
await onSync.stream.firstWhere(
|
||||
(sync) => sync.rooms?.join?.containsKey(roomId) ?? false);
|
||||
}
|
||||
}
|
||||
return roomId;
|
||||
}
|
||||
|
||||
/// Checks if the given user has encryption keys. May query keys from the
|
||||
/// server to answer this.
|
||||
Future<bool> userOwnsEncryptionKeys(String userId) async {
|
||||
if (userId == userID) return encryptionEnabled;
|
||||
if (_userDeviceKeys.containsKey(userId)) {
|
||||
return true;
|
||||
}
|
||||
final keys = await queryKeys({userId: []});
|
||||
return keys.deviceKeys?.isNotEmpty ?? false;
|
||||
}
|
||||
|
||||
/// Creates a new space and returns the Room ID. The parameters are mostly
|
||||
/// the same like in [createRoom()].
|
||||
/// Be aware that spaces appear in the [rooms] list. You should check if a
|
||||
|
|
|
|||
|
|
@ -148,7 +148,17 @@ class User extends Event {
|
|||
|
||||
/// Returns an existing direct chat ID with this user or creates a new one.
|
||||
/// Returns null on error.
|
||||
Future<String> startDirectChat() async => room.client.startDirectChat(id);
|
||||
Future<String> startDirectChat({
|
||||
bool? enableEncryption,
|
||||
List<StateEvent>? initialState,
|
||||
bool waitForSync = true,
|
||||
}) async =>
|
||||
room.client.startDirectChat(
|
||||
id,
|
||||
enableEncryption: enableEncryption,
|
||||
initialState: initialState,
|
||||
waitForSync: waitForSync,
|
||||
);
|
||||
|
||||
/// The newest presence of this user if there is any and null if not.
|
||||
Presence? get presence => room.client.presences[id];
|
||||
|
|
|
|||
|
|
@ -67,14 +67,25 @@ class DeviceKeysList {
|
|||
}
|
||||
}
|
||||
|
||||
Future<KeyVerification> startVerification() async {
|
||||
/// Starts a verification with this device. This might need to create a new
|
||||
/// direct chat to send the verification request over this room. For this you
|
||||
/// can set parameters here.
|
||||
Future<KeyVerification> startVerification({
|
||||
bool? newDirectChatEnableEncryption,
|
||||
List<StateEvent>? newDirectChatInitialState,
|
||||
}) async {
|
||||
final encryption = client.encryption;
|
||||
if (encryption == null) {
|
||||
throw Exception('Encryption not enabled');
|
||||
}
|
||||
if (userId != client.userID) {
|
||||
// in-room verification with someone else
|
||||
final roomId = await client.startDirectChat(userId);
|
||||
final roomId = await client.startDirectChat(
|
||||
userId,
|
||||
enableEncryption: newDirectChatEnableEncryption,
|
||||
initialState: newDirectChatInitialState,
|
||||
waitForSync: false,
|
||||
);
|
||||
|
||||
final room =
|
||||
client.getRoomById(roomId) ?? Room(id: roomId, client: client);
|
||||
|
|
|
|||
|
|
@ -560,6 +560,12 @@ void main() {
|
|||
bunnyContent);
|
||||
await client.dispose(closeDatabase: true);
|
||||
});
|
||||
test('startDirectChat', () async {
|
||||
await matrix.startDirectChat('@alice:example.com', waitForSync: false);
|
||||
});
|
||||
test('createGroupChat', () async {
|
||||
await matrix.createGroupChat(groupName: 'Testgroup', waitForSync: false);
|
||||
});
|
||||
test('Test the fake store api', () async {
|
||||
final database = await getDatabase(null);
|
||||
final client1 = Client(
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ void main() {
|
|||
expect(req?.room != null, false);
|
||||
|
||||
req = await client.userDeviceKeys['@alice:example.com']
|
||||
?.startVerification();
|
||||
?.startVerification(newDirectChatEnableEncryption: false);
|
||||
expect(req != null, true);
|
||||
expect(req?.room != null, true);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -119,7 +119,9 @@ void main() {
|
|||
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||
.setDirectVerified(false);
|
||||
final req1 =
|
||||
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
||||
await client1.userDeviceKeys[client2.userID]!.startVerification(
|
||||
newDirectChatEnableEncryption: false,
|
||||
);
|
||||
var evt = getLastSentEvent(req1);
|
||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||
|
||||
|
|
@ -221,8 +223,8 @@ void main() {
|
|||
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||
.setDirectVerified(true);
|
||||
await client1.encryption!.ssss.clearCache();
|
||||
final req1 =
|
||||
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
||||
final req1 = await client1.userDeviceKeys[client2.userID]!
|
||||
.startVerification(newDirectChatEnableEncryption: false);
|
||||
expect(req1.state, KeyVerificationState.askSSSS);
|
||||
await req1.openSSSS(recoveryKey: ssssKey);
|
||||
await Future.delayed(Duration(seconds: 1));
|
||||
|
|
@ -241,8 +243,8 @@ void main() {
|
|||
// the other one has to have their master key verified to trigger asking for ssss
|
||||
client2.userDeviceKeys[client2.userID]!.masterKey!
|
||||
.setDirectVerified(true);
|
||||
final req1 =
|
||||
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
||||
final req1 = await client1.userDeviceKeys[client2.userID]!
|
||||
.startVerification(newDirectChatEnableEncryption: false);
|
||||
var evt = getLastSentEvent(req1);
|
||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||
|
||||
|
|
@ -345,8 +347,8 @@ void main() {
|
|||
// make sure our master key is *not* verified to not triger SSSS for now
|
||||
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||
.setDirectVerified(false);
|
||||
final req1 =
|
||||
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
||||
final req1 = await client1.userDeviceKeys[client2.userID]!
|
||||
.startVerification(newDirectChatEnableEncryption: false);
|
||||
var evt = getLastSentEvent(req1);
|
||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||
|
||||
|
|
@ -375,8 +377,8 @@ void main() {
|
|||
// make sure our master key is *not* verified to not triger SSSS for now
|
||||
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||
.setDirectVerified(false);
|
||||
final req1 =
|
||||
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
||||
final req1 = await client1.userDeviceKeys[client2.userID]!
|
||||
.startVerification(newDirectChatEnableEncryption: false);
|
||||
var evt = getLastSentEvent(req1);
|
||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||
|
||||
|
|
@ -436,8 +438,8 @@ void main() {
|
|||
// make sure our master key is *not* verified to not triger SSSS for now
|
||||
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||
.setDirectVerified(false);
|
||||
final req1 =
|
||||
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
||||
final req1 = await client1.userDeviceKeys[client2.userID]!
|
||||
.startVerification(newDirectChatEnableEncryption: false);
|
||||
final evt = getLastSentEvent(req1);
|
||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ void main() {
|
|||
await user1.setPower(50);
|
||||
});
|
||||
test('startDirectChat', () async {
|
||||
await user1.startDirectChat();
|
||||
await user1.startDirectChat(waitForSync: false);
|
||||
});
|
||||
test('getPresence', () async {
|
||||
await client.handleSync(SyncUpdate.fromJson({
|
||||
|
|
|
|||
Loading…
Reference in New Issue