new streams

This commit is contained in:
Jana Dönszelmann 2026-02-24 12:41:00 +01:00
parent 3963fc50c3
commit c73be7166f
No known key found for this signature in database
13 changed files with 748 additions and 174 deletions

View file

@ -4,6 +4,7 @@ use std::{
io,
path::{Path, PathBuf},
process::exit,
rc::Rc,
};
use tui_widget_list::{ListBuilder, ListView};
@ -21,6 +22,7 @@ use ratatui::{
crossterm::event::{self, Event, KeyCode, KeyModifiers},
layout::{Constraint, HorizontalAlignment, Layout, Rect},
style::Style,
text::Span,
widgets::{
Block, Clear, List, ListItem, ListState, Padding, Paragraph, StatefulWidget, Widget, Wrap,
},
@ -29,6 +31,7 @@ use ratatui::{
pub mod filter;
pub mod log_viewer;
pub mod model;
pub mod processing;
pub mod reader;
pub fn run(logs_dir: PathBuf) {
@ -68,13 +71,9 @@ impl Tab {
}
}
fn initialize_filter(
lv: &mut LogViewer,
file: &mut LogfileReader,
kind: Option<FilterKind>,
) -> WipFilter {
fn initialize_filter(lv: &mut LogViewer, kind: Option<FilterKind>) -> WipFilter {
let matcher = if lv.footer_selected {
let footer_fields = lv.footer_fields(file);
let footer_fields = lv.footer_fields();
let (key, value) = footer_fields
.get(lv.footer_list.selected.unwrap_or(0))
.map_or((None, None), |(k, v)| (Some(k), Some(v)));
@ -84,7 +83,7 @@ fn initialize_filter(
})
} else {
Some(WipMatcher::Specific {
path: Some(lv.path().clone()),
hash: lv.selected().map(|i| i.hash()),
})
};
@ -115,7 +114,7 @@ impl App {
}
fn current_file_path(&self) -> Option<PathBuf> {
self.current_file.as_ref().map(|i| i.path.to_path_buf())
self.current_file.as_ref().map(|i| i.path())
}
fn replace_tab(&mut self, tab: Tab) {
@ -244,23 +243,19 @@ impl App {
(KeyCode::Left, Tab::CreateFilter { filter }) => {
filter.left();
}
(KeyCode::Right, Tab::LogViewer(lv)) => {
if let Some(file) = &mut self.current_file {
lv.enter(file)
}
}
(KeyCode::Right, Tab::LogViewer(lv)) => lv.enter(),
(KeyCode::Tab, Tab::LogViewer(lv)) => {
lv.switch_focus();
}
(KeyCode::Char('r'), Tab::LogViewer(lv)) => {
if let Some(file) = &mut self.current_file {
let filter = initialize_filter(lv, file, Some(FilterKind::Remove));
let filter = initialize_filter(lv, Some(FilterKind::Remove));
self.push_tab(Tab::CreateFilter { filter });
}
}
(KeyCode::Char('i'), Tab::LogViewer(lv)) => {
if let Some(file) = &mut self.current_file {
let filter = initialize_filter(lv, file, Some(FilterKind::Inline));
let filter = initialize_filter(lv, Some(FilterKind::Inline));
self.push_tab(Tab::CreateFilter { filter });
}
}
@ -271,8 +266,8 @@ impl App {
{
match LogfileReader::new(&selected.path()) {
Ok(i) => {
self.current_file = Some(i);
self.replace_tab(Tab::LogViewer(LogViewer::new()));
self.current_file = Some(i.clone());
self.replace_tab(Tab::LogViewer(LogViewer::new(i.iter())));
}
Err(e) => {
panic!()
@ -281,22 +276,26 @@ impl App {
}
}
Tab::LogViewer(lv) => {
if let Some(file) = &mut self.current_file {
if lv.footer_selected {
let filter = initialize_filter(lv, file, None);
self.push_tab(Tab::CreateFilter { filter });
} else {
lv.enter(file)
}
if lv.footer_selected {
let filter = initialize_filter(lv, None);
self.push_tab(Tab::CreateFilter { filter });
} else {
lv.enter()
}
}
Tab::Empty => {}
Tab::CreateFilter { filter } => {
if let FilterSelection::Confirm = filter.selection
&& let Some(file) = &mut self.current_file
{
if let Some(filter) = filter.validate() {
file.add_filter(filter);
if let FilterSelection::Confirm = filter.selection {
let filter_clone = filter.clone();
if let Some(lv) = self.tabs.iter_mut().rev().find_map(|i| {
if let Tab::LogViewer(lv) = i {
Some(lv)
} else {
None
}
}) && let Some(filter) = filter_clone.validate()
{
lv.add_filter(Rc::new(filter));
self.pop_tab();
if let Tab::LogViewer(lv) = self.current_tab() {
@ -419,22 +418,20 @@ impl Widget for &mut App {
StatefulWidget::render(list, main_area, buf, state);
}
Tab::LogViewer(lv) => {
let Some(file) = &mut self.current_file else {
continue;
};
lv.update_num_items(main_area.height as usize);
let (items, start, selected) = lv
.items(file, main_area.height as usize)
.unwrap_or_else(|| (Vec::new(), 0, 0));
let (items, selected_offset) = lv
.items(main_area.height as usize)
.unwrap_or_else(|| (Vec::new(), 0));
Paragraph::new(selected_offset.to_string()).render(right, buf);
let list = List::new(items.into_iter().enumerate().map(|(idx, i)| {
let line = i.line_text(false);
let mut list_item = ListItem::new(line);
if idx + start == selected {
if idx == selected_offset {
list_item = list_item.style(highlighted);
}
@ -442,7 +439,7 @@ impl Widget for &mut App {
}));
Widget::render(list, main_area, buf);
let items = lv.footer_fields(file);
let items = lv.footer_fields();
let width = 20;
let builder = ListBuilder::new(|cx| {
let Some((k, v)) = &items.get(cx.index) else {