Skip to content

Commit

Permalink
feat: Loader component (#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
marc2332 committed Mar 21, 2023
1 parent a162523 commit 59df928
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 13 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions components/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ freya-elements = { path = "../elements", version = "0.1.0" }
freya-node-state = { path = "../state", version = "0.1.0" }
freya-hooks = { path = "../hooks", version = "0.1.0" }
open = "1"
tokio = { version = "1.23.0", features = ["sync", "rt-multi-thread", "time"] }

[dev-dependencies]
freya = { path = "../freya", version = "0.1.0" }
2 changes: 2 additions & 0 deletions components/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod button;
mod dropdown;
mod external_link;
mod input;
mod loader;
mod router_link;
mod scroll_views;
mod slider;
Expand All @@ -18,6 +19,7 @@ pub use button::*;
pub use dropdown::*;
pub use external_link::*;
pub use input::*;
pub use loader::*;
pub use router_link::*;
pub use scroll_views::*;
pub use slider::*;
Expand Down
53 changes: 53 additions & 0 deletions components/src/loader.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use std::time::Duration;

use dioxus::prelude::*;
use freya_elements as dioxus_elements;
use freya_hooks::use_get_theme;
use tokio::time::interval;

/// [`Loader`] component properties. Currently empty.
#[derive(Props, PartialEq)]
pub struct LoaderProps {}

/// `Loader` component.
///
/// # Props
/// See [`LoaderProps`].
///
/// # Styling
/// Inherits the [`LoaderTheme`](freya_hooks::LoaderTheme) theme.
///
#[allow(non_snake_case)]
pub fn Loader(cx: Scope<LoaderProps>) -> Element {
let theme = use_get_theme(cx);
let degrees = use_state(cx, || 0);

let loader_theme = theme.loader;

use_effect(cx, (), move |_| {
to_owned![degrees];
async move {
let mut ticker = interval(Duration::from_millis(28));
loop {
ticker.tick().await;
if *degrees.get() > 360 {
degrees.set(0);
} else {
degrees += 10;
}
}
}
});

render!(svg {
rotate: "{degrees}",
width: "31",
height: "31",
svg_content: r#"
<svg width="31" height="31" viewBox="0 0 31 31" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.5235 27.6652C22.2292 27.6652 27.6652 22.2292 27.6652 15.5235C27.6652 8.81783 22.2292 3.38182 15.5235 3.38182C8.81783 3.38182 3.38182 8.81783 3.38182 15.5235C3.38182 22.2292 8.81783 27.6652 15.5235 27.6652Z" stroke="{loader_theme.primary_color}" stroke-width="4"/>
<path d="M27.6652 15.5235C27.6652 8.81859 22.2284 3.38182 15.5235 3.38182" stroke="{loader_theme.secondary_color}" stroke-width="4"/>
</svg>
"#
})
}
53 changes: 40 additions & 13 deletions examples/app_dog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
windows_subsystem = "windows"
)]

use std::time::Duration;

use freya::prelude::*;
use reqwest::Url;
use serde::Deserialize;
use tokio::time::sleep;

fn main() {
launch(app);
Expand All @@ -30,15 +33,28 @@ async fn fetch_image(url: Url) -> Option<Vec<u8>> {
Some(data.to_vec())
}

#[derive(PartialEq)]
pub enum ImageStatus {
Loading,
Stopped,
Loaded,
}

fn app(cx: Scope) -> Element {
let bytes = use_state(cx, || None);
let status = use_state(cx, || ImageStatus::Stopped);
let image_bytes = use_state::<Option<Vec<u8>>>(cx, || None);

let fetch = move || {
to_owned![bytes];
to_owned![image_bytes, status];
cx.spawn(async move {
if let Some(url) = fetch_random_dog().await {
if let Some(doggo) = fetch_image(url).await {
bytes.set(Some(doggo))
status.set(ImageStatus::Loading);
let img = fetch_image(url).await;
sleep(Duration::from_millis(1000)).await;
if let Some(img) = img {
// Image loaded
image_bytes.set(Some(img));
status.set(ImageStatus::Loaded)
}
}
})
Expand All @@ -53,21 +69,32 @@ fn app(cx: Scope) -> Element {
width: "100%",
height: "calc(100% - 58)",
radius: "25",
bytes.as_ref().map(|bytes| {
let image_data = bytes_to_data(cx, bytes);
render!{
image {
width: "100%",
height: "100%",
image_data: image_data
}
display: "center",
direction: "both",
if *status.get() == ImageStatus::Loading {
rsx!(
Loader {}
)
}else if *status.get() == ImageStatus::Loaded {
rsx!{
image_bytes.as_ref().map(|bytes| {
let image_data = bytes_to_data(cx, bytes);
rsx!(
image {
width: "100%",
height: "100%",
image_data: image_data
}
)
})
}
})
}
}
container {
padding: "10",
height: "58",
width: "100%",
direction: "horizontal",
Button {
onclick: move |_| fetch(),
label {
Expand Down
16 changes: 16 additions & 0 deletions hooks/src/use_theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ pub struct AccordionTheme {
pub background: &'static str,
}

/// Theming properties for Loader component.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct LoaderTheme {
pub primary_color: &'static str,
pub secondary_color: &'static str,
}

/// Theming properties for Themes.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Theme {
Expand All @@ -122,6 +129,7 @@ pub struct Theme {
pub dropdown: DropdownTheme,
pub dropdown_item: DropdownItemTheme,
pub accordion: AccordionTheme,
pub loader: LoaderTheme,
}

/// `Light` theme
Expand Down Expand Up @@ -179,6 +187,10 @@ pub const LIGHT_THEME: Theme = Theme {
color: "white",
background: "rgb(30, 30, 30)",
},
loader: LoaderTheme {
primary_color: "rgb(50, 50, 50)",
secondary_color: "rgb(150, 150, 150)",
},
};

/// `Dark` theme
Expand Down Expand Up @@ -230,4 +242,8 @@ pub const DARK_THEME: Theme = Theme {
color: "black",
background: "rgb(215, 215, 215)",
},
loader: LoaderTheme {
primary_color: "rgb(150, 150, 150)",
secondary_color: "rgb(255, 255, 255)",
},
};

0 comments on commit 59df928

Please sign in to comment.