@@ -5,49 +5,42 @@ import 'package:watch_it/watch_it.dart';
55import '../../../common/view/build_context_x.dart' ;
66import '../../../common/view/ui_constants.dart' ;
77import '../../chat_model.dart' ;
8- import '../../room_x.dart' ;
98import '../../search_model.dart' ;
109import '../chat_avatar.dart' ;
1110import '../chat_profile_dialog.dart' ;
1211
13- class ChatSeenByIndicator extends StatefulWidget
14- with WatchItStatefulWidgetMixin {
15- const ChatSeenByIndicator ({
12+ class ChatEventSeenByIndicator extends StatelessWidget with WatchItMixin {
13+ const ChatEventSeenByIndicator ({
1614 super .key,
17- required this .room,
18- required this .timeline,
15+ required this .event,
1916 });
2017
21- final Room room;
22- final Timeline timeline;
18+ final Event event;
2319
2420 static const maxAvatars = 7 ;
2521
26- @override
27- State <ChatSeenByIndicator > createState () => _ChatSeenByIndicatorState ();
28- }
29-
30- class _ChatSeenByIndicatorState extends State <ChatSeenByIndicator > {
31- @override
32- void initState () {
33- super .initState ();
34- widget.room.requestParticipants ();
35- }
36-
3722 @override
3823 Widget build (BuildContext context) {
39- final events = watchStream (
40- (ChatModel m) => m.getReadEventsFromSync (widget.room),
41- initialValue: widget.timeline.events,
42- ).data;
43- final list = < Event > {...widget.timeline.events, ...? events}.toList ();
44- final seenByUsers = widget.room.getSeenByUsers (list);
24+ watchFuture (
25+ (ChatModel m) => m.requestParticipants (event.room),
26+ initialValue: event.room.getParticipants (),
27+ );
28+
29+ final seenByUsers = watchStream (
30+ (ChatModel m) => m.getRoomsReceipts (event),
31+ initialValue: event.receipts,
32+ )
33+ .data
34+ ? .map ((e) => e.user)
35+ .where ((e) => e.id != di <ChatModel >().myUserId)
36+ .toList () ??
37+ [];
4538
4639 return Container (
4740 width: double .infinity,
48- alignment: widget .room.isDirectChat ||
49- di <ChatModel >().isUserEvent (list.first ) &&
50- list.first .type != EventTypes .Reaction
41+ alignment: event .room.isDirectChat ||
42+ di <ChatModel >().isUserEvent (event ) &&
43+ event .type != EventTypes .Reaction
5144 ? Alignment .centerRight
5245 : Alignment .centerLeft,
5346 child: AnimatedContainer (
@@ -60,35 +53,19 @@ class _ChatSeenByIndicatorState extends State<ChatSeenByIndicator> {
6053 child: Wrap (
6154 spacing: kSmallPadding,
6255 children: [
63- ...(seenByUsers.length > ChatSeenByIndicator .maxAvatars
64- ? seenByUsers.sublist (0 , ChatSeenByIndicator .maxAvatars)
56+ ...(seenByUsers.length > maxAvatars
57+ ? seenByUsers.sublist (
58+ 0 ,
59+ maxAvatars,
60+ )
6561 : seenByUsers)
6662 .map (
67- (user) => Tooltip (
63+ (user) => ChatEventSeenByAvatar (
6864 key: ValueKey (user.id + user.avatarUrl.toString ()),
69- message: user.displayName ?? user.id,
70- child: InkWell (
71- borderRadius: BorderRadius .circular (15 ),
72- onTap: () async {
73- final profile =
74- await di <SearchModel >().lookupProfile (user.id);
75- if (context.mounted) {
76- showDialog (
77- context: context,
78- builder: (context) =>
79- ChatProfileDialog (userId: profile.userId),
80- );
81- }
82- },
83- child: ChatAvatar (
84- avatarUri: user.avatarUrl,
85- fallBackIconSize: 10 ,
86- dimension: 15 ,
87- ),
88- ),
65+ user: user,
8966 ),
9067 ),
91- if (seenByUsers.length > ChatSeenByIndicator . maxAvatars)
68+ if (seenByUsers.length > maxAvatars)
9269 SizedBox (
9370 width: 15 ,
9471 height: 15 ,
@@ -97,7 +74,7 @@ class _ChatSeenByIndicatorState extends State<ChatSeenByIndicator> {
9774 borderRadius: BorderRadius .circular (30 ),
9875 child: Center (
9976 child: Text (
100- '+${seenByUsers .length - ChatSeenByIndicator . maxAvatars }' ,
77+ '+${seenByUsers .length - maxAvatars }' ,
10178 style: const TextStyle (fontSize: 9 ),
10279 ),
10380 ),
@@ -109,3 +86,36 @@ class _ChatSeenByIndicatorState extends State<ChatSeenByIndicator> {
10986 );
11087 }
11188}
89+
90+ class ChatEventSeenByAvatar extends StatelessWidget {
91+ const ChatEventSeenByAvatar ({
92+ super .key,
93+ required this .user,
94+ });
95+
96+ final User user;
97+
98+ @override
99+ Widget build (BuildContext context) {
100+ return Tooltip (
101+ message: user.displayName ?? user.id,
102+ child: InkWell (
103+ borderRadius: BorderRadius .circular (15 ),
104+ onTap: () async {
105+ final profile = await di <SearchModel >().lookupProfile (user.id);
106+ if (context.mounted) {
107+ showDialog (
108+ context: context,
109+ builder: (context) => ChatProfileDialog (userId: profile.userId),
110+ );
111+ }
112+ },
113+ child: ChatAvatar (
114+ avatarUri: user.avatarUrl,
115+ fallBackIconSize: 10 ,
116+ dimension: 15 ,
117+ ),
118+ ),
119+ );
120+ }
121+ }
0 commit comments