feat: introduce -n for no borders

This commit is contained in:
Tal 2025-02-09 15:38:33 +01:00
parent 22a0851d40
commit b87a525c74
6 changed files with 53 additions and 24 deletions

2
Cargo.lock generated
View File

@ -1453,7 +1453,7 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "lowfi"
version = "1.5.6"
version = "1.5.7"
dependencies = [
"Inflector",
"arc-swap",

View File

@ -1,6 +1,6 @@
[package]
name = "lowfi"
version = "1.5.6"
version = "1.5.7"
edition = "2021"
description = "An extremely simple lofi player."
license = "MIT"

View File

@ -59,6 +59,10 @@ struct Args {
#[clap(long, short)]
minimalist: bool,
/// Whether to not include borders in the UI.
#[clap(long, short)]
no_borders: bool,
/// Whether to start lowfi paused.
#[clap(long, short)]
paused: bool,

View File

@ -55,7 +55,9 @@ lazy_static! {
pub struct Window {
/// The top & bottom borders, which are here since they can be
/// prerendered, as they don't change from window to window.
borders: [String; 2],
///
/// [None] if the option to not include windows is set.
borders: Option<[String; 2]>,
/// The output, currently just an [`Stdout`].
out: Stdout,
@ -63,13 +65,20 @@ pub struct Window {
impl Window {
/// Initializes a new [Window].
pub fn new(width: usize) -> Self {
Self {
borders: [
///
/// * `width` - Width of the windows.
/// * `borders` - Whether to include borders in the window, or not.
pub fn new(width: usize, borders: bool) -> Self {
let borders = borders.then(|| {
[
format!("{}\r\n", "".repeat(width + 2)),
// This one doesn't have a leading \r\n to avoid extra space under the window.
format!("{}", "".repeat(width + 2)),
],
]
});
Self {
borders,
out: stdout(),
}
}
@ -79,26 +88,35 @@ impl Window {
let len = content.len() as u16;
let menu: String = content.into_iter().fold(String::new(), |mut output, x| {
if self.borders.is_some() {
write!(output, "│ {} │\r\n", x.reset()).unwrap();
} else {
write!(output, "{}\r\n", x.reset()).unwrap();
}
output
});
// We're doing this because Windows is stupid and can't stand
// writing to the last line repeatedly. Again, it's stupid.
// writing to the last line repeatedly.
#[cfg(windows)]
let (rendered, height) = (
format!("{}{}{}\r\n", self.borders[0], menu, self.borders[1]),
len + 2,
let output_len = len;
#[cfg(not(windows))]
let output_len = len - 1;
let (mut rendered, height) = self.borders.as_ref().map_or_else(
|| (menu.trim().to_owned(), output_len),
|borders| {
(
format!("{}{}{}", borders[0], menu, borders[1]),
output_len + 2,
)
},
);
// Unix has no such ridiculous limitations, so we calculate
// the height of the window accurately.
#[cfg(not(windows))]
let (rendered, height) = (
format!("{}{}{}", self.borders[0], menu, self.borders[1]),
len + 1,
);
// Similar reasoning to the previous comment defining `output_len`.
#[cfg(windows)]
rendered.push_str("\r\n");
crossterm::execute!(
self.out,
@ -116,9 +134,15 @@ impl Window {
/// The code for the terminal interface itself.
///
/// * `minimalist` - All this does is hide the bottom control bar.
/// * `borders` - Whether to include borders or not.
/// * `width` - The width of player
async fn interface(player: Arc<Player>, minimalist: bool, width: usize) -> eyre::Result<()> {
let mut window = Window::new(width);
async fn interface(
player: Arc<Player>,
minimalist: bool,
borders: bool,
width: usize,
) -> eyre::Result<()> {
let mut window = Window::new(width, borders);
loop {
// Load `current` once so that it doesn't have to be loaded over and over
@ -140,7 +164,7 @@ async fn interface(player: Arc<Player>, minimalist: bool, width: usize) -> eyre:
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 {
} else {
// If enough time has passed, we'll reset it back to 0.
VOLUME_TIMER.store(0, Ordering::Relaxed);
}
@ -237,6 +261,7 @@ pub async fn start(player: Arc<Player>, sender: Sender<Messages>, args: Args) ->
let interface = task::spawn(interface(
Arc::clone(&player),
args.minimalist,
!args.no_borders,
21 + args.width.min(32) * 2,
));

View File

@ -104,7 +104,7 @@ pub fn action(player: &Player, current: Option<&Arc<Info>>, width: usize) -> Str
if len > width {
let chopped: String = main.graphemes(true).take(width + 1).collect();
format!("{}...", chopped)
format!("{chopped}...")
} else {
format!("{}{}", main, " ".repeat(width - len))
}

View File

@ -82,7 +82,7 @@ impl List {
let name = dirs::data_dir()
.unwrap()
.join("lowfi")
.join(format!("{}.txt", arg));
.join(format!("{arg}.txt"));
let name = if name.exists() { name } else { arg.into() };