aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpablu <me@pablu.de>2026-05-18 11:59:33 +0200
committerpablu <me@pablu.de>2026-05-18 12:00:19 +0200
commita6b4b29aaa222fa5c2f30cad233e97cb8125f96f (patch)
treecead87b613c568fc9a9b80a6db3b9269bc5e217f
parentedd7bcc589253172da41ab2d97eec301ef02988d (diff)
Add some metadata to Cargo.toml, update README to include guru install, update ui to have status bar
-rw-r--r--Cargo.toml4
-rw-r--r--README.md10
-rw-r--r--src/ui.rs43
3 files changed, 48 insertions, 9 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 03c79fb..ab8ecc1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,6 +2,10 @@
name = "qview"
version = "0.1.0"
edition = "2024"
+authors = [ "me@pablu.de" ]
+readme = "README.md"
+license = "MIT"
+
[dependencies]
color-eyre = "0.6.5"
diff --git a/README.md b/README.md
index c1584ab..087f073 100644
--- a/README.md
+++ b/README.md
@@ -48,6 +48,16 @@ Ui changes kind of frequently right now, take these with a grain of salt
## Installation
+### Gentoo (via guru overlay)
+
+qview is available as an ebuild in the official [Gentoo guru overlay](https://wiki.gentoo.org/wiki/Project:GURU).
+
+Install with:
+
+```bash
+emerge app-misc/qview
+```
+
### Build from source
Requirements:
diff --git a/src/ui.rs b/src/ui.rs
index 6b32974..46615b0 100644
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -5,22 +5,47 @@ use ratatui::{
layout::{Alignment, Constraint, Direction, Layout, Spacing},
prelude::Rect,
style::{Color, Modifier, Style, Stylize},
+ symbols,
text::{Line, Span, Text},
- widgets::{Block, Borders, Clear, List, ListItem, ListState, Paragraph, Wrap},
+ widgets::{Block, Borders, Clear, List, ListItem, ListState, Paragraph, Tabs, Wrap},
};
-use crate::{app::App, gentoo::Package, theme::Theme};
+use crate::{
+ app::{App, ViewState},
+ gentoo::Package,
+ theme::Theme,
+};
pub fn ui(frame: &mut Frame, app: &mut App) {
frame.render_widget(Block::default().bg(Theme::BG), frame.area());
+ let layout = Layout::vertical(vec![Constraint::Length(3), Constraint::Fill(1)]);
+ let [tab_bar, rest] = frame.area().layout(&layout);
+
+ render_tab(frame, tab_bar, &app.view);
+
match app.view {
- crate::app::ViewState::Dashboard => render_dashboard(frame, app),
- crate::app::ViewState::InstalledPackages => render_installed_packages(frame, app),
+ crate::app::ViewState::Dashboard => render_dashboard(frame, rest, app),
+ crate::app::ViewState::InstalledPackages => render_installed_packages(frame, rest, app),
}
}
-fn render_dashboard(frame: &mut Frame, app: &App) {
+fn render_tab(frame: &mut Frame, area: Rect, selected_tab: &ViewState) {
+ let selected_index = match selected_tab {
+ ViewState::Dashboard => 0,
+ ViewState::InstalledPackages => 1,
+ };
+
+ let tabs = Tabs::new(vec!["Dashboard", "Installed", "Search"])
+ .block(Block::default().borders(Borders::ALL).style(Theme::block()))
+ .highlight_style(Theme::success())
+ .select(selected_index)
+ .divider(symbols::DOT)
+ .padding(" ", " ");
+ frame.render_widget(tabs, area);
+}
+
+fn render_dashboard(frame: &mut Frame, area: Rect, app: &App) {
let logo = "
██████╗ ██╗ ██╗██╗███████╗██╗ ██╗
██╔═══██╗██║ ██║██║██╔════╝██║ ██║
@@ -40,7 +65,7 @@ fn render_dashboard(frame: &mut Frame, app: &App) {
let layout = Layout::vertical(constraints);
- let [logo_top, stats, _fill, key_hints] = frame.area().layout(&layout);
+ let [logo_top, stats, _fill, key_hints] = area.layout(&layout);
let [stats_top, stats_middle, stats_bottom] = Layout::vertical([
Constraint::Fill(1),
@@ -150,11 +175,11 @@ fn create_stats<'a>(title: &'a str, value: &'a str) -> Paragraph<'a> {
.alignment(Alignment::Center)
}
-fn render_installed_packages(frame: &mut Frame, app: &mut App) {
+fn render_installed_packages(frame: &mut Frame, area: Rect, app: &mut App) {
let constraints = [Constraint::Fill(1), Constraint::Length(3)];
let layout = Layout::vertical(constraints);
- let [top, bottom] = frame.area().layout(&layout);
+ let [top, bottom] = area.layout(&layout);
let split =
Layout::horizontal([Constraint::Percentage(50), Constraint::Percentage(50)]).split(top);
@@ -211,7 +236,7 @@ fn render_installed_packages(frame: &mut Frame, app: &mut App) {
app.textarea.set_style(Theme::muted());
app.textarea.set_cursor_line_style(Style::default());
- let area = search_popup_rect(70, frame.area());
+ let area = search_popup_rect(70, area);
frame.render_widget(
Block::default().style(Style::default().bg(Theme::BG).add_modifier(Modifier::DIM)),