@@ -7,7 +7,7 @@ use tdlib::enums::StickerFormat;
77use tdlib:: types:: Sticker as TdSticker ;
88
99use crate :: session:: Session ;
10- use crate :: utils:: { decode_image_from_path, spawn } ;
10+ use crate :: utils:: decode_image_from_path;
1111
1212mod imp {
1313 use super :: * ;
@@ -16,7 +16,7 @@ mod imp {
1616 #[ derive( Debug , Default , glib:: Properties ) ]
1717 #[ properties( wrapper_type = super :: Sticker ) ]
1818 pub ( crate ) struct Sticker {
19- pub ( super ) message_id : Cell < i64 > ,
19+ pub ( super ) handle : RefCell < Option < glib :: JoinHandle < ( ) > > > ,
2020 pub ( super ) aspect_ratio : Cell < f64 > ,
2121 pub ( super ) child : RefCell < Option < gtk:: Widget > > ,
2222
@@ -95,13 +95,7 @@ glib::wrapper! {
9595}
9696
9797impl Sticker {
98- pub ( crate ) fn set_sticker (
99- & self ,
100- sticker : TdSticker ,
101- looped : bool ,
102- session : Session ,
103- message_id : i64 ,
104- ) {
98+ pub ( crate ) fn set_sticker ( & self , sticker : TdSticker , looped : bool , session : Session ) {
10599 // TODO: draw sticker outline with cairo
106100 self . set_child ( None ) ;
107101
@@ -110,18 +104,22 @@ impl Sticker {
110104 let aspect_ratio = sticker. width as f64 / sticker. height as f64 ;
111105 imp. aspect_ratio . set ( aspect_ratio) ;
112106
113- imp. message_id . set ( message_id) ;
114-
115107 let format = sticker. format ;
116108
117- spawn ( clone ! ( @weak self as obj, @weak session => async move {
118- if sticker. sticker. local. is_downloading_completed {
119- obj. load_sticker( & sticker. sticker. local. path, looped, format) . await ;
120- } else {
121- let file_id = sticker. sticker. id;
109+ let context = glib:: MainContext :: default ( ) ;
110+ let handle = context. spawn_local ( clone ! ( @weak self as obj, @weak session => async move {
111+ if sticker. sticker. local. is_downloading_completed {
112+ obj. load_sticker( & sticker. sticker. local. path, looped, format) . await ;
113+ } else {
114+ let file_id = sticker. sticker. id;
122115 obj. download_sticker( file_id, & session, looped, format) . await
123116 }
124117 } ) ) ;
118+
119+ // Widget can be recycled by ListView
120+ if let Some ( old_handle) = imp. handle . replace ( Some ( handle) ) {
121+ old_handle. abort ( ) ;
122+ } ;
125123 }
126124
127125 pub ( crate ) fn play_animation ( & self ) {
@@ -153,7 +151,6 @@ impl Sticker {
153151
154152 async fn load_sticker ( & self , path : & str , looped : bool , format : StickerFormat ) {
155153 let path = path. to_owned ( ) ;
156- let message_id = self . imp ( ) . message_id . get ( ) ;
157154
158155 let widget: gtk:: Widget = match format {
159156 StickerFormat :: Tgs => {
@@ -183,10 +180,6 @@ impl Sticker {
183180 _ => unimplemented ! ( ) ,
184181 } ;
185182
186- if self . imp ( ) . message_id . get ( ) != message_id {
187- return ;
188- }
189-
190183 self . set_child ( Some ( widget) ) ;
191184 }
192185
0 commit comments