use ratatui::widgets::{ListState, TableState};
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum ActiveTab {
Overview,
Input,
Logs,
}
pub struct App {
pub overview_details: Vec<(String, String)>,
pub input_details: Vec<(String, String)>,
pub logs: Vec<(String, Vec<(String, String)>)>,
pub active_tab: ActiveTab,
pub overview_scroll_state: TableState,
pub input_scroll_state: TableState,
pub logs_scroll_state: ListState,
pub should_quit: bool,
pub gas_used: u128,
pub gas_limit: u128,
}
impl App {
pub fn new(
overview_details: Vec<(String, String)>,
input_details: Vec<(String, String)>,
logs: Vec<(String, Vec<(String, String)>)>,
gas_used: u128,
gas_limit: u128,
) -> App {
let mut app = App {
overview_details,
input_details,
logs,
active_tab: ActiveTab::Overview,
overview_scroll_state: TableState::default(),
input_scroll_state: TableState::default(),
logs_scroll_state: ListState::default(),
should_quit: false,
gas_used,
gas_limit,
};
if !app.overview_details.is_empty() {
app.overview_scroll_state.select(Some(0));
}
if !app.input_details.is_empty() {
app.input_scroll_state.select(Some(0));
}
if !app.logs.is_empty() {
app.logs_scroll_state.select(Some(0));
}
app
}
pub fn on_tick(&mut self) {}
pub fn quit(&mut self) {
self.should_quit = true;
}
pub fn next_tab(&mut self) {
self.active_tab = match self.active_tab {
ActiveTab::Overview => ActiveTab::Input,
ActiveTab::Input => ActiveTab::Logs,
ActiveTab::Logs => ActiveTab::Overview,
};
}
pub fn previous_tab(&mut self) {
self.active_tab = match self.active_tab {
ActiveTab::Overview => ActiveTab::Logs,
ActiveTab::Logs => ActiveTab::Input,
ActiveTab::Input => ActiveTab::Overview,
};
}
pub fn scroll_down(&mut self) {
match self.active_tab {
ActiveTab::Overview => {
let i = match self.overview_scroll_state.selected() {
Some(i) => {
if i >= self.overview_details.len() - 1 {
0
} else {
i + 1
}
}
None => 0,
};
self.overview_scroll_state.select(Some(i));
}
ActiveTab::Input => {
let i = match self.input_scroll_state.selected() {
Some(i) => {
if i >= self.input_details.len() - 1 {
0
} else {
i + 1
}
}
None => 0,
};
self.input_scroll_state.select(Some(i));
}
ActiveTab::Logs => {
let i = match self.logs_scroll_state.selected() {
Some(i) => {
if i >= self.logs.len() - 1 {
0
} else {
i + 1
}
}
None => 0,
};
self.logs_scroll_state.select(Some(i));
}
}
}
pub fn scroll_up(&mut self) {
match self.active_tab {
ActiveTab::Overview => {
let i = match self.overview_scroll_state.selected() {
Some(i) => {
if i == 0 {
self.overview_details.len() - 1
} else {
i - 1
}
}
None => 0,
};
self.overview_scroll_state.select(Some(i));
}
ActiveTab::Input => {
let i = match self.input_scroll_state.selected() {
Some(i) => {
if i == 0 {
self.input_details.len().saturating_sub(1)
} else {
i - 1
}
}
None => 0,
};
self.input_scroll_state.select(Some(i));
}
ActiveTab::Logs => {
let i = match self.logs_scroll_state.selected() {
Some(i) => {
if i == 0 {
self.logs.len() - 1
} else {
i - 1
}
}
None => 0,
};
self.logs_scroll_state.select(Some(i));
}
}
}
}
pub fn split_transaction_details(
details: Vec<(String, String)>,
) -> (Vec<(String, String)>, Vec<(String, String)>) {
let mut overview = Vec::new();
let mut fn_rows = Vec::new();
let mut param_rows = Vec::new();
let mut input_rows = Vec::new();
for (k, v) in details {
match k.as_str() {
"Function Name" => fn_rows.push((k, v)),
_ if k.starts_with("Param ") => param_rows.push((k, v)),
"Input" => input_rows.push((k, v)),
_ => overview.push((k, v)),
}
}
let mut input = Vec::new();
input.extend(fn_rows);
input.extend(param_rows);
input.extend(input_rows);
(overview, input)
}