UI Polish: Mobile Categories, Lazy Loading, and CSS Fixes
This commit is contained in:
parent
665a8209e4
commit
4472f6852a
5 changed files with 304 additions and 139 deletions
|
|
@ -58,6 +58,8 @@ html {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
background-color: var(--yt-bg-primary);
|
||||||
|
/* Fix white bar issue */
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
|
@ -66,6 +68,7 @@ body {
|
||||||
color: var(--yt-text-primary);
|
color: var(--yt-text-primary);
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
|
@ -194,7 +197,7 @@ button {
|
||||||
.yt-search-input {
|
.yt-search-input {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
background: var(--yt-bg-primary);
|
background: var(--yt-bg-secondary);
|
||||||
border: 1px solid var(--yt-border);
|
border: 1px solid var(--yt-border);
|
||||||
border-right: none;
|
border-right: none;
|
||||||
border-radius: 20px 0 0 20px;
|
border-radius: 20px 0 0 20px;
|
||||||
|
|
@ -371,6 +374,7 @@ button {
|
||||||
padding: 12px 0 24px;
|
padding: 12px 0 24px;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
scrollbar-width: none;
|
scrollbar-width: none;
|
||||||
|
flex-wrap: nowrap;
|
||||||
-ms-overflow-style: none;
|
-ms-overflow-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -430,7 +434,12 @@ button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
transition: transform 0.3s ease;
|
opacity: 0;
|
||||||
|
transition: opacity 0.5s ease, transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-thumbnail.loaded {
|
||||||
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.yt-video-card:hover .yt-thumbnail {
|
.yt-video-card:hover .yt-thumbnail {
|
||||||
|
|
@ -819,11 +828,28 @@ button {
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.yt-header-center {
|
.yt-header-center {
|
||||||
display: none;
|
display: flex;
|
||||||
|
/* Show search on mobile */
|
||||||
|
margin: 0 8px;
|
||||||
|
max-width: none;
|
||||||
|
flex: 1;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-search-input {
|
||||||
|
padding: 0 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
border-radius: 18px 0 0 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-search-btn {
|
||||||
|
width: 48px;
|
||||||
|
border-radius: 0 18px 18px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.yt-mobile-search {
|
.yt-mobile-search {
|
||||||
display: flex;
|
display: none;
|
||||||
|
/* Hide icon since bar is visible */
|
||||||
}
|
}
|
||||||
|
|
||||||
.yt-signin-text {
|
.yt-signin-text {
|
||||||
|
|
@ -831,8 +857,9 @@ button {
|
||||||
}
|
}
|
||||||
|
|
||||||
.yt-video-grid {
|
.yt-video-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: repeat(2, 1fr);
|
||||||
gap: 0;
|
gap: 8px;
|
||||||
|
padding: 0 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.yt-video-card {
|
.yt-video-card {
|
||||||
|
|
@ -851,6 +878,10 @@ button {
|
||||||
.yt-categories {
|
.yt-categories {
|
||||||
padding: 8px 0 16px;
|
padding: 8px 0 16px;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
overflow-x: auto;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.yt-category-pill {
|
.yt-category-pill {
|
||||||
|
|
@ -1170,4 +1201,131 @@ button {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Floating Back Button */
|
||||||
|
.yt-floating-back {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 24px;
|
||||||
|
right: 24px;
|
||||||
|
width: 56px;
|
||||||
|
height: 56px;
|
||||||
|
background: var(--yt-accent-blue);
|
||||||
|
color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: none;
|
||||||
|
/* Hidden on desktop */
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 20px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||||
|
z-index: 2000;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.2s, background 0.2s;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-floating-back:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
background: #2c95dd;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.yt-floating-back {
|
||||||
|
display: flex;
|
||||||
|
/* Show only on mobile */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile V2 Overrides */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.yt-video-grid {
|
||||||
|
grid-template-columns: repeat(2, 1fr) !important;
|
||||||
|
gap: 8px !important;
|
||||||
|
padding: 0 4px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-video-card {
|
||||||
|
padding: 4px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-categories {
|
||||||
|
display: flex !important;
|
||||||
|
flex-wrap: nowrap !important;
|
||||||
|
grid-template-rows: none !important;
|
||||||
|
padding-right: 16px !important;
|
||||||
|
white-space: nowrap !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-floating-back {
|
||||||
|
background: var(--yt-accent-red) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-floating-back:active {
|
||||||
|
background: #cc0000 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile V4 Overrides - Pixel Perfect Polish */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
|
||||||
|
/* Optimize Categories */
|
||||||
|
.yt-categories {
|
||||||
|
padding: 8px 0 8px 8px !important;
|
||||||
|
/* Left padding for start, no right padding */
|
||||||
|
width: 100% !important;
|
||||||
|
mask-image: linear-gradient(to right, black 95%, transparent 100%);
|
||||||
|
-webkit-mask-image: linear-gradient(to right, black 95%, transparent 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-chip {
|
||||||
|
font-size: 12px !important;
|
||||||
|
padding: 6px 12px !important;
|
||||||
|
height: 30px !important;
|
||||||
|
border-radius: 6px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Maximize Thumbnails */
|
||||||
|
.yt-main {
|
||||||
|
padding: 0 !important;
|
||||||
|
/* Edge to edge */
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-video-grid {
|
||||||
|
gap: 1px !important;
|
||||||
|
/* Minimal gap */
|
||||||
|
padding: 0 !important;
|
||||||
|
background: var(--yt-bg-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-video-card,
|
||||||
|
.skeleton-card {
|
||||||
|
padding: 0 !important;
|
||||||
|
margin-bottom: 4px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-thumbnail-container,
|
||||||
|
.skeleton-thumb {
|
||||||
|
border-radius: 6px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-video-details {
|
||||||
|
padding: 6px 8px 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-video-title {
|
||||||
|
font-size: 13px !important;
|
||||||
|
line-height: 1.2 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reduce header padding to match */
|
||||||
|
.yt-header {
|
||||||
|
padding: 0 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Filter bar spacing */
|
||||||
|
.yt-filter-bar {
|
||||||
|
padding-left: 0 !important;
|
||||||
|
padding-right: 0 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -36,6 +36,31 @@ let currentPage = 1;
|
||||||
let isLoading = false;
|
let isLoading = false;
|
||||||
let hasMore = true; // Track if there are more videos to load
|
let hasMore = true; // Track if there are more videos to load
|
||||||
|
|
||||||
|
// --- Lazy Loading ---
|
||||||
|
const imageObserver = new IntersectionObserver((entries, observer) => {
|
||||||
|
entries.forEach(entry => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
const img = entry.target;
|
||||||
|
const src = img.getAttribute('data-src');
|
||||||
|
if (src) {
|
||||||
|
img.src = src;
|
||||||
|
img.onload = () => img.classList.add('loaded');
|
||||||
|
img.removeAttribute('data-src');
|
||||||
|
}
|
||||||
|
observer.unobserve(img);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, {
|
||||||
|
rootMargin: '50px 0px',
|
||||||
|
threshold: 0.1
|
||||||
|
});
|
||||||
|
|
||||||
|
window.observeImages = function () {
|
||||||
|
document.querySelectorAll('img[data-src]').forEach(img => {
|
||||||
|
imageObserver.observe(img);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// --- Infinite Scroll ---
|
// --- Infinite Scroll ---
|
||||||
function initInfiniteScroll() {
|
function initInfiniteScroll() {
|
||||||
const observer = new IntersectionObserver((entries) => {
|
const observer = new IntersectionObserver((entries) => {
|
||||||
|
|
@ -234,7 +259,7 @@ async function loadTrending(reset = true) {
|
||||||
|
|
||||||
card.innerHTML = `
|
card.innerHTML = `
|
||||||
<div class="yt-thumbnail-container">
|
<div class="yt-thumbnail-container">
|
||||||
<img class="yt-thumbnail" src="${video.thumbnail}" alt="${escapeHtml(video.title)}" loading="lazy">
|
<img class="yt-thumbnail" data-src="${video.thumbnail}" alt="${escapeHtml(video.title)}">
|
||||||
${video.duration ? `<span class="yt-duration">${video.duration}</span>` : ''}
|
${video.duration ? `<span class="yt-duration">${video.duration}</span>` : ''}
|
||||||
</div>
|
</div>
|
||||||
<div class="yt-video-details">
|
<div class="yt-video-details">
|
||||||
|
|
@ -255,6 +280,7 @@ async function loadTrending(reset = true) {
|
||||||
sectionDiv.appendChild(scrollContainer);
|
sectionDiv.appendChild(scrollContainer);
|
||||||
resultsArea.appendChild(sectionDiv);
|
resultsArea.appendChild(sectionDiv);
|
||||||
});
|
});
|
||||||
|
if (window.observeImages) window.observeImages();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -299,7 +325,7 @@ function displayResults(videos, append = false) {
|
||||||
card.style.width = '100%';
|
card.style.width = '100%';
|
||||||
card.style.maxWidth = '200px';
|
card.style.maxWidth = '200px';
|
||||||
card.innerHTML = `
|
card.innerHTML = `
|
||||||
<img src="${video.thumbnail}" class="yt-short-thumb" style="width:100%; aspect-ratio:9/16; height:auto;" loading="lazy">
|
<img data-src="${video.thumbnail}" class="yt-short-thumb" style="width:100%; aspect-ratio:9/16; height:auto;">
|
||||||
<p class="yt-short-title">${escapeHtml(video.title)}</p>
|
<p class="yt-short-title">${escapeHtml(video.title)}</p>
|
||||||
<p class="yt-short-views">${formatViews(video.view_count)} views</p>
|
<p class="yt-short-views">${formatViews(video.view_count)} views</p>
|
||||||
`;
|
`;
|
||||||
|
|
@ -308,7 +334,7 @@ function displayResults(videos, append = false) {
|
||||||
card.className = 'yt-video-card';
|
card.className = 'yt-video-card';
|
||||||
card.innerHTML = `
|
card.innerHTML = `
|
||||||
<div class="yt-thumbnail-container">
|
<div class="yt-thumbnail-container">
|
||||||
<img class="yt-thumbnail" src="${video.thumbnail}" alt="${escapeHtml(video.title)}" loading="lazy">
|
<img class="yt-thumbnail" data-src="${video.thumbnail}" alt="${escapeHtml(video.title)}">
|
||||||
${video.duration ? `<span class="yt-duration">${video.duration}</span>` : ''}
|
${video.duration ? `<span class="yt-duration">${video.duration}</span>` : ''}
|
||||||
</div>
|
</div>
|
||||||
<div class="yt-video-details">
|
<div class="yt-video-details">
|
||||||
|
|
@ -337,6 +363,8 @@ function displayResults(videos, append = false) {
|
||||||
});
|
});
|
||||||
resultsArea.appendChild(card);
|
resultsArea.appendChild(card);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (window.observeImages) window.observeImages();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format view count (YouTube style)
|
// Format view count (YouTube style)
|
||||||
|
|
@ -425,28 +453,51 @@ function initTheme() {
|
||||||
let savedTheme = localStorage.getItem('theme');
|
let savedTheme = localStorage.getItem('theme');
|
||||||
|
|
||||||
// If no saved preference, use Time of Day (Auto)
|
// If no saved preference, use Time of Day (Auto)
|
||||||
// Approximation: 6 AM to 6 PM is Light (Sunrise/Sunset)
|
|
||||||
if (!savedTheme) {
|
if (!savedTheme) {
|
||||||
const hour = new Date().getHours();
|
const hour = new Date().getHours();
|
||||||
savedTheme = (hour >= 6 && hour < 18) ? 'light' : 'dark';
|
savedTheme = (hour >= 6 && hour < 18) ? 'light' : 'dark';
|
||||||
}
|
}
|
||||||
|
|
||||||
document.documentElement.setAttribute('data-theme', savedTheme);
|
setTheme(savedTheme, false); // Initial set without saving (already saved or computed)
|
||||||
|
}
|
||||||
|
|
||||||
// Update toggle if exists
|
function setTheme(theme, save = true) {
|
||||||
const toggle = document.getElementById('themeToggle');
|
document.documentElement.setAttribute('data-theme', theme);
|
||||||
if (toggle) {
|
if (save) {
|
||||||
toggle.checked = savedTheme === 'dark';
|
localStorage.setItem('theme', theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update UI Buttons (if on settings page)
|
||||||
|
const btnLight = document.getElementById('themeBtnLight');
|
||||||
|
const btnDark = document.getElementById('themeBtnDark');
|
||||||
|
|
||||||
|
if (btnLight && btnDark) {
|
||||||
|
btnLight.classList.remove('active');
|
||||||
|
btnDark.classList.remove('active');
|
||||||
|
|
||||||
|
if (theme === 'light') btnLight.classList.add('active');
|
||||||
|
else btnDark.classList.add('active');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleTheme() {
|
// Ensure theme persists on back navigation (BFCache)
|
||||||
const current = document.documentElement.getAttribute('data-theme');
|
window.addEventListener('pageshow', (event) => {
|
||||||
const newTheme = current === 'light' ? 'dark' : 'light';
|
// Re-apply theme from storage to ensure it matches user preference
|
||||||
|
// even if page was restored from cache with old state
|
||||||
|
const savedTheme = localStorage.getItem('theme');
|
||||||
|
if (savedTheme) {
|
||||||
|
setTheme(savedTheme, false);
|
||||||
|
} else {
|
||||||
|
initTheme();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
document.documentElement.setAttribute('data-theme', newTheme);
|
// Sync across tabs
|
||||||
localStorage.setItem('theme', newTheme);
|
window.addEventListener('storage', (event) => {
|
||||||
}
|
if (event.key === 'theme') {
|
||||||
|
setTheme(event.newValue, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// --- Profile Logic ---
|
// --- Profile Logic ---
|
||||||
async function updateProfile(e) {
|
async function updateProfile(e) {
|
||||||
|
|
|
||||||
|
|
@ -42,26 +42,11 @@
|
||||||
|
|
||||||
|
|
||||||
<!-- Shorts Section -->
|
<!-- Shorts Section -->
|
||||||
<div id="shortsSection" class="yt-section">
|
|
||||||
<div class="yt-section-header">
|
|
||||||
<h2><i class="fas fa-bolt"></i> Shorts</h2>
|
|
||||||
</div>
|
|
||||||
<div class="yt-shorts-container">
|
|
||||||
<button class="yt-shorts-arrow yt-shorts-left" onclick="scrollShorts('left')">
|
|
||||||
<i class="fas fa-chevron-left"></i>
|
|
||||||
</button>
|
|
||||||
<div id="shortsGrid" class="yt-shorts-grid">
|
|
||||||
<!-- Shorts loaded via JS -->
|
|
||||||
</div>
|
|
||||||
<button class="yt-shorts-arrow yt-shorts-right" onclick="scrollShorts('right')">
|
|
||||||
<i class="fas fa-chevron-right"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Videos Section -->
|
<!-- Videos Section -->
|
||||||
<div id="videosSection" class="yt-section">
|
<div id="videosSection" class="yt-section">
|
||||||
<div class="yt-section-header">
|
<div class="yt-section-header" style="display:none;">
|
||||||
<h2><i class="fas fa-play-circle"></i> Videos</h2>
|
<h2><i class="fas fa-play-circle"></i> Videos</h2>
|
||||||
</div>
|
</div>
|
||||||
<div id="resultsArea" class="yt-video-grid">
|
<div id="resultsArea" class="yt-video-grid">
|
||||||
|
|
@ -356,39 +341,44 @@
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
background: var(--yt-bg-secondary);
|
background: var(--yt-bg-secondary);
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.5s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.yt-short-title {
|
.yt-short-thumb.loaded {
|
||||||
font-size: 14px;
|
opacity: 1;
|
||||||
font-weight: 500;
|
|
||||||
margin-top: 8px;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
line-clamp: 2;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.yt-short-views {
|
.yt-short-title {
|
||||||
font-size: 12px;
|
font-size: 14px;
|
||||||
color: var(--yt-text-secondary);
|
font-weight: 500;
|
||||||
margin-top: 4px;
|
margin-top: 8px;
|
||||||
}
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
@media (max-width: 768px) {
|
line-clamp: 2;
|
||||||
.yt-shorts-arrow {
|
-webkit-box-orient: vertical;
|
||||||
display: none;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.yt-filter-bar {
|
.yt-short-views {
|
||||||
padding: 0 10px;
|
font-size: 12px;
|
||||||
top: 56px;
|
color: var(--yt-text-secondary);
|
||||||
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.yt-sort-container {
|
@media (max-width: 768px) {
|
||||||
/* Legacy override if needed */
|
.yt-shorts-arrow {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-filter-bar {
|
||||||
|
padding: 0 10px;
|
||||||
|
top: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-sort-container {
|
||||||
|
/* Legacy override if needed */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -461,13 +451,14 @@
|
||||||
const card = document.createElement('div');
|
const card = document.createElement('div');
|
||||||
card.className = 'yt-short-card';
|
card.className = 'yt-short-card';
|
||||||
card.innerHTML = `
|
card.innerHTML = `
|
||||||
<img src="${video.thumbnail}" class="yt-short-thumb" loading="lazy">
|
<img data-src="${video.thumbnail}" class="yt-short-thumb">
|
||||||
<p class="yt-short-title">${escapeHtml(video.title)}</p>
|
<p class="yt-short-title">${escapeHtml(video.title)}</p>
|
||||||
<p class="yt-short-views">${formatViews(video.view_count)} views</p>
|
<p class="yt-short-views">${formatViews(video.view_count)} views</p>
|
||||||
`;
|
`;
|
||||||
card.onclick = () => window.location.href = `/watch?v=${video.id}`;
|
card.onclick = () => window.location.href = `/watch?v=${video.id}`;
|
||||||
shortsGrid.appendChild(card);
|
shortsGrid.appendChild(card);
|
||||||
});
|
});
|
||||||
|
if (window.observeImages) window.observeImages();
|
||||||
} else {
|
} else {
|
||||||
shortsGrid.innerHTML = '<p style="color:var(--yt-text-secondary);padding:20px;">No shorts found</p>';
|
shortsGrid.innerHTML = '<p style="color:var(--yt-text-secondary);padding:20px;">No shorts found</p>';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,10 +45,6 @@
|
||||||
<button class="yt-menu-btn" onclick="toggleSidebar()" aria-label="Menu">
|
<button class="yt-menu-btn" onclick="toggleSidebar()" aria-label="Menu">
|
||||||
<i class="fas fa-bars"></i>
|
<i class="fas fa-bars"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="yt-menu-btn" id="headerBackBtn" onclick="history.back()" aria-label="Back"
|
|
||||||
style="display:none;">
|
|
||||||
<i class="fas fa-arrow-left"></i>
|
|
||||||
</button>
|
|
||||||
<a href="/" class="yt-logo"
|
<a href="/" class="yt-logo"
|
||||||
style="text-decoration: none; display: flex; align-items: center; gap: 4px;">
|
style="text-decoration: none; display: flex; align-items: center; gap: 4px;">
|
||||||
<span style="color: #ff0000; font-size: 24px;"><i class="fas fa-play-circle"></i></span>
|
<span style="color: #ff0000; font-size: 24px;"><i class="fas fa-play-circle"></i></span>
|
||||||
|
|
@ -67,9 +63,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="yt-header-end">
|
<div class="yt-header-end">
|
||||||
<button class="yt-icon-btn yt-mobile-search" onclick="toggleMobileSearch()" aria-label="Search">
|
<!-- Mobile Search Icon Removed - Search will be visible -->
|
||||||
|
<!-- <button class="yt-icon-btn yt-mobile-search" onclick="toggleMobileSearch()" aria-label="Search">
|
||||||
<i class="fas fa-search"></i>
|
<i class="fas fa-search"></i>
|
||||||
</button>
|
</button> -->
|
||||||
{% if session.get('user_id') %}
|
{% if session.get('user_id') %}
|
||||||
<div class="yt-avatar" title="{{ session.username }}">
|
<div class="yt-avatar" title="{{ session.username }}">
|
||||||
{{ session.username[0]|upper }}
|
{{ session.username[0]|upper }}
|
||||||
|
|
@ -172,6 +169,11 @@
|
||||||
<main class="yt-main" id="mainContent">
|
<main class="yt-main" id="mainContent">
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<!-- Floating Back Button (Mobile) -->
|
||||||
|
<button id="floatingBackBtn" class="yt-floating-back" onclick="history.back()" aria-label="Go Back">
|
||||||
|
<i class="fas fa-arrow-left"></i>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
|
||||||
|
|
@ -428,17 +430,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Back Button Logic ---
|
// --- Back Button Logic ---
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
// Back Button Logic Removed (Handled Server-Side)
|
||||||
const path = window.location.pathname;
|
|
||||||
const menuBtn = document.querySelector('.yt-menu-btn');
|
|
||||||
const backBtnHeader = document.getElementById('headerBackBtn');
|
|
||||||
|
|
||||||
// If not home, swap menu for back
|
|
||||||
if (path !== '/' && backBtnHeader) {
|
|
||||||
if (menuBtn) menuBtn.style.display = 'none';
|
|
||||||
backBtnHeader.style.display = 'flex';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
/* Queue Drawer Styles */
|
/* Queue Drawer Styles */
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,11 @@
|
||||||
<h3>Appearance</h3>
|
<h3>Appearance</h3>
|
||||||
<p class="yt-settings-desc">Customize how KV-Tube looks on your device.</p>
|
<p class="yt-settings-desc">Customize how KV-Tube looks on your device.</p>
|
||||||
<div class="yt-setting-row">
|
<div class="yt-setting-row">
|
||||||
<span>Dark Mode</span>
|
<span>Theme Mode</span>
|
||||||
<label class="yt-switch">
|
<div class="yt-theme-selector">
|
||||||
<input type="checkbox" id="themeToggle" checked onchange="toggleTheme()">
|
<button type="button" class="yt-theme-btn" id="themeBtnLight" onclick="setTheme('light')">Light</button>
|
||||||
<span class="yt-slider round"></span>
|
<button type="button" class="yt-theme-btn" id="themeBtnDark" onclick="setTheme('dark')">Dark</button>
|
||||||
</label>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -140,63 +140,36 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Toggle Switch */
|
/* Theme Selector */
|
||||||
.yt-setting-row {
|
.yt-theme-selector {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
gap: 12px;
|
||||||
align-items: center;
|
background: var(--yt-bg-elevated);
|
||||||
padding: 8px 0;
|
padding: 4px;
|
||||||
}
|
|
||||||
|
|
||||||
.yt-switch {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
width: 48px;
|
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.yt-switch input {
|
|
||||||
opacity: 0;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.yt-slider {
|
|
||||||
position: absolute;
|
|
||||||
cursor: pointer;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background-color: #666;
|
|
||||||
transition: .4s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.yt-slider:before {
|
|
||||||
position: absolute;
|
|
||||||
content: "";
|
|
||||||
height: 18px;
|
|
||||||
width: 18px;
|
|
||||||
left: 3px;
|
|
||||||
bottom: 3px;
|
|
||||||
background-color: white;
|
|
||||||
transition: .4s;
|
|
||||||
}
|
|
||||||
|
|
||||||
input:checked+.yt-slider {
|
|
||||||
background-color: var(--yt-accent-blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
input:checked+.yt-slider:before {
|
|
||||||
transform: translateX(24px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.yt-slider.round {
|
|
||||||
border-radius: 24px;
|
border-radius: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.yt-slider.round:before {
|
.yt-theme-btn {
|
||||||
border-radius: 50%;
|
flex: 1;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--yt-text-secondary);
|
||||||
|
background: transparent;
|
||||||
|
transition: all 0.2s;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-theme-btn:hover {
|
||||||
|
color: var(--yt-text-primary);
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-theme-btn.active {
|
||||||
|
background: var(--yt-bg-primary);
|
||||||
|
color: var(--yt-text-primary);
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue