--features sound (#63)
to enable `sound` notification for local builds only. Needed to avoid endless issues by building the app for different platforms. Sound support can be hard.
This commit is contained in:
parent
a54b1b409a
commit
7ff167368d
@ -31,5 +31,8 @@ notify-rust = "4.11.4"
|
|||||||
rodio = { version = "0.20.1", features = [
|
rodio = { version = "0.20.1", features = [
|
||||||
"symphonia-mp3",
|
"symphonia-mp3",
|
||||||
"symphonia-wav",
|
"symphonia-wav",
|
||||||
], default-features = false }
|
], default-features = false, optional = true }
|
||||||
thiserror = "2.0.11"
|
thiserror = { version = "2.0.11", optional = true }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
sound = ["dep:rodio", "dep:thiserror"]
|
||||||
|
|||||||
@ -77,11 +77,17 @@ Options:
|
|||||||
--menu Open the menu.
|
--menu Open the menu.
|
||||||
-r, --reset Reset stored values to default values.
|
-r, --reset Reset stored values to default values.
|
||||||
-n, --notification <NOTIFICATION> Toggle desktop notifications on or off. Experimental. [possible values: on, off]
|
-n, --notification <NOTIFICATION> Toggle desktop notifications on or off. Experimental. [possible values: on, off]
|
||||||
--sound <SOUND> Path to sound file (.mp3 or .wav) to play as notification. Experimental.
|
|
||||||
-h, --help Print help
|
-h, --help Print help
|
||||||
-V, --version Print version
|
-V, --version Print version
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Extra option (if `--features sound` is enabled by local build only):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
--sound <SOUND> Path to sound file (.mp3 or .wav) to play as notification. Experimental.
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
## Cargo
|
## Cargo
|
||||||
|
|||||||
15
src/app.rs
15
src/app.rs
@ -3,7 +3,6 @@ use crate::{
|
|||||||
common::{AppEditMode, AppTime, AppTimeFormat, Content, Notification, Style},
|
common::{AppEditMode, AppTime, AppTimeFormat, Content, Notification, Style},
|
||||||
constants::TICK_VALUE_MS,
|
constants::TICK_VALUE_MS,
|
||||||
events::{self, TuiEventHandler},
|
events::{self, TuiEventHandler},
|
||||||
sound::Sound,
|
|
||||||
storage::AppStorage,
|
storage::AppStorage,
|
||||||
terminal::Terminal,
|
terminal::Terminal,
|
||||||
widgets::{
|
widgets::{
|
||||||
@ -15,6 +14,10 @@ use crate::{
|
|||||||
timer::{Timer, TimerState},
|
timer::{Timer, TimerState},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "sound")]
|
||||||
|
use crate::sound::Sound;
|
||||||
|
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
buffer::Buffer,
|
buffer::Buffer,
|
||||||
@ -37,6 +40,7 @@ pub struct App {
|
|||||||
content: Content,
|
content: Content,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
notification: Notification,
|
notification: Notification,
|
||||||
|
#[allow(dead_code)] // w/ `--features sound` available only
|
||||||
sound_path: Option<PathBuf>,
|
sound_path: Option<PathBuf>,
|
||||||
app_time: AppTime,
|
app_time: AppTime,
|
||||||
countdown: CountdownState,
|
countdown: CountdownState,
|
||||||
@ -51,7 +55,6 @@ pub struct AppArgs {
|
|||||||
pub style: Style,
|
pub style: Style,
|
||||||
pub with_decis: bool,
|
pub with_decis: bool,
|
||||||
pub notification: Notification,
|
pub notification: Notification,
|
||||||
pub sound_path: Option<PathBuf>,
|
|
||||||
pub show_menu: bool,
|
pub show_menu: bool,
|
||||||
pub app_time_format: AppTimeFormat,
|
pub app_time_format: AppTimeFormat,
|
||||||
pub content: Content,
|
pub content: Content,
|
||||||
@ -65,6 +68,7 @@ pub struct AppArgs {
|
|||||||
pub elapsed_value_countdown: Duration,
|
pub elapsed_value_countdown: Duration,
|
||||||
pub current_value_timer: Duration,
|
pub current_value_timer: Duration,
|
||||||
pub app_tx: events::AppEventTx,
|
pub app_tx: events::AppEventTx,
|
||||||
|
pub sound_path: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FromAppArgs {
|
pub struct FromAppArgs {
|
||||||
@ -83,7 +87,6 @@ impl From<FromAppArgs> for App {
|
|||||||
with_decis: args.decis || stg.with_decis,
|
with_decis: args.decis || stg.with_decis,
|
||||||
show_menu: args.menu || stg.show_menu,
|
show_menu: args.menu || stg.show_menu,
|
||||||
notification: args.notification.unwrap_or(stg.notification),
|
notification: args.notification.unwrap_or(stg.notification),
|
||||||
sound_path: args.sound,
|
|
||||||
app_time_format: stg.app_time_format,
|
app_time_format: stg.app_time_format,
|
||||||
content: args.mode.unwrap_or(stg.content),
|
content: args.mode.unwrap_or(stg.content),
|
||||||
style: args.style.unwrap_or(stg.style),
|
style: args.style.unwrap_or(stg.style),
|
||||||
@ -100,6 +103,10 @@ impl From<FromAppArgs> for App {
|
|||||||
elapsed_value_countdown: stg.elapsed_value_countdown,
|
elapsed_value_countdown: stg.elapsed_value_countdown,
|
||||||
current_value_timer: stg.current_value_timer,
|
current_value_timer: stg.current_value_timer,
|
||||||
app_tx,
|
app_tx,
|
||||||
|
#[cfg(feature = "sound")]
|
||||||
|
sound_path: args.sound,
|
||||||
|
#[cfg(not(feature = "sound"))]
|
||||||
|
sound_path: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,11 +249,13 @@ impl App {
|
|||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[allow(unused_variables)] // `app` is used by `--features sound` only
|
||||||
// Closure to handle `AppEvent`'s
|
// Closure to handle `AppEvent`'s
|
||||||
let handle_app_events = |app: &mut Self, event: events::AppEvent| -> Result<()> {
|
let handle_app_events = |app: &mut Self, event: events::AppEvent| -> Result<()> {
|
||||||
match event {
|
match event {
|
||||||
events::AppEvent::ClockDone => {
|
events::AppEvent::ClockDone => {
|
||||||
debug!("AppEvent::ClockDone");
|
debug!("AppEvent::ClockDone");
|
||||||
|
#[cfg(feature = "sound")]
|
||||||
if let Some(path) = app.sound_path.clone() {
|
if let Some(path) = app.sound_path.clone() {
|
||||||
_ = Sound::new(path).and_then(|sound| sound.play()).or_else(
|
_ = Sound::new(path).and_then(|sound| sound.play()).or_else(
|
||||||
|err| -> Result<()> {
|
|err| -> Result<()> {
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
common::{Content, Notification, Style},
|
common::{Content, Notification, Style},
|
||||||
duration, sound,
|
duration,
|
||||||
sound::SoundError,
|
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "sound")]
|
||||||
|
use crate::{sound, sound::SoundError};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
#[cfg(feature = "sound")]
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
@ -48,6 +50,7 @@ pub struct Args {
|
|||||||
)]
|
)]
|
||||||
pub notification: Option<Notification>,
|
pub notification: Option<Notification>,
|
||||||
|
|
||||||
|
#[cfg(feature = "sound")]
|
||||||
#[arg(
|
#[arg(
|
||||||
long,
|
long,
|
||||||
value_enum,
|
value_enum,
|
||||||
@ -58,6 +61,7 @@ pub struct Args {
|
|||||||
pub sound: Option<PathBuf>,
|
pub sound: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "sound")]
|
||||||
/// Custom parser for sound file
|
/// Custom parser for sound file
|
||||||
fn sound_file_parser(s: &str) -> Result<PathBuf, SoundError> {
|
fn sound_file_parser(s: &str) -> Result<PathBuf, SoundError> {
|
||||||
let path = PathBuf::from(s);
|
let path = PathBuf::from(s);
|
||||||
|
|||||||
@ -8,12 +8,14 @@ mod logging;
|
|||||||
|
|
||||||
mod args;
|
mod args;
|
||||||
mod duration;
|
mod duration;
|
||||||
mod sound;
|
|
||||||
mod storage;
|
mod storage;
|
||||||
mod terminal;
|
mod terminal;
|
||||||
mod utils;
|
mod utils;
|
||||||
mod widgets;
|
mod widgets;
|
||||||
|
|
||||||
|
#[cfg(feature = "sound")]
|
||||||
|
mod sound;
|
||||||
|
|
||||||
use app::{App, FromAppArgs};
|
use app::{App, FromAppArgs};
|
||||||
use args::Args;
|
use args::Args;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user