async.rs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. //! Render a bunch of doggos!
  2. //!
  3. use std::collections::HashMap;
  4. use dioxus::prelude::*;
  5. fn main() {
  6. dioxus::desktop::launch(app);
  7. }
  8. #[derive(Debug, Clone, PartialEq, serde::Deserialize)]
  9. struct ListBreeds {
  10. message: HashMap<String, Vec<String>>,
  11. }
  12. fn app(cx: Scope) -> Element {
  13. let fut = use_future(&cx, || async move {
  14. reqwest::get("https://dog.ceo/api/breeds/list/all")
  15. .await
  16. .unwrap()
  17. .json::<ListBreeds>()
  18. .await
  19. });
  20. let selected_breed = use_state(&cx, || None);
  21. match fut.value() {
  22. Some(Ok(breeds)) => cx.render(rsx! {
  23. div {
  24. h1 {"Select a dog breed!"}
  25. div { display: "flex",
  26. ul { flex: "50%",
  27. breeds.message.keys().map(|breed| rsx!(
  28. li {
  29. button {
  30. onclick: move |_| selected_breed.set(Some(breed.clone())),
  31. "{breed}"
  32. }
  33. }
  34. ))
  35. }
  36. div { flex: "50%",
  37. match &*selected_breed {
  38. Some(breed) => rsx!( Breed { breed: breed.clone() } ),
  39. None => rsx!("No Breed selected"),
  40. }
  41. }
  42. }
  43. }
  44. }),
  45. Some(Err(e)) => cx.render(rsx! {
  46. div { "Error fetching breeds" }
  47. }),
  48. None => cx.render(rsx! {
  49. div { "Loading dogs..." }
  50. }),
  51. }
  52. }
  53. #[inline_props]
  54. fn Breed(cx: Scope, breed: String) -> Element {
  55. #[derive(serde::Deserialize)]
  56. struct DogApi {
  57. message: String,
  58. }
  59. let endpoint = format!("https://dog.ceo/api/breed/{}/images/random", breed);
  60. let fut = use_future(&cx, || async move {
  61. reqwest::get(endpoint).await.unwrap().json::<DogApi>().await
  62. });
  63. cx.render(match fut.value() {
  64. Some(Ok(resp)) => rsx! {
  65. button {
  66. onclick: move |_| fut.restart(),
  67. "Click to fetch another doggo"
  68. }
  69. div {
  70. img {
  71. max_width: "500px",
  72. max_height: "500px",
  73. src: "{resp.message}",
  74. }
  75. }
  76. },
  77. Some(Err(_)) => rsx! { div { "loading dogs failed" } },
  78. None => rsx! { div { "loading dogs..." } },
  79. })
  80. }