dog_app.rs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #![allow(non_snake_case)]
  2. //! Render a bunch of doggos!
  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 breed = use_state(&cx, || None);
  14. let breeds = use_future(&cx, (), |_| async move {
  15. reqwest::get("https://dog.ceo/api/breeds/list/all")
  16. .await
  17. .unwrap()
  18. .json::<ListBreeds>()
  19. .await
  20. });
  21. match breeds.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(|cur_breed| rsx!(
  28. li {
  29. button {
  30. onclick: move |_| breed.set(Some(cur_breed.clone())),
  31. "{cur_breed}"
  32. }
  33. }
  34. ))
  35. }
  36. div { flex: "50%",
  37. match breed.get() {
  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! { div { "Error fetching breeds" } }),
  46. None => cx.render(rsx! { div { "Loading dogs..." } }),
  47. }
  48. }
  49. #[derive(serde::Deserialize, Debug)]
  50. struct DogApi {
  51. message: String,
  52. }
  53. #[inline_props]
  54. fn Breed(cx: Scope, breed: String) -> Element {
  55. let fut = use_future(&cx, (breed,), |(breed,)| async move {
  56. reqwest::get(format!("https://dog.ceo/api/breed/{}/images/random", breed))
  57. .await
  58. .unwrap()
  59. .json::<DogApi>()
  60. .await
  61. });
  62. cx.render(match fut.value() {
  63. Some(Ok(resp)) => rsx! {
  64. button {
  65. onclick: move |_| fut.restart(),
  66. "Click to fetch another doggo"
  67. }
  68. div {
  69. img {
  70. max_width: "500px",
  71. max_height: "500px",
  72. src: "{resp.message}",
  73. }
  74. }
  75. },
  76. Some(Err(_)) => rsx! { div { "loading dogs failed" } },
  77. None => rsx! { div { "loading dogs..." } },
  78. })
  79. }