2025-02-09 07:09:20 +01:00
|
|
|
use based::ui::components::Shell;
|
2025-01-17 19:35:35 +01:00
|
|
|
use based::ui::primitives::space::Fraction;
|
|
|
|
use based::ui::{prelude::*, AttrExtendable};
|
2024-12-18 20:09:07 +01:00
|
|
|
use based::{
|
|
|
|
auth::MaybeUser,
|
|
|
|
format::format_date,
|
|
|
|
request::{RequestContext, StringResponse},
|
2024-12-14 00:24:10 +01:00
|
|
|
};
|
2025-01-17 19:35:35 +01:00
|
|
|
use maud::{html, PreEscaped, Render};
|
2024-12-18 20:09:07 +01:00
|
|
|
use rocket::{get, State};
|
2024-12-14 00:24:10 +01:00
|
|
|
|
2025-02-09 07:09:20 +01:00
|
|
|
use crate::check_private;
|
|
|
|
use crate::config::Config;
|
2025-01-17 19:35:35 +01:00
|
|
|
use crate::library::Video;
|
2024-12-22 20:19:52 +01:00
|
|
|
use crate::{
|
|
|
|
library::{history::VideoHistory, Library},
|
|
|
|
pages::components::video_element_wide,
|
|
|
|
};
|
2024-12-14 00:24:10 +01:00
|
|
|
|
2024-12-18 19:24:38 +01:00
|
|
|
use super::components::render_page;
|
2024-12-14 00:24:10 +01:00
|
|
|
|
|
|
|
#[get("/watch?<v>")]
|
|
|
|
pub async fn watch_page(
|
2024-12-18 19:24:38 +01:00
|
|
|
ctx: RequestContext,
|
2024-12-14 00:24:10 +01:00
|
|
|
library: &State<Library>,
|
|
|
|
v: String,
|
2024-12-18 20:09:07 +01:00
|
|
|
user: MaybeUser,
|
2025-02-09 07:09:20 +01:00
|
|
|
conf: &State<Config>,
|
|
|
|
shell: &State<Shell>,
|
2024-12-18 20:09:07 +01:00
|
|
|
) -> StringResponse {
|
2025-02-09 07:09:20 +01:00
|
|
|
check_private!(conf, user, shell, ctx);
|
|
|
|
|
2024-12-14 00:24:10 +01:00
|
|
|
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()
|
|
|
|
};
|
|
|
|
|
2024-12-22 20:19:52 +01:00
|
|
|
if let Some(user) = user.user() {
|
|
|
|
user.insert_history(video.id).await;
|
|
|
|
}
|
|
|
|
|
2025-01-17 19:35:35 +01:00
|
|
|
let youtube_meta = video.youtube_meta().await;
|
|
|
|
let rec = build_rec(&library, &video).await;
|
2024-12-14 23:33:47 +01:00
|
|
|
|
2025-02-09 07:09:20 +01:00
|
|
|
let content =
|
2025-01-17 19:35:35 +01:00
|
|
|
Margin(
|
|
|
|
Screen::large(Flex(Nothing()).direction(Direction::Row)).on(
|
|
|
|
Flex(
|
|
|
|
Div().vanish()
|
|
|
|
.push(
|
|
|
|
Screen::large(Width(Fraction::_10on12, Nothing())).on(
|
|
|
|
Div().push(
|
2025-01-22 19:10:33 +01:00
|
|
|
Context(Aspect::Video(
|
2025-01-21 14:12:43 +01:00
|
|
|
Background(
|
2025-01-17 19:35:35 +01:00
|
|
|
Rounded(
|
2025-01-22 19:57:43 +01:00
|
|
|
Video().controls().autoplay().width(1080).add_src(
|
2025-01-22 19:10:33 +01:00
|
|
|
Source(&format!("/video/raw?v={}", video.id), Some("video/mp4".to_string()))
|
2025-02-09 07:09:20 +01:00
|
|
|
).poster(&format!("/video/thumbnail?v={}", video.id))
|
2025-01-17 19:35:35 +01:00
|
|
|
).size(Size::Large)
|
2025-01-21 14:12:43 +01:00
|
|
|
).color(Colors::Black)
|
2025-01-17 19:35:35 +01:00
|
|
|
))
|
|
|
|
).push(
|
|
|
|
Context(Margin(Padding(
|
2025-01-21 14:12:43 +01:00
|
|
|
Background(
|
2025-01-17 19:35:35 +01:00
|
|
|
Rounded(
|
|
|
|
Shadow::large(
|
|
|
|
Div()
|
|
|
|
.push(
|
|
|
|
Text(&video.title)._2xl().semibold()
|
|
|
|
)
|
|
|
|
.push_some(youtube_meta.as_ref(), |meta: &_| {
|
2025-01-21 14:12:43 +01:00
|
|
|
Div()
|
2025-01-17 19:35:35 +01:00
|
|
|
.push(
|
2025-01-22 19:57:43 +01:00
|
|
|
Context(Margin(Flex(
|
2025-01-17 19:35:35 +01:00
|
|
|
Div().vanish().push(
|
2025-01-22 19:57:43 +01:00
|
|
|
Margin(Text(&meta.uploader_name).color(&Gray::_300).xl()).bottom(ScreenValue::_4)
|
2025-01-17 19:35:35 +01:00
|
|
|
).push(
|
2025-01-22 19:57:43 +01:00
|
|
|
Margin(Text(&format!("{} Views ﹣ {}", meta.views, format_date(&meta.upload_date))).color(&Gray::_300).xl()).bottom(ScreenValue::_4)
|
2025-01-17 19:35:35 +01:00
|
|
|
)
|
2025-01-22 19:57:43 +01:00
|
|
|
).justify(Justify::Between).group()).top(ScreenValue::_2))
|
2025-01-17 19:35:35 +01:00
|
|
|
)
|
|
|
|
.push(
|
2025-01-22 19:57:43 +01:00
|
|
|
Context(Link(&format!("https://www.youtube.com/watch?v={}", meta.id),
|
|
|
|
Text("Watch on YouTube").color(&Red::_400))
|
2025-01-17 19:35:35 +01:00
|
|
|
)
|
|
|
|
).push(
|
2025-01-22 19:57:43 +01:00
|
|
|
Context(Margin(
|
|
|
|
Text(meta.description.trim_ascii()).sm().color(&Gray::_300).wrap(TextWrap::Pretty).whitespace(TextWhitespace::BreakSpaces)
|
|
|
|
).y(ScreenValue::_2).top(ScreenValue::_6)
|
|
|
|
))
|
2025-01-17 19:35:35 +01:00
|
|
|
}
|
|
|
|
)
|
|
|
|
)).size(Size::Large)
|
2025-01-21 14:12:43 +01:00
|
|
|
).color(Stone::_900)
|
2025-01-22 19:57:43 +01:00
|
|
|
).all(ScreenValue::_4)).top(ScreenValue::_8))
|
2025-01-17 19:35:35 +01:00
|
|
|
)
|
|
|
|
)
|
|
|
|
).push(
|
|
|
|
rec
|
|
|
|
)
|
|
|
|
).direction(Direction::Column).gap(ScreenValue::_6))
|
2025-02-09 07:09:20 +01:00
|
|
|
).x(ScreenValue::_10).top(ScreenValue::_6).render();
|
2024-12-14 00:24:10 +01:00
|
|
|
|
2024-12-18 19:24:38 +01:00
|
|
|
render_page(
|
2025-02-09 07:09:20 +01:00
|
|
|
&shell,
|
2024-12-18 19:24:38 +01:00
|
|
|
ctx,
|
|
|
|
content,
|
|
|
|
&format!("{} - WatchDogs", video.title),
|
2024-12-18 20:09:07 +01:00
|
|
|
user.into(),
|
2024-12-18 19:24:38 +01:00
|
|
|
)
|
|
|
|
.await
|
2024-12-14 00:24:10 +01:00
|
|
|
}
|
2025-01-17 19:35:35 +01:00
|
|
|
|
|
|
|
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);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2025-01-22 19:57:43 +01:00
|
|
|
Width(
|
2025-01-17 19:35:35 +01:00
|
|
|
Fraction::_1on3,
|
|
|
|
Div()
|
|
|
|
.id("recommendations")
|
|
|
|
.push(
|
|
|
|
Margin(
|
|
|
|
Paragraph(Context(
|
|
|
|
SpaceBetween(
|
2025-02-09 07:09:20 +01:00
|
|
|
Flex(
|
|
|
|
Div()
|
|
|
|
.vanish()
|
|
|
|
.push(Span("In ")._4xl().extrabold())
|
|
|
|
.push(Link(
|
|
|
|
&format!("/d/{}", video.directory),
|
|
|
|
Text(&video.directory)
|
|
|
|
.color(&Blue::_500)
|
|
|
|
._4xl()
|
|
|
|
.extrabold(),
|
|
|
|
)),
|
|
|
|
)
|
2025-01-17 19:35:35 +01:00
|
|
|
.group()
|
|
|
|
.justify(Justify::Center),
|
|
|
|
)
|
|
|
|
.x(ScreenValue::_2),
|
|
|
|
))
|
|
|
|
.align(TextAlignment::Center)
|
|
|
|
._4xl()
|
|
|
|
.extrabold(),
|
|
|
|
)
|
|
|
|
.bottom(ScreenValue::_2),
|
|
|
|
)
|
|
|
|
.push(video_elements),
|
2025-01-22 19:57:43 +01:00
|
|
|
)
|
2025-01-17 19:35:35 +01:00
|
|
|
.render()
|
|
|
|
}
|