mirror of
https://github.com/talwat/lowfi
synced 2025-01-26 18:31:26 +00:00
docs: improve internal documentation
This commit is contained in:
parent
ac9b196675
commit
301b831737
@ -184,17 +184,19 @@ impl Player {
|
|||||||
sink.pause();
|
sink.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let client = Client::builder()
|
||||||
|
.user_agent(concat!(
|
||||||
|
env!("CARGO_PKG_NAME"),
|
||||||
|
"/",
|
||||||
|
env!("CARGO_PKG_VERSION")
|
||||||
|
))
|
||||||
|
.timeout(TIMEOUT)
|
||||||
|
.build()?;
|
||||||
|
|
||||||
let player = Self {
|
let player = Self {
|
||||||
tracks: RwLock::new(VecDeque::with_capacity(5)),
|
tracks: RwLock::new(VecDeque::with_capacity(5)),
|
||||||
current: ArcSwapOption::new(None),
|
current: ArcSwapOption::new(None),
|
||||||
client: Client::builder()
|
client,
|
||||||
.user_agent(concat!(
|
|
||||||
env!("CARGO_PKG_NAME"),
|
|
||||||
"/",
|
|
||||||
env!("CARGO_PKG_VERSION")
|
|
||||||
))
|
|
||||||
.timeout(TIMEOUT)
|
|
||||||
.build()?,
|
|
||||||
sink,
|
sink,
|
||||||
volume,
|
volume,
|
||||||
list,
|
list,
|
||||||
|
@ -47,9 +47,13 @@ const FRAME_DELTA: f32 = 1.0 / FPS as f32;
|
|||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// The volume timer, which controls how long the volume display should
|
/// The volume timer, which controls how long the volume display should
|
||||||
/// show up and when it should disappear.
|
/// 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);
|
static ref VOLUME_TIMER: AtomicUsize = AtomicUsize::new(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Recieves input from the terminal for various events.
|
||||||
async fn input(sender: Sender<Messages>) -> eyre::Result<()> {
|
async fn input(sender: Sender<Messages>) -> eyre::Result<()> {
|
||||||
let mut reader = EventStream::new();
|
let mut reader = EventStream::new();
|
||||||
|
|
||||||
@ -110,26 +114,32 @@ async fn input(sender: Sender<Messages>) -> eyre::Result<()> {
|
|||||||
|
|
||||||
/// The code for the terminal interface itself.
|
/// The code for the terminal interface itself.
|
||||||
///
|
///
|
||||||
/// `volume_timer` is a bit strange, but it tracks how long the `volume` bar
|
/// * `minimalist` - All this does is hide the bottom control bar.
|
||||||
/// has been displayed for, so that it's only displayed for a certain amount of frames.
|
|
||||||
async fn interface(player: Arc<Player>, minimalist: bool) -> eyre::Result<()> {
|
async fn interface(player: Arc<Player>, minimalist: bool) -> eyre::Result<()> {
|
||||||
let mut stdout = std::io::stdout();
|
let mut stdout = std::io::stdout();
|
||||||
|
|
||||||
loop {
|
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 volume = player.sink.volume();
|
||||||
let percentage = format!("{}%", (volume * 100.0).round().abs());
|
let percentage = format!("{}%", (volume * 100.0).round().abs());
|
||||||
|
|
||||||
|
let timer = VOLUME_TIMER.load(Ordering::Relaxed);
|
||||||
let middle = match timer {
|
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),
|
_ => components::audio_bar(volume, &percentage, WIDTH - 17),
|
||||||
};
|
};
|
||||||
|
|
||||||
if timer > 0 && timer <= AUDIO_BAR_DURATION {
|
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);
|
VOLUME_TIMER.fetch_add(1, Ordering::Relaxed);
|
||||||
} else if timer > AUDIO_BAR_DURATION {
|
} else if timer > AUDIO_BAR_DURATION {
|
||||||
|
// If enough time has passed, we'll reset it back to 0.
|
||||||
VOLUME_TIMER.store(0, Ordering::Relaxed);
|
VOLUME_TIMER.store(0, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::{sync::Arc, time::Duration};
|
use std::{ops::Deref, sync::Arc, time::Duration};
|
||||||
|
|
||||||
use crossterm::style::Stylize;
|
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.
|
/// 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<Info>>, width: usize) -> String {
|
||||||
let mut duration = Duration::new(0, 0);
|
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;
|
let mut filled = 0;
|
||||||
if let Some(current) = player.current.load().as_ref() {
|
if let Some(current) = current {
|
||||||
if let Some(x) = current.duration {
|
if let Some(x) = current.duration {
|
||||||
duration = x;
|
duration = x;
|
||||||
|
|
||||||
@ -80,17 +84,15 @@ impl ActionBar {
|
|||||||
|
|
||||||
/// Creates the top/action bar, which has the name of the track and it's status.
|
/// Creates the top/action bar, which has the name of the track and it's status.
|
||||||
/// This also creates all the needed padding.
|
/// This also creates all the needed padding.
|
||||||
pub fn action(player: &Player, width: usize) -> String {
|
pub fn action(player: &Player, current: Option<&Arc<Info>>, width: usize) -> String {
|
||||||
let (main, len) = player
|
let (main, len) = current
|
||||||
.current
|
.map_or(ActionBar::Loading, |info| {
|
||||||
.load()
|
let info = info.deref().clone();
|
||||||
.as_ref()
|
|
||||||
.map_or(ActionBar::Loading, |x| {
|
|
||||||
let name = (*Arc::clone(x)).clone();
|
|
||||||
if player.sink.is_paused() {
|
if player.sink.is_paused() {
|
||||||
ActionBar::Paused(name)
|
ActionBar::Paused(info)
|
||||||
} else {
|
} else {
|
||||||
ActionBar::Playing(name)
|
ActionBar::Playing(info)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.format();
|
.format();
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
//! Has all of the functions for the `scrape` command.
|
//! 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 futures::{stream::FuturesUnordered, StreamExt};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
@ -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 bytes::Bytes;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
@ -7,19 +10,7 @@ use super::Track;
|
|||||||
|
|
||||||
/// Represents a list of tracks that can be played.
|
/// Represents a list of tracks that can be played.
|
||||||
///
|
///
|
||||||
/// # Format
|
/// See the [README](https://github.com/talwat/lowfi?tab=readme-ov-file#the-format) for more details about the 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.
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct List {
|
pub struct List {
|
||||||
lines: Vec<String>,
|
lines: Vec<String>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user