feat: Store presences in database
This commit is contained in:
parent
7bcd5840e1
commit
8cc863b1a3
|
|
@ -1791,12 +1791,13 @@ class Client extends MatrixApi {
|
||||||
await _handleRooms(leave, direction: direction);
|
await _handleRooms(leave, direction: direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (final newPresence in sync.presence ?? []) {
|
for (final newPresence in sync.presence ?? <Presence>[]) {
|
||||||
final cachedPresence = CachedPresence.fromMatrixEvent(newPresence);
|
final cachedPresence = CachedPresence.fromMatrixEvent(newPresence);
|
||||||
presences[newPresence.senderId] = cachedPresence;
|
presences[newPresence.senderId] = cachedPresence;
|
||||||
// ignore: deprecated_member_use_from_same_package
|
// ignore: deprecated_member_use_from_same_package
|
||||||
onPresence.add(newPresence);
|
onPresence.add(newPresence);
|
||||||
onPresenceChanged.add(cachedPresence);
|
onPresenceChanged.add(cachedPresence);
|
||||||
|
await database?.storePresence(newPresence.senderId, cachedPresence);
|
||||||
}
|
}
|
||||||
for (final newAccountData in sync.accountData ?? []) {
|
for (final newAccountData in sync.accountData ?? []) {
|
||||||
await database?.storeAccountData(
|
await database?.storeAccountData(
|
||||||
|
|
@ -2924,6 +2925,25 @@ class Client extends MatrixApi {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The newest presence of this user if there is any. Fetches it from the
|
||||||
|
/// database first and then from the server if necessary or returns offline.
|
||||||
|
Future<CachedPresence> fetchCurrentPresence(String userId) async {
|
||||||
|
final cachedPresence = presences[userId];
|
||||||
|
if (cachedPresence != null) {
|
||||||
|
return cachedPresence;
|
||||||
|
}
|
||||||
|
|
||||||
|
final dbPresence = await database?.getPresence(userId);
|
||||||
|
if (dbPresence != null) return presences[userId] = dbPresence;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final newPresence = await getPresence(userId);
|
||||||
|
return CachedPresence.fromPresenceResponse(newPresence, userId);
|
||||||
|
} catch (e) {
|
||||||
|
return CachedPresence.neverSeen(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool _disposed = false;
|
bool _disposed = false;
|
||||||
bool _aborted = false;
|
bool _aborted = false;
|
||||||
Future _currentTransaction = Future.sync(() => {});
|
Future _currentTransaction = Future.sync(() => {});
|
||||||
|
|
|
||||||
|
|
@ -312,4 +312,8 @@ abstract class DatabaseApi {
|
||||||
Future<String> exportDump();
|
Future<String> exportDump();
|
||||||
|
|
||||||
Future<bool> importDump(String export);
|
Future<bool> importDump(String export);
|
||||||
|
|
||||||
|
Future<void> storePresence(String userId, CachedPresence presence);
|
||||||
|
|
||||||
|
Future<CachedPresence?> getPresence(String userId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1478,6 +1478,18 @@ class HiveCollectionsDatabase extends DatabaseApi {
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> storePresence(String userId, CachedPresence presence) =>
|
||||||
|
_presencesBox.put(userId, presence.toJson());
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<CachedPresence?> getPresence(String userId) async {
|
||||||
|
final rawPresence = await _presencesBox.get(userId);
|
||||||
|
if (rawPresence == null) return null;
|
||||||
|
|
||||||
|
return CachedPresence.fromJson(copyMap(rawPresence));
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<String> exportDump() async {
|
Future<String> exportDump() async {
|
||||||
final dataMap = {
|
final dataMap = {
|
||||||
|
|
|
||||||
|
|
@ -1450,6 +1450,18 @@ class FamedlySdkHiveDatabase extends DatabaseApi {
|
||||||
return raw as String;
|
return raw as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> storePresence(String userId, CachedPresence presence) =>
|
||||||
|
_presencesBox.put(userId, presence.toJson());
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<CachedPresence?> getPresence(String userId) async {
|
||||||
|
final rawPresence = await _presencesBox.get(userId);
|
||||||
|
if (rawPresence == null) return null;
|
||||||
|
|
||||||
|
return CachedPresence.fromJson(copyMap(rawPresence));
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<String> exportDump() {
|
Future<String> exportDump() {
|
||||||
// see no need to implement this in a deprecated part
|
// see no need to implement this in a deprecated part
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,36 @@ class CachedPresence {
|
||||||
bool? currentlyActive;
|
bool? currentlyActive;
|
||||||
String userid;
|
String userid;
|
||||||
|
|
||||||
|
factory CachedPresence.fromJson(Map<String, Object?> json) =>
|
||||||
|
CachedPresence._(
|
||||||
|
presence: PresenceType.values
|
||||||
|
.singleWhere((type) => type.name == json['presence']),
|
||||||
|
lastActiveTimestamp: json['last_active_timestamp'] != null
|
||||||
|
? DateTime.fromMillisecondsSinceEpoch(
|
||||||
|
json['last_active_timestamp'] as int)
|
||||||
|
: null,
|
||||||
|
statusMsg: json['status_msg'] as String?,
|
||||||
|
currentlyActive: json['currently_active'] as bool?,
|
||||||
|
userid: json['user_id'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, Object?> toJson() => {
|
||||||
|
'user_id': userid,
|
||||||
|
'presence': presence.name,
|
||||||
|
if (lastActiveTimestamp != null)
|
||||||
|
'last_active_timestamp': lastActiveTimestamp?.millisecondsSinceEpoch,
|
||||||
|
if (statusMsg != null) 'status_msg': statusMsg,
|
||||||
|
if (currentlyActive != null) 'currently_active': currentlyActive,
|
||||||
|
};
|
||||||
|
|
||||||
|
CachedPresence._({
|
||||||
|
required this.userid,
|
||||||
|
required this.presence,
|
||||||
|
this.lastActiveTimestamp,
|
||||||
|
this.statusMsg,
|
||||||
|
this.currentlyActive,
|
||||||
|
});
|
||||||
|
|
||||||
CachedPresence(this.presence, int? lastActiveAgo, this.statusMsg,
|
CachedPresence(this.presence, int? lastActiveAgo, this.statusMsg,
|
||||||
this.currentlyActive, this.userid) {
|
this.currentlyActive, this.userid) {
|
||||||
if (lastActiveAgo != null) {
|
if (lastActiveAgo != null) {
|
||||||
|
|
@ -49,7 +79,7 @@ class CachedPresence {
|
||||||
|
|
||||||
Presence toPresence() {
|
Presence toPresence() {
|
||||||
final content = <String, dynamic>{
|
final content = <String, dynamic>{
|
||||||
'presence': presence.toString(),
|
'presence': presence.name.toString(),
|
||||||
};
|
};
|
||||||
if (currentlyActive != null) content['currently_active'] = currentlyActive!;
|
if (currentlyActive != null) content['currently_active'] = currentlyActive!;
|
||||||
if (lastActiveTimestamp != null) {
|
if (lastActiveTimestamp != null) {
|
||||||
|
|
|
||||||
|
|
@ -155,20 +155,10 @@ class User extends Event {
|
||||||
@Deprecated('Use fetchCurrentPresence() instead')
|
@Deprecated('Use fetchCurrentPresence() instead')
|
||||||
Future<CachedPresence> get currentPresence => fetchCurrentPresence();
|
Future<CachedPresence> get currentPresence => fetchCurrentPresence();
|
||||||
|
|
||||||
/// The newest presence of this user if there is any. Fetches it from the server if necessary or returns offline.
|
/// The newest presence of this user if there is any. Fetches it from the
|
||||||
Future<CachedPresence> fetchCurrentPresence() async {
|
/// database first and then from the server if necessary or returns offline.
|
||||||
final cachedPresence = room.client.presences[id];
|
Future<CachedPresence> fetchCurrentPresence() =>
|
||||||
if (cachedPresence != null) {
|
room.client.fetchCurrentPresence(id);
|
||||||
return cachedPresence;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final newPresence = await room.client.getPresence(id);
|
|
||||||
return CachedPresence.fromPresenceResponse(newPresence, id);
|
|
||||||
} catch (e) {
|
|
||||||
return CachedPresence.neverSeen(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether the client is able to ban/unban this user.
|
/// Whether the client is able to ban/unban this user.
|
||||||
bool get canBan => room.canBan && powerLevel < room.ownPowerLevel;
|
bool get canBan => room.canBan && powerLevel < room.ownPowerLevel;
|
||||||
|
|
|
||||||
|
|
@ -457,6 +457,25 @@ void testDatabase(
|
||||||
'deviceId',
|
'deviceId',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
test('getStorePresences', () async {
|
||||||
|
const userId = '@alice:example.com';
|
||||||
|
final presence = CachedPresence(
|
||||||
|
PresenceType.online,
|
||||||
|
100,
|
||||||
|
'test message',
|
||||||
|
true,
|
||||||
|
'@alice:example.com',
|
||||||
|
);
|
||||||
|
await database.storePresence(
|
||||||
|
userId,
|
||||||
|
presence,
|
||||||
|
);
|
||||||
|
final storedPresence = await database.getPresence(userId);
|
||||||
|
expect(
|
||||||
|
presence.toJson(),
|
||||||
|
storedPresence?.toJson(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// Clearing up from here
|
// Clearing up from here
|
||||||
test('clearSSSSCache', () async {
|
test('clearSSSSCache', () async {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue