diff options
| author | 2025-02-12 01:51:20 +0100 | |
|---|---|---|
| committer | 2025-02-12 01:51:20 +0100 | |
| commit | 89a412695af321356a6f05f9111510d35a839983 (patch) | |
| tree | 12b342eb17688cbb07e6c9fd8748c42ef7591501 /examples/gallery | |
| parent | bf205a88b66a6fa8ea6d9a259bfd0ed0b42a97b7 (diff) | |
| parent | e78c757cad5619c77a588054b42e9b87335d6e86 (diff) | |
| download | iced-89a412695af321356a6f05f9111510d35a839983.tar.gz iced-89a412695af321356a6f05f9111510d35a839983.tar.bz2 iced-89a412695af321356a6f05f9111510d35a839983.zip | |
Merge pull request #2805 from iced-rs/feature/sipper-support
`sipper` support and some QoL
Diffstat (limited to '')
| -rw-r--r-- | examples/gallery/Cargo.toml | 1 | ||||
| -rw-r--r-- | examples/gallery/src/civitai.rs | 106 | ||||
| -rw-r--r-- | examples/gallery/src/main.rs | 34 | 
3 files changed, 80 insertions, 61 deletions
| diff --git a/examples/gallery/Cargo.toml b/examples/gallery/Cargo.toml index c9dc1e9d..6e8aba06 100644 --- a/examples/gallery/Cargo.toml +++ b/examples/gallery/Cargo.toml @@ -17,6 +17,7 @@ serde.features = ["derive"]  bytes.workspace = true  image.workspace = true +sipper.workspace = true  tokio.workspace = true  blurhash = "0.2.3" diff --git a/examples/gallery/src/civitai.rs b/examples/gallery/src/civitai.rs index 18d2a040..04589030 100644 --- a/examples/gallery/src/civitai.rs +++ b/examples/gallery/src/civitai.rs @@ -1,5 +1,6 @@  use bytes::Bytes;  use serde::Deserialize; +use sipper::{sipper, Straw};  use tokio::task;  use std::fmt; @@ -45,58 +46,72 @@ impl Image {          self,          width: u32,          height: u32, -    ) -> Result<Rgba, Error> { +    ) -> Result<Blurhash, Error> {          task::spawn_blocking(move || {              let pixels = blurhash::decode(&self.hash, width, height, 1.0)?; -            Ok::<_, Error>(Rgba { -                width, -                height, -                pixels: Bytes::from(pixels), +            Ok::<_, Error>(Blurhash { +                rgba: Rgba { +                    width, +                    height, +                    pixels: Bytes::from(pixels), +                },              })          })          .await?      } -    pub async fn download(self, size: Size) -> Result<Rgba, Error> { -        let client = reqwest::Client::new(); - -        let bytes = client -            .get(match size { -                Size::Original => self.url, -                Size::Thumbnail { width } => self -                    .url -                    .split("/") -                    .map(|part| { -                        if part.starts_with("width=") { -                            format!("width={}", width * 2) // High DPI -                        } else { -                            part.to_owned() -                        } -                    }) -                    .collect::<Vec<_>>() -                    .join("/"), +    pub fn download(self, size: Size) -> impl Straw<Rgba, Blurhash, Error> { +        sipper(move |mut sender| async move { +            let client = reqwest::Client::new(); + +            if let Size::Thumbnail { width, height } = size { +                let image = self.clone(); + +                drop(task::spawn(async move { +                    if let Ok(blurhash) = image.blurhash(width, height).await { +                        sender.send(blurhash).await; +                    } +                })); +            } + +            let bytes = client +                .get(match size { +                    Size::Original => self.url, +                    Size::Thumbnail { width, .. } => self +                        .url +                        .split("/") +                        .map(|part| { +                            if part.starts_with("width=") { +                                format!("width={}", width * 2) // High DPI +                            } else { +                                part.to_owned() +                            } +                        }) +                        .collect::<Vec<_>>() +                        .join("/"), +                }) +                .send() +                .await? +                .error_for_status()? +                .bytes() +                .await?; + +            let image = task::spawn_blocking(move || { +                Ok::<_, Error>( +                    image::ImageReader::new(io::Cursor::new(bytes)) +                        .with_guessed_format()? +                        .decode()? +                        .to_rgba8(), +                )              }) -            .send() -            .await? -            .error_for_status()? -            .bytes() -            .await?; +            .await??; -        let image = task::spawn_blocking(move || { -            Ok::<_, Error>( -                image::ImageReader::new(io::Cursor::new(bytes)) -                    .with_guessed_format()? -                    .decode()? -                    .to_rgba8(), -            ) -        }) -        .await??; - -        Ok(Rgba { -            width: image.width(), -            height: image.height(), -            pixels: Bytes::from(image.into_raw()), +            Ok(Rgba { +                width: image.width(), +                height: image.height(), +                pixels: Bytes::from(image.into_raw()), +            })          })      }  } @@ -106,6 +121,11 @@ impl Image {  )]  pub struct Id(u32); +#[derive(Debug, Clone)] +pub struct Blurhash { +    pub rgba: Rgba, +} +  #[derive(Clone)]  pub struct Rgba {      pub width: u32, @@ -125,7 +145,7 @@ impl fmt::Debug for Rgba {  #[derive(Debug, Clone, Copy)]  pub enum Size {      Original, -    Thumbnail { width: u32 }, +    Thumbnail { width: u32, height: u32 },  }  #[derive(Debug, Clone)] diff --git a/examples/gallery/src/main.rs b/examples/gallery/src/main.rs index ab22679d..abafaf2d 100644 --- a/examples/gallery/src/main.rs +++ b/examples/gallery/src/main.rs @@ -14,7 +14,8 @@ use iced::widget::{  };  use iced::window;  use iced::{ -    color, Animation, ContentFit, Element, Fill, Subscription, Task, Theme, +    color, Animation, ContentFit, Element, Fill, Function, Subscription, Task, +    Theme,  };  use std::collections::HashMap; @@ -40,7 +41,7 @@ enum Message {      ImageDownloaded(Result<Rgba, Error>),      ThumbnailDownloaded(Id, Result<Rgba, Error>),      ThumbnailHovered(Id, bool), -    BlurhashDecoded(Id, Result<Rgba, Error>), +    BlurhashDecoded(Id, civitai::Blurhash),      Open(Id),      Close,      Animate(Instant), @@ -94,18 +95,14 @@ impl Gallery {                      return Task::none();                  }; -                Task::batch(vec![ -                    Task::perform( -                        image.clone().blurhash(Preview::WIDTH, Preview::HEIGHT), -                        move |result| Message::BlurhashDecoded(id, result), -                    ), -                    Task::perform( -                        image.download(Size::Thumbnail { -                            width: Preview::WIDTH, -                        }), -                        move |result| Message::ThumbnailDownloaded(id, result), -                    ), -                ]) +                Task::sip( +                    image.download(Size::Thumbnail { +                        width: Preview::WIDTH, +                        height: Preview::HEIGHT, +                    }), +                    Message::BlurhashDecoded.with(id), +                    Message::ThumbnailDownloaded.with(id), +                )              }              Message::ImageDownloaded(Ok(rgba)) => {                  self.viewer.show(rgba); @@ -131,9 +128,11 @@ impl Gallery {                  Task::none()              } -            Message::BlurhashDecoded(id, Ok(rgba)) => { +            Message::BlurhashDecoded(id, blurhash) => {                  if !self.previews.contains_key(&id) { -                    let _ = self.previews.insert(id, Preview::loading(rgba)); +                    let _ = self +                        .previews +                        .insert(id, Preview::loading(blurhash.rgba));                  }                  Task::none() @@ -167,8 +166,7 @@ impl Gallery {              }              Message::ImagesListed(Err(error))              | Message::ImageDownloaded(Err(error)) -            | Message::ThumbnailDownloaded(_, Err(error)) -            | Message::BlurhashDecoded(_, Err(error)) => { +            | Message::ThumbnailDownloaded(_, Err(error)) => {                  dbg!(error);                  Task::none() | 
