parent
09beb0bcc2
commit
bb61c16429
5 changed files with 108 additions and 60 deletions
|
@ -74,6 +74,7 @@ async fn launch() -> _ {
|
|||
routes![
|
||||
pages::assets::video_file,
|
||||
pages::assets::video_thumbnail,
|
||||
pages::assets::fav_icon,
|
||||
pages::index::search,
|
||||
pages::index::channel_page,
|
||||
pages::yt::yt_tags,
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
use rocket::{fs::NamedFile, get, State};
|
||||
use rocket::{
|
||||
fs::NamedFile,
|
||||
get,
|
||||
http::{ContentType, Status},
|
||||
State,
|
||||
};
|
||||
|
||||
use crate::library::Library;
|
||||
|
||||
|
@ -29,3 +34,11 @@ pub async fn video_thumbnail(v: &str, library: &State<Library>) -> Option<NamedF
|
|||
|
||||
NamedFile::open(format!("{thumbnail_path}.jpg")).await.ok()
|
||||
}
|
||||
|
||||
#[get("/favicon")]
|
||||
pub async fn fav_icon() -> (Status, (ContentType, &'static [u8])) {
|
||||
(
|
||||
Status::Ok,
|
||||
(ContentType::PNG, include_bytes!("../../src/icon.png")),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -28,6 +28,27 @@ impl<'r> FromRequest<'r> for HTMX {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn htmx_link(
|
||||
url: &str,
|
||||
class: &str,
|
||||
onclick: &str,
|
||||
content: PreEscaped<String>,
|
||||
) -> PreEscaped<String> {
|
||||
html!(
|
||||
a class=(class) onclick=(onclick) href=(url) hx-get=(url) hx-target="#main_content" hx-push-url="true" hx-swap="innerHTML" {
|
||||
(content);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
pub fn script(script: &str) -> PreEscaped<String> {
|
||||
html!(
|
||||
script {
|
||||
(PreEscaped(script))
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
pub fn shell(content: PreEscaped<String>, title: &str) -> PreEscaped<String> {
|
||||
html! {
|
||||
html {
|
||||
|
@ -38,11 +59,25 @@ pub fn shell(content: PreEscaped<String>, title: &str) -> PreEscaped<String> {
|
|||
meta name="viewport" content="width=device-width, initial-scale=1.0";
|
||||
};
|
||||
body class="bg-black text-white" {
|
||||
header class="bg-gray-800 text-white shadow-md py-2" {
|
||||
(script(include_str!("../scripts/header.js")));
|
||||
|
||||
div class="flex justify-start px-6" {
|
||||
|
||||
(htmx_link("/", "flex items-center space-x-2", "stopAllVideos()", html!(
|
||||
img src="/favicon" alt="Logo" class="w-10 h-10 rounded-md";
|
||||
span class="font-semibold text-xl" { "WatchDogs" };
|
||||
)))
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
div id="main_content" {
|
||||
(content)
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,8 +140,11 @@ pub fn format_number(num: i32) -> String {
|
|||
}
|
||||
|
||||
pub async fn video_element_wide(video: &mut Video) -> PreEscaped<String> {
|
||||
htmx_link(
|
||||
&format!("/watch?v={}", video.id),
|
||||
"flex items-center w-full p-4 bg-gray-900 shadow-lg rounded-lg overflow-hidden mb-2 mt-2",
|
||||
"stopAllVideos()",
|
||||
html!(
|
||||
a href=(format!("/watch?v={}", video.id)) class="flex items-center w-full p-4 bg-gray-900 shadow-lg rounded-lg overflow-hidden mb-2 mt-2" {
|
||||
div class="flex-shrink-0" {
|
||||
img width="480" src=(format!("/video/thumbnail?v={}", video.id)) alt="Video Thumbnail" class="w-48 h-32 object-cover rounded-md";
|
||||
};
|
||||
|
@ -133,13 +171,16 @@ pub async fn video_element_wide(video: &mut Video) -> PreEscaped<String> {
|
|||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn video_element(video: &mut Video) -> PreEscaped<String> {
|
||||
htmx_link(
|
||||
&format!("/watch?v={}", video.id),
|
||||
"max-w-sm mx-auto p-4 max-h-60 aspect-video",
|
||||
"stopAllVideos()",
|
||||
html!(
|
||||
a href=(format!("/watch?v={}", video.id)) class="max-w-sm mx-auto p-4 max-h-60 aspect-video" {
|
||||
div class="bg-gray-900 shadow-lg rounded-lg overflow-hidden" {
|
||||
div class="relative" {
|
||||
img width="480" src=(format!("/video/thumbnail?v={}", video.id)) alt="Video Thumbnail" class="w-full h-auto object-cover aspect-video";
|
||||
|
@ -156,23 +197,6 @@ pub async fn video_element(video: &mut Video) -> PreEscaped<String> {
|
|||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
pub fn header(query: &str) -> PreEscaped<String> {
|
||||
html!(
|
||||
header style="padding: 10px 0; display: flex; justify-content: space-between;" {
|
||||
a href="/" style="text-decoration: none; margin-left: 20px;" {
|
||||
div style="margin-right: 20px;display:flex;align-items: center" {
|
||||
img src="/icon" width="64" style="margin-top: -25px;margin-right: 15px;border-radius: 20%;";
|
||||
p style="font-size: 42px;" { "WatchDogs" };
|
||||
};
|
||||
};
|
||||
div style="width: 35px;" {};
|
||||
div style="flex-grow: 1; text-align: center;" {
|
||||
(search_bar(query));
|
||||
};
|
||||
};
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,10 @@ use rocket::{
|
|||
};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{library::Library, pages::components::video_element};
|
||||
use crate::{
|
||||
library::Library,
|
||||
pages::components::{htmx_link, video_element},
|
||||
};
|
||||
|
||||
use super::{
|
||||
api_response,
|
||||
|
@ -69,7 +72,7 @@ pub async fn index_page(htmx: HTMX, library: &State<Library>) -> (Status, (Conte
|
|||
h1 class="text-center text-4xl font-extrabold leading-tight mt-8" { "Directories:" };
|
||||
div class="flex flex-wrap p-10" {
|
||||
@for dir in library.get_directories().await {
|
||||
a class="px-3 py-2 m-2 bg-purple-500 text-white rounded-full cursor-pointer hover:bg-purple-600" href=(format!("/d/{dir}")) { (dir) };
|
||||
(htmx_link(&format!("/d/{dir}"), "px-3 py-2 m-2 bg-purple-500 text-white rounded-full cursor-pointer hover:bg-purple-600", "", html! { (dir) }));
|
||||
br;
|
||||
};
|
||||
};
|
||||
|
|
7
src/scripts/header.js
Normal file
7
src/scripts/header.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
function stopAllVideos() {
|
||||
const videos = document.querySelectorAll('video');
|
||||
|
||||
videos.forEach(video => {
|
||||
video.pause();
|
||||
});
|
||||
}
|
Loading…
Add table
Reference in a new issue