feat(ui): add configurable message timestamps and card rendering layout
This commit is contained in:
@@ -722,6 +722,8 @@ pub struct UiSettings {
|
||||
pub show_cursor_outside_insert: bool,
|
||||
#[serde(default = "UiSettings::default_syntax_highlighting")]
|
||||
pub syntax_highlighting: bool,
|
||||
#[serde(default = "UiSettings::default_show_timestamps")]
|
||||
pub show_timestamps: bool,
|
||||
}
|
||||
|
||||
impl UiSettings {
|
||||
@@ -765,6 +767,10 @@ impl UiSettings {
|
||||
false
|
||||
}
|
||||
|
||||
const fn default_show_timestamps() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn deserialize_role_label_mode<'de, D>(
|
||||
deserializer: D,
|
||||
) -> std::result::Result<RoleLabelDisplay, D::Error>
|
||||
@@ -831,6 +837,7 @@ impl Default for UiSettings {
|
||||
scrollback_lines: Self::default_scrollback_lines(),
|
||||
show_cursor_outside_insert: Self::default_show_cursor_outside_insert(),
|
||||
syntax_highlighting: Self::default_syntax_highlighting(),
|
||||
show_timestamps: Self::default_show_timestamps(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ anyhow = { workspace = true }
|
||||
uuid = { workspace = true }
|
||||
serde_json.workspace = true
|
||||
serde.workspace = true
|
||||
chrono = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
tokio-test = { workspace = true }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1029,14 +1029,15 @@ fn render_messages(frame: &mut Frame<'_>, area: Rect, app: &mut ChatApp) {
|
||||
|
||||
// Calculate viewport dimensions for autoscroll calculations
|
||||
let viewport_height = area.height.saturating_sub(2) as usize; // subtract borders
|
||||
let content_width = area.width.saturating_sub(4).max(20);
|
||||
app.set_viewport_dimensions(viewport_height, usize::from(content_width));
|
||||
let card_width = usize::from(area.width.saturating_sub(4).max(20));
|
||||
let body_width = card_width.saturating_sub(4).max(12);
|
||||
app.set_viewport_dimensions(viewport_height, body_width);
|
||||
|
||||
let total_messages = app.message_count();
|
||||
let mut formatter = app.formatter().clone();
|
||||
|
||||
// Reserve space for borders and the message indent so text fits within the block
|
||||
formatter.set_wrap_width(usize::from(content_width));
|
||||
formatter.set_wrap_width(body_width);
|
||||
|
||||
// Build the lines for messages using cached rendering
|
||||
let mut lines: Vec<Line<'static>> = Vec::new();
|
||||
@@ -1055,8 +1056,8 @@ fn render_messages(frame: &mut Frame<'_>, area: Rect, app: &mut ChatApp) {
|
||||
MessageRenderContext::new(
|
||||
&mut formatter,
|
||||
role_label_mode,
|
||||
content_width as usize,
|
||||
message_index + 1 == total_messages,
|
||||
body_width,
|
||||
card_width,
|
||||
is_streaming,
|
||||
app.get_loading_indicator(),
|
||||
&theme,
|
||||
@@ -1064,9 +1065,6 @@ fn render_messages(frame: &mut Frame<'_>, area: Rect, app: &mut ChatApp) {
|
||||
),
|
||||
);
|
||||
lines.extend(message_lines);
|
||||
if message_index + 1 < total_messages {
|
||||
lines.push(Line::from(String::new()));
|
||||
}
|
||||
}
|
||||
|
||||
// Add loading indicator ONLY if we're loading and there are no messages at all,
|
||||
|
||||
Reference in New Issue
Block a user