mirror of
https://github.com/hulthe/inkopslista.git
synced 2026-09-18 18:03:39 +02:00
99 lines
2.8 KiB
Rust
99 lines
2.8 KiB
Rust
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.
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
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;
|
|
});
|
|
}
|
|
|
|
/// Spawn a fallible async function.
|
|
///
|
|
/// Update the `ConnectionStatus` in the GUI depending on whether the result is an error.
|
|
// FIXME: this function is duplicated from the one above, but without the `Send` requirement on the future.
|
|
#[cfg(target_arch = "wasm32")]
|
|
pub fn spawn<Fut>(&self, f: impl FnOnce() -> Fut + Send + 'static)
|
|
where
|
|
Fut: Future<Output = anyhow::Result<()>>,
|
|
Fut: '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;
|
|
});
|
|
}
|
|
}
|