mirror of
https://github.com/talwat/lowfi
synced 2025-12-19 13:13:21 +00:00
feat: add clock feature
This commit is contained in:
parent
af8d45905f
commit
abc88b2c86
102
Cargo.lock
generated
102
Cargo.lock
generated
@ -24,6 +24,15 @@ dependencies = [
|
|||||||
"pkg-config",
|
"pkg-config",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android_system_properties"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstream"
|
name = "anstream"
|
||||||
version = "0.6.21"
|
version = "0.6.21"
|
||||||
@ -312,6 +321,17 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.42"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
|
||||||
|
dependencies = [
|
||||||
|
"iana-time-zone",
|
||||||
|
"num-traits",
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.53"
|
version = "4.5.53"
|
||||||
@ -1032,6 +1052,30 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone"
|
||||||
|
version = "0.1.64"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"iana-time-zone-haiku",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-core 0.62.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone-haiku"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icu_collections"
|
name = "icu_collections"
|
||||||
version = "2.1.1"
|
version = "2.1.1"
|
||||||
@ -1284,6 +1328,7 @@ version = "2.0.0-dev"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"dirs",
|
"dirs",
|
||||||
@ -2993,7 +3038,7 @@ version = "0.54.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49"
|
checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-core",
|
"windows-core 0.54.0",
|
||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3003,10 +3048,45 @@ version = "0.54.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65"
|
checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-result",
|
"windows-result 0.1.2",
|
||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.62.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
||||||
|
dependencies = [
|
||||||
|
"windows-implement",
|
||||||
|
"windows-interface",
|
||||||
|
"windows-link",
|
||||||
|
"windows-result 0.4.1",
|
||||||
|
"windows-strings",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-implement"
|
||||||
|
version = "0.60.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-interface"
|
||||||
|
version = "0.59.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-link"
|
name = "windows-link"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@ -3022,6 +3102,24 @@ dependencies = [
|
|||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-strings"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.45.0"
|
version = "0.45.0"
|
||||||
|
|||||||
@ -42,6 +42,7 @@ arc-swap = "1.7.1"
|
|||||||
|
|
||||||
# Data
|
# Data
|
||||||
reqwest = { version = "0.12.9", features = ["stream", "http2", "default-tls"], default-features = false }
|
reqwest = { version = "0.12.9", features = ["stream", "http2", "default-tls"], default-features = false }
|
||||||
|
chrono = { version = "0.4.42", features = ["clock"], default-features = false }
|
||||||
bytes = "1.9.0"
|
bytes = "1.9.0"
|
||||||
|
|
||||||
# I/O
|
# I/O
|
||||||
|
|||||||
@ -41,6 +41,10 @@ pub struct Args {
|
|||||||
#[clap(long, short)]
|
#[clap(long, short)]
|
||||||
borderless: bool,
|
borderless: bool,
|
||||||
|
|
||||||
|
/// Include a small clock in the UI.
|
||||||
|
#[clap(long, short)]
|
||||||
|
clock: bool,
|
||||||
|
|
||||||
/// Start lowfi paused.
|
/// Start lowfi paused.
|
||||||
#[clap(long, short)]
|
#[clap(long, short)]
|
||||||
paused: bool,
|
paused: bool,
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
player::Current,
|
player::Current,
|
||||||
ui::{self, window::Window},
|
ui::{self, interface::Clock, window::Window},
|
||||||
Args,
|
Args,
|
||||||
};
|
};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
@ -170,6 +170,7 @@ impl Handle {
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut interval = tokio::time::interval(params.delta);
|
let mut interval = tokio::time::interval(params.delta);
|
||||||
let mut window = Window::new(state.width, params.borderless);
|
let mut window = Window::new(state.width, params.borderless);
|
||||||
|
let mut clock = params.clock.then(|| Clock::new(&mut window));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if let Ok(message) = rx.try_recv() {
|
if let Ok(message) = rx.try_recv() {
|
||||||
@ -181,6 +182,7 @@ impl Handle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clock.as_mut().map(|x| x.update(&mut window));
|
||||||
interface::draw(&mut state, &mut window, params)?;
|
interface::draw(&mut state, &mut window, params)?;
|
||||||
interval.tick().await;
|
interval.tick().await;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,48 @@
|
|||||||
use std::{env, time::Duration};
|
use std::{env, time::Duration};
|
||||||
|
|
||||||
|
use tokio::time::Instant;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ui::{self, components, window::Window},
|
ui::{self, components, window::Window},
|
||||||
Args,
|
Args,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// An extremely simple clock to be used alongside the [`Window`].
|
||||||
|
pub struct Clock(Instant);
|
||||||
|
|
||||||
|
impl Clock {
|
||||||
|
/// Small shorthand for getting the local time now, and formatting it.
|
||||||
|
#[inline]
|
||||||
|
fn now() -> chrono::format::DelayedFormat<chrono::format::StrftimeItems<'static>> {
|
||||||
|
chrono::Local::now().format("%H:%M:%S")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks if the last update was long enough ago, and if so,
|
||||||
|
/// updates the displayed clock.
|
||||||
|
///
|
||||||
|
/// This is to avoid constant calls to [`chrono::Local::now`], which
|
||||||
|
/// is somewhat expensive because of timezones.
|
||||||
|
pub fn update(&mut self, window: &mut Window) {
|
||||||
|
if self.0.elapsed().as_secs() >= 1 {
|
||||||
|
window.display(Self::now(), 8);
|
||||||
|
self.0 = Instant::now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Simply creates a new clock, and renders it's initial state to the window top.
|
||||||
|
pub fn new(window: &mut Window) -> Self {
|
||||||
|
window.display(Self::now(), 8);
|
||||||
|
|
||||||
|
Self(Instant::now())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Default)]
|
#[derive(Copy, Clone, Debug, Default)]
|
||||||
pub struct Params {
|
pub struct Params {
|
||||||
pub borderless: bool,
|
pub borderless: bool,
|
||||||
pub minimalist: bool,
|
pub minimalist: bool,
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
|
pub clock: bool,
|
||||||
pub delta: Duration,
|
pub delta: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,6 +61,7 @@ impl TryFrom<&Args> for Params {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
delta,
|
delta,
|
||||||
enabled: !disabled,
|
enabled: !disabled,
|
||||||
|
clock: args.clock,
|
||||||
minimalist: args.minimalist,
|
minimalist: args.minimalist,
|
||||||
borderless: args.borderless,
|
borderless: args.borderless,
|
||||||
})
|
})
|
||||||
@ -46,7 +80,7 @@ pub(crate) fn menu(state: &mut ui::State, params: Params) -> Vec<String> {
|
|||||||
Some(timer) => {
|
Some(timer) => {
|
||||||
let volume = state.sink.volume();
|
let volume = state.sink.volume();
|
||||||
let percentage = format!("{}%", (volume * 100.0).round().abs());
|
let percentage = format!("{}%", (volume * 100.0).round().abs());
|
||||||
if timer.elapsed() > Duration::from_secs(1) {
|
if timer.elapsed() > Duration::from_millis(500) {
|
||||||
state.timer = None;
|
state.timer = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
use std::io::{stdout, Stdout};
|
use std::{
|
||||||
|
fmt::Display,
|
||||||
|
io::{stdout, Stdout},
|
||||||
|
};
|
||||||
|
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
cursor::{MoveToColumn, MoveUp},
|
cursor::{MoveToColumn, MoveUp},
|
||||||
@ -17,7 +20,7 @@ pub struct Window {
|
|||||||
borderless: bool,
|
borderless: bool,
|
||||||
|
|
||||||
/// The top & bottom borders, which are here since they can be
|
/// The top & bottom borders, which are here since they can be
|
||||||
/// prerendered, as they don't change from window to window.
|
/// prerendered, as they don't change every single draw.
|
||||||
///
|
///
|
||||||
/// If the option to not include borders is set, these will just be empty [String]s.
|
/// If the option to not include borders is set, these will just be empty [String]s.
|
||||||
pub(crate) borders: [String; 2],
|
pub(crate) borders: [String; 2],
|
||||||
@ -51,6 +54,12 @@ impl Window {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds text to the top of the window.
|
||||||
|
pub fn display(&mut self, display: impl Display, len: usize) {
|
||||||
|
let new = format!("┌─ {} {}─┐", display, "─".repeat(self.width - len - 2));
|
||||||
|
self.borders[0] = new;
|
||||||
|
}
|
||||||
|
|
||||||
/// Renders the window itself, but doesn't actually draw it.
|
/// Renders the window itself, but doesn't actually draw it.
|
||||||
///
|
///
|
||||||
/// `testing` just determines whether to add special features
|
/// `testing` just determines whether to add special features
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user