Implement shuffle, repeat and their indicators
This commit is contained in:
parent
ef22a84021
commit
a65ad793dc
|
|
@ -3,7 +3,8 @@ mod rpc;
|
||||||
use crabidy_core::proto::crabidy::{
|
use crabidy_core::proto::crabidy::{
|
||||||
crabidy_service_client::CrabidyServiceClient,
|
crabidy_service_client::CrabidyServiceClient,
|
||||||
get_update_stream_response::Update as StreamUpdate, GetLibraryNodeRequest,
|
get_update_stream_response::Update as StreamUpdate, GetLibraryNodeRequest,
|
||||||
InitResponse as InitialData, LibraryNode, PlayState, Queue, QueueTrack, Track, TrackPosition,
|
InitResponse as InitialData, LibraryNode, PlayState, Queue, QueueModifiers, QueueTrack, Track,
|
||||||
|
TrackPosition,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
|
|
@ -386,6 +387,7 @@ impl LibraryView {
|
||||||
struct NowPlayingView {
|
struct NowPlayingView {
|
||||||
play_state: PlayState,
|
play_state: PlayState,
|
||||||
duration: Option<Duration>,
|
duration: Option<Duration>,
|
||||||
|
modifiers: QueueModifiers,
|
||||||
position: Option<Duration>,
|
position: Option<Duration>,
|
||||||
track: Option<Track>,
|
track: Option<Track>,
|
||||||
}
|
}
|
||||||
|
|
@ -409,6 +411,9 @@ impl NowPlayingView {
|
||||||
}
|
}
|
||||||
self.track = active;
|
self.track = active;
|
||||||
}
|
}
|
||||||
|
fn update_modifiers(&mut self, mods: &QueueModifiers) {
|
||||||
|
self.modifiers = mods.clone();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct App {
|
struct App {
|
||||||
|
|
@ -438,6 +443,7 @@ impl App {
|
||||||
let now_playing = NowPlayingView {
|
let now_playing = NowPlayingView {
|
||||||
play_state: PlayState::Unspecified,
|
play_state: PlayState::Unspecified,
|
||||||
duration: None,
|
duration: None,
|
||||||
|
modifiers: QueueModifiers::default(),
|
||||||
position: None,
|
position: None,
|
||||||
track: None,
|
track: None,
|
||||||
};
|
};
|
||||||
|
|
@ -480,6 +486,8 @@ enum MessageFromUi {
|
||||||
TogglePlay,
|
TogglePlay,
|
||||||
ChangeVolume(f32),
|
ChangeVolume(f32),
|
||||||
ToggleMute,
|
ToggleMute,
|
||||||
|
ToggleShuffle,
|
||||||
|
ToggleRepeat,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn poll(
|
async fn poll(
|
||||||
|
|
@ -531,6 +539,12 @@ async fn poll(
|
||||||
MessageFromUi::ToggleMute => {
|
MessageFromUi::ToggleMute => {
|
||||||
rpc_client.toggle_mute().await?
|
rpc_client.toggle_mute().await?
|
||||||
}
|
}
|
||||||
|
MessageFromUi::ToggleShuffle => {
|
||||||
|
rpc_client.toggle_shuffle().await?
|
||||||
|
}
|
||||||
|
MessageFromUi::ToggleRepeat => {
|
||||||
|
rpc_client.toggle_repeat().await?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(resp) = rpc_client.update_stream.next() => {
|
Some(resp) = rpc_client.update_stream.next() => {
|
||||||
|
|
@ -614,6 +628,9 @@ fn run_ui(tx: Sender<MessageFromUi>, rx: Receiver<MessageToUi>) {
|
||||||
if let Some(ps) = PlayState::from_i32(init_data.play_state) {
|
if let Some(ps) = PlayState::from_i32(init_data.play_state) {
|
||||||
app.now_playing.update_play_state(ps);
|
app.now_playing.update_play_state(ps);
|
||||||
}
|
}
|
||||||
|
if let Some(mods) = init_data.mods {
|
||||||
|
app.now_playing.update_modifiers(&mods);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MessageToUi::Update(update) => match update {
|
MessageToUi::Update(update) => match update {
|
||||||
StreamUpdate::Queue(queue) => {
|
StreamUpdate::Queue(queue) => {
|
||||||
|
|
@ -629,7 +646,11 @@ fn run_ui(tx: Sender<MessageFromUi>, rx: Receiver<MessageToUi>) {
|
||||||
app.now_playing.update_play_state(ps);
|
app.now_playing.update_play_state(ps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
StreamUpdate::Mods(mods) => {
|
||||||
|
app.now_playing.update_modifiers(&mods);
|
||||||
|
}
|
||||||
|
StreamUpdate::Mute(_) => { /* FIXME: implement */ }
|
||||||
|
StreamUpdate::Volume(_) => { /* FIXME: implement */ }
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -663,6 +684,12 @@ fn run_ui(tx: Sender<MessageFromUi>, rx: Receiver<MessageToUi>) {
|
||||||
(_, KeyModifiers::NONE, KeyCode::Char('m')) => {
|
(_, KeyModifiers::NONE, KeyCode::Char('m')) => {
|
||||||
tx.send(MessageFromUi::ToggleMute);
|
tx.send(MessageFromUi::ToggleMute);
|
||||||
}
|
}
|
||||||
|
(_, KeyModifiers::NONE, KeyCode::Char('z')) => {
|
||||||
|
tx.send(MessageFromUi::ToggleShuffle);
|
||||||
|
}
|
||||||
|
(_, KeyModifiers::NONE, KeyCode::Char('x')) => {
|
||||||
|
tx.send(MessageFromUi::ToggleRepeat);
|
||||||
|
}
|
||||||
(_, KeyModifiers::CONTROL, KeyCode::Char('n')) => {
|
(_, KeyModifiers::CONTROL, KeyCode::Char('n')) => {
|
||||||
app.queue.play_next();
|
app.queue.play_next();
|
||||||
}
|
}
|
||||||
|
|
@ -875,8 +902,12 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
|
||||||
Some(album) => album.title.to_string(),
|
Some(album) => album.title.to_string(),
|
||||||
None => "No album".to_string(),
|
None => "No album".to_string(),
|
||||||
};
|
};
|
||||||
|
let mods = format!(
|
||||||
|
"Shuffle: {}, Repeat {}",
|
||||||
|
&app.now_playing.modifiers.shuffle, &app.now_playing.modifiers.repeat
|
||||||
|
);
|
||||||
vec![
|
vec![
|
||||||
Spans::from(Span::raw("")),
|
Spans::from(Span::raw(mods)),
|
||||||
Spans::from(Span::raw(play_text)),
|
Spans::from(Span::raw(play_text)),
|
||||||
Spans::from(vec![
|
Spans::from(vec![
|
||||||
Span::styled(
|
Span::styled(
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use crabidy_core::proto::crabidy::{
|
||||||
GetUpdateStreamRequest, GetUpdateStreamResponse, InitRequest, InitResponse, InsertRequest,
|
GetUpdateStreamRequest, GetUpdateStreamResponse, InitRequest, InitResponse, InsertRequest,
|
||||||
LibraryNode, NextRequest, PrevRequest, QueueRequest, RemoveRequest, ReplaceRequest,
|
LibraryNode, NextRequest, PrevRequest, QueueRequest, RemoveRequest, ReplaceRequest,
|
||||||
RestartTrackRequest, SetCurrentRequest, SetCurrentResponse, ToggleMuteRequest,
|
RestartTrackRequest, SetCurrentRequest, SetCurrentResponse, ToggleMuteRequest,
|
||||||
TogglePlayRequest, TogglePlayResponse,
|
TogglePlayRequest, TogglePlayResponse, ToggleRepeatRequest, ToggleShuffleRequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
|
@ -21,6 +21,7 @@ use tonic::{
|
||||||
Request, Streaming,
|
Request, Streaming,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// FIXME: use anyhow + thiserror
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum RpcClientError {
|
enum RpcClientError {
|
||||||
NotFound,
|
NotFound,
|
||||||
|
|
@ -175,6 +176,18 @@ impl RpcClient {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn toggle_shuffle(&mut self) -> Result<(), Box<dyn Error>> {
|
||||||
|
let toggle_shuffle_request = Request::new(ToggleShuffleRequest {});
|
||||||
|
self.client.toggle_shuffle(toggle_shuffle_request).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn toggle_repeat(&mut self) -> Result<(), Box<dyn Error>> {
|
||||||
|
let toggle_repeat_request = Request::new(ToggleRepeatRequest {});
|
||||||
|
self.client.toggle_repeat(toggle_repeat_request).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn change_volume(&mut self, delta: f32) -> Result<(), Box<dyn Error>> {
|
pub async fn change_volume(&mut self, delta: f32) -> Result<(), Box<dyn Error>> {
|
||||||
let change_volume_request = Request::new(ChangeVolumeRequest { delta });
|
let change_volume_request = Request::new(ChangeVolumeRequest { delta });
|
||||||
self.client.change_volume(change_volume_request).await?;
|
self.client.change_volume(change_volume_request).await?;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue