@@ -13,6 +13,8 @@ use std::time::{Duration, Instant};
1313
1414use emojis:: Emoji ;
1515use matrix_sdk:: ruma:: events:: receipt:: ReceiptThread ;
16+ use matrix_sdk:: ruma:: events:: room:: MediaSource ;
17+ use matrix_sdk:: ruma:: OwnedMxcUri ;
1618use ratatui:: {
1719 buffer:: Buffer ,
1820 layout:: { Alignment , Rect } ,
@@ -90,9 +92,9 @@ use modalkit::{
9092 prelude:: { CommandType , WordStyle } ,
9193} ;
9294
93- use crate :: config:: ImagePreviewProtocolValues ;
95+ use crate :: config:: { ImagePreviewProtocolValues , ImagePreviewSize } ;
9496use crate :: notifications:: NotificationHandle ;
95- use crate :: preview:: { source_from_event, PreviewManager } ;
97+ use crate :: preview:: { source_from_event, PreviewKind , PreviewManager } ;
9698use crate :: {
9799 message:: { Message , MessageEvent , MessageKey , MessageTimeStamp , Messages } ,
98100 worker:: Requester ,
@@ -682,7 +684,7 @@ pub type IambResult<T> = UIResult<T, IambInfo>;
682684///
683685/// The event identifier used as a key here is the ID for the reaction, and not for the message
684686/// it's reacting to.
685- pub type MessageReactions = HashMap < OwnedEventId , ( String , OwnedUserId ) > ;
687+ pub type MessageReactions = HashMap < OwnedEventId , ( String , OwnedUserId , Option < MediaSource > ) > ;
686688
687689/// Errors encountered during application use.
688690#[ derive( thiserror:: Error , Debug ) ]
@@ -984,22 +986,25 @@ impl RoomInfo {
984986 }
985987
986988 /// Get the reactions and their counts for a message.
987- pub fn get_reactions ( & self , event_id : & EventId ) -> Vec < ( & str , usize ) > {
989+ pub fn get_reactions ( & self , event_id : & EventId ) -> Vec < ( & str , usize , & Option < MediaSource > ) > {
988990 if let Some ( reacts) = self . reactions . get ( event_id) {
989991 let mut counts = HashMap :: new ( ) ;
990992
991993 let mut seen_user_reactions = BTreeSet :: new ( ) ;
992994
993- for ( key, user) in reacts. values ( ) {
995+ for ( key, user, source ) in reacts. values ( ) {
994996 if !seen_user_reactions. contains ( & ( key, user) ) {
995997 seen_user_reactions. insert ( ( key, user) ) ;
996- let count = counts. entry ( key. as_str ( ) ) . or_default ( ) ;
997- * count += 1 ;
998+ let count = counts. entry ( key. as_str ( ) ) . or_insert ( ( 0 , source ) ) ;
999+ count. 0 += 1 ;
9981000 }
9991001 }
10001002
1001- let mut reactions = counts. into_iter ( ) . collect :: < Vec < _ > > ( ) ;
1002- reactions. sort ( ) ;
1003+ let mut reactions = counts
1004+ . into_iter ( )
1005+ . map ( |( key, ( count, source) ) | ( key, count, source) )
1006+ . collect :: < Vec < _ > > ( ) ;
1007+ reactions. sort_by_key ( |item| ( item. 0 , item. 1 ) ) ;
10031008
10041009 reactions
10051010 } else {
@@ -1060,24 +1065,46 @@ impl RoomInfo {
10601065 }
10611066
10621067 /// Insert a reaction to a message.
1063- pub fn insert_reaction ( & mut self , react : ReactionEvent ) {
1064- match react {
1065- MessageLikeEvent :: Original ( react) => {
1066- let rel_id = react. content . relates_to . event_id ;
1067- let key = react. content . relates_to . key ;
1068+ fn insert_reaction ( & mut self , react : ReactionEvent , source : Option < MediaSource > ) {
1069+ let MessageLikeEvent :: Original ( react) = react else {
1070+ return ;
1071+ } ;
1072+ let rel_id = react. content . relates_to . event_id ;
1073+ let key = react. content . relates_to . key ;
10681074
1069- let message = self . reactions . entry ( rel_id. clone ( ) ) . or_default ( ) ;
1070- let event_id = react. event_id ;
1071- let user_id = react. sender ;
1075+ let message = self . reactions . entry ( rel_id. clone ( ) ) . or_default ( ) ;
1076+ let event_id = react. event_id ;
1077+ let user_id = react. sender ;
10721078
1073- message. insert ( event_id. clone ( ) , ( key, user_id) ) ;
1079+ message. insert ( event_id. clone ( ) , ( key, user_id, source ) ) ;
10741080
1075- let loc = EventLocation :: Reaction ( rel_id) ;
1076- self . keys . insert ( event_id, loc) ;
1077- } ,
1078- MessageLikeEvent :: Redacted ( _) => {
1079- return ;
1080- } ,
1081+ let loc = EventLocation :: Reaction ( rel_id) ;
1082+ self . keys . insert ( event_id, loc) ;
1083+ }
1084+
1085+ /// Insert a reaction to a message.
1086+ pub fn insert_reaction_with_preview (
1087+ & mut self ,
1088+ react : ReactionEvent ,
1089+ settings : & ApplicationSettings ,
1090+ previews : & mut PreviewManager ,
1091+ worker : & Requester ,
1092+ ) {
1093+ let MessageLikeEvent :: Original ( ref orig_react) = react else {
1094+ return ;
1095+ } ;
1096+ let image_uri = OwnedMxcUri :: from ( orig_react. content . relates_to . key . as_str ( ) ) ;
1097+ let source = if image_uri. is_valid ( ) && settings. tunables . image_preview . is_some ( ) {
1098+ Some ( MediaSource :: Plain ( image_uri) )
1099+ } else {
1100+ None
1101+ } ;
1102+
1103+ self . insert_reaction ( react, source. clone ( ) ) ;
1104+
1105+ if let ( Some ( source) , Some ( _) ) = ( source, & settings. tunables . image_preview ) {
1106+ let size = ImagePreviewSize { width : 2 , height : 1 } ;
1107+ previews. register_preview ( settings, source, PreviewKind :: Reaction , size, worker) ;
10811108 }
10821109 }
10831110
@@ -1219,7 +1246,13 @@ impl RoomInfo {
12191246 ( self . get_event_mut ( & event_id) , & settings. tunables . image_preview )
12201247 {
12211248 msg. image_preview = Some ( source. clone ( ) ) ;
1222- previews. register_preview ( settings, source, image_preview. size , worker)
1249+ previews. register_preview (
1250+ settings,
1251+ source,
1252+ PreviewKind :: Message ,
1253+ image_preview. size ,
1254+ worker,
1255+ )
12231256 }
12241257 }
12251258 }
@@ -1376,7 +1409,7 @@ impl RoomInfo {
13761409 if let Some ( reactions) = self . reactions . get ( event_id) {
13771410 reactions
13781411 . values ( )
1379- . any ( |( annotation, user) | annotation == emoji && user == user_id)
1412+ . any ( |( annotation, user, _ ) | annotation == emoji && user == user_id)
13801413 } else {
13811414 false
13821415 }
@@ -2129,16 +2162,17 @@ pub mod tests {
21292162
21302163 for i in 0 ..3 {
21312164 let event_id = format ! ( "$house_{}" , i) ;
2132- info. insert_reaction ( MessageLikeEvent :: Original (
2133- matrix_sdk:: ruma:: events:: OriginalMessageLikeEvent {
2165+ info. insert_reaction (
2166+ MessageLikeEvent :: Original ( matrix_sdk:: ruma:: events:: OriginalMessageLikeEvent {
21342167 content : content. clone ( ) ,
21352168 event_id : OwnedEventId :: from_str ( & event_id) . unwrap ( ) ,
21362169 sender : owned_user_id ! ( "@foo:example.org" ) ,
21372170 origin_server_ts : MilliSecondsSinceUnixEpoch :: now ( ) ,
21382171 room_id : owned_room_id ! ( "!foo:example.org" ) ,
21392172 unsigned : MessageLikeUnsigned :: new ( ) ,
2140- } ,
2141- ) ) ;
2173+ } ) ,
2174+ None ,
2175+ ) ;
21422176 }
21432177
21442178 let content = ReactionEventContent :: new ( Annotation :: new (
@@ -2148,36 +2182,40 @@ pub mod tests {
21482182
21492183 for i in 0 ..2 {
21502184 let event_id = format ! ( "$smile_{}" , i) ;
2151- info. insert_reaction ( MessageLikeEvent :: Original (
2152- matrix_sdk:: ruma:: events:: OriginalMessageLikeEvent {
2185+ info. insert_reaction (
2186+ MessageLikeEvent :: Original ( matrix_sdk:: ruma:: events:: OriginalMessageLikeEvent {
21532187 content : content. clone ( ) ,
21542188 event_id : OwnedEventId :: from_str ( & event_id) . unwrap ( ) ,
21552189 sender : owned_user_id ! ( "@foo:example.org" ) ,
21562190 origin_server_ts : MilliSecondsSinceUnixEpoch :: now ( ) ,
21572191 room_id : owned_room_id ! ( "!foo:example.org" ) ,
21582192 unsigned : MessageLikeUnsigned :: new ( ) ,
2159- } ,
2160- ) ) ;
2193+ } ) ,
2194+ None ,
2195+ ) ;
21612196 }
21622197
21632198 for i in 2 ..4 {
21642199 let event_id = format ! ( "$smile_{}" , i) ;
2165- info. insert_reaction ( MessageLikeEvent :: Original (
2166- matrix_sdk:: ruma:: events:: OriginalMessageLikeEvent {
2200+ info. insert_reaction (
2201+ MessageLikeEvent :: Original ( matrix_sdk:: ruma:: events:: OriginalMessageLikeEvent {
21672202 content : content. clone ( ) ,
21682203 event_id : OwnedEventId :: from_str ( & event_id) . unwrap ( ) ,
21692204 sender : owned_user_id ! ( "@bar:example.org" ) ,
21702205 origin_server_ts : MilliSecondsSinceUnixEpoch :: now ( ) ,
21712206 room_id : owned_room_id ! ( "!foo:example.org" ) ,
21722207 unsigned : MessageLikeUnsigned :: new ( ) ,
2173- } ,
2174- ) ) ;
2208+ } ) ,
2209+ None ,
2210+ ) ;
21752211 }
21762212
2177- assert_eq ! ( info. get_reactions( & owned_event_id!( "$my_reaction" ) ) , vec![
2178- ( "🏠" , 1 ) ,
2179- ( "🙂" , 2 )
2180- ] ) ;
2213+ let reacts: Vec < _ > = info
2214+ . get_reactions ( & owned_event_id ! ( "$my_reaction" ) )
2215+ . into_iter ( )
2216+ . map ( |( key, count, _) | ( key, count) )
2217+ . collect ( ) ;
2218+ assert_eq ! ( reacts, vec![ ( "🏠" , 1 ) , ( "🙂" , 2 ) ] ) ;
21812219 }
21822220
21832221 #[ test]
0 commit comments