Extract minibuffer
All checks were successful
Cargo CI / Build and Test (pull_request) Successful in 1m58s
Cargo CI / Lint (pull_request) Successful in 1m6s

This commit is contained in:
Wojciech Kozlowski 2024-08-29 15:29:11 +02:00
parent 52b730f5a9
commit 3596dac800
2 changed files with 95 additions and 82 deletions

76
src/tui/ui/minibuffer.rs Normal file
View File

@ -0,0 +1,76 @@
use ratatui::{layout::Alignment, widgets::Paragraph};
use crate::tui::{
app::{AppPublicState, AppState},
ui::UiDisplay,
};
pub struct Minibuffer<'a> {
pub paragraphs: Vec<Paragraph<'a>>,
pub columns: u16,
}
impl Minibuffer<'_> {
pub fn paragraphs(state: &AppPublicState) -> Self {
let columns = 3;
let mut mb = match state {
AppState::Browse(_) => Minibuffer {
paragraphs: vec![
Paragraph::new("m: show info overlay"),
Paragraph::new("g: show reload menu"),
Paragraph::new("ctrl+s: search artist"),
Paragraph::new("f: fetch musicbrainz"),
],
columns,
},
AppState::Info(_) => Minibuffer {
paragraphs: vec![Paragraph::new("m: hide info overlay")],
columns,
},
AppState::Reload(_) => Minibuffer {
paragraphs: vec![
Paragraph::new("g: hide reload menu"),
Paragraph::new("d: reload database"),
Paragraph::new("l: reload library"),
],
columns,
},
AppState::Search(ref s) => Minibuffer {
paragraphs: vec![
Paragraph::new(format!("I-search: {s}")),
Paragraph::new("ctrl+s: search next".to_string()).alignment(Alignment::Center),
Paragraph::new("ctrl+g: cancel search".to_string())
.alignment(Alignment::Center),
],
columns,
},
AppState::Matches(public) => Minibuffer {
paragraphs: vec![
Paragraph::new(UiDisplay::display_matching_info(public.matching)),
Paragraph::new("q: abort"),
],
columns: 2,
},
AppState::Error(_) => Minibuffer {
paragraphs: vec![Paragraph::new(
"Press any key to dismiss the error message...",
)],
columns: 0,
},
AppState::Critical(_) => Minibuffer {
paragraphs: vec![Paragraph::new("Press ctrl+c to terminate the program...")],
columns: 0,
},
};
if !state.is_search() {
mb.paragraphs = mb
.paragraphs
.into_iter()
.map(|p| p.alignment(Alignment::Center))
.collect();
}
mb
}
}

View File

@ -1,5 +1,8 @@
mod minibuffer;
use std::collections::HashMap;
use minibuffer::Minibuffer;
use musichoard::collection::{
album::{Album, AlbumDate, AlbumPrimaryType, AlbumSecondaryType, AlbumSeq, AlbumStatus},
artist::Artist,
@ -490,87 +493,6 @@ impl<'a, 'b> TrackState<'a, 'b> {
}
}
struct Minibuffer<'a> {
paragraphs: Vec<Paragraph<'a>>,
columns: u16,
}
impl Minibuffer<'_> {
fn paragraphs(state: &AppPublicState) -> Self {
let columns = 3;
let mut mb = match state {
AppState::Browse(_) => Minibuffer {
paragraphs: vec![
Paragraph::new("m: show info overlay"),
Paragraph::new("g: show reload menu"),
Paragraph::new("ctrl+s: search artist"),
Paragraph::new("f: fetch musicbrainz"),
],
columns,
},
AppState::Info(_) => Minibuffer {
paragraphs: vec![Paragraph::new("m: hide info overlay")],
columns,
},
AppState::Reload(_) => Minibuffer {
paragraphs: vec![
Paragraph::new("g: hide reload menu"),
Paragraph::new("d: reload database"),
Paragraph::new("l: reload library"),
],
columns,
},
AppState::Search(ref s) => Minibuffer {
paragraphs: vec![
Paragraph::new(format!("I-search: {s}")),
Paragraph::new("ctrl+s: search next".to_string()).alignment(Alignment::Center),
Paragraph::new("ctrl+g: cancel search".to_string())
.alignment(Alignment::Center),
],
columns,
},
AppState::Matches(public) => Minibuffer {
paragraphs: vec![
Paragraph::new(Minibuffer::display_matching_info(public.matching)),
Paragraph::new("q: abort"),
],
columns: 2,
},
AppState::Error(_) => Minibuffer {
paragraphs: vec![Paragraph::new(
"Press any key to dismiss the error message...",
)],
columns: 0,
},
AppState::Critical(_) => Minibuffer {
paragraphs: vec![Paragraph::new("Press ctrl+c to terminate the program...")],
columns: 0,
},
};
if !state.is_search() {
mb.paragraphs = mb
.paragraphs
.into_iter()
.map(|p| p.alignment(Alignment::Center))
.collect();
}
mb
}
fn display_matching_info(matching: Option<&Album>) -> String {
match matching {
Some(matching) => format!(
"Matching: {} | {}",
AlbumState::display_album_date(&matching.date),
&matching.id.title
),
None => String::from("Matching: nothing"),
}
}
}
struct ReloadMenu;
impl ReloadMenu {
@ -856,7 +778,7 @@ impl Ui {
frame: &mut Frame,
) {
let area = OverlayBuilder::default().build(frame.size());
let matching_string = Minibuffer::display_matching_info(matching);
let matching_string = UiDisplay::display_matching_info(matching);
let list = matches.map(|m| Ui::build_match_list(m)).unwrap_or_default();
Self::render_overlay_list_widget(&matching_string, list, state, true, area, frame)
}
@ -907,6 +829,21 @@ impl IUi for Ui {
}
}
pub struct UiDisplay;
impl UiDisplay {
fn display_matching_info(matching: Option<&Album>) -> String {
match matching {
Some(matching) => format!(
"Matching: {} | {}",
AlbumState::display_album_date(&matching.date),
&matching.id.title
),
None => String::from("Matching: nothing"),
}
}
}
#[cfg(test)]
mod tests {
use musichoard::collection::{album::AlbumId, artist::ArtistId};