@@ -1730,25 +1730,36 @@ impl Chat {
1730
1730
1731
1731
/// Returns profile image path for the chat.
1732
1732
pub async fn get_profile_image ( & self , context : & Context ) -> Result < Option < PathBuf > > {
1733
- if let Some ( image_rel ) = self . param . get ( Param :: ProfileImage ) {
1734
- if !image_rel . is_empty ( ) {
1735
- return Ok ( Some ( get_abs_path ( context , Path :: new ( & image_rel ) ) ) ) ;
1736
- }
1737
- } else if self . id . is_archived_link ( ) {
1738
- if let Ok ( image_rel ) = get_archive_icon ( context) . await {
1739
- return Ok ( Some ( get_abs_path ( context , Path :: new ( & image_rel ) ) ) ) ;
1740
- }
1733
+ if self . id . is_archived_link ( ) {
1734
+ // This is not a real chat, but the "Archive" button
1735
+ // that is shown at the top of the chats list
1736
+ return Ok ( Some ( get_archive_icon ( context ) . await ? ) ) ;
1737
+ } else if self . is_device_talk ( ) {
1738
+ return Ok ( Some ( get_device_icon ( context) . await ? ) ) ;
1739
+ } else if self . is_self_talk ( ) {
1740
+ return Ok ( Some ( get_saved_messages_icon ( context ) . await ? ) ) ;
1741
1741
} else if self . typ == Chattype :: Single {
1742
+ // For 1:1 chats, we always use the same avatar as for the contact
1743
+ // This is before the `self.is_encrypted()` check, because that function
1744
+ // has two database calls, i.e. it's slow
1742
1745
let contacts = get_chat_contacts ( context, self . id ) . await ?;
1743
1746
if let Some ( contact_id) = contacts. first ( ) {
1744
- if let Ok ( contact) = Contact :: get_by_id ( context, * contact_id) . await {
1745
- return contact. get_profile_image ( context) . await ;
1746
- }
1747
+ let contact = Contact :: get_by_id ( context, * contact_id) . await ?;
1748
+ return contact. get_profile_image ( context) . await ;
1747
1749
}
1748
- } else if self . typ == Chattype :: Broadcast {
1749
- if let Ok ( image_rel) = get_broadcast_icon ( context) . await {
1750
+ } else if !self . is_encrypted ( context) . await ? {
1751
+ // This is an email-contact chat, show a special avatar that marks it as such
1752
+ return Ok ( Some ( get_abs_path (
1753
+ context,
1754
+ Path :: new ( & get_email_contact_icon ( context) . await ?) ,
1755
+ ) ) ) ;
1756
+ } else if let Some ( image_rel) = self . param . get ( Param :: ProfileImage ) {
1757
+ // Load the group avatar, or the device-chat / saved-messages icon
1758
+ if !image_rel. is_empty ( ) {
1750
1759
return Ok ( Some ( get_abs_path ( context, Path :: new ( & image_rel) ) ) ) ;
1751
1760
}
1761
+ } else if self . typ == Chattype :: Broadcast {
1762
+ return Ok ( Some ( get_broadcast_icon ( context) . await ?) ) ;
1752
1763
}
1753
1764
Ok ( None )
1754
1765
}
@@ -2422,69 +2433,63 @@ pub struct ChatInfo {
2422
2433
// - [ ] email
2423
2434
}
2424
2435
2425
- pub ( crate ) async fn update_saved_messages_icon ( context : & Context ) -> Result < ( ) > {
2426
- if let Some ( ChatIdBlocked { id : chat_id, .. } ) =
2427
- ChatIdBlocked :: lookup_by_contact ( context, ContactId :: SELF ) . await ?
2428
- {
2429
- let icon = include_bytes ! ( "../assets/icon-saved-messages.png" ) ;
2430
- let blob =
2431
- BlobObject :: create_and_deduplicate_from_bytes ( context, icon, "saved-messages.png" ) ?;
2432
- let icon = blob. as_name ( ) . to_string ( ) ;
2433
-
2434
- let mut chat = Chat :: load_from_db ( context, chat_id) . await ?;
2435
- chat. param . set ( Param :: ProfileImage , icon) ;
2436
- chat. update_param ( context) . await ?;
2436
+ async fn get_asset_icon ( context : & Context , name : & str , bytes : & [ u8 ] ) -> Result < PathBuf > {
2437
+ ensure ! ( name. starts_with( "icon-" ) ) ;
2438
+ if let Some ( icon) = context. sql . get_raw_config ( name) . await ? {
2439
+ return Ok ( get_abs_path ( context, Path :: new ( & icon) ) ) ;
2437
2440
}
2438
- Ok ( ( ) )
2439
- }
2440
2441
2441
- pub ( crate ) async fn update_device_icon ( context : & Context ) -> Result < ( ) > {
2442
- if let Some ( ChatIdBlocked { id : chat_id, .. } ) =
2443
- ChatIdBlocked :: lookup_by_contact ( context, ContactId :: DEVICE ) . await ?
2444
- {
2445
- let icon = include_bytes ! ( "../assets/icon-device.png" ) ;
2446
- let blob = BlobObject :: create_and_deduplicate_from_bytes ( context, icon, "device.png" ) ?;
2447
- let icon = blob. as_name ( ) . to_string ( ) ;
2442
+ let blob =
2443
+ BlobObject :: create_and_deduplicate_from_bytes ( context, bytes, & format ! ( "{name}.png" ) ) ?;
2444
+ let icon = blob. as_name ( ) . to_string ( ) ;
2445
+ context. sql . set_raw_config ( name, Some ( & icon) ) . await ?;
2448
2446
2449
- let mut chat = Chat :: load_from_db ( context, chat_id) . await ?;
2450
- chat. param . set ( Param :: ProfileImage , & icon) ;
2451
- chat. update_param ( context) . await ?;
2447
+ Ok ( get_abs_path ( context, Path :: new ( & icon) ) )
2448
+ }
2452
2449
2453
- let mut contact = Contact :: get_by_id ( context, ContactId :: DEVICE ) . await ?;
2454
- contact. param . set ( Param :: ProfileImage , icon) ;
2455
- contact. update_param ( context) . await ?;
2456
- }
2457
- Ok ( ( ) )
2450
+ pub ( crate ) async fn get_saved_messages_icon ( context : & Context ) -> Result < PathBuf > {
2451
+ get_asset_icon (
2452
+ context,
2453
+ "icon-saved-messages" ,
2454
+ include_bytes ! ( "../assets/icon-saved-messages.png" ) ,
2455
+ )
2456
+ . await
2458
2457
}
2459
2458
2460
- pub ( crate ) async fn get_broadcast_icon ( context : & Context ) -> Result < String > {
2461
- if let Some ( icon) = context. sql . get_raw_config ( "icon-broadcast" ) . await ? {
2462
- return Ok ( icon) ;
2463
- }
2459
+ pub ( crate ) async fn get_device_icon ( context : & Context ) -> Result < PathBuf > {
2460
+ get_asset_icon (
2461
+ context,
2462
+ "icon-device" ,
2463
+ include_bytes ! ( "../assets/icon-device.png" ) ,
2464
+ )
2465
+ . await
2466
+ }
2464
2467
2465
- let icon = include_bytes ! ( "../assets/icon-broadcast.png" ) ;
2466
- let blob = BlobObject :: create_and_deduplicate_from_bytes ( context, icon, "broadcast.png" ) ?;
2467
- let icon = blob. as_name ( ) . to_string ( ) ;
2468
- context
2469
- . sql
2470
- . set_raw_config ( "icon-broadcast" , Some ( & icon) )
2471
- . await ?;
2472
- Ok ( icon)
2468
+ pub ( crate ) async fn get_broadcast_icon ( context : & Context ) -> Result < PathBuf > {
2469
+ get_asset_icon (
2470
+ context,
2471
+ "icon-broadcast" ,
2472
+ include_bytes ! ( "../assets/icon-broadcast.png" ) ,
2473
+ )
2474
+ . await
2473
2475
}
2474
2476
2475
- pub ( crate ) async fn get_archive_icon ( context : & Context ) -> Result < String > {
2476
- if let Some ( icon) = context. sql . get_raw_config ( "icon-archive" ) . await ? {
2477
- return Ok ( icon) ;
2478
- }
2477
+ pub ( crate ) async fn get_archive_icon ( context : & Context ) -> Result < PathBuf > {
2478
+ get_asset_icon (
2479
+ context,
2480
+ "icon-archive" ,
2481
+ include_bytes ! ( "../assets/icon-archive.png" ) ,
2482
+ )
2483
+ . await
2484
+ }
2479
2485
2480
- let icon = include_bytes ! ( "../assets/icon-archive.png" ) ;
2481
- let blob = BlobObject :: create_and_deduplicate_from_bytes ( context, icon, "archive.png" ) ?;
2482
- let icon = blob. as_name ( ) . to_string ( ) ;
2483
- context
2484
- . sql
2485
- . set_raw_config ( "icon-archive" , Some ( & icon) )
2486
- . await ?;
2487
- Ok ( icon)
2486
+ pub ( crate ) async fn get_email_contact_icon ( context : & Context ) -> Result < PathBuf > {
2487
+ get_asset_icon (
2488
+ context,
2489
+ "icon-email-contact" ,
2490
+ include_bytes ! ( "../assets/icon-email-contact.png" ) ,
2491
+ )
2492
+ . await
2488
2493
}
2489
2494
2490
2495
async fn update_special_chat_name (
@@ -2658,12 +2663,6 @@ impl ChatIdBlocked {
2658
2663
. await ?;
2659
2664
}
2660
2665
2661
- match contact_id {
2662
- ContactId :: SELF => update_saved_messages_icon ( context) . await ?,
2663
- ContactId :: DEVICE => update_device_icon ( context) . await ?,
2664
- _ => ( ) ,
2665
- }
2666
-
2667
2666
Ok ( Self {
2668
2667
id : chat_id,
2669
2668
blocked : create_blocked,
0 commit comments