login waiting dialog works, THIS COMMIT NEEDS TO BE REFACTORED

This commit is contained in:
filipriec
2025-04-18 14:44:04 +02:00
parent 73d9a6367c
commit 2b37de3b4d
11 changed files with 276 additions and 175 deletions

View File

@@ -21,7 +21,7 @@ pub fn render_add_table(
f: &mut Frame,
area: Rect,
theme: &Theme,
_app_state: &AppState, // Currently unused, might be needed later
app_state: &AppState, // Currently unused, might be needed later
add_table_state: &mut AddTableState,
is_edit_mode: bool, // Determines if canvas inputs are in edit mode
highlight_state: &HighlightState, // For text highlighting in canvas
@@ -486,15 +486,16 @@ pub fn render_add_table(
// --- DIALOG ---
// Render the dialog overlay if it's active
if _app_state.ui.dialog.dialog_show { // Use the passed-in app_state
if app_state.ui.dialog.dialog_show { // Use the passed-in app_state
dialog::render_dialog(
f,
f.area(), // Render over the whole frame area
theme,
&_app_state.ui.dialog.dialog_title,
&_app_state.ui.dialog.dialog_message,
&_app_state.ui.dialog.dialog_buttons,
_app_state.ui.dialog.dialog_active_button_index,
&app_state.ui.dialog.dialog_title,
&app_state.ui.dialog.dialog_message,
&app_state.ui.dialog.dialog_buttons,
app_state.ui.dialog.dialog_active_button_index,
app_state.ui.dialog.is_loading,
);
}
}

View File

@@ -142,7 +142,8 @@ pub fn render_login(
&app_state.ui.dialog.dialog_title,
&app_state.ui.dialog.dialog_message,
&app_state.ui.dialog.dialog_buttons, // Pass buttons slice
app_state.ui.dialog.dialog_active_button_index, // Pass active index
app_state.ui.dialog.dialog_active_button_index,
app_state.ui.dialog.is_loading,
);
}
}

View File

@@ -168,6 +168,7 @@ pub fn render_register(
&app_state.ui.dialog.dialog_message,
&app_state.ui.dialog.dialog_buttons,
app_state.ui.dialog.dialog_active_button_index,
app_state.ui.dialog.is_loading,
);
}
}

View File

