From 301b831737fc95587e85ee7f150536682e999135 Mon Sep 17 00:00:00 2001 From: Tal <83217276+talwat@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:06:52 +0200 Subject: [PATCH] docs: improve internal documentation --- src/player.rs | 18 ++++++++++-------- src/player/ui.rs | 20 +++++++++++++++----- src/player/ui/components.rs | 28 +++++++++++++++------------- src/scrape.rs | 3 +++ src/tracks/list.rs | 17 ++++------------- 5 files changed, 47 insertions(+), 39 deletions(-) diff --git a/src/player.rs b/src/player.rs index a428108..986de47 100644 --- a/src/player.rs +++ b/src/player.rs @@ -184,17 +184,19 @@ impl Player { sink.pause(); } + let client = Client::builder() + .user_agent(concat!( + env!("CARGO_PKG_NAME"), + "/", + env!("CARGO_PKG_VERSION") + )) + .timeout(TIMEOUT) + .build()?; + let player = Self { tracks: RwLock::new(VecDeque::with_capacity(5)), current: ArcSwapOption::new(None), - client: Client::builder() - .user_agent(concat!( - env!("CARGO_PKG_NAME"), - "/", - env!("CARGO_PKG_VERSION") - )) - .timeout(TIMEOUT) - .build()?, + client, sink, volume, list, diff --git a/src/player/ui.rs b/src/player/ui.rs index 39f6d4f..a8ef832 100644 --- a/src/player/ui.rs +++ b/src/player/ui.rs @@ -47,9 +47,13 @@ const FRAME_DELTA: f32 = 1.0 / FPS as f32; lazy_static! { /// The volume timer, which controls how long the volume display should /// show up and when it should disappear. + /// + /// When this is 0, it means that the audio bar shouldn't be displayed. + /// To make it start counting, you need to set it to 1. static ref VOLUME_TIMER: AtomicUsize = AtomicUsize::new(0); } +/// Recieves input from the terminal for various events. async fn input(sender: Sender) -> eyre::Result<()> { let mut reader = EventStream::new(); @@ -110,26 +114,32 @@ async fn input(sender: Sender) -> eyre::Result<()> { /// The code for the terminal interface itself. /// -/// `volume_timer` is a bit strange, but it tracks how long the `volume` bar -/// has been displayed for, so that it's only displayed for a certain amount of frames. +/// * `minimalist` - All this does is hide the bottom control bar. async fn interface(player: Arc, minimalist: bool) -> eyre::Result<()> { let mut stdout = std::io::stdout(); loop { - let action = components::action(&player, WIDTH); + // Load `current` once so that it doesn't have to be loaded over and over + // again by different UI components. + let current = player.current.load(); + let current = current.as_ref(); + + let action = components::action(&player, current, WIDTH); - let timer = VOLUME_TIMER.load(Ordering::Relaxed); let volume = player.sink.volume(); let percentage = format!("{}%", (volume * 100.0).round().abs()); + let timer = VOLUME_TIMER.load(Ordering::Relaxed); let middle = match timer { - 0 => components::progress_bar(&player, WIDTH - 16), + 0 => components::progress_bar(&player, current, WIDTH - 16), _ => components::audio_bar(volume, &percentage, WIDTH - 17), }; if timer > 0 && timer <= AUDIO_BAR_DURATION { + // We'll keep increasing the timer until it eventually hits `AUDIO_BAR_DURATION`. VOLUME_TIMER.fetch_add(1, Ordering::Relaxed); } else if timer > AUDIO_BAR_DURATION { + // If enough time has passed, we'll reset it back to 0. VOLUME_TIMER.store(0, Ordering::Relaxed); } diff --git a/src/player/ui/components.rs b/src/player/ui/components.rs index e989903..d24ce82 100644 --- a/src/player/ui/components.rs +++ b/src/player/ui/components.rs @@ -1,4 +1,4 @@ -use std::{sync::Arc, time::Duration}; +use std::{ops::Deref, sync::Arc, time::Duration}; use crossterm::style::Stylize; @@ -13,12 +13,16 @@ pub fn format_duration(duration: &Duration) -> String { } /// Creates the progress bar, as well as all the padding needed. -pub fn progress_bar(player: &Player, width: usize) -> String { +pub fn progress_bar(player: &Player, current: Option<&Arc>, width: usize) -> String { let mut duration = Duration::new(0, 0); - let elapsed = player.sink.get_pos(); + let elapsed = if current.is_some() { + player.sink.get_pos() + } else { + Duration::new(0, 0) + }; let mut filled = 0; - if let Some(current) = player.current.load().as_ref() { + if let Some(current) = current { if let Some(x) = current.duration { duration = x; @@ -80,17 +84,15 @@ impl ActionBar { /// Creates the top/action bar, which has the name of the track and it's status. /// This also creates all the needed padding. -pub fn action(player: &Player, width: usize) -> String { - let (main, len) = player - .current - .load() - .as_ref() - .map_or(ActionBar::Loading, |x| { - let name = (*Arc::clone(x)).clone(); +pub fn action(player: &Player, current: Option<&Arc>, width: usize) -> String { + let (main, len) = current + .map_or(ActionBar::Loading, |info| { + let info = info.deref().clone(); + if player.sink.is_paused() { - ActionBar::Paused(name) + ActionBar::Paused(info) } else { - ActionBar::Playing(name) + ActionBar::Playing(info) } }) .format(); diff --git a/src/scrape.rs b/src/scrape.rs index 3783c15..9942d8a 100644 --- a/src/scrape.rs +++ b/src/scrape.rs @@ -1,4 +1,7 @@ //! Has all of the functions for the `scrape` command. +//! +//! This command is completely optional, and as such isn't subject to the same +//! quality standards as the rest of the codebase. use futures::{stream::FuturesUnordered, StreamExt}; use lazy_static::lazy_static; diff --git a/src/tracks/list.rs b/src/tracks/list.rs index 1f19aa4..e00f9c5 100644 --- a/src/tracks/list.rs +++ b/src/tracks/list.rs @@ -1,3 +1,6 @@ +//! The module containing all of the logic behind track lists, +//! as well as obtaining track names & downloading the raw mp3 data. + use bytes::Bytes; use rand::Rng; use reqwest::Client; @@ -7,19 +10,7 @@ use super::Track; /// Represents a list of tracks that can be played. /// -/// # Format -/// -/// In [List]'s, the first line should be the base URL, followed -/// by the rest of the tracks. -/// -/// Each track will be first appended to the base URL, and then -/// the result use to download the track. All tracks should end -/// in `.mp3` and as such must be in the MP3 format. -/// -/// lowfi won't put a `/` between the base & track for added flexibility, -/// so for most cases you should have a trailing `/` in your base url. -/// The exception to this is if the track name begins with something like -/// `https://`, where in that case the base will not be prepended to it. +/// See the [README](https://github.com/talwat/lowfi?tab=readme-ov-file#the-format) for more details about the format. #[derive(Clone)] pub struct List { lines: Vec,