use based::ui::primitives::space::Fraction; use based::ui::{prelude::*, AttrExtendable}; use based::{ auth::MaybeUser, format::format_date, request::{RequestContext, StringResponse}, }; use maud::{html, PreEscaped, Render}; use rocket::{get, State}; use crate::library::Video; use crate::yt_meta::YouTubeMeta; use crate::{ library::{history::VideoHistory, Library}, pages::components::video_element_wide, }; use super::components::render_page; #[get("/watch?<v>")] pub async fn watch_page( ctx: RequestContext, library: &State<Library>, v: String, user: MaybeUser, ) -> StringResponse { let video = if let Some(video) = library.get_video_by_id(&v).await { video } else { // TODO : Error handling library.get_video_by_youtube_id(&v).await.unwrap() }; if let Some(user) = user.user() { user.insert_history(video.id).await; } let youtube_meta = video.youtube_meta().await; let rec = build_rec(&library, &video).await; let content = Container( Margin( Screen::large(Flex(Nothing()).direction(Direction::Row)).on( Flex( Div().vanish() .push( Margin( Screen::large(Width(Fraction::_10on12, Nothing())).on( Div().push( Context(Aspect::video( Background(Colors::Black, Rounded( html! { video controls autoplay class="w-full h-full" { source src=(format!("/video/raw?v={}", video.id)) type="video/mp4" { "Your browser does not support the video" }; }; } ).size(Size::Large) ) )) ).push( Context(Margin(Padding( Background(Stone::_900, Rounded( Shadow::large( Div() .push( Text(&video.title)._2xl().semibold() ) .push_some(youtube_meta.as_ref(), |meta: &_| { Div().vanish() .push( Margin(Flex( Div().vanish().push( Margin(Text(&format_date(&meta.upload_date)).color(&Gray::_300)).bottom(ScreenValue::_4) ).push( Margin(Text(&format!("{} Views ﹣ {}", meta.views, format_date(&meta.upload_date))).color(&Gray::_300)).bottom(ScreenValue::_4) ) ).justify(Justify::Between).group()).top(ScreenValue::_2) ) .push( Link(&format!("https://www.youtube.com/watch?v={}", meta.id), Text("Watch on YouTube").color(&Red::_400) ) ).push( Margin(Text(&meta.description).bold().color(&Gray::_300).wrap(TextWrap::Pretty).whitespace(TextWhitespace::BreakSpaces)).bottom(ScreenValue::_2).top(ScreenValue::_2) ) } ) )).size(Size::Large) ) ).all(ScreenValue::_4)).top(ScreenValue::_8)) ) ) ).top(ScreenValue::_10) ).push( rec ) ).direction(Direction::Column).gap(ScreenValue::_6)) ).x(ScreenValue::auto).top(ScreenValue::_6) ).render(); render_page( ctx, content, &format!("{} - WatchDogs", video.title), user.into(), ) .await } pub async fn build_rec(library: &Library, video: &Video) -> PreEscaped<String> { let videos = library.get_directory_videos(&video.directory).await; let video_elements = html! { @for video in videos { (video_element_wide(&video).await); }; }; Margin(Width( Fraction::_1on3, Div() .id("recommendations") .push( Margin( Paragraph(Context( SpaceBetween( Flex(Div().vanish().push(Span("In ")).push(Link( &format!("/d/{}", video.directory), Text(&video.directory).color(&Blue::_500), ))) .group() .justify(Justify::Center), ) .x(ScreenValue::_2), )) .align(TextAlignment::Center) ._4xl() .extrabold(), ) .bottom(ScreenValue::_2), ) .push(video_elements), )) .top(ScreenValue::_8) .render() }