@@ -18,6 +18,7 @@ pub fn render_dialog(
dialog_message: &str,
dialog_buttons: &[String],
dialog_active_button_index: usize,
is_loading: bool,
) {
// Calculate required height based on the actual number of lines in the message
let message_lines: Vec<_> = dialog_message.lines().collect();
@@ -63,27 +64,36 @@ pub fn render_dialog(
vertical: 1, // Top/Bottom padding inside border
});
// Layout for Message and Buttons based on actual message height
let mut constraints = vec![
// Allocate space for message, ensuring at least 1 line height
Constraint::Length(message_height.max(1)), // Use actual calculated height
];
if button_row_height > 0 {
constraints.push(Constraint::Length(button_row_height));
}
if is_loading {
// --- Loading State ---
let loading_text = Paragraph::new(dialog_message) // Use the message passed for loading
.style(Style::default().fg(theme.fg).add_modifier(Modifier::ITALIC))
.alignment(Alignment::Center);
// Render loading message centered in the inner area
f.render_widget(loading_text, inner_area);
} else {
// --- Normal State (Message + Buttons) ---
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints(constraints)
.split(inner_area);
// Layout for Message and Buttons based on actual message height
let mut constraints = vec![
// Allocate space for message, ensuring at least 1 line height
Constraint::Length(message_height.max(1)), // Use actual calculated height
];
if button_row_height > 0 {
constraints.push(Constraint::Length(button_row_height));
}
// Render Message
let available_width = inner_area.width as usize;
let ellipsis = "...";
let ellipsis_width = UnicodeWidthStr::width(ellipsis);
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints(constraints)
.split(inner_area);
let processed_lines: Vec<Line> =
message_lines
// Render Message
let available_width = inner_area.width as usize;
let ellipsis = "...";
let ellipsis_width = UnicodeWidthStr::width(ellipsis);
let processed_lines: Vec<Line> = message_lines
.into_iter()
.map(|line| {
let line_width = UnicodeWidthStr::width(line);
@@ -91,81 +101,83 @@ pub fn render_dialog(
// Truncate with ellipsis
let mut truncated_len = 0;
let mut current_width = 0;
// Iterate over graphemes to handle multi-byte characters correctly
for (idx, grapheme) in line.grapheme_indices(true) {
let grapheme_width = UnicodeWidthStr::width(grapheme);
if current_width + grapheme_width > available_width.saturating_sub(ellipsis_width) {
break; // Stop before exceeding width needed for text + ellipsis
if current_width + grapheme_width
> available_width.saturating_sub(ellipsis_width)
{
break;
}
current_width += grapheme_width;
truncated_len = idx + grapheme.len(); // Store the byte index of the end of the last fitting grapheme
truncated_len = idx + grapheme.len();
}
let truncated_line = format!("{}{}", &line[..truncated_len], ellipsis);
Line::from(Span::styled(truncated_line, Style::default().fg(theme.fg)))
let truncated_line =
format!("{}{}", &line[..truncated_len], ellipsis);
Line::from(Span::styled(
truncated_line,
Style::default().fg(theme.fg),
))
} else {
// Line fits, use it as is
Line::from(Span::styled(line, Style::default().fg(theme.fg)))
}
})
.collect();
.collect();
let message_paragraph =
Paragraph::new(Text::from(processed_lines)).alignment(Alignment::Center);
// Render message in the first chunk
f.render_widget(message_paragraph, chunks[0]);
let message_paragraph =
Paragraph::new(Text::from(processed_lines)).alignment(Alignment::Center);
f.render_widget(message_paragraph, chunks[0]); // Render message in the first chunk
// Render Buttons if they exist and there's a chunk for them
if !dialog_buttons.is_empty() && chunks.len() > 1 {
let button_area = chunks[1];
let button_count = dialog_buttons.len();
// Render Buttons if they exist and there's a chunk for them
if !dialog_buttons.is_empty() && chunks.len() > 1 {
let button_area = chunks[1];
let button_count = dialog_buttons.len();
// Use Ratio for potentially more even distribution with few buttons
let button_constraints = std::iter::repeat(Constraint::Ratio(
1,
button_count as u32,
))
.take(button_count)
.collect::<Vec<_>>();
let button_constraints = std::iter::repeat(Constraint::Ratio(
1,
button_count as u32,
))
.take(button_count)
.collect::<Vec<_>>();
let button_chunks = Layout::default()
.direction(Direction::Horizontal)
.constraints(button_constraints)
.horizontal_margin(1) // Add space between buttons
.split(button_area);
let button_chunks = Layout::default()
.direction(Direction::Horizontal)
.constraints(button_constraints)
.horizontal_margin(1) // Add space between buttons
.split(button_area);
for (i, button_label) in dialog_buttons.iter().enumerate() {
// Ensure we don't try to render into a non-existent chunk
if i >= button_chunks.len() {
break;
}
for (i, button_label) in dialog_buttons.iter().enumerate() {
if i >= button_chunks.len() {
break;
}
let is_active = i == dialog_active_button_index;
let (button_style, border_style) = if is_active {
(
Style::default()
let is_active = i == dialog_active_button_index;
let (button_style, border_style) = if is_active {
(
Style::default()
.fg(theme.highlight)
.add_modifier(Modifier::BOLD),
Style::default().fg(theme.accent), // Highlight border
)
} else {
(
Style::default().fg(theme.fg),
Style::default().fg(theme.border), // Normal border
)
};
Style::default().fg(theme.accent),
)
} else {
(
Style::default().fg(theme.fg),
Style::default().fg(theme.border),
)
};
let button_block = Block::default()
.borders(Borders::ALL)
.border_type(BorderType::Plain)
.border_style(border_style);
let button_block = Block::default()
.borders(Borders::ALL)
.border_type(BorderType::Plain)
.border_style(border_style);
f.render_widget(
Paragraph::new(button_label.as_str())
f.render_widget(
Paragraph::new(button_label.as_str())
.block(button_block)
.style(button_style)
.alignment(Alignment::Center),
button_chunks[i],
);
button_chunks[i],
);
}
}
}
}