dog_app.rs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. use dioxus::prelude::*;
  2. use std::collections::HashMap;
  3. fn main() {
  4. launch(app);
  5. }
  6. fn app() -> Element {
  7. let mut breed = use_signal(|| "deerhound".to_string());
  8. let breed_list = use_resource(|| async move {
  9. let list = reqwest::get("https://dog.ceo/api/breeds/list/all")
  10. .await
  11. .unwrap()
  12. .json::<ListBreeds>()
  13. .await;
  14. let Ok(breeds) = list else {
  15. return rsx! { "error fetching breeds" };
  16. };
  17. rsx! {
  18. for cur_breed in breeds.message.keys().take(10).cloned() {
  19. li { key: "{cur_breed}",
  20. button { onclick: move |_| breed.set(cur_breed.clone()),
  21. "{cur_breed}"
  22. }
  23. }
  24. }
  25. }
  26. });
  27. let Some(breed_list) = breed_list.value().cloned() else {
  28. return rsx! { "loading breeds..." };
  29. };
  30. rsx! {
  31. h1 { "Select a dog breed!" }
  32. div { height: "500px", display: "flex",
  33. ul { flex: "50%", {breed_list} }
  34. div { flex: "50%", BreedPic { breed } }
  35. }
  36. }
  37. }
  38. #[component]
  39. fn BreedPic(breed: Signal<String>) -> Element {
  40. let fut = use_resource(|| async move {
  41. reqwest::get(format!("https://dog.ceo/api/breed/{breed}/images/random"))
  42. .await
  43. .unwrap()
  44. .json::<DogApi>()
  45. .await
  46. });
  47. match fut.value().read().as_ref() {
  48. Some(Ok(resp)) => rsx! {
  49. div {
  50. button { onclick: move |_| fut.restart(), "Click to fetch another doggo" }
  51. img { max_width: "500px", max_height: "500px", src: "{resp.message}" }
  52. }
  53. },
  54. _ => rsx! { "loading image..." },
  55. }
  56. }
  57. #[derive(Debug, Clone, PartialEq, serde::Deserialize)]
  58. struct ListBreeds {
  59. message: HashMap<String, Vec<String>>,
  60. }
  61. #[derive(serde::Deserialize, Debug)]
  62. struct DogApi {
  63. message: String,
  64. }