@@ -337,10 +337,23 @@ impl Network {
337337 self . start_collection_playback ( offset) . await ;
338338 }
339339 IoEvent :: PreFetchAllSavedTracks => {
340- self . prefetch_all_saved_tracks ( ) . await ;
340+ // Spawn prefetch as a separate task to avoid blocking playback
341+ let spotify = self . spotify . clone ( ) ;
342+ let app = self . app . clone ( ) ;
343+ let large_search_limit = self . large_search_limit ;
344+ tokio:: spawn ( async move {
345+ Self :: prefetch_all_saved_tracks_task ( spotify, app, large_search_limit) . await ;
346+ } ) ;
341347 }
342348 IoEvent :: PreFetchAllPlaylistTracks ( playlist_id) => {
343- self . prefetch_all_playlist_tracks ( playlist_id) . await ;
349+ // Spawn prefetch as a separate task to avoid blocking playback
350+ let spotify = self . spotify . clone ( ) ;
351+ let app = self . app . clone ( ) ;
352+ let large_search_limit = self . large_search_limit ;
353+ tokio:: spawn ( async move {
354+ Self :: prefetch_all_playlist_tracks_task ( spotify, app, large_search_limit, playlist_id)
355+ . await ;
356+ } ) ;
344357 }
345358 } ;
346359
@@ -1133,10 +1146,15 @@ impl Network {
11331146
11341147 /// Pre-fetch all saved tracks pages in background for seamless playback
11351148 /// This loads all remaining pages that haven't been loaded yet
1136- async fn prefetch_all_saved_tracks ( & mut self ) {
1149+ /// Runs as a separate async task to avoid blocking other operations
1150+ async fn prefetch_all_saved_tracks_task (
1151+ spotify : AuthCodeSpotify ,
1152+ app : Arc < Mutex < App > > ,
1153+ large_search_limit : u32 ,
1154+ ) {
11371155 // Get current state
11381156 let ( current_total, pages_loaded) = {
1139- let app = self . app . lock ( ) . await ;
1157+ let app = app. lock ( ) . await ;
11401158 if let Some ( saved_tracks) = app. library . saved_tracks . get_results ( Some ( 0 ) ) {
11411159 (
11421160 saved_tracks. total ,
@@ -1148,20 +1166,19 @@ impl Network {
11481166 } ;
11491167
11501168 // Calculate how many tracks we already have
1151- let tracks_loaded = pages_loaded * self . large_search_limit ;
1169+ let tracks_loaded = pages_loaded * large_search_limit;
11521170
11531171 // Fetch remaining pages (limit to reasonable amount to avoid memory issues)
11541172 let max_tracks_to_prefetch = 500 ; // ~10 pages
11551173 let mut offset = tracks_loaded;
11561174
11571175 while offset < current_total && offset < tracks_loaded + max_tracks_to_prefetch {
1158- match self
1159- . spotify
1160- . current_user_saved_tracks_manual ( None , Some ( self . large_search_limit ) , Some ( offset) )
1176+ match spotify
1177+ . current_user_saved_tracks_manual ( None , Some ( large_search_limit) , Some ( offset) )
11611178 . await
11621179 {
11631180 Ok ( saved_tracks) => {
1164- let mut app = self . app . lock ( ) . await ;
1181+ let mut app = app. lock ( ) . await ;
11651182 // Add liked song IDs to the set
11661183 saved_tracks. items . iter ( ) . for_each ( |item| {
11671184 if let Some ( track_id) = & item. track . id {
@@ -1171,20 +1188,26 @@ impl Network {
11711188 // Add page to the saved tracks
11721189 app. library . saved_tracks . pages . push ( saved_tracks) ;
11731190 }
1174- Err ( e ) => {
1175- self . handle_error ( anyhow ! ( e ) ) . await ;
1191+ Err ( _e ) => {
1192+ // Silently fail in background task - don't show errors to user
11761193 break ;
11771194 }
11781195 }
1179- offset += self . large_search_limit ;
1196+ offset += large_search_limit;
11801197 }
11811198 }
11821199
11831200 /// Pre-fetch all tracks from a playlist in background
1184- async fn prefetch_all_playlist_tracks ( & mut self , playlist_id : PlaylistId < ' static > ) {
1201+ /// Runs as a separate async task to avoid blocking other operations
1202+ async fn prefetch_all_playlist_tracks_task (
1203+ spotify : AuthCodeSpotify ,
1204+ app : Arc < Mutex < App > > ,
1205+ large_search_limit : u32 ,
1206+ playlist_id : PlaylistId < ' static > ,
1207+ ) {
11851208 // Get current playlist state
11861209 let current_total = {
1187- let app = self . app . lock ( ) . await ;
1210+ let app = app. lock ( ) . await ;
11881211 if let Some ( playlist_tracks) = & app. playlist_tracks {
11891212 playlist_tracks. total
11901213 } else {
@@ -1194,41 +1217,40 @@ impl Network {
11941217
11951218 // Get current offset
11961219 let current_offset = {
1197- let app = self . app . lock ( ) . await ;
1220+ let app = app. lock ( ) . await ;
11981221 app. playlist_offset
11991222 } ;
12001223
12011224 // Fetch remaining pages (limit to avoid memory issues)
12021225 let max_tracks_to_prefetch = 500 ; // ~10 pages
1203- let mut offset = current_offset + self . large_search_limit ;
1226+ let mut offset = current_offset + large_search_limit;
12041227
12051228 while offset < current_total && offset < current_offset + max_tracks_to_prefetch {
1206- match self
1207- . spotify
1229+ match spotify
12081230 . playlist_items_manual (
12091231 playlist_id. clone ( ) ,
12101232 None ,
12111233 None ,
1212- Some ( self . large_search_limit ) ,
1234+ Some ( large_search_limit) ,
12131235 Some ( offset) ,
12141236 )
12151237 . await
12161238 {
12171239 Ok ( playlist_page) => {
12181240 // Store the fetched tracks
1219- let mut app = self . app . lock ( ) . await ;
1241+ let mut app = app. lock ( ) . await ;
12201242 // Extend playlist tracks items
12211243 if let Some ( ref mut existing) = app. playlist_tracks {
12221244 existing. items . extend ( playlist_page. items ) ;
12231245 existing. total = playlist_page. total ; // Update total in case it changed
12241246 }
12251247 }
1226- Err ( e ) => {
1227- self . handle_error ( anyhow ! ( e ) ) . await ;
1248+ Err ( _e ) => {
1249+ // Silently fail in background task - don't show errors to user
12281250 break ;
12291251 }
12301252 }
1231- offset += self . large_search_limit ;
1253+ offset += large_search_limit;
12321254 }
12331255 }
12341256
0 commit comments