use ratatui::widgets::{Block, Borders, Paragraph, Scrollbar, ScrollbarState};
use ratatui::style::Style;
use ratatui::Frame;
use ratatui::layout::{Rect, Layout as RatLayout, Direction, Constraint};
use ratatui::text::{Text, Line, Span};
use crate::tui::app::SelectedItem;
use crate::Config;
use crate::tui::widgets::color::parse_color;
use ratskin::RatSkin;
use termimad::minimad::Text as MinimadText;
use std::cmp;
fn get_content_string(item: &SelectedItem) -> String {
match item {
SelectedItem::Task(task) => {
let mut content = format!("**Title:** {}\n", task.title);
content.push_str(&format!("**Status:** {}\n", task.status));
if let Some(ref due_date) = task.due_date {
content.push_str(&format!("**Due Date:** {}\n", due_date));
}
if let Some(ref description) = task.description {
content.push_str("\n**Description/Notes:**\n\n");
content.push_str(description);
content.push('\n');
}
if let Some(ref tags) = task.tags {
content.push_str(&format!("\n**Tags:** {}\n", tags));
}
content
}
SelectedItem::Note(note) => {
let mut content = format!("**Title:** {}\n", note.title);
if let Some(ref tags) = note.tags {
content.push_str(&format!("\n**Tags:** {}\n", tags));
}
if let Some(ref note_content) = note.content {
content.push_str("\n**Content:**\n\n");
content.push_str(note_content);
content.push('\n');
}
content
}
SelectedItem::Journal(journal) => {
let mut content = format!("**Date:** {}\n", journal.date);
if let Some(ref title) = journal.title {
content.push_str(&format!("**Title:** {}\n", title));
}
if let Some(ref tags) = journal.tags {
content.push_str(&format!("\n**Tags:** {}\n", tags));
}
if let Some(ref journal_content) = journal.content {
content.push_str("\n**Content:**\n\n");
content.push_str(journal_content);
content.push('\n');
}
content
}
}
}
pub fn render_item_view(f: &mut Frame, area: Rect, item: &SelectedItem, config: &Config, scroll_offset: usize) {
if area.width < 2 || area.height < 2 {
return;
}
let horizontal = RatLayout::default()
.direction(Direction::Horizontal)
.constraints([
Constraint::Min(1),
Constraint::Length(1), ])
.split(area);
let content_area = horizontal[0];
let scrollbar_area = horizontal[1];
let viewport_height = (area.height - 2) as usize;
let content_string = get_content_string(item);
let text_width = (content_area.width.saturating_sub(2)) as usize;
let content_text_input = MinimadText::from(content_string.as_str());
let text_width_u16: u16 = text_width.try_into().unwrap_or(u16::MAX);
let content_lines = RatSkin::default().parse(content_text_input, text_width_u16);
let ratatui_lines: Vec<Line> = content_lines.into_iter().map(|line| {
let spans: Vec<Span> = line.spans.into_iter().map(|span| {
Span::styled(
span.content.to_string(),
span.style
)
}).collect();
Line::from(spans)
}).collect();
let content_text = Text::from(ratatui_lines);
let total_lines = content_text.lines.len();
let max_scroll = total_lines.saturating_sub(viewport_height);
let scroll_offset = cmp::min(scroll_offset, max_scroll);
let start_line = scroll_offset;
let end_line = cmp::min(start_line + viewport_height, total_lines);
let visible_text = if start_line < total_lines {
Text::from(content_text.lines[start_line..end_line].to_vec())
} else {
Text::default()
};
let title = match item {
SelectedItem::Task(_) => "Task",
SelectedItem::Note(_) => "Note",
SelectedItem::Journal(_) => "Journal Entry",
};
let base_style = Style::default().fg(parse_color(&config.get_active_theme().fg));
let paragraph = Paragraph::new(visible_text)
.block(Block::default().borders(Borders::ALL).title(title))
.style(base_style)
.wrap(ratatui::widgets::Wrap { trim: false });
f.render_widget(paragraph, content_area);
if total_lines > viewport_height {
let content_inner_height = content_area.height.saturating_sub(2);
let scrollbar_inner_area = Rect::new(
scrollbar_area.x,
content_area.y + 1, scrollbar_area.width,
content_inner_height, );
let mut scrollbar_state = ScrollbarState::new(total_lines)
.viewport_content_length(viewport_height)
.position(scroll_offset);
let scrollbar = Scrollbar::default()
.orientation(ratatui::widgets::ScrollbarOrientation::VerticalRight)
.begin_symbol(Some("↑"))
.end_symbol(Some("↓"))
.track_symbol(Some("│"))
.thumb_symbol("█");
f.render_stateful_widget(scrollbar, scrollbar_inner_area, &mut scrollbar_state);
}
}