mirror of
https://github.com/hulthe/inkopslista.git
synced 2026-09-18 18:03:39 +02:00
Add connection status indicator
This commit is contained in:
@@ -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;
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user