diff options
| author | Fuwn <[email protected]> | 2022-07-16 10:47:07 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2022-07-16 10:47:07 +0000 |
| commit | f63f2b749aa0ff4efdc367b514aba08c23dd7c89 (patch) | |
| tree | e7d692aeff08cabc8d6d321aa05c4f0c25d7ca45 /src/ui.rs | |
| download | sydney-f63f2b749aa0ff4efdc367b514aba08c23dd7c89.tar.xz sydney-f63f2b749aa0ff4efdc367b514aba08c23dd7c89.zip | |
feat: initial release
Diffstat (limited to 'src/ui.rs')
| -rw-r--r-- | src/ui.rs | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/src/ui.rs b/src/ui.rs new file mode 100644 index 0000000..b43a119 --- /dev/null +++ b/src/ui.rs @@ -0,0 +1,142 @@ +// This file is part of Germ <https://github.com/gemrest/sydney>. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// Copyright (C) 2022-2022 Fuwn <[email protected]> +// SPDX-License-Identifier: GPL-3.0-only + +use tui::{ + layout::{Constraint, Direction, Layout, Rect}, + style::{Color, Style}, + widgets, + widgets::{ListItem, Paragraph}, +}; + +pub fn ui<B: tui::backend::Backend>( + f: &mut tui::Frame<'_, B>, + app: &mut crate::App, +) { + let chunks = Layout::default() + .direction(Direction::Vertical) + .constraints( + [ + Constraint::Percentage(95), + Constraint::Percentage(4), + Constraint::Percentage(1), + ] + .as_ref(), + ) + .split(f.size()); + + let items: Vec<ListItem<'_>> = app + .items + .items + .iter() + .map(|(text_lines, _link)| { + let mut spans = vec![]; + + for line in text_lines { + spans.push(tui::text::Spans::from(line.as_str())); + } + + ListItem::new(spans) + }) + .collect(); + + let items = widgets::List::new(items).highlight_style( + Style::default() + .bg(Color::White) + .fg(Color::Black) + .add_modifier(tui::style::Modifier::BOLD), + ); + + f.render_stateful_widget(items, chunks[0], &mut app.items.state); + f.render_widget( + Paragraph::new(app.url.to_string()) + .style(Style::default().bg(Color::White).fg(Color::Black)), + chunks[1], + ); + + if let Some(error) = app.error.as_ref() { + f.render_widget( + Paragraph::new(&**error).style(Style::default().bg(Color::Red)), + chunks[2], + ); + } else if !app.input.is_empty() { + f.render_widget(Paragraph::new(&*app.input), chunks[2]); + } + + if app.accept_response_input { + let block = widgets::Block::default() + .title(app.url.to_string()) + .borders(widgets::Borders::ALL); + let area = centered_rect(60, 20, f.size()); + + f.render_widget(widgets::Clear, area); + f.render_widget(block.clone(), area); + f.render_widget( + Paragraph::new(format!( + "{} {}", + app.response_input_text.trim(), + app.response_input + )) + .wrap(widgets::Wrap { + trim: false + }), + block.inner(area), + ); + } + + if let Some(error) = &app.error { + let block = widgets::Block::default() + .title("Sydney") + .borders(widgets::Borders::ALL) + .style(Style::default().bg(Color::Cyan)); + let area = centered_rect(60, 20, f.size()); + + f.render_widget(widgets::Clear, area); + f.render_widget(block.clone(), area); + f.render_widget( + Paragraph::new(error.to_string()).wrap(widgets::Wrap { + trim: false + }), + block.inner(area), + ); + } +} + +fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect { + let popup_layout = Layout::default() + .direction(Direction::Vertical) + .constraints( + [ + Constraint::Percentage((100 - percent_y) / 2), + Constraint::Percentage(percent_y), + Constraint::Percentage((100 - percent_y) / 2), + ] + .as_ref(), + ) + .split(r); + + Layout::default() + .direction(Direction::Horizontal) + .constraints( + [ + Constraint::Percentage((100 - percent_x) / 2), + Constraint::Percentage(percent_x), + Constraint::Percentage((100 - percent_x) / 2), + ] + .as_ref(), + ) + .split(popup_layout[1])[1] +} |