You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
4.6 KiB
HTML
168 lines
4.6 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>{{ username }}'s Videos</title>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
background: #111;
|
|
color: #eee;
|
|
text-align: center;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
h1 {
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.back-link {
|
|
display: inline-block;
|
|
margin: 10px;
|
|
color: #0af;
|
|
text-decoration: none;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
|
gap: 18px;
|
|
margin: 20px;
|
|
padding: 0 20px;
|
|
}
|
|
|
|
.video-card {
|
|
background: #222;
|
|
padding: 10px;
|
|
border-radius: 8px;
|
|
transition: transform 0.2s ease;
|
|
position: relative;
|
|
/* <-- allow overlay star positioning */
|
|
}
|
|
|
|
.video-card:hover {
|
|
transform: scale(1.03);
|
|
}
|
|
|
|
.thumb-link {
|
|
display: block;
|
|
position: relative;
|
|
}
|
|
|
|
.video-card img {
|
|
width: 100%;
|
|
border-radius: 5px;
|
|
cursor: pointer;
|
|
display: block;
|
|
}
|
|
|
|
.video-size {
|
|
margin-top: 8px;
|
|
font-size: 14px;
|
|
color: #bbb;
|
|
}
|
|
|
|
/* Favorite star */
|
|
.fav-btn {
|
|
position: absolute;
|
|
top: 12px;
|
|
right: 12px;
|
|
font-size: 1.2rem;
|
|
line-height: 1;
|
|
border: none;
|
|
background: rgba(0, 0, 0, 0.45);
|
|
color: #fff;
|
|
cursor: pointer;
|
|
padding: .25rem .45rem;
|
|
border-radius: 6px;
|
|
backdrop-filter: blur(2px);
|
|
}
|
|
|
|
.fav-btn[aria-pressed="true"] {
|
|
color: gold;
|
|
}
|
|
|
|
.fav-btn:hover {
|
|
transform: scale(1.05);
|
|
}
|
|
|
|
.pagination {
|
|
margin: 20px 0;
|
|
}
|
|
|
|
.pagination a {
|
|
color: #0af;
|
|
margin: 0 8px;
|
|
text-decoration: none;
|
|
font-size: 16px;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<h1>🎥 Videos for {{ username }}</h1>
|
|
<a href="/" class="back-link">⬅ Back to Dashboard</a>
|
|
|
|
<div class="grid">
|
|
{% for video in videos %}
|
|
<div class="video-card">
|
|
<div class="thumb-wrap">
|
|
<a class="thumb-link" href="/video/{{ video['video_id'] }}">
|
|
<img src="/{{ video.thumbnail }}" alt="Thumbnail">
|
|
</a>
|
|
|
|
<!-- Star overlay INSIDE the thumb-wrap so it sits on top of the image -->
|
|
<button class="fav-btn" data-video-id="{{ video.video_id }}"
|
|
aria-pressed="{{ 'true' if video.is_favorite else 'false' }}"
|
|
title="{{ 'Unfavorite' if video.is_favorite else 'Favorite' }}">
|
|
{{ '★' if video.is_favorite else '☆' }}
|
|
</button>
|
|
</div>
|
|
|
|
<p class="video-size">{{ "%.2f"|format(video.size/1024) }} GB</p>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<div class="pagination">
|
|
{% if page > 1 %}
|
|
<a href="?page={{ page-1 }}">⬅ Prev</a>
|
|
{% endif %}
|
|
<span>Page {{ page }} / {{ total_pages }}</span>
|
|
{% if page < total_pages %} <a href="?page={{ page+1 }}">Next ➡</a>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<script>
|
|
// Handle favorite toggles (and prevent navigating when clicking the star)
|
|
document.addEventListener('click', async (e) => {
|
|
const btn = e.target.closest('.fav-btn');
|
|
if (!btn) return;
|
|
|
|
// prevent the underlying link click if someone clicks near the corner
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
const vid = btn.dataset.videoId;
|
|
try {
|
|
const res = await fetch(`/api/fav/toggle/${encodeURIComponent(vid)}`, {
|
|
method: 'POST'
|
|
});
|
|
const data = await res.json();
|
|
if (!res.ok || !data.ok) throw new Error(data.error || 'Failed');
|
|
|
|
const isFav = data.is_favorite;
|
|
btn.textContent = isFav ? '★' : '☆';
|
|
btn.setAttribute('aria-pressed', isFav ? 'true' : 'false');
|
|
btn.title = isFav ? 'Unfavorite' : 'Favorite';
|
|
} catch (err) {
|
|
alert('Could not toggle favorite. ' + (err?.message || ''));
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
|
|
</html> |