aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cli.rs22
-rw-r--r--src/daemon.rs101
2 files changed, 105 insertions, 18 deletions
diff --git a/src/cli.rs b/src/cli.rs
index 13ef67c..1d83262 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -21,6 +21,15 @@ pub enum Commands {
21 Restart, 21 Restart,
22 /// Play a track, album, or artist 22 /// Play a track, album, or artist
23 Play { 23 Play {
24 /// Play immediately (add after current and skip to it)
25 #[arg(short = 'i', long = "now", group = "position")]
26 now: bool,
27 /// Add to queue after current track (don't skip)
28 #[arg(short = 'n', long = "next", group = "position")]
29 next: bool,
30 /// Add to end of queue (default)
31 #[arg(short = 'l', long = "last", group = "position")]
32 last: bool,
24 #[arg(value_name = "QUERY")] 33 #[arg(value_name = "QUERY")]
25 query: Option<String>, 34 query: Option<String>,
26 }, 35 },
@@ -102,9 +111,18 @@ impl Cli {
102 Commands::Restart => { 111 Commands::Restart => {
103 crate::daemon::restart_daemon()?; 112 crate::daemon::restart_daemon()?;
104 } 113 }
105 Commands::Play { query } => { 114 Commands::Play {
115 now, next, query, ..
116 } => {
106 if let Some(q) = query { 117 if let Some(q) = query {
107 crate::daemon::send_command(format!("play {}", q))?; 118 let pos = if *now {
119 "now"
120 } else if *next {
121 "next"
122 } else {
123 "last"
124 };
125 crate::daemon::send_command(format!("play {} {}", pos, q))?;
108 } else { 126 } else {
109 crate::daemon::send_command("play".to_string())?; 127 crate::daemon::send_command("play".to_string())?;
110 } 128 }
diff --git a/src/daemon.rs b/src/daemon.rs
index 4122c37..b0da698 100644
--- a/src/daemon.rs
+++ b/src/daemon.rs
@@ -149,6 +149,16 @@ impl Queue {
149 self.update_shuffle_indices(); 149 self.update_shuffle_indices();
150 } 150 }
151 151
152 fn insert_after_current(&mut self, path: PathBuf) {
153 let insert_idx = self.position + 1;
154 self.tracks.insert(insert_idx, Track::from_path(path));
155 self.update_shuffle_indices();
156 }
157
158 fn track_at(&self, idx: usize) -> Option<&Track> {
159 self.tracks.get(idx)
160 }
161
152 fn set_shuffle(&mut self, mode: ShuffleMode) { 162 fn set_shuffle(&mut self, mode: ShuffleMode) {
153 self.shuffle = mode.clone(); 163 self.shuffle = mode.clone();
154 self.update_shuffle_indices(); 164 self.update_shuffle_indices();
@@ -545,30 +555,89 @@ fn process_command(
545 } 555 }
546 } 556 }
547 _ if cmd.starts_with("play ") => { 557 _ if cmd.starts_with("play ") => {
548 let path_str = &cmd[5..].trim(); 558 let rest = &cmd[5..].trim();
549 let path = std::path::PathBuf::from(path_str); 559 let (position, path_str): (&str, &str) = if let Some((pos, p)) = rest.split_once(' ') {
560 if pos == "now" || pos == "next" || pos == "last" {
561 (pos, p)
562 } else {
563 ("last", rest)
564 }
565 } else {
566 ("last", rest)
567 };
568 let path_str = path_str.to_string();
569
570 if path_str.is_empty() {
571 return "Usage: play [now|next|last] <path>\n".to_string();
572 }
573
574 let path = std::path::PathBuf::from(path_str.clone());
550 if path.is_file() { 575 if path.is_file() {
551 // Add to queue and play
552 if let Ok(mut q) = queue.lock() { 576 if let Ok(mut q) = queue.lock() {
553 q.add_track(path.clone()); 577 match position {
578 "now" => {
579 q.insert_after_current(path.clone());
580 q.position += 1;
581 if let Some(track) = q.track_at(q.position) {
582 audio.play(track.path.clone());
583 }
584 format!("Playing now: {}\n", path_str)
585 }
586 "next" => {
587 q.insert_after_current(path.clone());
588 format!("Queued next: {}\n", path_str)
589 }
590 _ => {
591 q.add_track(path.clone());
592 audio.play(path);
593 format!("Playing: {}\n", path_str)
594 }
595 }
596 } else {
597 "Error accessing queue\n".to_string()
554 } 598 }
555 audio.play(path);
556 format!("Playing: {}\n", path_str)
557 } else if path.is_dir() { 599 } else if path.is_dir() {
558 // Find all audio files in directory
559 match find_audio_in_dir(&path) { 600 match find_audio_in_dir(&path) {
560 Some(files) if !files.is_empty() => { 601 Some(files) if !files.is_empty() => {
561 if let Ok(mut q) = queue.lock() { 602 if let Ok(mut q) = queue.lock() {
562 for file in &files { 603 match position {
563 q.add_track(file.clone()); 604 "now" => {
564 } 605 for file in &files {
565 // If shuffle is on, shuffled_indices is already set 606 q.insert_after_current(file.clone());
566 // Play the first track from the shuffled list 607 }
567 if let Some(track) = q.current() { 608 q.position += 1;
568 audio.play(track.path.clone()); 609 if let Some(track) = q.track_at(q.position) {
610 audio.play(track.path.clone());
611 }
612 format!(
613 "Playing now: {} tracks from {}\n",
614 files.len(),
615 path_str
616 )
617 }
618 "next" => {
619 for file in &files {
620 q.insert_after_current(file.clone());
621 }
622 format!(
623 "Queued next: {} tracks from {}\n",
624 files.len(),
625 path_str
626 )
627 }
628 _ => {
629 for file in &files {
630 q.add_track(file.clone());
631 }
632 if let Some(track) = q.current() {
633 audio.play(track.path.clone());
634 }
635 format!("Queued {} tracks from: {}\n", files.len(), path_str)
636 }
569 } 637 }
638 } else {
639 "Error accessing queue\n".to_string()
570 } 640 }
571 format!("Queued {} tracks from: {}\n", files.len(), path_str)
572 } 641 }
573 _ => format!("Error: No audio files found in '{}'\n", path_str), 642 _ => format!("Error: No audio files found in '{}'\n", path_str),
574 } 643 }
@@ -621,7 +690,7 @@ fn process_command(
621 for (display_idx, &track_idx) in indices.iter().enumerate() { 690 for (display_idx, &track_idx) in indices.iter().enumerate() {
622 if let Some(track) = q.tracks.get(track_idx) { 691 if let Some(track) = q.tracks.get(track_idx) {
623 let track_str = track.display_string(display_idx); 692 let track_str = track.display_string(display_idx);
624 if display_idx == current_position { 693 if track_idx == current_position {
625 output.push_str(&format!("> {} (playing)\n", track_str)); 694 output.push_str(&format!("> {} (playing)\n", track_str));
626 } else { 695 } else {
627 output.push_str(&format!(" {}\n", track_str)); 696 output.push_str(&format!(" {}\n", track_str));