enum CallbackAction {
SelectDevice,
PlayPause,
+ SkipNext,
+ SkipPrev,
+ Volume,
Preset,
}
use connectr::osx::MenuItem;
struct MenuItems {
- device: Vec<MenuItem>,
+ device: Vec<(MenuItem, String)>,
play: MenuItem,
+ next: MenuItem,
+ prev: MenuItem,
preset: Vec<MenuItem>,
}
struct ConnectrApp {
menu: MenuItems,
}
+fn play_action_label(is_playing: bool) -> &'static str {
+ match is_playing {
+ true => "Pause",
+ false => "Play",
+ }
+}
+
fn main() {
let mut app = ConnectrApp {
menu: MenuItems {
- device: Vec::<MenuItem>::new(),
+ device: Vec::<(MenuItem, String)>::new(),
play: ptr::null_mut(),
+ next: ptr::null_mut(),
+ prev: ptr::null_mut(),
preset: Vec::<MenuItem>::new(),
}
};
let device_list = spotify.request_device_list();
- status.add_label("DEVICES:");
+ status.add_label("Devices:");
status.add_separator();
println!("Visible Devices:");
let _ = tx.send(json::encode(&cmd).unwrap());
});
let item = status.add_item(&dev.name, cb, dev.is_active);
- app.menu.device.push(item);
+ app.menu.device.push((item, dev.id.clone()));
}
println!("");
status.set_tooltip(&play_str);
status.add_label("");
- status.add_label("ACTIONS:");
+ status.add_label("Actions:");
status.add_separator();
{
- let play_str = match player_state.is_playing {
- true => "PAUSE",
- false => "PLAY",
- };
+ let play_str = play_action_label(player_state.is_playing);
let cb: osx::NSCallback = Box::new(move |sender, tx| {
let is_playing = &player_state.is_playing;
let cmd = MenuCallbackCommand {
let _ = tx.send(json::encode(&cmd).unwrap());
});
app.menu.play = status.add_item(&play_str, cb, false);
+
+ let cb: osx::NSCallback = Box::new(move |sender, tx| {
+ let cmd = MenuCallbackCommand {
+ action: CallbackAction::SkipNext,
+ sender: sender,
+ data: String::new(),
+ };
+ let _ = tx.send(json::encode(&cmd).unwrap());
+ });
+ app.menu.next = status.add_item("Next", cb, false);
+
+ let cb: osx::NSCallback = Box::new(move |sender, tx| {
+ let cmd = MenuCallbackCommand {
+ action: CallbackAction::SkipPrev,
+ sender: sender,
+ data: String::new(),
+ };
+ let _ = tx.send(json::encode(&cmd).unwrap());
+ });
+ app.menu.prev = status.add_item("Previous", cb, false);
}
status.add_label("");
- status.add_label("PRESETS:");
+ status.add_label("Presets:");
status.add_separator();
{
- for uri in vec!["spotify:user:mrmekon:playlist:4c8eKK6kKrcdt1HToEX7Jc",
- "spotify:user:spotify:playlist:37i9dQZEVXcOmDhsenkuCu"] {
+ let presets = spotify.get_presets();
+ for preset in presets {
+ let ref name = preset.0;
+ let uri = preset.1.clone();
let cb: osx::NSCallback = Box::new(move |sender, tx| {
let cmd = MenuCallbackCommand {
action: CallbackAction::Preset,
};
let _ = tx.send(json::encode(&cmd).unwrap());
});
- let item = status.add_item(uri, cb, false);
+ let item = status.add_item(&name.clone(), cb, false);
app.menu.preset.push(item);
}
}
+ status.add_label("");
+ status.add_label("Volume:");
+ status.add_separator();
+ {
+ let mut i = 0;
+ while i <= 100 {
+ let vol_str = format!("{}%", i);
+ let cb: osx::NSCallback = Box::new(move |sender, tx| {
+ let cmd = MenuCallbackCommand {
+ action: CallbackAction::Volume,
+ sender: sender,
+ data: i.to_string(),
+ };
+ let _ = tx.send(json::encode(&cmd).unwrap());
+ });
+ app.menu.play = status.add_item(&vol_str, cb, false);
+ i += 10;
+ }
+ }
+
loop {
spotify.await_once(false);
if let Ok(s) = rx.try_recv() {
match cmd.action {
CallbackAction::SelectDevice => {
let device = &app.menu.device;
- for item in device {
+ for dev in device {
+ let &(ref item, _) = dev;
status.unsel_item(*item as u64);
}
status.sel_item(cmd.sender);
true => {require(spotify.pause());},
false => {require(spotify.play(None));},
}
- //let player_state = spotify.request_player_state();
- let play_str = match player_state.is_playing {
- false => "PAUSE",
- true => "PLAY",
- };
+ let play_str = play_action_label(!player_state.is_playing);
status.update_item(app.menu.play, play_str);
},
CallbackAction::Preset => {
play_uri(&mut spotify, None, Some(&cmd.data));
}
+ CallbackAction::SkipNext => {
+ require(spotify.next());
+ }
+ CallbackAction::SkipPrev => {
+ require(spotify.previous());
+ }
+ CallbackAction::Volume => {
+ let vol = cmd.data.parse::<u32>().unwrap();
+ require(spotify.volume(vol));
+ }
}
}
status.run(false);
pub access_token: Option<String>,
pub refresh_token: Option<String>,
pub expire_utc: Option<u64>,
+ pub presets: Vec<(String,String)>,
}
pub fn read_settings() -> Option<Settings> {
println!("Read access token from INI!");
}
+ let mut presets = Vec::<(String,String)>::new();
+ if let Some(section) = conf.section(Some("presets".to_owned())) {
+ for (key, value) in section {
+ presets.push((key.to_owned(), value.to_owned()));
+ }
+ }
+
Some(Settings { secret: secret.to_string(), client_id: client_id.to_string(), port: port,
- access_token: access, refresh_token: refresh, expire_utc: expire_utc})
+ access_token: access, refresh_token: refresh, expire_utc: expire_utc,
+ presets: presets})
}
pub type SettingsError = String;
self.set_target_device(Some(device));
http::http(spotify_api::PLAYER, "", &body, http::HttpMethod::PUT, self.bearer_token())
}
+ pub fn get_presets(&mut self) -> &Vec<(String,String)> {
+ &self.settings.presets
+ }
}