Add audio playback upon notification
This commit is contained in:
		
							
								
								
									
										29
									
								
								src/alert.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/alert.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
use rodio::{Decoder, Source};
 | 
			
		||||
use std::error::Error;
 | 
			
		||||
use std::fs::File;
 | 
			
		||||
use std::io::BufReader;
 | 
			
		||||
use std::path::PathBuf;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub struct Alert {
 | 
			
		||||
    path: PathBuf,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Alert {
 | 
			
		||||
    pub fn new(path: PathBuf) -> Self {
 | 
			
		||||
        Self { path }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn load(&mut self, path: PathBuf) {
 | 
			
		||||
        self.path = path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn play(&self) -> Result<(), Box<dyn Error>> {
 | 
			
		||||
        let file = File::open(&self.path)?;
 | 
			
		||||
        let device = rodio::default_output_device().ok_or("No default output device found.")?;
 | 
			
		||||
        let source = Decoder::new(BufReader::new(file))?;
 | 
			
		||||
 | 
			
		||||
        rodio::play_raw(&device, source.convert_samples());
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
pub use alert::Alert;
 | 
			
		||||
pub use pomodoro::Pomodoro;
 | 
			
		||||
 | 
			
		||||
mod alert;
 | 
			
		||||
mod pomodoro;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -1,7 +1,41 @@
 | 
			
		||||
use directories::ProjectDirs;
 | 
			
		||||
use domasi::Alert;
 | 
			
		||||
use domasi::Pomodoro;
 | 
			
		||||
use std::fs;
 | 
			
		||||
use std::path::PathBuf;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let mut domasi: Pomodoro = Default::default();
 | 
			
		||||
 | 
			
		||||
    domasi.start();
 | 
			
		||||
    match get_alert() {
 | 
			
		||||
        Some(alert) => domasi.start_with_alert(alert),
 | 
			
		||||
        None => domasi.start(),
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn get_alert() -> Option<Alert> {
 | 
			
		||||
    let alert_dir = ProjectDirs::from("moe", "paoda", "domasi")
 | 
			
		||||
        .unwrap()
 | 
			
		||||
        .data_dir()
 | 
			
		||||
        .to_path_buf()
 | 
			
		||||
        .join("alert");
 | 
			
		||||
 | 
			
		||||
    let file = find_alert_file(alert_dir)?;
 | 
			
		||||
    Some(Alert::new(file))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn find_alert_file(path: PathBuf) -> Option<PathBuf> {
 | 
			
		||||
    let items = fs::read_dir(path).ok()?;
 | 
			
		||||
 | 
			
		||||
    for entry_result in items {
 | 
			
		||||
        if let Ok(entry) = entry_result {
 | 
			
		||||
            if let Some(ext) = entry.path().extension() {
 | 
			
		||||
                if let Some("mp3") | Some("wav") | Some("ogg") | Some("flac") = ext.to_str() {
 | 
			
		||||
                    return Some(entry.path());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    None
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
use super::Alert;
 | 
			
		||||
use std::error::Error;
 | 
			
		||||
use std::fmt::{Display, Formatter, Result as FmtResult};
 | 
			
		||||
use std::io::{self, Write};
 | 
			
		||||
@@ -23,15 +24,30 @@ impl Pomodoro {
 | 
			
		||||
        Self::default()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn start(&mut self) {
 | 
			
		||||
    pub fn start_with_alert(&mut self, alert: Alert) {
 | 
			
		||||
        loop {
 | 
			
		||||
            if let Status::Complete = self.poll() {
 | 
			
		||||
            if let Status::Complete = self.poll(Some(&alert)) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            thread::sleep(POLLING_RATE);
 | 
			
		||||
 | 
			
		||||
            Self::sleep();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn start(&mut self) {
 | 
			
		||||
        loop {
 | 
			
		||||
            if let Status::Complete = self.poll(None) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Self::sleep()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn sleep() {
 | 
			
		||||
        thread::sleep(POLLING_RATE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn notify_complete(&self) -> Result<(), Box<dyn Error>> {
 | 
			
		||||
        let mut toast = notify_rust::Notification::new();
 | 
			
		||||
        toast.summary("Pomodoro cycle complete!");
 | 
			
		||||
@@ -86,7 +102,7 @@ impl Pomodoro {
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn poll(&mut self) -> Status {
 | 
			
		||||
    fn poll(&mut self, maybe_alert: Option<&Alert>) -> Status {
 | 
			
		||||
        let status = self.check();
 | 
			
		||||
 | 
			
		||||
        match status {
 | 
			
		||||
@@ -115,6 +131,10 @@ impl Pomodoro {
 | 
			
		||||
                    State::Work | State::ShortBreak | State::LongBreak => Some(Instant::now()),
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                if let Some(alert) = maybe_alert {
 | 
			
		||||
                    let _ = alert.play();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                let _ = self.notify();
 | 
			
		||||
                self.display_time();
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user