fix db
This commit is contained in:
parent
44e9d78b08
commit
9acd8a1b58
40
css/main.css
40
css/main.css
@ -463,7 +463,6 @@ body.light-theme::-webkit-scrollbar-thumb:hover, body.light-theme .item-details:
|
||||
==============================================
|
||||
*/
|
||||
|
||||
/* Styles to manage hero loading state and content section visibility */
|
||||
.hero.loading .hero-content {
|
||||
opacity: 0;
|
||||
}
|
||||
@ -472,9 +471,8 @@ body.light-theme::-webkit-scrollbar-thumb:hover, body.light-theme .item-details:
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Custom styles for settings modal descriptions */
|
||||
#settingsModal .text-muted {
|
||||
color: var(--text-primary); /* MODIFIED: Replaced 'white !important' for theme consistency */
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
#main-view {
|
||||
@ -904,8 +902,10 @@ body.sidebar-collapsed #main-container {
|
||||
.item-poster {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
padding-bottom: 150%;
|
||||
height: auto;
|
||||
aspect-ratio: 2 / 3;
|
||||
object-fit: cover;
|
||||
background-color: var(--secondary);
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
transition: transform 0.6s cubic-bezier(0.23, 1, 0.32, 1);
|
||||
@ -915,12 +915,6 @@ body.sidebar-collapsed #main-container {
|
||||
transform: scale(1.08);
|
||||
}
|
||||
|
||||
.item-poster img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.item-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@ -3043,9 +3037,8 @@ body.miniplayer-active #musicPlayerContainer {
|
||||
#volumeSlider {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
/* Removed writing-mode: bt-lr; */
|
||||
width: 100px; /* Adjusted for horizontal orientation */
|
||||
height: 8px; /* Adjusted for horizontal orientation */
|
||||
width: 100px;
|
||||
height: 8px;
|
||||
background: var(--glass);
|
||||
border-radius: 4px;
|
||||
}
|
||||
@ -3408,8 +3401,6 @@ body.miniplayer-active { padding-bottom: 85px; }
|
||||
|
||||
|
||||
/* --- m3u-generator.css --- */
|
||||
/* M3U Generator Section */
|
||||
|
||||
.m3u-animated-item {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
@ -3516,7 +3507,7 @@ body.miniplayer-active { padding-bottom: 85px; }
|
||||
margin-right: 0.8rem;
|
||||
background-color: var(--secondary);
|
||||
border: 1px solid var(--glass-border);
|
||||
flex-shrink: 0; /* Prevent shrinking */
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
#m3u-libraries-container .form-check-label {
|
||||
@ -3524,7 +3515,7 @@ body.miniplayer-active { padding-bottom: 85px; }
|
||||
cursor: pointer;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.2; /* Ensure consistent line height */
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
#m3u-libraries-container .form-check-input:checked {
|
||||
@ -3559,7 +3550,7 @@ body.miniplayer-active { padding-bottom: 85px; }
|
||||
font-family: 'Orbitron', sans-serif;
|
||||
font-size: 1.4rem;
|
||||
margin-bottom: 1.5rem;
|
||||
color: white; /* Changed to white for better visibility */
|
||||
color: white;
|
||||
}
|
||||
|
||||
.m3u-instructions {
|
||||
@ -3579,19 +3570,18 @@ body.miniplayer-active { padding-bottom: 85px; }
|
||||
padding: 1rem;
|
||||
font-size: 1rem;
|
||||
border-radius: var(--border-radius-md);
|
||||
transition: all 0.3s ease; /* Added for animation */
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
#download-m3u-btn:hover {
|
||||
transform: translateY(-3px); /* Added for hover effect */
|
||||
box-shadow: var(--shadow-lg); /* Added for hover effect */
|
||||
transform: translateY(-3px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
#download-m3u-btn span {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
/* Loading state for libraries */
|
||||
#m3u-libraries-loader {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -3607,7 +3597,6 @@ body.miniplayer-active { padding-bottom: 85px; }
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
/* Light Theme */
|
||||
.light-theme .m3u-config-panel {
|
||||
background: var(--secondary);
|
||||
}
|
||||
@ -3638,7 +3627,6 @@ body.miniplayer-active { padding-bottom: 85px; }
|
||||
color: var(--accent-dark);
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 992px) {
|
||||
.m3u-container {
|
||||
grid-template-columns: 1fr;
|
||||
@ -3920,4 +3908,4 @@ body.miniplayer-active { padding-bottom: 85px; }
|
||||
.provider-card:hover .provider-tooltip {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
@ -29,6 +29,7 @@ export const state = {
|
||||
localSeries: [],
|
||||
localArtists: [],
|
||||
localPhotos: [],
|
||||
localContentLookup: new Set(),
|
||||
db: null,
|
||||
lastScrollPosition: 0,
|
||||
currentItemId: null,
|
||||
|
70
js/ui.js
70
js/ui.js
@ -64,6 +64,29 @@ export async function loadLocalContent() {
|
||||
state.jellyfinMovies = jfMovies;
|
||||
state.jellyfinSeries = jfSeries;
|
||||
|
||||
state.localContentLookup.clear();
|
||||
const normalize = (str) => str ? str.toLowerCase().trim().replace(/\s+/g, ' ') : '';
|
||||
|
||||
const processSource = (source) => {
|
||||
if (!Array.isArray(source)) return;
|
||||
source.forEach(server => {
|
||||
if (server && Array.isArray(server.titulos)) {
|
||||
server.titulos.forEach(t => {
|
||||
if (t && t.title) {
|
||||
const year = t.year ? String(t.year).slice(0, 4) : 'any';
|
||||
const lookupKey = `${normalize(t.title)}|${year}`;
|
||||
state.localContentLookup.add(lookupKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
processSource(state.localMovies);
|
||||
processSource(state.localSeries);
|
||||
processSource(state.jellyfinMovies);
|
||||
processSource(state.jellyfinSeries);
|
||||
|
||||
} catch (error) {
|
||||
showNotification(_("errorLoadingLocalContent"), "error");
|
||||
}
|
||||
@ -79,7 +102,6 @@ export function resetView() {
|
||||
const heroBg1 = document.querySelector('.hero-background-1');
|
||||
const heroBg2 = document.querySelector('.hero-background-2');
|
||||
|
||||
// Hide all main content sections
|
||||
if (mainContent) {
|
||||
mainContent.style.display = 'none';
|
||||
}
|
||||
@ -93,12 +115,10 @@ export function resetView() {
|
||||
document.getElementById('providers-section').style.display = 'none';
|
||||
document.getElementById('m3u-generator-section').style.display = 'none';
|
||||
|
||||
// Show hero if enabled
|
||||
if (heroSection) {
|
||||
if (state.settings.showHero) {
|
||||
heroSection.style.display = 'flex';
|
||||
|
||||
// Clear dynamic hero content and reset to default
|
||||
if (state.heroIntervalId) {
|
||||
clearInterval(state.heroIntervalId);
|
||||
state.heroIntervalId = null;
|
||||
@ -148,7 +168,7 @@ export function switchView(viewType) {
|
||||
}
|
||||
|
||||
if (mainContent) {
|
||||
mainContent.style.display = 'block'; // Ensure main content is visible when switching views
|
||||
mainContent.style.display = 'block';
|
||||
}
|
||||
|
||||
const sidebar = document.getElementById('sidebar-nav');
|
||||
@ -182,7 +202,6 @@ export function switchView(viewType) {
|
||||
if (el) el.style.display = 'none';
|
||||
});
|
||||
|
||||
// Explicitly reset the Providers section to its initial state before view switch
|
||||
const providersSection = document.getElementById('providers-section');
|
||||
if (providersSection) {
|
||||
const detailsContainer = document.getElementById('provider-details-container');
|
||||
@ -271,7 +290,6 @@ export function switchView(viewType) {
|
||||
loadProviders();
|
||||
break;
|
||||
case 'm3u-generator':
|
||||
// The m3u-generator.js file handles its own initialization
|
||||
break;
|
||||
}
|
||||
|
||||
@ -453,31 +471,22 @@ function isContentAvailableLocally(title, type, year) {
|
||||
|
||||
const normalize = (str) => str.toLowerCase().trim().replace(/\s+/g, ' ');
|
||||
const normalizedTitle = normalize(title);
|
||||
const yearKey = year ? String(year).slice(0, 4) : 'any';
|
||||
|
||||
const checkSource = (source, itemType) => {
|
||||
if (!Array.isArray(source)) return false;
|
||||
return source.some(server =>
|
||||
server && Array.isArray(server.titulos) &&
|
||||
server.titulos.some(t => {
|
||||
if (!t || typeof t.title !== 'string') return false;
|
||||
const localTitle = normalize(t.title);
|
||||
if (localTitle !== normalizedTitle) return false;
|
||||
if (year && t.year && Math.abs(parseInt(t.year) - parseInt(year)) > 1) return false;
|
||||
if (itemType && t.type && t.type.toLowerCase() !== itemType.toLowerCase()) return false;
|
||||
return true;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
if (checkSource(state.localMovies, 'movie')) return true;
|
||||
if (checkSource(state.localSeries, 'series')) return true;
|
||||
if (checkSource(state.jellyfinMovies, 'movie')) return true;
|
||||
if (checkSource(state.jellyfinSeries, 'series')) return true;
|
||||
const lookupKey = `${normalizedTitle}|${yearKey}`;
|
||||
|
||||
if (state.localContentLookup.has(lookupKey)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const lookupKeyAnyYear = `${normalizedTitle}|any`;
|
||||
if (yearKey !== 'any' && state.localContentLookup.has(lookupKeyAnyYear)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
export function renderGrid(items, append = false, gridId = 'content-grid') {
|
||||
const grid = document.getElementById(gridId);
|
||||
if (!append) grid.innerHTML = '';
|
||||
@ -513,7 +522,7 @@ export function renderGrid(items, append = false, gridId = 'content-grid') {
|
||||
card.dataset.id = item.id;
|
||||
card.dataset.type = itemType;
|
||||
card.innerHTML = `
|
||||
<div class="item-poster" style="background-image: url('${posterPath}')"></div>
|
||||
<img src="${posterPath}" class="item-poster" loading="lazy" alt="${title}">
|
||||
${voteAvg >= 7.8 ? '<span class="badge top-badge">TOP</span>' : ''}
|
||||
${isAvailable ? `<span class="badge available-badge"><i class="fas fa-check-circle"></i> ${_('local')}</span>` : ''}
|
||||
<div class="item-overlay">
|
||||
@ -1274,7 +1283,6 @@ export async function initializeHeroSection() {
|
||||
const heroSection = document.getElementById('hero-section');
|
||||
if (heroSection.style.display === 'none' || !state.settings.showHero) return;
|
||||
|
||||
// Clear existing timers for slide changes and initial load
|
||||
if (state.heroIntervalId) {
|
||||
clearInterval(state.heroIntervalId);
|
||||
state.heroIntervalId = null;
|
||||
@ -1289,7 +1297,6 @@ export async function initializeHeroSection() {
|
||||
const content = document.querySelector('.hero-content');
|
||||
const heroButtons = content.querySelector('.hero-buttons');
|
||||
|
||||
// Set static background and show default content
|
||||
content.querySelector('.hero-title').textContent = _('heroWelcome');
|
||||
content.querySelector('.hero-subtitle').textContent = _('heroSubtitle');
|
||||
content.querySelector('#hero-rating').innerHTML = '';
|
||||
@ -1303,7 +1310,6 @@ export async function initializeHeroSection() {
|
||||
gsap.set(content, { autoAlpha: 1 });
|
||||
heroSection.classList.remove('loading');
|
||||
|
||||
// After 5 seconds, load the dynamic content if we are still on the home view
|
||||
state.heroLoadTimeoutId = setTimeout(() => {
|
||||
if (state.currentView === 'home') {
|
||||
loadTmdbHeroContent();
|
||||
@ -1318,7 +1324,7 @@ export async function initializeHeroSection() {
|
||||
const popularItems = data.results.filter(i => i.backdrop_path && i.overview).slice(0, 8);
|
||||
|
||||
if (popularItems.length === 0) {
|
||||
return; // Keep static image if no items
|
||||
return;
|
||||
}
|
||||
|
||||
let currentBg = bg1;
|
||||
@ -1966,4 +1972,4 @@ export function showPrevPhoto() {
|
||||
export async function loadProviders() {
|
||||
const providers = await fetchAllProviders(state.settings.watchRegion);
|
||||
renderProviders(providers);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user