1
0

dog_app.rs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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 breeds = 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 (breed, set_breed) = use_state(&cx, || None);
  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(|breed| rsx!(
  28. li {
  29. button {
  30. onclick: move |_| set_breed(Some(breed.clone())),
  31. "{breed}"
  32. }
  33. }
  34. ))
  35. }
  36. div { flex: "50%",
  37. match 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, Debug)]
  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. let (name, set_name) = use_state(&cx, || breed.clone());
  64. if name != breed {
  65. set_name(breed.clone());
  66. fut.restart();
  67. }
  68. cx.render(match fut.value() {
  69. Some(Ok(resp)) => rsx! {
  70. button {
  71. onclick: move |_| fut.restart(),
  72. "Click to fetch another doggo"
  73. }
  74. div {
  75. img {
  76. max_width: "500px",
  77. max_height: "500px",
  78. src: "{resp.message}",
  79. }
  80. }
  81. },
  82. Some(Err(_)) => rsx! { div { "loading dogs failed" } },
  83. None => rsx! { div { "loading dogs..." } },
  84. })
  85. }