@@ -5,12 +5,15 @@ use gtk::subclass::prelude::*;
5
5
use gtk:: { glib, CompositeTemplate } ;
6
6
use tdlib:: enums:: ChatMembers :: ChatMembers as TdChatMembers ;
7
7
use tdlib:: enums:: User :: User as TdUser ;
8
- use tdlib:: enums:: { ChatMemberStatus , MessageSender , UserType } ;
8
+ use tdlib:: enums:: { MessageSender , UserType } ;
9
9
use tdlib:: functions;
10
- use tdlib:: types:: { BasicGroupFullInfo , ChatMember , ChatMembers , SupergroupFullInfo } ;
10
+ use tdlib:: types:: {
11
+ BasicGroupFullInfo , ChatMember as TdChatMember , ChatMembers , SupergroupFullInfo ,
12
+ } ;
11
13
12
14
use crate :: i18n:: ngettext_f;
13
- use crate :: tdlib:: { BasicGroup , BoxedUserStatus , Chat , ChatType , Supergroup , User } ;
15
+ use crate :: session:: components:: ChatMemberRow ;
16
+ use crate :: tdlib:: { BasicGroup , BoxedUserStatus , Chat , ChatMember , ChatType , Supergroup , User } ;
14
17
use crate :: utils:: spawn;
15
18
use crate :: { expressions, strings} ;
16
19
@@ -34,7 +37,7 @@ mod imp {
34
37
#[ template_child]
35
38
pub ( super ) members_page : TemplateChild < adw:: ViewStackPage > ,
36
39
#[ template_child]
37
- pub ( super ) members_list : TemplateChild < gtk:: ListBox > ,
40
+ pub ( super ) members_list : TemplateChild < gtk:: ListView > ,
38
41
}
39
42
40
43
#[ glib:: object_subclass]
@@ -310,81 +313,63 @@ impl ChatInfoWindow {
310
313
self . update_info_list_visibility ( ) ;
311
314
}
312
315
313
- async fn append_members ( & self , members : Vec < ChatMember > ) {
314
- let session = self . chat ( ) . unwrap ( ) . session ( ) ;
315
- let client_id = session . client_id ( ) ;
316
+ async fn append_members ( & self , members : Vec < TdChatMember > ) {
317
+ let members : Vec < _ > = {
318
+ let mut users : Vec < User > = vec ! [ ] ;
316
319
317
- let members_list = & self . imp ( ) . members_list ;
320
+ let session = self . chat ( ) . unwrap ( ) . session ( ) ;
321
+ let client_id = session. client_id ( ) ;
318
322
319
- for member in members {
320
- if let MessageSender :: User ( user) = member. member_id {
321
- if let Ok ( TdUser ( user) ) = functions:: get_user ( user. user_id , client_id) . await {
322
- let user_row = adw:: ActionRow :: new ( ) ;
323
- user_row. set_title_lines ( 1 ) ;
324
- user_row. set_subtitle_lines ( 1 ) ;
325
-
326
- let user = User :: from_td_object ( user, & session) ;
327
-
328
- let user_expression = gtk:: ObjectExpression :: new ( & user) ;
329
- let name_expression = expressions:: user_display_name ( & user_expression) ;
330
- name_expression. bind ( & user_row, "title" , Some ( & user) ) ;
331
-
332
- User :: this_expression ( "status" )
333
- . chain_closure :: < String > ( closure ! (
334
- |_: Option <glib:: Object >, status: BoxedUserStatus | {
335
- strings:: user_status( & status. 0 )
336
- }
337
- ) )
338
- . bind ( & user_row, "subtitle" , Some ( & user) ) ;
339
-
340
- if let UserType :: Bot ( _) = user. type_ ( ) . 0 {
341
- user_row. set_subtitle ( & gettext ( "bot" ) ) ;
342
- } else {
343
- User :: this_expression ( "status" )
344
- . chain_closure :: < String > ( closure ! (
345
- |_: Option <glib:: Object >, status: BoxedUserStatus | {
346
- strings:: user_status( & status. 0 )
347
- }
348
- ) )
349
- . bind ( & user_row, "subtitle" , Some ( & user) ) ;
350
- } ;
351
-
352
- let avatar = crate :: session:: components:: Avatar :: new ( ) ;
353
-
354
- avatar. set_item ( Some ( user. upcast ( ) ) ) ;
355
- avatar. set_size ( 32 ) ;
356
- user_row. add_prefix ( & avatar) ;
357
-
358
- let status = match member. status {
359
- ChatMemberStatus :: Creator ( owner) => {
360
- let title = if owner. custom_title . is_empty ( ) {
361
- gettext ( "Owner" )
362
- } else {
363
- owner. custom_title
364
- } ;
365
- Some ( title)
366
- }
367
- ChatMemberStatus :: Administrator ( admin) => {
368
- let title = if admin. custom_title . is_empty ( ) {
369
- gettext ( "Admin" )
370
- } else {
371
- admin. custom_title
372
- } ;
373
- Some ( title)
374
- }
375
- _ => None ,
376
- } ;
377
-
378
- if let Some ( text) = status {
379
- let owner_label = gtk:: Label :: new ( Some ( & text) ) ;
380
- owner_label. set_yalign ( 0.2 ) ;
381
- owner_label. set_css_classes ( & [ "caption" , "accent" ] ) ;
382
- user_row. add_suffix ( & owner_label) ;
323
+ for member in & members {
324
+ let user = match member. member_id {
325
+ MessageSender :: User ( ref user) => {
326
+ let TdUser ( user) =
327
+ functions:: get_user ( user. user_id , client_id) . await . unwrap ( ) ;
328
+ User :: from_td_object ( user, & session)
383
329
}
384
-
385
- members_list . append ( & user_row ) ;
386
- }
330
+ MessageSender :: Chat ( _ ) => unreachable ! ( ) ,
331
+ } ;
332
+ users . push ( user ) ;
387
333
}
334
+
335
+ members
336
+ . into_iter ( )
337
+ . zip ( users. into_iter ( ) )
338
+ . map ( |( member, user) | ChatMember :: new ( member, user) )
339
+ . collect ( )
340
+ } ;
341
+
342
+ let members_list = & self . imp ( ) . members_list ;
343
+
344
+ let selection_model: gtk:: NoSelection = members_list. model ( ) . unwrap ( ) . downcast ( ) . unwrap ( ) ;
345
+
346
+ let model: gtk:: gio:: ListStore = if let Some ( model) = selection_model. model ( ) {
347
+ model. downcast ( ) . unwrap ( )
348
+ } else {
349
+ let model = gtk:: gio:: ListStore :: new ( ChatMember :: static_type ( ) ) ;
350
+ selection_model. set_model ( Some ( & model) ) ;
351
+ model
352
+ } ;
353
+
354
+ model. extend_from_slice ( & members) ;
355
+
356
+ if members_list. factory ( ) . is_none ( ) {
357
+ let factory = gtk:: SignalListItemFactory :: new ( ) ;
358
+
359
+ factory. connect_setup ( move |_, list_item| {
360
+ list_item. set_property ( "child" , ChatMemberRow :: new ( ) ) ;
361
+ } ) ;
362
+
363
+ factory. connect_bind ( move |_, list_item| {
364
+ let list_item: & gtk:: ListItem = list_item. downcast_ref ( ) . unwrap ( ) ;
365
+
366
+ let user_row: ChatMemberRow = list_item. child ( ) . unwrap ( ) . downcast ( ) . unwrap ( ) ;
367
+ let member: ChatMember = list_item. item ( ) . unwrap ( ) . downcast ( ) . unwrap ( ) ;
368
+
369
+ user_row. bind_member ( member) ;
370
+ } ) ;
371
+
372
+ members_list. set_factory ( Some ( & factory) ) ;
388
373
}
389
374
}
390
375
0 commit comments