1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| use yew::prelude::*;
#[derive(Clone, PartialEq)] struct Video { id: usize, title: String, speaker: String, url: String, }
#[derive(Properties, PartialEq)] struct VideosListProps { videos: Vec<Video>, on_click: Callback<Video>, }
#[derive(Clone, Properties, PartialEq)] struct VideosDetailsProps { video: Video, }
#[function_component(VideoDetails)] fn video_details(VideosDetailsProps { video }: &VideosDetailsProps) -> Html { html! { <div> <h3>{ video.title.clone() }</h3> <img src="https://via.placeholder.com/640x360.png?text=Video+Player+Placeholder" alt="video thumbnail" /> </div> } }
#[function_component(VideosList)] fn videos_list(VideosListProps { videos, on_click }: &VideosListProps) -> Html { videos .iter() .map(|video| { let on_video_select = { let on_click = on_click.clone(); let video = video.clone(); Callback::from(move |_| on_click.emit(video.clone())) }; html! { <p onclick={on_video_select} style="cursor: pointer;">{format!("{}: {}", video.speaker, video.title)}</p> } }) .collect() }
#[function_component(App)] pub fn app() -> Html { let videos = vec![ Video { id: 1, title: "Building and breaking things".to_string(), speaker: "John Doe".to_string(), url: "https://youtu.be/PsaFVLr8t4E".to_string(), }, Video { id: 2, title: "The development process".to_string(), speaker: "Jane Smith".to_string(), url: "https://youtu.be/PsaFVLr8t4E".to_string(), }, Video { id: 3, title: "The Web 7.0".to_string(), speaker: "Matt Miller".to_string(), url: "https://youtu.be/PsaFVLr8t4E".to_string(), }, Video { id: 4, title: "Mouseless development".to_string(), speaker: "Tom Jerry".to_string(), url: "https://youtu.be/PsaFVLr8t4E".to_string(), }, ];
let selected_video = use_state(|| None);
let on_video_select = { let selected_video = selected_video.clone(); Callback::from(move |video: Video| selected_video.set(Some(video))) };
let details = selected_video.as_ref().map(|video| { html! { <VideoDetails video={video.clone()} /> } });
html! { <> <h1>{ "RustConf Explorer" }</h1> <div> <h3>{ "Videos to watch" }</h3> <VideosList videos={videos} on_click={on_video_select} /> </div> { for details } </> } }
|