refactor, added ip validation
This commit is contained in:
170
src/ui/mod.rs
Normal file
170
src/ui/mod.rs
Normal file
@@ -0,0 +1,170 @@
|
||||
#![allow(non_snake_case)]
|
||||
mod centeredRect;
|
||||
|
||||
use ratatui::{
|
||||
Frame,
|
||||
layout::{Constraint, Direction, Layout},
|
||||
style::{Color, Style},
|
||||
text::{Line, Span, Text},
|
||||
widgets::{Block, Borders, List, ListItem, Paragraph, Wrap},
|
||||
};
|
||||
|
||||
use crate::app::status::CurrentScreen;
|
||||
use crate::app::{AppState, status::EditingField};
|
||||
use crate::ui::centeredRect::centered_rect;
|
||||
|
||||
pub fn ui(frame: &mut Frame, app: &AppState) {
|
||||
let chunks = Layout::default()
|
||||
.direction(ratatui::layout::Direction::Vertical)
|
||||
.constraints([
|
||||
Constraint::Length(3),
|
||||
Constraint::Min(3),
|
||||
Constraint::Length(3),
|
||||
])
|
||||
.split(frame.area());
|
||||
|
||||
let footerChunks = Layout::default()
|
||||
.direction(ratatui::layout::Direction::Horizontal)
|
||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
|
||||
.split(chunks[2]);
|
||||
|
||||
let titleBlock = Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.style(Style::default());
|
||||
|
||||
let title = Paragraph::new(Text::styled(
|
||||
"Create new entry",
|
||||
Style::default().fg(Color::Green),
|
||||
))
|
||||
.block(titleBlock);
|
||||
|
||||
frame.render_widget(title, chunks[0]);
|
||||
|
||||
let mut currentItems = Vec::<ListItem>::new();
|
||||
for (i, e) in app.entries.iter().enumerate() {
|
||||
currentItems.push(ListItem::new(Line::from(Span::styled(
|
||||
format!("{}. {}", i, e),
|
||||
Style::default().fg(Color::Yellow),
|
||||
))));
|
||||
}
|
||||
let list = List::new(currentItems);
|
||||
frame.render_widget(list, chunks[1]);
|
||||
|
||||
if let CurrentScreen::Exit = app.screen {
|
||||
let exitPopup = Block::default()
|
||||
.title("Save and Exit?")
|
||||
.borders(Borders::ALL)
|
||||
.style(Style::default().bg(Color::DarkGray));
|
||||
|
||||
let exitText = Text::styled(
|
||||
"Save the current config and exit? (enter/esc)",
|
||||
Style::default().fg(Color::Red),
|
||||
);
|
||||
let exitPara = Paragraph::new(exitText)
|
||||
.block(exitPopup)
|
||||
.wrap(Wrap { trim: false });
|
||||
|
||||
let area = centered_rect(60, 25, frame.area());
|
||||
frame.render_widget(exitPara, area);
|
||||
}
|
||||
|
||||
if let Some(edit) = &app.currentlyEditing {
|
||||
let popup = Block::default()
|
||||
.title("Add an entry")
|
||||
.borders(Borders::NONE)
|
||||
.style(Style::default().bg(Color::DarkGray));
|
||||
let area = centered_rect(60, 25, frame.area());
|
||||
frame.render_widget(popup, area);
|
||||
|
||||
let fields = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.margin(1)
|
||||
.constraints([
|
||||
Constraint::Percentage(25),
|
||||
Constraint::Percentage(25),
|
||||
Constraint::Percentage(25),
|
||||
Constraint::Percentage(25),
|
||||
])
|
||||
.split(area);
|
||||
|
||||
let mut fromIPBlock = Block::default().title("From IP").borders(Borders::ALL);
|
||||
let mut toIPBlock = Block::default().title("To IP").borders(Borders::ALL);
|
||||
let mut fromPortBlock = Block::default().title("From Port").borders(Borders::ALL);
|
||||
let mut toPortBlock = Block::default().title("To Port").borders(Borders::ALL);
|
||||
|
||||
let activeStyle = Style::default().bg(Color::LightYellow).fg(Color::Black);
|
||||
|
||||
match edit {
|
||||
EditingField::FromIP => fromIPBlock = fromIPBlock.style(activeStyle),
|
||||
EditingField::ToIP => toIPBlock = toIPBlock.style(activeStyle),
|
||||
EditingField::FromPort => fromPortBlock = fromPortBlock.style(activeStyle),
|
||||
EditingField::ToPort => toPortBlock = toPortBlock.style(activeStyle),
|
||||
}
|
||||
|
||||
let fromIPPara = Paragraph::new(app.fromIP.clone()).block(fromIPBlock);
|
||||
let toIPPara = Paragraph::new(app.toIP.clone()).block(toIPBlock);
|
||||
let fromPortPara = Paragraph::new(app.fromPort.clone()).block(fromPortBlock);
|
||||
let toPortPara = Paragraph::new(app.toPort.clone()).block(toPortBlock);
|
||||
|
||||
frame.render_widget(fromIPPara, fields[0]);
|
||||
frame.render_widget(fromPortPara, fields[1]);
|
||||
frame.render_widget(toIPPara, fields[2]);
|
||||
frame.render_widget(toPortPara, fields[3]);
|
||||
};
|
||||
|
||||
let screenHelp = vec![
|
||||
match app.screen {
|
||||
CurrentScreen::Main => Span::styled("Main Screen", Style::default().fg(Color::Green)),
|
||||
CurrentScreen::Add => Span::styled("Add entry", Style::default().fg(Color::Yellow)),
|
||||
CurrentScreen::Exit => {
|
||||
Span::styled("Exit Screen", Style::default().fg(Color::LightRed))
|
||||
}
|
||||
CurrentScreen::Settings => Span::styled("Settings", Style::default().fg(Color::Blue)),
|
||||
}
|
||||
.to_owned(),
|
||||
Span::styled(" | ", Style::default().fg(Color::White)),
|
||||
{
|
||||
if let Some(editing) = &app.currentlyEditing {
|
||||
let curEdit = match editing {
|
||||
EditingField::FromIP => "From IP",
|
||||
EditingField::ToIP => "To IP",
|
||||
EditingField::FromPort => "From Port",
|
||||
EditingField::ToPort => "To Port",
|
||||
};
|
||||
Span::styled(
|
||||
format!("Editing: {curEdit}"),
|
||||
Style::default().fg(Color::Green),
|
||||
)
|
||||
} else {
|
||||
Span::styled("Not Editing", Style::default().fg(Color::DarkGray))
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
let helpFooter =
|
||||
Paragraph::new(Line::from(screenHelp)).block(Block::default().borders(Borders::ALL));
|
||||
|
||||
let keybinds = {
|
||||
match app.screen {
|
||||
CurrentScreen::Main => Span::styled(
|
||||
"(a) add entry / (q) save and quit",
|
||||
Style::default().fg(Color::Red),
|
||||
),
|
||||
CurrentScreen::Add => Span::styled(
|
||||
"(l) localhost / (enter/tab) next field / (c) clear / (C) clear all / (esc) main menu",
|
||||
Style::default().fg(Color::Red),
|
||||
),
|
||||
CurrentScreen::Settings => Span::styled("", Style::default().fg(Color::Red)),
|
||||
CurrentScreen::Exit => Span::styled(
|
||||
"(enter) save and exit / (esc) main menu",
|
||||
Style::default().fg(Color::Red),
|
||||
),
|
||||
}
|
||||
};
|
||||
|
||||
let keyBindFooter =
|
||||
Paragraph::new(Line::from(keybinds)).block(Block::default().borders(Borders::ALL));
|
||||
|
||||
frame.render_widget(helpFooter, footerChunks[0]);
|
||||
frame.render_widget(keyBindFooter, footerChunks[1]);
|
||||
}
|
||||
Reference in New Issue
Block a user