Add connection status indicator

This commit is contained in:
2026-03-22 11:40:32 +01:00
parent 9257a6e52a
commit bada5982c8
6 changed files with 161 additions and 68 deletions
+67
View File
@@ -0,0 +1,67 @@
use std::sync::Arc;
use slint::ComponentHandle;
use tokio::sync::mpsc;
use crate::{runtime::spawn, ui};
/// A thing for spawning I/O-tasks and updating the GUI `ConnectionStatus` with the result.
#[derive(Clone)]
pub struct Io {
state: Arc<State>,
}
struct State {
status: mpsc::Sender<ui::ConnectionStatus>,
}
impl Io {
pub fn new(app: &ui::App) -> Self {
let (tx, mut rx) = mpsc::channel(10);
let app_weak = app.as_weak();
spawn(async move {
loop {
let Some(status) = rx.recv().await else {
return;
};
let _ = app_weak.upgrade_in_event_loop(move |app| {
app.global::<ui::State>().set_connection_status(status);
});
}
});
Io {
state: Arc::new(State { status: tx }),
}
}
/// Spawn a fallible async function.
///
/// Update the `ConnectionStatus` in the GUI depending on whether the result is an error.
pub fn spawn<Fut>(&self, f: impl FnOnce() -> Fut + Send + 'static)
where
Fut: Future<Output = anyhow::Result<()>>,
Fut: Send + 'static,
{
let io = self.clone();
spawn(async move {
let _ = io.state.status.send(ui::ConnectionStatus::Syncing).await;
let result = f().await;
let was_error = result.is_err();
if let Err(e) = result {
eprintln!("{e:?}");
}
let _ = io
.state
.status
.send(if was_error {
ui::ConnectionStatus::Error
} else {
ui::ConnectionStatus::Idle
})
.await;
});
}
}