use std::sync::Arc;
use crate::audio::{self, SPECTRUM_SIZE, SpectrumBuffer};
use crate::config::Config;
use crate::player::Player;
pub struct App {
pub radio_names: Vec<String>,
pub urls: std::collections::HashMap<String, String>,
pub selected: usize,
pub player: Player,
pub playing: Option<String>,
pub spectrum: Vec<f32>,
pub running: bool,
pub show_selector: bool,
pub show_help: bool,
audio_spectrum: Arc<SpectrumBuffer>,
}
impl App {
pub fn new(config: Config, initial_radio: Option<&str>) -> Self {
let radio_names = config.sorted_names();
let selected = initial_radio
.and_then(|name| radio_names.iter().position(|n| n == name))
.unwrap_or(0);
let mut app = Self {
radio_names,
urls: config.radios,
selected,
player: Player::new(),
playing: None,
spectrum: vec![0.0f32; SPECTRUM_SIZE],
running: true,
show_selector: false,
show_help: false,
audio_spectrum: audio::spawn_capture(),
};
app.play_selected();
app
}
fn play_selected(&mut self) {
if let Some(url) = self
.radio_names
.get(self.selected)
.and_then(|n| self.urls.get(n))
{
let url = url.clone();
if self.player.play(&url).is_ok() {
self.playing = Some(self.radio_names[self.selected].clone());
}
}
}
pub fn toggle_selector(&mut self) {
self.show_selector = !self.show_selector;
}
pub fn next(&mut self) {
if !self.radio_names.is_empty() {
self.selected = (self.selected + 1) % self.radio_names.len();
}
}
pub fn previous(&mut self) {
if !self.radio_names.is_empty() {
self.selected = self
.selected
.checked_sub(1)
.unwrap_or(self.radio_names.len() - 1);
}
}
pub fn toggle_play(&mut self) {
let name = &self.radio_names[self.selected];
if self.playing.as_deref() == Some(name.as_str()) {
self.player.stop();
self.playing = None;
} else if let Some(url) = self.urls.get(name)
&& self.player.play(url).is_ok() {
self.playing = Some(name.clone());
}
}
pub fn tick(&mut self) {
self.spectrum.copy_from_slice(self.audio_spectrum.read());
}
pub fn quit(&mut self) {
self.running = false;
}
}