Skip to content

Commit

Permalink
Use Task::run in download_progress example
Browse files Browse the repository at this point in the history
  • Loading branch information
hecrj committed Nov 22, 2024
1 parent 53b7f50 commit 6ccc828
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 43 deletions.
19 changes: 4 additions & 15 deletions examples/download_progress/src/download.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
use iced::futures::{SinkExt, Stream, StreamExt};
use iced::stream::try_channel;
use iced::Subscription;

use std::hash::Hash;
use std::sync::Arc;

// Just a little utility function
pub fn file<I: 'static + Hash + Copy + Send + Sync, T: ToString>(
id: I,
url: T,
) -> iced::Subscription<(I, Result<Progress, Error>)> {
Subscription::run_with_id(
id,
download(url.to_string()).map(move |progress| (id, progress)),
)
}

fn download(url: String) -> impl Stream<Item = Result<Progress, Error>> {
pub fn download(
url: impl AsRef<str>,
) -> impl Stream<Item = Result<Progress, Error>> {
try_channel(1, move |mut output| async move {
let response = reqwest::get(&url).await?;
let response = reqwest::get(url.as_ref()).await?;
let total = response.content_length().ok_or(Error::NoContentLength)?;

let _ = output.send(Progress::Downloading { percent: 0.0 }).await;
Expand Down
68 changes: 40 additions & 28 deletions examples/download_progress/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
mod download;

use download::download;

use iced::task;
use iced::widget::{button, center, column, progress_bar, text, Column};
use iced::{Center, Element, Right, Subscription};
use iced::{Center, Element, Right, Task};

pub fn main() -> iced::Result {
iced::application(
"Download Progress - Iced",
Example::update,
Example::view,
)
.subscription(Example::subscription)
.run()
}

Expand All @@ -23,7 +25,7 @@ struct Example {
pub enum Message {
Add,
Download(usize),
DownloadProgressed((usize, Result<download::Progress, download::Error>)),
DownloadProgressed(usize, Result<download::Progress, download::Error>),
}

impl Example {
Expand All @@ -34,32 +36,38 @@ impl Example {
}
}

fn update(&mut self, message: Message) {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::Add => {
self.last_id += 1;

self.downloads.push(Download::new(self.last_id));

Task::none()
}
Message::Download(index) => {
if let Some(download) = self.downloads.get_mut(index) {
download.start();
}
let Some(download) = self.downloads.get_mut(index) else {
return Task::none();
};

let task = download.start();

task.map(move |progress| {
Message::DownloadProgressed(index, progress)
})
}
Message::DownloadProgressed((id, progress)) => {
Message::DownloadProgressed(id, progress) => {
if let Some(download) =
self.downloads.iter_mut().find(|download| download.id == id)
{
download.progress(progress);
}

Task::none()
}
}
}

fn subscription(&self) -> Subscription<Message> {
Subscription::batch(self.downloads.iter().map(Download::subscription))
}

fn view(&self) -> Element<Message> {
let downloads =
Column::with_children(self.downloads.iter().map(Download::view))
Expand Down Expand Up @@ -90,7 +98,7 @@ struct Download {
#[derive(Debug)]
enum State {
Idle,
Downloading { progress: f32 },
Downloading { progress: f32, _task: task::Handle },
Finished,
Errored,
}
Expand All @@ -103,22 +111,36 @@ impl Download {
}
}

pub fn start(&mut self) {
pub fn start(
&mut self,
) -> Task<Result<download::Progress, download::Error>> {
match self.state {
State::Idle { .. }
| State::Finished { .. }
| State::Errored { .. } => {
self.state = State::Downloading { progress: 0.0 };
let (task, handle) = Task::stream(download(
"https://huggingface.co/\
mattshumer/Reflection-Llama-3.1-70B/\
resolve/main/model-00001-of-00162.safetensors",
))
.abortable();

self.state = State::Downloading {
progress: 0.0,
_task: handle.abort_on_drop(),
};

task
}
State::Downloading { .. } => {}
State::Downloading { .. } => Task::none(),
}
}

pub fn progress(
&mut self,
new_progress: Result<download::Progress, download::Error>,
) {
if let State::Downloading { progress } = &mut self.state {
if let State::Downloading { progress, .. } = &mut self.state {
match new_progress {
Ok(download::Progress::Downloading { percent }) => {
*progress = percent;
Expand All @@ -133,20 +155,10 @@ impl Download {
}
}

pub fn subscription(&self) -> Subscription<Message> {
match self.state {
State::Downloading { .. } => {
download::file(self.id, "https://huggingface.co/mattshumer/Reflection-Llama-3.1-70B/resolve/main/model-00001-of-00162.safetensors")
.map(Message::DownloadProgressed)
}
_ => Subscription::none(),
}
}

pub fn view(&self) -> Element<Message> {
let current_progress = match &self.state {
State::Idle { .. } => 0.0,
State::Downloading { progress } => *progress,
State::Downloading { progress, .. } => *progress,
State::Finished { .. } => 100.0,
State::Errored { .. } => 0.0,
};
Expand Down

0 comments on commit 6ccc828

Please sign in to comment.