[User] Request user sync and async

This commit is contained in:
Christian Pauly 2019-11-15 11:08:43 +00:00
parent dcb1c42044
commit b58dd46e8d
3 changed files with 46 additions and 9 deletions

View File

@ -27,7 +27,6 @@ import 'package:famedlysdk/src/utils/ChatTime.dart';
import 'package:famedlysdk/src/utils/Receipt.dart';
import './Room.dart';
import 'User.dart';
/// Defines a timeline event for a room.
class Event extends RoomState {
@ -106,8 +105,7 @@ class Event extends RoomState {
for (var entry in room.roomAccountData["m.receipt"].content.entries) {
if (entry.value["event_id"] == eventId)
receiptsList.add(Receipt(
room.states[entry.key]?.asUser ?? User(entry.key),
ChatTime(entry.value["ts"])));
room.getUserByMXIDSync(entry.key), ChatTime(entry.value["ts"])));
}
return receiptsList;
}

View File

@ -176,8 +176,7 @@ class Room {
List<dynamic> typingMxid = ephemerals["m.typing"].content["user_ids"];
List<User> typingUsers = [];
for (int i = 0; i < typingMxid.length; i++)
typingUsers.add(
states[typingMxid[i]]?.asUser ?? User(typingMxid[i], room: this));
typingUsers.add(getUserByMXIDSync(typingMxid[i]));
return typingUsers;
}
@ -707,16 +706,56 @@ class Room {
return participants;
}
/// Returns the [User] object for the given [mxID] or requests it from
/// the homeserver and waits for a response.
Future<User> getUserByMXID(String mxID) async {
if (states[mxID] != null) return states[mxID].asUser;
return requestUser(mxID);
}
/// Returns the [User] object for the given [mxID] or requests it from
/// the homeserver and returns a default [User] object while waiting.
User getUserByMXIDSync(String mxID) {
if (states[mxID] != null)
return states[mxID].asUser;
else {
requestUser(mxID);
return User(mxID, room: this);
}
}
Set<String> _requestingMatrixIds = Set();
/// Requests a missing [User] for this room. Important for clients using
/// lazy loading.
Future<User> requestUser(String mxID) async {
if (mxID == null || !_requestingMatrixIds.add(mxID)) return null;
final dynamic resp = await client.connection.jsonRequest(
type: HTTPType.GET,
action: "/client/r0/rooms/$id/state/m.room.member/$mxID");
if (resp is ErrorResponse) return null;
return User(mxID,
if (resp is ErrorResponse) {
_requestingMatrixIds.remove(mxID);
return null;
}
final User user = User(mxID,
displayName: resp["displayname"],
avatarUrl: resp["avatar_url"],
room: this);
states[mxID] = user;
if (client.store != null)
client.store.transaction(() {
client.store.storeEventUpdate(
EventUpdate(
content: resp,
roomID: id,
type: "state",
eventType: "m.room.member"),
);
return;
});
if (onUpdate != null) onUpdate();
_requestingMatrixIds.remove(mxID);
return user;
}
/// Searches for the event in the store. If it isn't found, try to request it

View File

@ -43,7 +43,7 @@ class RoomState {
/// The user who has sent this event if it is not a global account data event.
final String senderId;
User get sender => room.states[senderId]?.asUser ?? User(senderId);
User get sender => room.getUserByMXIDSync(senderId);
/// The time this event has received at the server. May be null for events like
/// account data.
@ -64,7 +64,7 @@ class RoomState {
/// the overwriting semantics for this piece of room state.
final String stateKey;
User get stateKeyUser => room.states[stateKey]?.asUser ?? User(stateKey);
User get stateKeyUser => room.getUserByMXIDSync(stateKey);
RoomState(
{this.content,