From 53da922fbf602f92d1f231939819fae1a4ba9bd5 Mon Sep 17 00:00:00 2001 From: simon busch Date: Mon, 20 Mar 2023 21:42:59 +0100 Subject: [PATCH] ADD modal + skeleton for actions --- readme.md | 15 ++++++ src/main.rs | 131 ++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 137 insertions(+), 9 deletions(-) diff --git a/readme.md b/readme.md index 7d4a475..276a36d 100644 --- a/readme.md +++ b/readme.md @@ -1,2 +1,17 @@ export GITHUB_USERNAME=myusername export GITHUB_TOKEN=mytoken + +Keys: + + +Navigate: +Up +Down + +Left: show comments + +'A' : show assignment +'C': show closed +'Q': close app +'ENTER': open the issue in the browser +'p': show actions diff --git a/src/main.rs b/src/main.rs index 9da08be..5d9898a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,11 +6,11 @@ use reqwest::header; use std::{error::Error, sync::mpsc}; use tui::{ backend::CrosstermBackend, - layout::{Alignment, Constraint, Direction, Layout}, + layout::{Alignment, Constraint, Direction, Layout, Rect}, style::{Color, Modifier, Style}, text::{Span, Spans}, - widgets::{Block, BorderType, Borders, Cell, List, ListItem, ListState, Paragraph, Row, Table, Tabs}, - Terminal, + widgets::{Block, BorderType, Borders, Cell, List, ListItem, ListState, Paragraph, Row, Table, Tabs, Clear}, + Terminal }; use crossterm::{ event::{self, Event as CEvent, KeyCode}, @@ -97,9 +97,15 @@ async fn main() -> Result<(), Box> { let mut issue_list_state_closed = ListState::default(); issue_list_state_closed.select(Some(0)); + let mut action_list_state = ListState::default(); + action_list_state.select(Some(0)); + let mut active_open = true; let mut show_comment = false; + // Create a flag to keep track of whether the prompt window is open + let mut prompt_open = false; + loop { terminal.draw(|rect| { let size = rect.size(); @@ -161,11 +167,41 @@ async fn main() -> Result<(), Box> { [Constraint::Percentage(30), Constraint::Percentage(70)].as_ref(), ) .split(chunks[1]); + if active_open == true && show_comment == false { - let selected_issue_index = issue_list_state_open.selected(); - let (left, right) = render_issues(&issues_list_open, selected_issue_index, show_comment); - rect.render_stateful_widget(left, data_chunck[0], &mut issue_list_state_open); - rect.render_widget(right, data_chunck[1]); + let selected_issue_index = issue_list_state_open.selected(); + let (left, right) = render_issues(&issues_list_open, selected_issue_index, show_comment); + rect.render_stateful_widget(left, data_chunck[0], &mut issue_list_state_open); + rect.render_widget(right, data_chunck[1]); + if prompt_open == true { + let items = vec![ + ListItem::new(" 1 - Close issue"), + ListItem::new(" 2 - Comment on issue"), + ListItem::new(" 3 - Reopen issue"), + ]; + + let list = List::new(items) + .block( + Block::default() + .borders(Borders::ALL) + .title("Actions") + ) + .highlight_style(Style::default().add_modifier(Modifier::BOLD)) + .highlight_symbol(">> "); + + let popup = Block::default() + .borders(Borders::ALL) + .title("Select an action") + .style(Style::default().fg(Color::White).bg(Color::Black)); + + let popup_chunk = centered_rect(50, 30, rect.size()); // Adjust the width and height values as needed + + // Render the list on top of the existing widgets + rect.render_widget(popup, popup_chunk); + rect.render_widget(Clear, popup_chunk); + rect.render_widget(list, popup_chunk); + + } } else if active_open == true && show_comment == true { let selected_issue_index = issue_list_state_open.selected(); let (left, right) = render_issues(&issues_list_open, selected_issue_index, show_comment); @@ -262,17 +298,84 @@ async fn main() -> Result<(), Box> { eprintln!("Failed to open URL '{}': {}", url, e); } } - } + }, KeyCode::Right => { if active_open == true { show_comment = true; } - } + }, KeyCode::Left => { if active_open == true { show_comment = false; } + }, + KeyCode::Char('1')=> { + // close issue + let state; + let list: &Vec; + if active_open == true { + state = &mut issue_list_state_open; + list = &issues_list_open; + } else { + state = &mut issue_list_state_closed; + list = &issues_list_closed; + } + if let Some(selected) = state.selected() { + let number = &list[selected].number; + if prompt_open { + println!("Enter a comment"); + println!("{}", number); + //todo + // -> implement github actions ... + } + } + }, + KeyCode::Char('2')=> { + // comment on the issue + let state; + let list: &Vec; + if active_open == true { + state = &mut issue_list_state_open; + list = &issues_list_open; + } else { + state = &mut issue_list_state_closed; + list = &issues_list_closed; + } + if let Some(selected) = state.selected() { + let number = &list[selected].number; + if prompt_open { + println!("Enter a comment"); + println!("{}", number); + //todo + // -> implement github actions ... + } + } + }, + KeyCode::Char('3')=> { + // reopen issue + let state; + let list: &Vec; + if active_open == true { + state = &mut issue_list_state_open; + list = &issues_list_open; + } else { + state = &mut issue_list_state_closed; + list = &issues_list_closed; + } + if let Some(selected) = state.selected() { + let number = &list[selected].number; + if prompt_open { + println!("Enter a comment"); + println!("{}", number); + //todo + // -> implement github actions ... + } + } + }, + KeyCode::Char('p') => { + prompt_open = !prompt_open; } + _ => {} }, Event::Tick => {} @@ -641,6 +744,16 @@ fn split_long_lines(s: &str, max_width: usize) -> String { lines.join("\n") } +fn centered_rect(width: u16, height: u16, parent: Rect) -> Rect { + let parent_width = parent.width; + let parent_height = parent.height; + + let x = (parent_width - width) / 2; + let y = (parent_height - height) / 2; + + Rect::new(x, y, width, height) +} + #[derive(Deserialize)] struct ApiResponse {