feat(tui): repo widgets only use required lines
All checks were successful
Rust / build (push) Successful in 10m58s
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
Release Please / Release-plz (push) Successful in 50s

Rather than filling all the space available, the RepoWidget now only
uses as many lines as it needs to show its contents.
This commit is contained in:
Paul Campbell 2024-08-28 09:14:02 +01:00
parent f85cbce4c6
commit 2959bdfad4
4 changed files with 31 additions and 24 deletions

View file

@ -4,11 +4,14 @@ use std::collections::BTreeMap;
use git_next_core::{ForgeAlias, RepoAlias};
use ratatui::{
buffer::Buffer,
layout::{Alignment, Constraint, Direction, Layout, Rect},
layout::{Alignment, Direction, Layout, Rect},
widgets::{block::Title, Block, Borders, Widget},
};
use crate::tui::{actor::RepoState, components::repo::RepoWidget};
use crate::tui::{
actor::RepoState,
components::{repo::RepoWidget, HeightContraintLength},
};
pub struct ExpandedForgeWidget<'a> {
pub forge_alias: &'a ForgeAlias,
@ -22,18 +25,22 @@ impl<'a> Widget for ExpandedForgeWidget<'a> {
let block = Block::default()
.title(Title::from(format!(" forge: {} ", self.forge_alias)).alignment(Alignment::Left))
.borders(Borders::ALL);
let children = self
.repos
.values()
.map(|repo_state| RepoWidget { repo_state })
.collect::<Vec<_>>();
let layout = Layout::default()
.direction(Direction::Vertical)
.constraints(
self.repos
children
.iter()
.map(|(_alias, _state)| Constraint::Fill(1)),
.map(HeightContraintLength::height_constraint_length),
)
.split(block.inner(area));
block.render(area, buf);
self.repos
.values()
.map(|repo_state| RepoWidget { repo_state })
children
.into_iter()
.enumerate()
.for_each(|(i, w)| w.render(layout[i], buf));
}

View file

@ -1,19 +1,18 @@
use git_next_core::git::graph::Log;
//
use ratatui::{
prelude::Constraint,
text::{Line, Text},
widgets::{Paragraph, Widget},
};
use super::HeightConstraint;
use super::HeightContraintLength;
pub struct CommitLog<'a> {
pub log: &'a Log,
}
impl<'a> HeightConstraint for CommitLog<'a> {
fn height_constraint(&self) -> Constraint {
Constraint::Length(u16::try_from(self.log.len()).unwrap_or(u16::MAX))
impl<'a> HeightContraintLength for CommitLog<'a> {
fn height_constraint_length(&self) -> u16 {
u16::try_from(self.log.len()).unwrap_or(u16::MAX)
}
}
impl<'a> Widget for CommitLog<'a> {

View file

@ -6,11 +6,7 @@ mod repo;
pub use configured_app::ConfiguredAppWidget;
pub use history::CommitLog;
use ratatui::layout::Constraint;
pub trait HeightConstraint {
fn height_constraint(&self) -> Constraint;
pub trait HeightContraintLength {
fn height_constraint_length(&self) -> u16;
}
// pub trait WidthConstraints {
// fn width_constraint(&self) -> Constraint;
// }

View file

@ -14,15 +14,20 @@ use identity::Identity;
use ratatui::{
buffer::Buffer,
layout::{Constraint, Rect},
layout::Rect,
widgets::{Block, Borders, Widget},
};
use super::HeightConstraint;
use super::HeightContraintLength;
pub struct RepoWidget<'a> {
pub repo_state: &'a RepoState,
}
impl<'a> HeightContraintLength for RepoWidget<'a> {
fn height_constraint_length(&self) -> u16 {
self.inner().height_constraint_length() + 2 // top + bottom borders
}
}
impl<'a> RepoWidget<'a> {
fn inner(&self) -> InnerRepoWidget {
match self.repo_state {
@ -101,11 +106,11 @@ struct InnerRepoWidget<'a> {
// pub next: &'a Commit,
// pub dev: &'a Commit,
}
impl<'a> HeightConstraint for InnerRepoWidget<'a> {
fn height_constraint(&self) -> ratatui::prelude::Constraint {
impl<'a> HeightContraintLength for InnerRepoWidget<'a> {
fn height_constraint_length(&self) -> u16 {
self.log
.map(|log| CommitLog { log })
.map_or(Constraint::Length(0), |w| w.height_constraint())
.map_or(0, |w| w.height_constraint_length())
}
}
impl<'a> Widget for InnerRepoWidget<'a> {
@ -123,7 +128,7 @@ impl<'a> Widget for InnerRepoWidget<'a> {
))
.borders(Borders::ALL);
if let Some(log) = self.log {
(CommitLog { log }).render(block.inner(area), buf);
CommitLog { log }.render(block.inner(area), buf);
}
block.render(area, buf);
}