Speedofmastery's picture
Not good optimize mobile first
1966bcd verified
// Fetch YouTube videos from API
async function fetchVideos() {
try {
// Using a mock API since YouTube API requires authentication
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'
}
});
// Fallback to mock data if API fails
if (!response.ok) {
return getMockVideos();
}
const data = await response.json();
return data.items;
} catch (error) {
console.error('Error fetching videos:', error);
return getMockVideos();
}
}
// Mock data for fallback
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()
}
}));
}
// Render videos to the page
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);
});
}
// Initialize the app
document.addEventListener('DOMContentLoaded', () => {
renderVideos();
setupMobileNavigation();
// Toggle dark mode
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();
});
// Mobile navigation setup
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');
});
// Close sidebar when clicking on a sidebar item on mobile
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');
}
});
});
}
}
// Responsive grid layout
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';
}
}
// Listen for window resize
window.addEventListener('resize', updateGridLayout);
window.addEventListener('load', updateGridLayout);