refreshPlayerList method
Refresh the list of available players
Implementation
Future<void> refreshPlayerList() async {
// Prevent concurrent refreshes
if (_isRefreshing) {
PlayerctlLogger.debug(
'Skipping refresh - already in progress',
'Refresh',
);
return;
}
_isRefreshing = true;
try {
final players = await _service.getAvailablePlayers();
final hasPlayer = players.isNotEmpty;
final previousSelected = _state.selectedPlayer;
String selected = _state.selectedPlayer;
bool needsReconnect = false;
// Case 1: No players available
if (players.isEmpty) {
selected = '';
PlayerctlLogger.player('No players available');
}
// Case 2: First time selecting a player
else if (selected.isEmpty) {
selected = players.first;
needsReconnect = true;
PlayerctlLogger.player('Auto-selecting first player: $selected');
}
// Case 3: Currently selected player no longer exists
else if (!players.contains(selected)) {
selected = players.first;
needsReconnect = true;
PlayerctlLogger.player(
'Selected player "$previousSelected" no longer available, switching to: $selected',
);
}
// Case 4: Selected player still exists (no change needed)
else {
PlayerctlLogger.debug(
'Current player "$selected" still available',
'Player',
);
}
_updateState(
_state.copyWith(
availablePlayers: players,
hasActivePlayer: hasPlayer,
selectedPlayer: selected,
currentMedia: hasPlayer ? _state.currentMedia : MediaInfo.empty(),
),
);
// If we switched to a different player, reconnect
if (needsReconnect && hasPlayer && selected != previousSelected) {
PlayerctlLogger.player('Reconnecting to new player: $selected');
// Stop all current syncing
stopListening();
_stopVolumeSync();
_stopMetadataRefresh();
// Small delay to ensure clean disconnect
await Future.delayed(const Duration(milliseconds: 100));
// Fetch metadata immediately for new player
try {
final metadata = await _service.getCurrentMetadata(selected);
if (metadata.isNotEmpty) {
_updateMediaInfo(metadata);
}
} catch (e) {
PlayerctlLogger.error(
'Error fetching metadata for player $selected',
'Player',
e,
);
}
// Fetch current state
await updateCurrentVolume();
await updateShuffleStatus();
await updateLoopStatus();
// Start listening and all sync timers
startListening(selected);
_startVolumeSync();
_startMetadataRefresh();
}
} catch (e) {
PlayerctlLogger.error('Error refreshing player list', 'Player', e);
} finally {
_isRefreshing = false;
}
}