feat: Store timestamp in the presence events
This fixes the presence never being accurate in the app.
This commit is contained in:
parent
2f232fefba
commit
907a0d2317
|
|
@ -26,6 +26,7 @@ export 'src/database/database_api.dart';
|
|||
export 'src/database/hive_database.dart';
|
||||
export 'src/database/fluffybox_database.dart';
|
||||
export 'src/event.dart';
|
||||
export 'src/presence.dart';
|
||||
export 'src/event_status.dart';
|
||||
export 'src/voip.dart';
|
||||
export 'src/voip_content.dart';
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ class Client extends MatrixApi {
|
|||
Map<String, BasicEvent> get accountData => _accountData;
|
||||
|
||||
/// Presences of users by a given matrix ID
|
||||
Map<String, Presence> presences = {};
|
||||
Map<String, CachedPresence> presences = {};
|
||||
|
||||
int _transactionCounter = 0;
|
||||
|
||||
|
|
@ -889,8 +889,14 @@ class Client extends MatrixApi {
|
|||
StreamController.broadcast();
|
||||
|
||||
/// Callback will be called on presences.
|
||||
@Deprecated(
|
||||
'Deprecated, use onPresenceChanged instead which has a timestamp.')
|
||||
final StreamController<Presence> onPresence = StreamController.broadcast();
|
||||
|
||||
/// Callback will be called on presence updates.
|
||||
final StreamController<CachedPresence> onPresenceChanged =
|
||||
StreamController.broadcast();
|
||||
|
||||
/// Callback will be called on account data updates.
|
||||
final StreamController<BasicEvent> onAccountData =
|
||||
StreamController.broadcast();
|
||||
|
|
@ -1467,8 +1473,11 @@ class Client extends MatrixApi {
|
|||
}
|
||||
}
|
||||
for (final newPresence in sync.presence ?? []) {
|
||||
presences[newPresence.senderId] = newPresence;
|
||||
final cachedPresence = CachedPresence.fromMatrixEvent(newPresence);
|
||||
presences[newPresence.senderId] = cachedPresence;
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
onPresence.add(newPresence);
|
||||
onPresenceChanged.add(cachedPresence);
|
||||
}
|
||||
for (final newAccountData in sync.accountData ?? []) {
|
||||
await database?.storeAccountData(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Famedly Matrix SDK
|
||||
* Copyright (C) 2019, 2020, 2021 Famedly GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import '../matrix.dart';
|
||||
|
||||
class CachedPresence {
|
||||
PresenceType presence;
|
||||
DateTime? lastActiveTimestamp;
|
||||
String? statusMsg;
|
||||
bool? currentlyActive;
|
||||
String userid;
|
||||
|
||||
CachedPresence(this.presence, int? lastActiveAgo, this.statusMsg,
|
||||
this.currentlyActive, this.userid) {
|
||||
if (lastActiveAgo != null) {
|
||||
lastActiveTimestamp =
|
||||
DateTime.now().subtract(Duration(milliseconds: lastActiveAgo));
|
||||
}
|
||||
}
|
||||
|
||||
CachedPresence.fromMatrixEvent(Presence event)
|
||||
: this(
|
||||
event.presence.presence,
|
||||
event.presence.lastActiveAgo,
|
||||
event.presence.statusMsg,
|
||||
event.presence.currentlyActive,
|
||||
event.senderId);
|
||||
|
||||
CachedPresence.fromPresenceResponse(GetPresenceResponse event, String userid)
|
||||
: this(event.presence, event.lastActiveAgo, event.statusMsg,
|
||||
event.currentlyActive, userid);
|
||||
|
||||
CachedPresence.neverSeen(String userid)
|
||||
: presence = PresenceType.offline,
|
||||
userid = userid;
|
||||
|
||||
Presence toPresence() {
|
||||
final content = <String, dynamic>{
|
||||
'presence': presence.toString(),
|
||||
};
|
||||
if (currentlyActive != null) content['currently_active'] = currentlyActive!;
|
||||
if (lastActiveTimestamp != null) {
|
||||
content['last_active_ago'] =
|
||||
DateTime.now().difference(lastActiveTimestamp!).inMilliseconds;
|
||||
}
|
||||
if (statusMsg != null) content['status_msg'] = statusMsg!;
|
||||
|
||||
final json = {
|
||||
'content': content,
|
||||
'sender': '@example:localhost',
|
||||
'type': 'm.presence'
|
||||
};
|
||||
|
||||
return Presence.fromJson(json);
|
||||
}
|
||||
}
|
||||
|
|
@ -158,7 +158,23 @@ class User extends Event {
|
|||
);
|
||||
|
||||
/// The newest presence of this user if there is any and null if not.
|
||||
Presence? get presence => room.client.presences[id];
|
||||
@Deprecated('Deprecated in favour of currentPresence.')
|
||||
Presence? get presence => room.client.presences[id]?.toPresence();
|
||||
|
||||
/// The newest presence of this user if there is any. Fetches it from the server if necessary or returns offline.
|
||||
Future<CachedPresence> get currentPresence async {
|
||||
final cachedPresence = room.client.presences[id];
|
||||
if (cachedPresence != null) {
|
||||
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.
|
||||
bool get canBan => room.canBan && powerLevel < room.ownPowerLevel;
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ void main() {
|
|||
|
||||
var presenceCounter = 0;
|
||||
var accountDataCounter = 0;
|
||||
matrix.onPresence.stream.listen((Presence data) {
|
||||
matrix.onPresenceChanged.stream.listen((CachedPresence data) {
|
||||
presenceCounter++;
|
||||
});
|
||||
matrix.onAccountData.stream.listen((BasicEvent data) {
|
||||
|
|
@ -150,7 +150,7 @@ void main() {
|
|||
expect(matrix.rooms.length, 2);
|
||||
expect(matrix.rooms[1].canonicalAlias,
|
||||
"#famedlyContactDiscovery:${matrix.userID!.split(":")[1]}");
|
||||
expect(matrix.presences['@alice:example.com']?.presence.presence,
|
||||
expect(matrix.presences['@alice:example.com']?.presence,
|
||||
PresenceType.online);
|
||||
expect(presenceCounter, 1);
|
||||
expect(accountDataCounter, 9);
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ void main() {
|
|||
]
|
||||
}
|
||||
}));
|
||||
expect(user1.presence?.presence.presence, PresenceType.online);
|
||||
expect((await user1.currentPresence).presence, PresenceType.online);
|
||||
});
|
||||
test('canBan', () async {
|
||||
expect(user1.canBan, false);
|
||||
|
|
|
|||
Loading…
Reference in New Issue