@@ -1161,14 +1161,126 @@ impl SpircTask {
11611161 }
11621162 }
11631163
1164- fn emit_state_update ( & self , state : Option < PlayerState > ) {
1165- if self . state_sender . receiver_count ( ) == 0 {
1164+ fn emit_player_update ( & self , state : Option < PlayerState > , last_state : Option < & PlayerState > ) {
1165+ if self . player_update_sender . receiver_count ( ) == 0
1166+ && self . player_state_sender . receiver_count ( ) == 0
1167+ {
11661168 return ;
11671169 }
11681170
11691171 let state = state. unwrap_or_else ( || self . connect_state . player ( ) . clone ( ) ) ;
1170- if let Err ( why) = self . state_sender . send ( state) {
1171- warn ! ( "couldn't emit state because: {why}" )
1172+
1173+ // Determine the reason for the update by diffing with last state
1174+ let reason = if let Some ( last) = last_state {
1175+ // Check in priority order: track > play/pause > shuffle > repeat > seek
1176+ let new_track_uri = state
1177+ . track
1178+ . as_ref ( )
1179+ . map ( |t| t. uri . clone ( ) )
1180+ . unwrap_or_default ( ) ;
1181+ let old_track_uri = last
1182+ . track
1183+ . as_ref ( )
1184+ . map ( |t| t. uri . clone ( ) )
1185+ . unwrap_or_default ( ) ;
1186+ if new_track_uri != old_track_uri {
1187+ let _ = self . player_state_sender . send ( Some ( state) ) ;
1188+ let _ = self . player_update_sender . send ( PlayerUpdateEvent {
1189+ reason : PlayerUpdateReason :: TrackChanged ,
1190+ } ) ;
1191+ return ;
1192+ }
1193+
1194+ let new_is_playing = state. is_playing && !state. is_paused ;
1195+ let old_is_playing = last. is_playing && !last. is_paused ;
1196+ if new_is_playing != old_is_playing {
1197+ let _ = self . player_state_sender . send ( Some ( state) ) ;
1198+ let _ = self . player_update_sender . send ( PlayerUpdateEvent {
1199+ reason : PlayerUpdateReason :: PlayPauseChanged ,
1200+ } ) ;
1201+ return ;
1202+ }
1203+
1204+ let new_shuffle = state
1205+ . options
1206+ . as_ref ( )
1207+ . map ( |o| o. shuffling_context )
1208+ . unwrap_or ( false ) ;
1209+ let old_shuffle = last
1210+ . options
1211+ . as_ref ( )
1212+ . map ( |o| o. shuffling_context )
1213+ . unwrap_or ( false ) ;
1214+ if new_shuffle != old_shuffle {
1215+ let _ = self . player_state_sender . send ( Some ( state) ) ;
1216+ let _ = self . player_update_sender . send ( PlayerUpdateEvent {
1217+ reason : PlayerUpdateReason :: ShuffleChanged ,
1218+ } ) ;
1219+ return ;
1220+ }
1221+
1222+ let new_repeat = state
1223+ . options
1224+ . as_ref ( )
1225+ . map ( |o| ( o. repeating_context , o. repeating_track ) ) ;
1226+ let old_repeat = last
1227+ . options
1228+ . as_ref ( )
1229+ . map ( |o| ( o. repeating_context , o. repeating_track ) ) ;
1230+ if new_repeat != old_repeat {
1231+ let _ = self . player_state_sender . send ( Some ( state) ) ;
1232+ let _ = self . player_update_sender . send ( PlayerUpdateEvent {
1233+ reason : PlayerUpdateReason :: RepeatChanged ,
1234+ } ) ;
1235+ return ;
1236+ }
1237+
1238+ if state. context_uri != last. context_uri {
1239+ let _ = self . player_state_sender . send ( Some ( state) ) ;
1240+ let _ = self . player_update_sender . send ( PlayerUpdateEvent {
1241+ reason : PlayerUpdateReason :: ContextChanged ,
1242+ } ) ;
1243+ return ;
1244+ }
1245+
1246+ // Detect seek: position jump (not just natural progress)
1247+ let position_diff =
1248+ ( state. position_as_of_timestamp - last. position_as_of_timestamp ) . abs ( ) ;
1249+ if position_diff > 5000 {
1250+ // threshold: 5 seconds
1251+ PlayerUpdateReason :: PositionChanged
1252+ } else {
1253+ // No significant change detected
1254+ PlayerUpdateReason :: Other
1255+ }
1256+ } else {
1257+ // No previous state (initial state)
1258+ PlayerUpdateReason :: Other
1259+ } ;
1260+
1261+ let _ = self . player_state_sender . send ( Some ( state) ) ;
1262+ if let Err ( why) = self . player_update_sender . send ( PlayerUpdateEvent { reason } ) {
1263+ warn ! ( "couldn't emit player update because: {why}" )
1264+ }
1265+ }
1266+
1267+ fn emit_cluster_update ( & self , event : ClusterUpdateEvent ) {
1268+ if self . cluster_update_sender . receiver_count ( ) == 0 {
1269+ return ;
1270+ }
1271+
1272+ if let Err ( why) = self . cluster_update_sender . send ( event) {
1273+ warn ! ( "couldn't emit cluster transition because: {why}" )
1274+ }
1275+ }
1276+
1277+ fn emit_queue_update ( & self , event : QueueUpdateEvent ) {
1278+ if self . queue_update_sender . receiver_count ( ) == 0 {
1279+ return ;
1280+ }
1281+
1282+ if let Err ( why) = self . queue_update_sender . send ( event) {
1283+ warn ! ( "couldn't emit queue update because: {why}" )
11721284 }
11731285 }
11741286
0 commit comments