diff --git a/src/ui/components/issue_conversation.rs b/src/ui/components/issue_conversation.rs index c4da2b5..3d5ab19 100644 --- a/src/ui/components/issue_conversation.rs +++ b/src/ui/components/issue_conversation.rs @@ -12,18 +12,19 @@ use rat_cursor::HasScreenCursor; use rat_widget::{ event::{HandleEvent, Outcome, TextOutcome, ct_event}, focus::{FocusBuilder, FocusFlag, HasFocus, Navigation}, + line_number::{LineNumberState, LineNumbers}, list::{ListState, selection::RowSelection}, paragraph::{Paragraph, ParagraphState}, textarea::{TextArea, TextAreaState, TextWrap}, }; use ratatui::{ buffer::Buffer, - layout::Rect, - style::{Color, Modifier, Style, Stylize}, + layout::{Rect, Spacing}, + style::{Color, Modifier, Style}, text::{Line, Span, Text}, - widgets::{self, Block, ListItem, StatefulWidget, Widget}, + widgets::{self, Block, Borders, ListItem, Padding, StatefulWidget, Widget}, }; -use ratatui_macros::{horizontal, line, span, vertical}; +use ratatui_macros::{horizontal, line, vertical}; use std::{ collections::{HashMap, HashSet}, sync::{Arc, OnceLock, RwLock}, @@ -170,7 +171,7 @@ pub struct TimelineEventView { } impl TimelineEventView { - fn from_api(event: TimelineEvent, fallback_id: u64) -> Option { + pub(crate) fn from_api(event: TimelineEvent, fallback_id: u64) -> Option { if matches!( event.event, IssueEvent::Commented | IssueEvent::LineCommented | IssueEvent::CommentDeleted @@ -210,6 +211,7 @@ impl TimelineEventView { pub struct IssueConversation { title: Option>, + ln_state: LineNumberState, action_tx: Option>, current: Option, cache_number: Option, @@ -264,13 +266,13 @@ enum MessageKey { } #[derive(Debug, Clone, Default)] -struct MarkdownRender { - lines: Vec>, - links: Vec, +pub(crate) struct MarkdownRender { + pub(crate) lines: Vec>, + pub(crate) links: Vec, } #[derive(Debug, Clone)] -struct RenderedLink { +pub(crate) struct RenderedLink { line: usize, col: usize, label: String, @@ -314,6 +316,7 @@ impl IssueConversation { action_tx: None, current: None, cache_number: None, + ln_state: LineNumberState::default(), cache_comments: Vec::new(), timeline_cache_number: None, cache_timeline: Vec::new(), @@ -358,48 +361,40 @@ impl IssueConversation { return; } self.area = area.main_content; - let title = self.title.clone().unwrap_or_default(); - let wrapped_title = wrap(&title, area.main_content.width.saturating_sub(2) as usize); - let title_para_height = wrapped_title.len() as u16 + 2; - let last_item = wrapped_title.last(); - let last_line = last_item - .as_ref() - .map(|l| { - line![ - l.to_string(), - span!( - " #{}", - self.current.as_ref().map(|s| s.number).unwrap_or_default() - ) - .dim() - ] - }) - .unwrap_or_else(|| Line::from("")); - let wrapped_title_len = wrapped_title.len() as u16; - let title_para = Text::from_iter( - wrapped_title - .into_iter() - .take(wrapped_title_len as usize - 1) - .map(Line::from) - .chain(std::iter::once(last_line)), - ); + let mut title = self.title.clone().unwrap_or_default().to_string(); + title.push_str(&format!( + " #{}", + self.current.as_ref().map(|s| s.number).unwrap_or_default() + )); + let title = title.trim(); + let wrapped_title = wrap(title, area.main_content.width.saturating_sub(2) as usize); + let title_para_height = wrapped_title.len() as u16 + 1; + let title_para = Text::from_iter(wrapped_title); let areas = vertical![==title_para_height, *=1, ==5].split(area.main_content); let title_area = areas[0]; let content_area = areas[1]; let input_area = areas[2]; - let content_split = horizontal![*=1, *=1].split(content_area); + let content_split = horizontal![*=1, *=1] + .spacing(Spacing::Overlap(1)) + .split(content_area); let list_area = content_split[0]; let body_area = content_split[1]; let items = self.build_items(list_area, body_area); let title_widget = widgets::Paragraph::new(title_para) - .block(Block::bordered().border_type(ratatui::widgets::BorderType::Rounded)) + .block( + Block::default() + .padding(Padding::horizontal(1)) + .borders(Borders::BOTTOM) + .merge_borders(ratatui::symbols::merge::MergeStrategy::Exact), + ) .style(Style::default().add_modifier(Modifier::BOLD)); title_widget.render(title_area, buf); - let mut list_block = Block::bordered() - .border_type(ratatui::widgets::BorderType::Rounded) + let mut list_block = Block::default() + .borders(Borders::RIGHT) + .merge_borders(ratatui::symbols::merge::MergeStrategy::Exact) .border_style(get_border_style(&self.list_state)); if !self.is_loading_current() { @@ -449,13 +444,26 @@ impl IssueConversation { match self.textbox_state { InputState::Input => { + let [line_numbers, input_area] = horizontal![==self.input_state.len_lines().checked_ilog10().unwrap_or(0) as u16 + 2, *=1].areas(input_area); + let ln_block = Block::default() + .borders(Borders::TOP) + .merge_borders(ratatui::symbols::merge::MergeStrategy::Exact) + .border_style(get_border_style(&self.input_state)); + let ln = LineNumbers::new() + .with_textarea(&self.input_state) + .block(ln_block) + .style(Style::default().dim()); + ln.render(line_numbers, buf, &mut self.ln_state); + let input_title = if let Some(err) = &self.post_error { format!("Comment (Ctrl+Enter to send) | {err}") } else { "Comment (Ctrl+Enter to send)".to_string() }; - let mut input_block = Block::bordered() - .border_type(ratatui::widgets::BorderType::Rounded) + let mut input_block = Block::default() + .borders(Borders::TOP) + .merge_borders(ratatui::symbols::merge::MergeStrategy::Exact) + .padding(Padding::horizontal(1)) .border_style(get_border_style(&self.input_state)); if !self.posting { input_block = input_block.title(input_title); @@ -636,8 +644,9 @@ impl IssueConversation { let body = Paragraph::new(body_lines) .block( - Block::bordered() - .border_type(ratatui::widgets::BorderType::Rounded) + Block::default() + .borders(Borders::LEFT) + .merge_borders(ratatui::symbols::merge::MergeStrategy::Exact) .border_style(get_border_style(&self.body_paragraph_state)) .title(if self.screen == MainScreen::DetailsFullscreen { "Message Body (PageUp/PageDown/Home/End | f/Esc: exit fullscreen)" @@ -2441,7 +2450,7 @@ pub(crate) fn render_markdown_lines(text: &str, width: usize, indent: usize) -> render_markdown(text, width, indent).lines } -fn render_markdown(text: &str, width: usize, indent: usize) -> MarkdownRender { +pub(crate) fn render_markdown(text: &str, width: usize, indent: usize) -> MarkdownRender { let mut renderer = MarkdownRenderer::new(width, indent); let options = Options::ENABLE_GFM | Options::ENABLE_STRIKETHROUGH diff --git a/src/ui/components/issue_convo_preview.rs b/src/ui/components/issue_convo_preview.rs new file mode 100644 index 0000000..9224d42 --- /dev/null +++ b/src/ui/components/issue_convo_preview.rs @@ -0,0 +1,152 @@ +use async_trait::async_trait; +use rat_widget::{ + event::{HandleEvent, Regular}, + focus::{FocusBuilder, FocusFlag, HasFocus}, + paragraph::ParagraphState, +}; +use ratatui::{ + buffer::Buffer, + layout::Rect, + widgets::{Block, Borders, StatefulWidget, Widget}, +}; +use std::sync::Arc; +use textwrap::wrap; + +use crate::{ + errors::AppError, + ui::{ + Action, + components::{Component, help::HelpElementKind, issue_conversation::render_markdown}, + layout::Layout, + utils::get_border_style, + }, +}; + +pub const HELP: &[HelpElementKind] = &[ + crate::help_text!("Issue Conversation Help"), + crate::help_keybind!("Up/Down", "select issue body/comment entry"), + crate::help_keybind!("PageUp/PageDown/Home/End", "scroll message body pane"), + crate::help_keybind!("t", "toggle timeline events"), + crate::help_keybind!("f", "toggle fullscreen body view"), + crate::help_keybind!("C", "close selected issue"), + crate::help_keybind!("l", "copy link to selected message"), + crate::help_keybind!("Enter (popup)", "confirm close reason"), + crate::help_keybind!("Ctrl+P", "toggle comment input/preview"), + crate::help_keybind!("e", "edit selected comment in external editor"), + crate::help_keybind!("r", "add reaction to selected comment"), + crate::help_keybind!("R", "remove reaction from selected comment"), + crate::help_keybind!("Ctrl+Enter / Alt+Enter", "send comment"), + crate::help_keybind!("Esc", "exit fullscreen / return to issue list"), +]; + +#[derive(Default)] +pub struct IssueConvoPreview { + action_tx: Option>, + body: Option>, + area: Rect, + paragraph_state: ParagraphState, + index: usize, + focus: FocusFlag, +} + +impl IssueConvoPreview { + pub fn new() -> Self { + Self::default() + } + + pub fn render(&mut self, area: Layout, buf: &mut Buffer) { + let block_template = Block::default() + .borders(Borders::LEFT | Borders::BOTTOM) + .border_style(get_border_style(&self.paragraph_state)); + + self.area = area.mini_convo_preview; + let Some(ref body) = self.body else { + let para = + ratatui::widgets::Paragraph::new("Select an issue to preview the conversation") + .block( + block_template + .title(format!("[{}] Issue Conversation]", self.index)) + .merge_borders(ratatui::symbols::merge::MergeStrategy::Exact), + ); + para.render(area.mini_convo_preview, buf); + return; + }; + let body_str = wrap( + body, + area.mini_convo_preview.width.saturating_sub(2) as usize, + ) + .join("\n"); + let rendered = render_markdown( + &body_str, + area.mini_convo_preview.width.saturating_sub(2).into(), + 2, + ) + .lines; + let para = rat_widget::paragraph::Paragraph::new(rendered).block( + Block::default() + .borders(Borders::LEFT | Borders::BOTTOM) + .title(format!("[{}] Issue Body", self.index)) + .merge_borders(ratatui::symbols::merge::MergeStrategy::Exact) + .border_style(get_border_style(&self.paragraph_state)), + ); + para.render(area.mini_convo_preview, buf, &mut self.paragraph_state); + } +} + +#[async_trait(?Send)] +impl Component for IssueConvoPreview { + fn render(&mut self, area: Layout, buf: &mut Buffer) { + self.render(area, buf); + } + + fn register_action_tx(&mut self, action_tx: tokio::sync::mpsc::Sender) { + self.action_tx = Some(action_tx); + } + + async fn handle_event(&mut self, event: Action) -> Result<(), AppError> { + match event { + Action::AppEvent(ref event) => { + self.paragraph_state.handle(event, Regular); + } + Action::ChangeIssueBodyPreview(body) => { + self.body = Some(body); + } + _ => {} + } + Ok(()) + } + + fn should_render(&self) -> bool { + true + } + + fn is_animating(&self) -> bool { + false + } + + fn set_index(&mut self, index: usize) { + self.index = index; + } + + fn set_global_help(&self) { + if let Some(action_tx) = &self.action_tx { + let _ = action_tx.try_send(Action::SetHelp(HELP)); + } + } +} + +impl HasFocus for IssueConvoPreview { + fn build(&self, builder: &mut FocusBuilder) { + let tag = builder.start(self); + builder.widget(&self.paragraph_state); + builder.end(tag); + } + + fn focus(&self) -> FocusFlag { + self.focus.clone() + } + + fn area(&self) -> Rect { + self.area + } +} diff --git a/src/ui/components/issue_detail.rs b/src/ui/components/issue_detail.rs index 255126c..ae18dc0 100644 --- a/src/ui/components/issue_detail.rs +++ b/src/ui/components/issue_detail.rs @@ -7,8 +7,9 @@ use ratatui::{ layout::{Constraint, Direction, Layout as RtLayout, Rect}, prelude::Widget, style::Style, + symbols::merge::MergeStrategy, text::{Line, Span, Text}, - widgets::{Block, Paragraph, Wrap}, + widgets::{Block, Borders, Paragraph, Wrap}, }; use ratatui_macros::line; @@ -115,9 +116,10 @@ impl IssuePreview { pub fn render(&mut self, area: Layout, buf: &mut Buffer) { self.area = area.issue_preview; - let block = Block::bordered() - .border_type(ratatui::widgets::BorderType::Rounded) - .title("Issue Info"); + let block = Block::default() + .borders(Borders::LEFT | Borders::TOP) + .border_style(Style::new().dim()) + .merge_borders(MergeStrategy::Exact); let inner = block.inner(area.issue_preview); block.render(area.issue_preview, buf); @@ -169,15 +171,6 @@ impl IssuePreview { _ => Style::new().cyan(), }; - let kind = if seed.is_pull_request { - "Pull Request" - } else { - "Issue" - }; - lines.push(Line::from(vec![ - Span::styled("Type: ", label_style), - Span::styled(kind, Style::new().cyan()), - ])); lines.push(Line::from(vec![ Span::styled("State: ", label_style), Span::styled(format!("{:?}", seed.state), state_style), diff --git a/src/ui/components/issue_list.rs b/src/ui/components/issue_list.rs index 366d0cc..bfc66cf 100644 --- a/src/ui/components/issue_list.rs +++ b/src/ui/components/issue_list.rs @@ -1,3 +1,4 @@ +#![allow(clippy::await_holding_lock)] use crate::{ app::GITHUB_CLIENT, bookmarks::Bookmarks, @@ -686,10 +687,7 @@ impl<'a> IssueList<'a> { area.main_content = split[0]; assign_input_area = split[1]; } - let mut block = Block::bordered() - .border_type(ratatui::widgets::BorderType::Rounded) - .border_style(get_border_style(&self.list_state)) - .padding(Padding::horizontal(3)); + let mut block = Block::default().padding(Padding::horizontal(3)); if self.state != LoadingState::Loading { let mut title = format!("[{}] Issues", self.index); if let Some(err) = &self.close_error { @@ -1165,7 +1163,19 @@ impl Component for IssueList<'_> { } let (issue_number, labels, preview_seed) = { let pool = self.issue_pool.read().expect("issue pool lock poisoned"); - let issue = pool.get_issue(self.issues[selected].0); + let issue = { pool.get_issue(self.issues[selected].0) }; + if let Some(body_id) = issue.body { + let body = pool.resolve_str(body_id); + self.action_tx + .as_ref() + .ok_or_else(|| { + AppError::Other(anyhow!( + "issue list action channel unavailable" + )) + })? + .send(crate::ui::Action::ChangeIssueBodyPreview(body.into())) + .await?; + } ( issue.number, issue.labels.clone(), diff --git a/src/ui/components/label_list.rs b/src/ui/components/label_list.rs index 4110162..480655b 100644 --- a/src/ui/components/label_list.rs +++ b/src/ui/components/label_list.rs @@ -19,7 +19,8 @@ use ratatui::{ buffer::Buffer, layout::{Constraint, Direction, Layout as TuiLayout, Rect}, style::{Color, Style, Stylize}, - widgets::{Block, Clear, ListItem, Paragraph, StatefulWidget, Widget}, + symbols::merge::MergeStrategy, + widgets::{Block, Borders, Clear, ListItem, Paragraph, StatefulWidget, Widget}, }; use ratatui_macros::{line, span}; use regex::RegexBuilder; @@ -204,7 +205,11 @@ impl LabelList { if self.needs_footer() { let areas = TuiLayout::default() .direction(Direction::Vertical) - .constraints([Constraint::Min(1), Constraint::Length(3)]) + .constraints([ + Constraint::Min(1), + Constraint::Length(3), + Constraint::Length(1), + ]) .split(area.label_list); list_area = areas[0]; footer_area = Some(areas[1]); @@ -219,8 +224,9 @@ impl LabelList { } else { format!("[{}] Labels (a:add d:remove)", self.index) }; - let block = Block::bordered() - .border_type(ratatui::widgets::BorderType::Rounded) + let block = Block::default() + .borders(Borders::LEFT | Borders::BOTTOM) + .merge_borders(MergeStrategy::Exact) .title(title) .border_style(get_border_style(&self.state)); let list = rat_widget::list::List::::new( @@ -1262,4 +1268,3 @@ impl HasFocus for LabelList { self.state.focus() } } - diff --git a/src/ui/components/mod.rs b/src/ui/components/mod.rs index 9d38540..ccda5d8 100644 --- a/src/ui/components/mod.rs +++ b/src/ui/components/mod.rs @@ -8,6 +8,7 @@ use ratatui::crossterm::event::Event; pub mod help; pub mod issue_conversation; +pub mod issue_convo_preview; pub mod issue_create; pub mod issue_detail; pub mod issue_list; diff --git a/src/ui/components/status_bar.rs b/src/ui/components/status_bar.rs index cef55b3..ed06849 100644 --- a/src/ui/components/status_bar.rs +++ b/src/ui/components/status_bar.rs @@ -5,9 +5,9 @@ use ratatui::widgets::Widget; use ratatui_macros::{line, span}; use std::sync::atomic::Ordering; -use crate::ui::components::issue_list::LOADED_ISSUE_COUNT; use crate::ui::components::DumbComponent; -use crate::ui::{layout::Layout, AppState}; +use crate::ui::components::issue_list::LOADED_ISSUE_COUNT; +use crate::ui::{AppState, layout::Layout}; pub struct StatusBar { repo_label: String, @@ -41,7 +41,7 @@ impl StatusBar { .end(span!(count_text).style(Style::new().black().on_blue()), "") .end( line![ - span!("q///").magenta(), " ", span!(" QUIT ").black().on_magenta().bold() ], diff --git a/src/ui/layout.rs b/src/ui/layout.rs index ea1a861..083d38d 100644 --- a/src/ui/layout.rs +++ b/src/ui/layout.rs @@ -1,9 +1,10 @@ -use ratatui::layout::Rect; +use ratatui::layout::{Rect, Spacing}; use ratatui_macros::{horizontal, vertical}; #[derive(Debug, Clone, Copy)] pub struct Layout { pub status_bar: Rect, + pub mini_convo_preview: Rect, pub main_content: Rect, pub label_list: Rect, pub text_search: Rect, @@ -16,12 +17,15 @@ pub struct Layout { impl Layout { pub fn new(area: Rect) -> Self { let [title_bar, main, status_bar] = vertical![==1, *=1, ==1].areas(area); - let [left, right] = horizontal![==70%, *=1].areas(main); - let [label_list, issue_preview] = vertical![*=1, *=1].areas(right); + let [left, right] = horizontal![==66%, *=1].areas(main); + let [mini_convo_preview, label_list, issue_preview] = vertical![==60%, *=1, *=1] + .spacing(Spacing::Overlap(1)) + .areas(right); let [text_search, bottom_search, main_content] = vertical![==3, ==3, *=1].areas(left); let [label_search, status_dropdown] = horizontal![*=1, ==30%].areas(bottom_search); Self { status_dropdown, + mini_convo_preview, title_bar, status_bar, main_content, @@ -34,6 +38,7 @@ impl Layout { pub fn fullscreen(area: Rect) -> Self { Self { + mini_convo_preview: area, status_bar: area, main_content: area, label_list: area, diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 73ccdfd..6a7eabe 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -18,6 +18,7 @@ use crate::{ Component, DumbComponent, help::HelpElementKind, issue_conversation::IssueConversation, + issue_convo_preview::IssueConvoPreview, issue_create::IssueCreate, issue_detail::IssuePreview, issue_list::{IssueList, MainScreen}, @@ -190,6 +191,7 @@ impl App { let issue_pool = Arc::new(RwLock::new(UiIssuePool::default())); let mut issue_conversation = IssueConversation::new(state.clone(), issue_pool.clone()); let mut issue_create = IssueCreate::new(state.clone(), issue_pool.clone()); + let mut issue_convo_preview = IssueConvoPreview::new(); let bookmarks = Arc::new(RwLock::new(read_bookmarks())); let issue_handler = GITHUB_CLIENT .get() @@ -211,6 +213,7 @@ impl App { 3 -> issue_conversation, 5 -> issue_create, 4 -> label_list, + 6 -> issue_convo_preview, 1 -> text_search, // this needs to be the last one )?; let effects_manager = EffectManager::default(); @@ -666,6 +669,7 @@ pub enum Action { EnterIssueDetails { seed: IssueConversationSeed, }, + ChangeIssueBodyPreview(Arc), IssueCommentsLoaded { number: u64, comments: Vec, diff --git a/src/ui/testing.rs b/src/ui/testing.rs index 73f025f..74260dd 100644 --- a/src/ui/testing.rs +++ b/src/ui/testing.rs @@ -214,7 +214,7 @@ fn make_issue( .choose(rng) .map(|author| author.author_id) .expect("author fixture list should not be empty"); - let state = if idx % 5 == 0 { + let state = if idx.is_multiple_of(5) { IssueState::Closed } else { IssueState::Open @@ -223,7 +223,7 @@ fn make_issue( "{} #{issue_number}", Sentence(3..6).fake_with_rng::(rng) ); - let shared_fragment = if idx % 2 == 0 { + let shared_fragment = if idx.is_multiple_of(2) { issue_body_fixture(1) } else { markdown_fixture(1) @@ -239,13 +239,13 @@ fn make_issue( let created_at_short = format_timestamp(created_ts, false); let created_at_full = format_timestamp(created_ts, true); let updated_at_short = format_timestamp(created_ts + 1_800, false); - let milestone = (idx % 3 == 0).then(|| { + let milestone = (idx.is_multiple_of(3)).then(|| { let milestone = milestones .choose(rng) .expect("milestone fixture list should not be empty"); pool.intern_str(milestone) }); - let assignee_count = 1 + (idx % authors.len().min(3).max(1)); + let assignee_count = 1 + (idx % authors.len().clamp(1, 3)); let assignees = authors .iter() .cycle() @@ -253,7 +253,7 @@ fn make_issue( .take(assignee_count) .map(|author| author.author_id) .collect(); - let is_pull_request = idx % 4 == 0; + let is_pull_request = idx.is_multiple_of(4); let pull_request_url = if is_pull_request { let url = format!("https://github.com/example/repo/pull/{issue_number}"); Some(pool.intern_str(&url)) diff --git a/src/ui/utils.rs b/src/ui/utils.rs index 194b6b3..7099784 100644 --- a/src/ui/utils.rs +++ b/src/ui/utils.rs @@ -12,7 +12,7 @@ pub fn get_loader_area(area: Rect) -> Rect { #[inline(always)] pub fn get_border_style(state: &impl HasFocus) -> Style { - let default_border_style = Style::default(); + let default_border_style = Style::default().dim(); let focused_border_style = Style::default().yellow(); if state.is_focused() { focused_border_style diff --git a/tests/snapshots/issue_preview__issue_preview_closed_issue.snap b/tests/snapshots/issue_preview__issue_preview_closed_issue.snap index 9feb229..f929dec 100644 --- a/tests/snapshots/issue_preview__issue_preview_closed_issue.snap +++ b/tests/snapshots/issue_preview__issue_preview_closed_issue.snap @@ -12,12 +12,12 @@ expression: result - ╭Issue Info╮ - │Type: │ - │Issue │ - │State: │ - │Closed │ - │Author: │ - │janedoe │ - │Created: │ - ╰──────────╯ + + + + + ┌───────────── + │State: Closed + │Author: + │janedoe + │Created: diff --git a/tests/snapshots/issue_preview__issue_preview_many_assignees.snap b/tests/snapshots/issue_preview__issue_preview_many_assignees.snap index 431fa51..14c7a97 100644 --- a/tests/snapshots/issue_preview__issue_preview_many_assignees.snap +++ b/tests/snapshots/issue_preview__issue_preview_many_assignees.snap @@ -12,12 +12,12 @@ expression: result - ╭Issue Info╮ - │Type: │ - │Issue │ - │State: │ - │Open │ - │Author: │ - │teamlead │ - │Created: │ - ╰──────────╯ + + + + + ┌───────────── + │State: Open + │Author: + │teamlead + │Created: diff --git a/tests/snapshots/issue_preview__issue_preview_no_selection.snap b/tests/snapshots/issue_preview__issue_preview_no_selection.snap index 9f41a91..12cf70d 100644 --- a/tests/snapshots/issue_preview__issue_preview_no_selection.snap +++ b/tests/snapshots/issue_preview__issue_preview_no_selection.snap @@ -12,12 +12,12 @@ expression: result - ╭Issue Info╮ - │Select an │ - │issue to │ - │see │ - │details. │ - │ │ - │ │ - │ │ - ╰──────────╯ + + + + + ┌───────────── + │Select an + │issue to see + │details. + │ diff --git a/tests/snapshots/issue_preview__issue_preview_open_issue.snap b/tests/snapshots/issue_preview__issue_preview_open_issue.snap index 189ff80..1460079 100644 --- a/tests/snapshots/issue_preview__issue_preview_open_issue.snap +++ b/tests/snapshots/issue_preview__issue_preview_open_issue.snap @@ -12,12 +12,12 @@ expression: result - ╭Issue Info╮ - │Type: │ - │Issue │ - │State: │ - │Open │ - │Author: │ - │johndoe │ - │Created: │ - ╰──────────╯ + + + + + ┌───────────── + │State: Open + │Author: + │johndoe + │Created: diff --git a/tests/snapshots/issue_preview__issue_preview_pull_request.snap b/tests/snapshots/issue_preview__issue_preview_pull_request.snap index 58625a1..732cbec 100644 --- a/tests/snapshots/issue_preview__issue_preview_pull_request.snap +++ b/tests/snapshots/issue_preview__issue_preview_pull_request.snap @@ -12,12 +12,12 @@ expression: result - ╭Issue Info╮ - │Type: Pull│ - │Request │ - │State: │ - │Open │ - │Author: │ - │devuser │ - │]8;;https://github.com/owner/repo/pull/456\Open #4...]8;;\ │ - ╰──────────╯ + + + + + ┌───────────── + │State: Open + │Author: + │devuser + │]8;;https://github.com/owner/repo/pull/456\Open #456 ...]8;;\ diff --git a/tests/snapshots/status_bar__status_bar_with_count.snap b/tests/snapshots/status_bar__status_bar_with_count.snap index f64ea20..1955bb2 100644 --- a/tests/snapshots/status_bar__status_bar_with_count.snap +++ b/tests/snapshots/status_bar__status_bar_with_count.snap @@ -4,4 +4,4 @@ expression: result --- - Logged in as testuser repo/owner P ? HELP q/// QUIT Issues: 42 diff --git a/tests/snapshots/text_search__text_search_both_inputs.snap b/tests/snapshots/text_search__text_search_both_inputs.snap index ddb5f81..8f45197 100644 --- a/tests/snapshots/text_search__text_search_both_inputs.snap +++ b/tests/snapshots/text_search__text_search_both_inputs.snap @@ -3,9 +3,9 @@ source: tests/text_search.rs expression: result --- -╭[0] Search────────────────────────────────────────────╮ -│authentication │ -╰──────────────────────────────────────────────────────╯ -╭Search Labels────────────────────────╮╭───────────────╮ -│security;bug ││ ▼ │ -╰─────────────────────────────────────╯╰───────────────╯ +╭[0] Search─────────────────────────────────────────╮ +│authentication │ +╰───────────────────────────────────────────────────╯ +╭Search Labels──────────────────────╮╭──────────────╮ +│security;bug ││ ▼ │ +╰───────────────────────────────────╯╰──────────────╯ diff --git a/tests/snapshots/text_search__text_search_label_input.snap b/tests/snapshots/text_search__text_search_label_input.snap index 3add1a0..30968a3 100644 --- a/tests/snapshots/text_search__text_search_label_input.snap +++ b/tests/snapshots/text_search__text_search_label_input.snap @@ -3,9 +3,9 @@ source: tests/text_search.rs expression: result --- -╭[0] Search────────────────────────────────────────────╮ -│ │ -╰──────────────────────────────────────────────────────╯ -╭Search Labels────────────────────────╮╭───────────────╮ -│priority:high ││ ▼ │ -╰─────────────────────────────────────╯╰───────────────╯ +╭[0] Search─────────────────────────────────────────╮ +│ │ +╰───────────────────────────────────────────────────╯ +╭Search Labels──────────────────────╮╭──────────────╮ +│priority:high ││ ▼ │ +╰───────────────────────────────────╯╰──────────────╯ diff --git a/tests/snapshots/text_search__text_search_loaded_state.snap b/tests/snapshots/text_search__text_search_loaded_state.snap index 2b810d7..78e0541 100644 --- a/tests/snapshots/text_search__text_search_loaded_state.snap +++ b/tests/snapshots/text_search__text_search_loaded_state.snap @@ -3,9 +3,9 @@ source: tests/text_search.rs expression: result --- -╭[0] Search────────────────────────────────────────────╮ -│ │ -╰──────────────────────────────────────────────────────╯ -╭Search Labels────────────────────────╮╭───────────────╮ -│ ││ ▼ │ -╰─────────────────────────────────────╯╰───────────────╯ +╭[0] Search─────────────────────────────────────────╮ +│ │ +╰───────────────────────────────────────────────────╯ +╭Search Labels──────────────────────╮╭──────────────╮ +│ ││ ▼ │ +╰───────────────────────────────────╯╰──────────────╯ diff --git a/tests/snapshots/text_search__text_search_with_input.snap b/tests/snapshots/text_search__text_search_with_input.snap index b846044..9161077 100644 --- a/tests/snapshots/text_search__text_search_with_input.snap +++ b/tests/snapshots/text_search__text_search_with_input.snap @@ -3,9 +3,9 @@ source: tests/text_search.rs expression: result --- -╭[0] Search────────────────────────────────────────────╮ -│bug fix │ -╰──────────────────────────────────────────────────────╯ -╭Search Labels────────────────────────╮╭───────────────╮ -│ ││ ▼ │ -╰─────────────────────────────────────╯╰───────────────╯ +╭[0] Search─────────────────────────────────────────╮ +│bug fix │ +╰───────────────────────────────────────────────────╯ +╭Search Labels──────────────────────╮╭──────────────╮ +│ ││ ▼ │ +╰───────────────────────────────────╯╰──────────────╯