diff --git a/lib/components/dialogs/presence_dialog.dart b/lib/components/dialogs/presence_dialog.dart index f5bc0b50..c5398d1d 100644 --- a/lib/components/dialogs/presence_dialog.dart +++ b/lib/components/dialogs/presence_dialog.dart @@ -34,15 +34,6 @@ class PresenceDialog extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(presence.getLocalizedStatusMessage(context)), - if (presence.presence != null) - Text( - presence.presence.toString().split('.').last, - style: TextStyle( - color: presence.presence.currentlyActive == true - ? Colors.green - : Theme.of(context).primaryColor, - ), - ) ], ), actions: [ diff --git a/lib/components/list_items/presence_list_item.dart b/lib/components/list_items/presence_list_item.dart index 2bc1c466..bd1e6511 100644 --- a/lib/components/list_items/presence_list_item.dart +++ b/lib/components/list_items/presence_list_item.dart @@ -1,15 +1,15 @@ import 'package:famedlysdk/famedlysdk.dart'; +import 'package:fluffychat/components/dialogs/presence_dialog.dart'; import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/views/chat.dart'; import 'package:flutter/material.dart'; -import '../../utils/client_presence_extension.dart'; import '../avatar.dart'; import '../matrix.dart'; class PresenceListItem extends StatelessWidget { - final Presence presence; + final Room room; - const PresenceListItem(this.presence); + const PresenceListItem(this.room); void _startChatAction(BuildContext context, String userId) async { final roomId = await User(userId, @@ -25,37 +25,42 @@ class PresenceListItem extends StatelessWidget { @override Widget build(BuildContext context) { - return FutureBuilder( - future: - Matrix.of(context).client.requestProfileCached(presence.senderId), - builder: (context, snapshot) { - Uri avatarUrl; - var displayname = presence.senderId.localpart; - if (snapshot.hasData) { - avatarUrl = snapshot.data.avatarUrl; - displayname = - snapshot.data.displayname ?? presence.senderId.localpart; - } - return InkWell( - onTap: () => _startChatAction(context, presence.senderId), - child: Container( - width: 80, - child: Column( - children: [ - SizedBox(height: 9), - Avatar(avatarUrl, displayname), - Padding( - padding: const EdgeInsets.all(6.0), - child: Text( - displayname, - overflow: TextOverflow.ellipsis, - maxLines: 1, - ), - ), - ], + final user = room.getUserByMXIDSync(room.directChatMatrixID); + final presence = + Matrix.of(context).client.presences[room.directChatMatrixID]; + return InkWell( + onTap: () => presence?.presence?.statusMsg == null + ? _startChatAction(context, user.id) + : showDialog( + context: context, + builder: (_) => PresenceDialog( + presence, + avatarUrl: user.avatarUrl, + displayname: user.calcDisplayname(), ), ), - ); - }); + child: Container( + width: 80, + child: Column( + children: [ + SizedBox(height: 9), + Avatar(user.avatarUrl, user.calcDisplayname()), + Padding( + padding: const EdgeInsets.all(6.0), + child: Text( + user.calcDisplayname(), + overflow: TextOverflow.ellipsis, + maxLines: 1, + style: TextStyle( + fontWeight: presence?.presence?.statusMsg == null + ? null + : FontWeight.bold, + ), + ), + ), + ], + ), + ), + ); } } diff --git a/lib/utils/client_presence_extension.dart b/lib/utils/client_presence_extension.dart index 42540d13..65f18850 100644 --- a/lib/utils/client_presence_extension.dart +++ b/lib/utils/client_presence_extension.dart @@ -1,16 +1,6 @@ import 'package:famedlysdk/famedlysdk.dart'; extension ClientPresenceExtension on Client { - List get statusList { - final statusList = presences.values.toList().reversed.toList(); - final directRooms = rooms.where((r) => r.isDirectChat).toList(); - statusList.removeWhere((p) => - directRooms.indexWhere((r) => r.directChatMatrixID == p.senderId) == - -1); - statusList.reversed.toList(); - return statusList; - } - static final Map presencesCache = {}; Future requestProfileCached(String senderId) async { diff --git a/lib/utils/presence_extension.dart b/lib/utils/presence_extension.dart index b3672985..c127cd31 100644 --- a/lib/utils/presence_extension.dart +++ b/lib/utils/presence_extension.dart @@ -8,8 +8,11 @@ extension PresenceExtension on Presence { if (presence.statusMsg?.isNotEmpty ?? false) { return presence.statusMsg; } - return L10n.of(context).lastActiveAgo( - DateTime.fromMillisecondsSinceEpoch(presence.lastActiveAgo) - .localizedTimeShort(context)); + if (presence.lastActiveAgo != null) { + return L10n.of(context).lastActiveAgo( + DateTime.fromMillisecondsSinceEpoch(presence.lastActiveAgo) + .localizedTimeShort(context)); + } + return L10n.of(context).lastSeenLongTimeAgo; } } diff --git a/lib/utils/room_status_extension.dart b/lib/utils/room_status_extension.dart index 6b5d043a..72306611 100644 --- a/lib/utils/room_status_extension.dart +++ b/lib/utils/room_status_extension.dart @@ -9,7 +9,10 @@ extension RoomStatusExtension on Room { String getLocalizedStatus(BuildContext context) { if (isDirectChat) { - if (directChatPresence != null) { + if (directChatPresence != null && + directChatPresence.presence != null && + (directChatPresence.presence.lastActiveAgo != null || + directChatPresence.presence.currentlyActive != null)) { if (directChatPresence.presence.currentlyActive == true) { return L10n.of(context).currentlyActive; } diff --git a/lib/views/chat_list.dart b/lib/views/chat_list.dart index 831e5dd1..657180af 100644 --- a/lib/views/chat_list.dart +++ b/lib/views/chat_list.dart @@ -19,7 +19,6 @@ import '../components/matrix.dart'; import '../l10n/l10n.dart'; import '../utils/app_route.dart'; import '../utils/url_launcher.dart'; -import '../utils/client_presence_extension.dart'; import 'archive.dart'; import 'homeserver_picker.dart'; import 'new_group.dart'; @@ -436,6 +435,16 @@ class _ChatListState extends State { (publicRoomsResponse?.chunk?.length ?? 0); final totalCount = rooms.length + publicRoomsCount; + final directChats = + rooms.where((r) => r.isDirectChat).toList(); + directChats.sort((a, b) => Matrix.of(context) + .client + .presences[b.directChatMatrixID] + ?.presence + ?.statusMsg != + null + ? 1 + : -1); return ListView.separated( controller: _scrollController, separatorBuilder: @@ -452,10 +461,7 @@ class _ChatListState extends State { itemCount: totalCount + 1, itemBuilder: (BuildContext context, int i) { if (i == 0) { - return (Matrix.of(context) - .client - .statusList - .isEmpty || + return (directChats.isEmpty || selectMode == SelectMode.share) ? Container() : PreferredSize( @@ -466,17 +472,12 @@ class _ChatListState extends State { child: ListView.builder( scrollDirection: Axis.horizontal, - itemCount: Matrix.of(context) - .client - .statusList - .length, - itemBuilder: (BuildContext - context, - int i) => - PresenceListItem( - Matrix.of(context) - .client - .statusList[i]), + itemCount: directChats.length, + itemBuilder: + (BuildContext context, + int i) => + PresenceListItem( + directChats[i]), ), ), );