use mobiler_core::*;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone)]
pub enum Msg {
StartUpload,
StartDownload,
Xfer(TransferEvent),
Cancel,
}
#[derive(Default, Serialize, Deserialize)]
pub struct Model {
pub busy: bool,
pub percent: Option<f64>,
pub saved_at: Option<String>,
pub error: Option<String>,
}
impl MyApp {
fn handle(&self, msg: Msg, model: &mut Model, cx: &mut Cx<Msg>) {
match msg {
Msg::StartUpload => {
model.busy = true;
model.percent = Some(0.0);
model.error = None;
cx.upload("https://example.com/upload", "receipts/2026-07.jpg")
.bearer("token123")
.start("xfer", Msg::Xfer);
}
Msg::StartDownload => {
model.busy = true;
model.percent = Some(0.0);
model.error = None;
cx.download("https://example.com/report.pdf", "downloads/report.pdf")
.start("xfer", Msg::Xfer);
}
Msg::Xfer(TransferEvent::Progress { transferred, total }) => {
model.percent = total.map(|t| transferred as f64 / t.max(1) as f64 * 100.0);
}
Msg::Xfer(TransferEvent::Done { outcome, handle }) => {
model.busy = false;
match outcome {
HttpOutcome::Response { status, .. } if (200..300).contains(&status) => {
model.saved_at = handle; }
HttpOutcome::Response { status, .. } => {
model.error = Some(format!("server rejected the transfer: http {status}"));
}
HttpOutcome::TransportError { message } => {
model.error = Some(message);
}
}
}
Msg::Cancel => {
cx.unsubscribe("xfer");
model.busy = false;
model.percent = None;
}
}
}
}