|
|
|
|
|
async function fetchVideos() { |
|
|
try { |
|
|
|
|
|
const response = await fetch('https://youtube-v31.p.rapidapi.com/search?q=music&part=snippet&maxResults=24', { |
|
|
method: 'GET', |
|
|
headers: { |
|
|
'X-RapidAPI-Key': 'your-api-key', |
|
|
'X-RapidAPI-Host': 'youtube-v31.p.rapidapi.com' |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
if (!response.ok) { |
|
|
return getMockVideos(); |
|
|
} |
|
|
|
|
|
const data = await response.json(); |
|
|
return data.items; |
|
|
} catch (error) { |
|
|
console.error('Error fetching videos:', error); |
|
|
return getMockVideos(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function getMockVideos() { |
|
|
return Array(12).fill().map((_, i) => ({ |
|
|
id: { videoId: `mock${i}` }, |
|
|
snippet: { |
|
|
title: `Awesome Video ${i + 1}`, |
|
|
channelTitle: `Channel ${i + 1}`, |
|
|
thumbnails: { |
|
|
medium: { |
|
|
url: `http://static.photos/technology/320x240/${i + 100}` |
|
|
} |
|
|
}, |
|
|
publishedAt: new Date().toISOString() |
|
|
} |
|
|
})); |
|
|
} |
|
|
|
|
|
|
|
|
async function renderVideos() { |
|
|
const videos = await fetchVideos(); |
|
|
const container = document.querySelector('main .grid'); |
|
|
|
|
|
videos.forEach((video, index) => { |
|
|
const videoCard = document.createElement('custom-video-card'); |
|
|
videoCard.setAttribute('video-id', video.id.videoId); |
|
|
videoCard.setAttribute('title', video.snippet.title); |
|
|
videoCard.setAttribute('channel', video.snippet.channelTitle); |
|
|
videoCard.setAttribute('thumbnail', video.snippet.thumbnails.medium.url); |
|
|
videoCard.setAttribute('published', video.snippet.publishedAt); |
|
|
videoCard.style.animationDelay = `${0.1 * (index % 8)}s`; |
|
|
container.appendChild(videoCard); |
|
|
}); |
|
|
} |
|
|
|
|
|
document.addEventListener('DOMContentLoaded', () => { |
|
|
renderVideos(); |
|
|
setupMobileNavigation(); |
|
|
|
|
|
|
|
|
const html = document.documentElement; |
|
|
const darkModeToggle = document.createElement('button'); |
|
|
darkModeToggle.innerHTML = '<i data-feather="moon"></i>'; |
|
|
darkModeToggle.className = 'p-2 rounded-full hover:bg-gray-700'; |
|
|
darkModeToggle.addEventListener('click', () => { |
|
|
html.classList.toggle('dark'); |
|
|
feather.replace(); |
|
|
}); |
|
|
|
|
|
document.querySelector('custom-navbar').shadowRoot.querySelector('.right-section').appendChild(darkModeToggle); |
|
|
feather.replace(); |
|
|
}); |
|
|
|
|
|
|
|
|
function setupMobileNavigation() { |
|
|
const mobileMenuBtn = document.querySelector('custom-navbar').shadowRoot.querySelector('.mobile-menu-btn'); |
|
|
const sidebar = document.querySelector('custom-sidebar'); |
|
|
const overlay = sidebar.shadowRoot.querySelector('.overlay'); |
|
|
|
|
|
if (mobileMenuBtn && sidebar && overlay) { |
|
|
mobileMenuBtn.addEventListener('click', () => { |
|
|
const sidebarElement = sidebar.shadowRoot.querySelector('.sidebar'); |
|
|
sidebarElement.classList.toggle('open'); |
|
|
overlay.classList.toggle('open'); |
|
|
}); |
|
|
|
|
|
overlay.addEventListener('click', () => { |
|
|
const sidebarElement = sidebar.shadowRoot.querySelector('.sidebar'); |
|
|
sidebarElement.classList.remove('open'); |
|
|
overlay.classList.remove('open'); |
|
|
}); |
|
|
|
|
|
|
|
|
const sidebarItems = sidebar.shadowRoot.querySelectorAll('.sidebar-item'); |
|
|
sidebarItems.forEach(item => { |
|
|
item.addEventListener('click', () => { |
|
|
if (window.innerWidth < 768) { |
|
|
const sidebarElement = sidebar.shadowRoot.querySelector('.sidebar'); |
|
|
sidebarElement.classList.remove('open'); |
|
|
overlay.classList.remove('open'); |
|
|
} |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function updateGridLayout() { |
|
|
const container = document.querySelector('main .grid'); |
|
|
if (!container) return; |
|
|
|
|
|
if (window.innerWidth < 640) { |
|
|
container.className = 'grid grid-cols-1 gap-3 mobile-p-2'; |
|
|
} else if (window.innerWidth < 768) { |
|
|
container.className = 'grid grid-cols-2 gap-3'; |
|
|
} else if (window.innerWidth < 1024) { |
|
|
container.className = 'grid grid-cols-3 gap-4'; |
|
|
} else { |
|
|
container.className = 'grid grid-cols-4 gap-4'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
window.addEventListener('resize', updateGridLayout); |
|
|
window.addEventListener('load', updateGridLayout); |
|
|
|