outputting to the status line
This commit is contained in:
@@ -20,16 +20,18 @@ pub fn render_status_line(
|
||||
current_fps: f64,
|
||||
app_state: &AppState,
|
||||
) {
|
||||
// --- START FIX ---
|
||||
// Ensure debug_text is always a &str, which implements UnicodeWidthStr.
|
||||
#[cfg(feature = "ui-debug")]
|
||||
let debug_text = app_state.debug_info.as_str();
|
||||
#[cfg(not(feature = "ui-debug"))]
|
||||
let debug_text = "";
|
||||
// --- END FIX ---
|
||||
|
||||
let debug_width = UnicodeWidthStr::width(debug_text);
|
||||
let debug_separator_width = if !debug_text.is_empty() { UnicodeWidthStr::width(" | ") } else { 0 };
|
||||
{
|
||||
// If ui-debug is enabled, we only show the debug info.
|
||||
let debug_text = &app_state.debug_info;
|
||||
let debug_span = Span::styled(
|
||||
debug_text.as_str(),
|
||||
Style::default().fg(theme.accent).bg(theme.bg),
|
||||
);
|
||||
let paragraph = Paragraph::new(Line::from(vec![debug_span]));
|
||||
f.render_widget(paragraph, area);
|
||||
return; // Early return to skip the normal status line rendering.
|
||||
}
|
||||
|
||||
let program_info = format!("multieko2 v{}", env!("CARGO_PKG_VERSION"));
|
||||
let mode_text = if is_edit_mode { "[EDIT]" } else { "[READ-ONLY]" };
|
||||
@@ -50,16 +52,25 @@ pub fn render_status_line(
|
||||
let separator = " | ";
|
||||
let separator_width = UnicodeWidthStr::width(separator);
|
||||
|
||||
let fixed_width_with_fps = mode_width + separator_width + separator_width +
|
||||
program_info_width + separator_width + fps_width +
|
||||
debug_separator_width + debug_width;
|
||||
let fixed_width_with_fps = mode_width
|
||||
+ separator_width
|
||||
+ separator_width
|
||||
+ program_info_width
|
||||
+ separator_width
|
||||
+ fps_width;
|
||||
|
||||
let show_fps = fixed_width_with_fps <= available_width;
|
||||
|
||||
let remaining_width_for_dir = available_width.saturating_sub(
|
||||
mode_width + separator_width +
|
||||
separator_width + program_info_width +
|
||||
(if show_fps { separator_width + fps_width } else { 0 }) +
|
||||
debug_separator_width + debug_width,
|
||||
mode_width
|
||||
+ separator_width
|
||||
+ separator_width
|
||||
+ program_info_width
|
||||
+ (if show_fps {
|
||||
separator_width + fps_width
|
||||
} else {
|
||||
0
|
||||
}),
|
||||
);
|
||||
|
||||
let dir_display_text_str = if UnicodeWidthStr::width(display_dir.as_str()) <= remaining_width_for_dir {
|
||||
@@ -76,10 +87,11 @@ pub fn render_status_line(
|
||||
}
|
||||
};
|
||||
|
||||
let mut current_content_width = mode_width + separator_width +
|
||||
UnicodeWidthStr::width(dir_display_text_str.as_str()) +
|
||||
separator_width + program_info_width +
|
||||
debug_separator_width + debug_width;
|
||||
let mut current_content_width = mode_width
|
||||
+ separator_width
|
||||
+ UnicodeWidthStr::width(dir_display_text_str.as_str())
|
||||
+ separator_width
|
||||
+ program_info_width;
|
||||
if show_fps {
|
||||
current_content_width += separator_width + fps_width;
|
||||
}
|
||||
@@ -92,15 +104,13 @@ pub fn render_status_line(
|
||||
Span::styled(program_info.as_str(), Style::default().fg(theme.secondary)),
|
||||
];
|
||||
|
||||
if show_fps {
|
||||
line_spans.push(Span::styled(separator, Style::default().fg(theme.border)));
|
||||
line_spans.push(Span::styled(fps_text.as_str(), Style::default().fg(theme.secondary)));
|
||||
}
|
||||
|
||||
#[cfg(feature = "ui-debug")]
|
||||
{
|
||||
line_spans.push(Span::styled(separator, Style::default().fg(theme.border)));
|
||||
line_spans.push(Span::styled(debug_text, Style::default().fg(theme.accent)));
|
||||
if show_fps {
|
||||
line_spans
|
||||
.push(Span::styled(separator, Style::default().fg(theme.border)));
|
||||
line_spans.push(Span::styled(
|
||||
fps_text.as_str(),
|
||||
Style::default().fg(theme.secondary),
|
||||
));
|
||||
}
|
||||
|
||||
let padding_needed = available_width.saturating_sub(current_content_width);
|
||||
@@ -111,8 +121,8 @@ pub fn render_status_line(
|
||||
));
|
||||
}
|
||||
|
||||
let paragraph = Paragraph::new(Line::from(line_spans))
|
||||
.style(Style::default().bg(theme.bg));
|
||||
let paragraph =
|
||||
Paragraph::new(Line::from(line_spans)).style(Style::default().bg(theme.bg));
|
||||
|
||||
f.render_widget(paragraph, area);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// client/src/main.rs
|
||||
use client::run_ui;
|
||||
#[cfg(feature = "ui-debug")]
|
||||
use client::utils::debug_logger::UiDebugWriter;
|
||||
use dotenvy::dotenv;
|
||||
use anyhow::Result;
|
||||
use tracing_subscriber;
|
||||
@@ -7,9 +9,18 @@ use std::env;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
#[cfg(feature = "ui-debug")]
|
||||
{
|
||||
// If ui-debug is on, set up our custom writer.
|
||||
let writer = UiDebugWriter::new();
|
||||
tracing_subscriber::fmt().with_writer(move || writer.clone()).init();
|
||||
}
|
||||
#[cfg(not(feature = "ui-debug"))]
|
||||
{
|
||||
if env::var("ENABLE_TRACING").is_ok() {
|
||||
tracing_subscriber::fmt::init();
|
||||
}
|
||||
}
|
||||
|
||||
dotenv().ok();
|
||||
run_ui().await
|
||||
|
||||
@@ -42,10 +42,9 @@ use crate::tui::{
|
||||
use crate::ui::handlers::context::UiContext;
|
||||
use crate::ui::handlers::rat_state::UiStateHandler;
|
||||
use anyhow::Result;
|
||||
use common::proto::multieko2::search::search_response::Hit; // Correctly imported
|
||||
use common::proto::multieko2::search::search_response::Hit;
|
||||
use crossterm::cursor::SetCursorStyle;
|
||||
use crossterm::event::KeyCode;
|
||||
use crossterm::event::{Event, KeyEvent};
|
||||
use crossterm::event::{Event, KeyCode, KeyEvent};
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::mpsc::unbounded_channel;
|
||||
use tracing::{info, error};
|
||||
@@ -186,15 +185,18 @@ impl EventHandler {
|
||||
let table_name = search_state.table_name.clone();
|
||||
let sender = self.search_result_sender.clone();
|
||||
|
||||
info!("--- 1. Spawning search task for query: '{}' ---", query);
|
||||
// We now move the grpc_client into the task, just like with login.
|
||||
tokio::spawn(async move {
|
||||
|
||||
info!("--- 2. Background task started. ---");
|
||||
match grpc_client.search_table(table_name, query).await {
|
||||
Ok(response) => {
|
||||
info!("Search successful. Received {} hits.", response.hits.len());
|
||||
info!("--- 3a. gRPC call successful. Found {} hits. ---", response.hits.len());
|
||||
let _ = sender.send(response.hits);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("gRPC search call failed: {}", e);
|
||||
error!("--- 3b. gRPC call failed: {} ---", e);
|
||||
let _ = sender.send(vec![]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ use crate::ui::handlers::render::render_ui;
|
||||
use crate::tui::functions::common::login::LoginResult;
|
||||
use crate::tui::functions::common::register::RegisterResult;
|
||||
use crate::ui::handlers::context::DialogPurpose;
|
||||
#[cfg(feature = "ui-debug")]
|
||||
use crate::utils::debug_logger::get_latest_debug_message;
|
||||
use crate::tui::functions::common::login;
|
||||
use crate::tui::functions::common::register;
|
||||
use crate::utils::columns::filter_user_columns;
|
||||
@@ -129,6 +131,7 @@ pub async fn run_ui() -> Result<()> {
|
||||
|
||||
match event_handler.search_result_receiver.try_recv() {
|
||||
Ok(hits) => {
|
||||
info!("--- 4. Main loop received message from channel. ---");
|
||||
if let Some(search_state) = app_state.search_state.as_mut() {
|
||||
search_state.results = hits;
|
||||
search_state.is_loading = false;
|
||||
@@ -517,10 +520,7 @@ pub async fn run_ui() -> Result<()> {
|
||||
|
||||
#[cfg(feature = "ui-debug")]
|
||||
{
|
||||
app_state.debug_info = format!(
|
||||
"Redraw -> event: {}, needs_redraw: {}, pos_changed: {}",
|
||||
event_processed, needs_redraw, position_changed
|
||||
);
|
||||
app_state.debug_info = get_latest_debug_message();
|
||||
}
|
||||
|
||||
if event_processed || needs_redraw || position_changed {
|
||||
|
||||
46
client/src/utils/debug_logger.rs
Normal file
46
client/src/utils/debug_logger.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
// client/src/utils/debug_logger.rs
|
||||
use lazy_static::lazy_static;
|
||||
use std::io;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
lazy_static! {
|
||||
static ref UI_DEBUG_BUFFER: Arc<Mutex<String>> =
|
||||
Arc::new(Mutex::new(String::from("Logger initialized...")));
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct UiDebugWriter;
|
||||
|
||||
impl Default for UiDebugWriter {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl UiDebugWriter {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
// Implement the io::Write trait for our writer.
|
||||
// tracing_subscriber can use any type that implements `MakeWriter`.
|
||||
// A simple way to do this is to have our writer implement `io::Write`.
|
||||
impl io::Write for UiDebugWriter {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
let mut buffer = UI_DEBUG_BUFFER.lock().unwrap();
|
||||
let message = String::from_utf8_lossy(buf);
|
||||
// We just want the latest message, trimmed of whitespace.
|
||||
*buffer = message.trim().to_string();
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// A public function to safely get the latest message from anywhere in the app.
|
||||
pub fn get_latest_debug_message() -> String {
|
||||
UI_DEBUG_BUFFER.lock().unwrap().clone()
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
// src/utils/mod.rs
|
||||
|
||||
pub mod columns;
|
||||
pub mod debug_logger;
|
||||
pub use columns::*;
|
||||
pub use debug_logger::*;
|
||||
|
||||
@@ -17,7 +17,8 @@ use common::proto::multieko2::search::{
|
||||
pub use common::proto::multieko2::search::searcher_server::SearcherServer;
|
||||
use common::proto::multieko2::search::searcher_server::Searcher;
|
||||
use common::search::register_slovak_tokenizers;
|
||||
use sqlx::{PgPool, Row}; // <-- Import PgPool and Row
|
||||
use sqlx::{PgPool, Row};
|
||||
use tracing::info;
|
||||
|
||||
// We need to hold the database pool in our service struct.
|
||||
pub struct SearcherService {
|
||||
@@ -263,6 +264,8 @@ impl Searcher for SearcherService {
|
||||
})
|
||||
.collect();
|
||||
|
||||
info!("--- SERVER: Successfully processed search. Returning {} hits. ---", hits.len());
|
||||
|
||||
let response = SearchResponse { hits };
|
||||
Ok(Response::new(response))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user