Fix border wrapping issue

This commit is contained in:
Ian Keane 2025-11-25 20:21:08 -05:00
parent 9ef6143dbd
commit 89d1c02690
2 changed files with 30 additions and 27 deletions

View file

@ -86,8 +86,8 @@ impl App {
}
match self.log_view_grouping {
LogViewGrouping::ByProject => line.starts_with("\t\t"),
LogViewGrouping::ByDate => line.starts_with('\t') && !line.starts_with("\t\t"),
LogViewGrouping::ByProject => line.starts_with(" "),
LogViewGrouping::ByDate => line.starts_with(" ") && !line.starts_with(" "),
}
}
@ -637,7 +637,7 @@ impl App {
if let Some(prev) = prev_stop {
let gap = start_local.signed_duration_since(prev);
if gap.num_minutes() >= 5 {
lines.push("\t ---".to_string());
lines.push(" ---".to_string());
// Note: don't add to frame_indices - separator is not an entry
}
}
@ -663,7 +663,7 @@ impl App {
};
let line_text = format!(
"\t{} to {} {:>9} {}",
" {} to {} {:>9} {}",
start_time, stop_time, duration_str, display_text
);
@ -763,7 +763,7 @@ impl App {
};
lines.push(format!(
"\t\t{} to {} {:>9}{}",
" {} to {} {:>9}{}",
start_time, stop_time, duration_str, tags_str
));
frame_indices.push(*idx);

View file

@ -2,7 +2,7 @@ use ratatui::{
layout::{Alignment, Constraint, Direction, Layout, Rect},
style::{Color, Modifier, Style},
text::{Line, Span},
widgets::{Block, Borders, Clear, List, ListItem, Paragraph, Row, Table, TableState},
widgets::{Block, Borders, Clear, Paragraph, Row, Table, TableState},
Frame,
};
@ -698,8 +698,8 @@ fn render_log_view(frame: &mut Frame, app: &App) {
.borders(Borders::ALL)
.style(Style::default().fg(ACTIVE_COLOR));
// Build list items with selection highlighting based on selection level
let items: Vec<ListItem> = {
// Build text lines with selection highlighting based on selection level
let text_lines: Vec<Line> = {
// Pre-calculate which line indices should be highlighted
let mut selected_date = String::new();
let mut selected_project = String::new();
@ -715,17 +715,17 @@ fn render_log_view(frame: &mut Frame, app: &App) {
let is_by_project = matches!(app.log_view_grouping, LogViewGrouping::ByProject);
for (_idx, line) in app.log_view_content.iter().enumerate() {
if !line.starts_with('\t') && !line.is_empty() && !line.starts_with(" ") {
if !line.starts_with(" ") && !line.is_empty() && !line.starts_with(" ") {
current_date = line.clone();
} else if line.starts_with(" ") && !line.starts_with("\t") {
} else if line.starts_with(" ") && !line.starts_with(" ") {
current_project = line.clone();
}
// Only count actual entries (not all tab-indented lines)
let is_entry = if is_by_project {
line.starts_with("\t\t") // Double tab for ByProject
line.starts_with(" ") // 8 spaces for ByProject
} else {
line.starts_with('\t') && !line.starts_with("\t\t") // Single tab for ByDate
line.starts_with(" ") && !line.starts_with(" ") // 4 spaces for ByDate
};
if is_entry {
@ -746,9 +746,9 @@ fn render_log_view(frame: &mut Frame, app: &App) {
for (idx, line) in app.log_view_content.iter().enumerate() {
// Use is_entry_line logic which excludes separator lines
let is_entry = if is_by_project {
line.starts_with("\t\t")
line.starts_with(" ")
} else {
line.starts_with('\t') && !line.starts_with("\t\t") && line.trim() != "---"
line.starts_with(" ") && !line.starts_with(" ") && line.trim() != "---"
};
if is_entry {
@ -767,19 +767,19 @@ fn render_log_view(frame: &mut Frame, app: &App) {
current_date = String::new();
for (idx, line) in app.log_view_content.iter().enumerate() {
if !line.starts_with('\t') && !line.is_empty() && !line.starts_with(" ") {
if !line.starts_with(" ") && !line.is_empty() && !line.starts_with(" ") {
current_date = line.clone();
if in_target_project {
break; // End of project group
}
} else if line.starts_with(" ") && !line.starts_with("\t") {
} else if line.starts_with(" ") && !line.starts_with(" ") {
if current_date == selected_date && line == &selected_project {
selected_line_start = idx;
in_target_project = true;
} else if in_target_project {
break; // Different project
}
} else if in_target_project && line.starts_with('\t') {
} else if in_target_project && line.starts_with(" ") {
selected_line_end = idx;
}
}
@ -789,7 +789,7 @@ fn render_log_view(frame: &mut Frame, app: &App) {
let mut in_target_day = false;
for (idx, line) in app.log_view_content.iter().enumerate() {
if !line.starts_with('\t') && !line.is_empty() && !line.starts_with(" ") {
if !line.starts_with(" ") && !line.is_empty() && !line.starts_with(" ") {
if line == &selected_date {
selected_line_start = idx;
in_target_day = true;
@ -820,17 +820,17 @@ fn render_log_view(frame: &mut Frame, app: &App) {
for (line_idx, line) in app.log_view_content.iter().enumerate() {
// New day header
if !line.starts_with('\t') && !line.is_empty() && !line.starts_with(" ") {
if !line.starts_with(" ") && !line.is_empty() && !line.starts_with(" ") {
current_day_start_entry = app.log_view_content[..line_idx]
.iter()
.filter(|l| l.starts_with('\t') && !l.is_empty() && l.trim() != "---")
.filter(|l| l.starts_with(" ") && !l.is_empty() && l.trim() != "---")
.count();
in_day = true;
} else if in_day && line.starts_with('\t') && !line.is_empty() && line.trim() != "---" {
} else if in_day && line.starts_with(" ") && !line.is_empty() && line.trim() != "---" {
// This is an entry line
let entry_idx = app.log_view_content[..=line_idx]
.iter()
.filter(|l| l.starts_with('\t') && !l.is_empty() && l.trim() != "---")
.filter(|l| l.starts_with(" ") && !l.is_empty() && l.trim() != "---")
.count()
.saturating_sub(1);
@ -868,12 +868,12 @@ fn render_log_view(frame: &mut Frame, app: &App) {
let is_separator = line.trim() == "---";
// Check if this line corresponds to an overlapping entry
let has_overlap = if !is_separator && is_by_date && line.starts_with('\t') && !line.is_empty() {
let has_overlap = if !is_separator && is_by_date && line.starts_with(" ") && !line.is_empty() {
// Count which entry this is (0-based in display order)
// Only count actual entry lines, not separator lines
let entry_idx = app.log_view_content[..=idx]
.iter()
.filter(|l| l.starts_with('\t') && !l.is_empty() && l.trim() != "---")
.filter(|l| l.starts_with(" ") && !l.is_empty() && l.trim() != "---")
.count()
.saturating_sub(1);
@ -894,13 +894,16 @@ fn render_log_view(frame: &mut Frame, app: &App) {
Style::default().fg(Color::White)
};
ListItem::new(Line::from(vec![Span::styled(line.clone(), style)]))
Line::from(vec![Span::styled(line.clone(), style)])
})
.collect()
};
let list = List::new(items).block(block);
frame.render_widget(list, chunks[0]);
let paragraph = Paragraph::new(text_lines)
.block(block)
.wrap(ratatui::widgets::Wrap { trim: false });
frame.render_widget(paragraph, chunks[0]);
// Render help hint at bottom if enabled
if app.config.show_help_hint {