Skip to content

Commit 1f4f68e

Browse files
committed
emit player updates to its broadcast channel
semantically diff for player changes. also emit cluster and queue updates to their broadcast channels
1 parent fb0203b commit 1f4f68e

1 file changed

Lines changed: 116 additions & 4 deletions

File tree

connect/src/spirc.rs

Lines changed: 116 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)