anycoder-0741e1f0 / index.html
Mousco's picture
Upload folder using huggingface_hub
3182906 verified
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>StreamTube - Visionnage de Vidéos</title>
<!-- Importation de FontAwesome pour les icônes -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Police Google Fonts: Roboto -->
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
<style>
/* --- VARIABLES CSS & RESET --- */
:root {
--primary-color: #ff0000;
--bg-color: #0f0f0f;
--bg-secondary: #1f1f1f;
--text-main: #ffffff;
--text-secondary: #aaaaaa;
--hover-color: #272727;
--border-color: #303030;
--sidebar-width: 240px;
--header-height: 60px;
--transition-speed: 0.3s;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Roboto', sans-serif;
}
body {
background-color: var(--bg-color);
color: var(--text-main);
overflow-x: hidden;
}
/* --- UI COMPONENTS (Toasts, Buttons) --- */
button {
cursor: pointer;
border: none;
outline: none;
background: transparent;
color: inherit;
transition: var(--transition-speed);
}
.btn-primary {
background-color: var(--primary-color);
color: white;
padding: 8px 16px;
border-radius: 18px;
font-weight: 500;
}
.btn-primary:hover {
background-color: #cc0000;
}
.btn-icon {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.btn-icon:hover {
background-color: var(--hover-color);
}
/* Custom Scrollbar */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: var(--bg-color);
}
::-webkit-scrollbar-thumb {
background: #717171;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: #a0a0a0;
}
/* Toast Notification */
#toast-container {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
z-index: 2000;
display: flex;
flex-direction: column;
gap: 10px;
}
.toast {
background-color: #333;
color: white;
padding: 12px 24px;
border-radius: 4px;
font-size: 0.9rem;
box-shadow: 0 4px 6px rgba(0,0,0,0.3);
animation: slideUp 0.3s ease-out forwards;
}
@keyframes slideUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
/* --- HEADER --- */
header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: var(--header-height);
background-color: var(--bg-color);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
z-index: 1000;
border-bottom: 1px solid var(--border-color);
}
.header-left {
display: flex;
align-items: center;
gap: 16px;
}
.logo {
display: flex;
align-items: center;
gap: 4px;
font-size: 1.2rem;
font-weight: 700;
letter-spacing: -0.5px;
color: white;
text-decoration: none;
}
.logo i {
color: var(--primary-color);
font-size: 1.5rem;
}
.header-center {
flex: 1;
max-width: 600px;
margin: 0 20px;
display: flex;
}
.search-bar {
display: flex;
width: 100%;
}
.search-bar input {
width: 100%;
background-color: #121212;
border: 1px solid var(--border-color);
border-right: none;
padding: 8px 16px;
border-radius: 20px 0 0 20px;
color: white;
font-size: 1rem;
}
.search-bar input:focus {
border-color: #1c62b9;
outline: none;
}
.search-bar button {
background-color: #222;
border: 1px solid var(--border-color);
border-radius: 0 20px 20px 0;
padding: 0 20px;
color: var(--text-secondary);
}
.header-right {
display: flex;
align-items: center;
gap: 12px;
}
.user-avatar {
width: 32px;
height: 32px;
border-radius: 50%;
background-color: #555;
overflow: hidden;
}
.user-avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
.built-with-link {
font-size: 0.8rem;
color: var(--text-secondary);
text-decoration: none;
margin-right: 10px;
display: none; /* Hidden on very small screens */
}
@media (min-width: 768px) {
.built-with-link { display: block; }
}
/* --- SIDEBAR --- */
.sidebar {
position: fixed;
top: var(--header-height);
left: 0;
width: var(--sidebar-width);
height: calc(100vh - var(--header-height));
background-color: var(--bg-color);
overflow-y: auto;
padding: 12px;
transition: transform 0.3s ease;
z-index: 900;
}
.nav-item {
display: flex;
align-items: center;
padding: 10px 12px;
border-radius: 10px;
color: var(--text-main);
text-decoration: none;
margin-bottom: 4px;
}
.nav-item:hover {
background-color: var(--hover-color);
}
.nav-item.active {
background-color: var(--hover-color);
font-weight: 500;
}
.nav-item i {
margin-right: 20px;
font-size: 1.1rem;
width: 24px;
text-align: center;
}
.nav-section-title {
padding: 16px 12px 8px;
font-size: 1rem;
font-weight: 500;
color: var(--text-main);
}
/* --- MAIN CONTENT AREA --- */
main {
margin-top: var(--header-height);
margin-left: var(--sidebar-width);
padding: 24px;
min-height: calc(100vh - var(--header-height));
transition: margin-left 0.3s ease;
}
/* --- HOME VIEW (GRID) --- */
.chips-container {
display: flex;
gap: 12px;
margin-bottom: 24px;
overflow-x: auto;
padding-bottom: 8px;
}
.chip {
background-color: var(--bg-secondary);
color: var(--text-main);
padding: 6px 12px;
border-radius: 8px;
font-size: 0.9rem;
white-space: nowrap;
cursor: pointer;
transition: background 0.2s;
border: 1px solid transparent;
}
.chip:hover {
background-color: #3f3f3f;
}
.chip.active {
background-color: var(--text-main);
color: var(--bg-color);
}
.video-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px 16px;
}
.video-card {
cursor: pointer;
transition: transform 0.2s;
}
.thumbnail-container {
position: relative;
width: 100%;
padding-top: 56.25%; /* 16:9 Aspect Ratio */
border-radius: 12px;
overflow: hidden;
background-color: #222;
}
.thumbnail-container img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.video-card:hover .thumbnail-container img {
transform: scale(1.05);
}
.duration {
position: absolute;
bottom: 8px;
right: 8px;
background-color: rgba(0, 0, 0, 0.8);
color: white;
padding: 2px 4px;
border-radius: 4px;
font-size: 0.8rem;
font-weight: 500;
}
.video-info {
display: flex;
margin-top: 12px;
gap: 12px;
}
.channel-icon {
width: 36px;
height: 36px;
border-radius: 50%;
background-color: #333;
flex-shrink: 0;
}
.video-details {
display: flex;
flex-direction: column;
}
.video-title {
font-size: 1rem;
font-weight: 500;
line-height: 1.4;
margin-bottom: 4px;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.channel-name, .video-meta {
font-size: 0.85rem;
color: var(--text-secondary);
}
.channel-name:hover {
color: var(--text-main);
}
/* --- WATCH VIEW --- */
#watch-view {
display: none; /* Hidden by default */
flex-direction: row;
gap: 24px;
}
.player-column {
flex: 1;
max-width: 900px;
}
.video-wrapper {
width: 100%;
aspect-ratio: 16/9;
background-color: black;
border-radius: 12px;
overflow: hidden;
margin-bottom: 12px;
}
video {
width: 100%;
height: 100%;
}
.watch-title {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 8px;
}
.watch-actions-bar {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid var(--border-color);
padding-bottom: 12px;
margin-bottom: 16px;
}
.channel-info-row {
display: flex;
align-items: center;
gap: 12px;
}
.subscribe-btn {
background-color: var(--text-main);
color: var(--bg-color);
padding: 8px 16px;
border-radius: 18px;
font-weight: 500;
font-size: 1rem;
margin-left: 12px;
}
.subscribe-btn.subscribed {
background-color: var(--bg-secondary);
color: var(--text-main);
}
.actions-buttons {
display: flex;
gap: 8px;
}
.action-chip {
display: flex;
align-items: center;
gap: 6px;
background-color: var(--bg-secondary);
padding: 8px 16px;
border-radius: 18px;
font-size: 0.9rem;
font-weight: 500;
}
.action-chip:hover {
background-color: var(--hover-color);
}
.description-box {
background-color: var(--bg-secondary);
padding: 12px;
border-radius: 12px;
font-size: 0.9rem;
line-height: 1.5;
margin-bottom: 24px;
}
.comments-section {
margin-top: 24px;
}
.comment {
display: flex;
gap: 12px;
margin-bottom: 16px;
}
.comment-body h4 {
font-size: 0.85rem;
margin-bottom: 4px;
}
.comment-body p {
font-size: 0.9rem;
line-height: 1.4;
}
/* Recommendations Sidebar in Watch View */
.recommendations-column {
width: 350px;
display: flex;
flex-direction: column;
gap: 12px;
}
.rec-video-card {
display: flex;
gap: 8px;
cursor: pointer;
}
.rec-thumbnail {
width: 168px;
height: 94px;
border-radius: 8px;
overflow: hidden;
position: relative;
flex-shrink: 0;
background-color: #222;
}
.rec-thumbnail img {
width: 100%;
height: 100%;
object-fit: cover;
}
.rec-info h4 {
font-size: 0.9rem;
font-weight: 500;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
margin-bottom: 4px;
}
.rec-info p {
font-size: 0.8rem;
color: var(--text-secondary);
}
/* --- RESPONSIVE MEDIA QUERIES --- */
@media (max-width: 1024px) {
.video-grid {
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
.recommendations-column {
width: 280px;
}
.rec-thumbnail {
width: 140px;
height: 80px;
}
}
@media (max-width: 900px) {
#watch-view {
flex-direction: column;
}
.recommendations-column {
width: 100%;
}
.rec-video-card {
flex-direction: row;
}
}
@media (max-width: 768px) {
.sidebar {
transform: translateX(-100%);
}
.sidebar.active {
transform: translateX(0);
box-shadow: 2px 0 10px rgba(0,0,0,0.5);
}
main {
margin-left: 0;
}
.header-center {
display: none; /* Simplify header for mobile */
}
.search-bar-mobile {
display: flex; /* Would need to implement mobile search toggle */
}
.video-grid {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<!-- Header -->
<header>
<div class="header-left">
<button class="btn-icon" id="menu-btn" aria-label="Menu">
<i class="fa-solid fa-bars"></i>
</button>
<a href="#" class="logo" onclick="app.goHome()">
<i class="fa-brands fa-youtube"></i>
<span>StreamTube</span>
</a>
</div>
<div class="header-center">
<div class="search-bar">
<input type="text" placeholder="Rechercher" id="search-input">
<button id="search-btn">
<i class="fa-solid fa-magnifying-glass"></i>
</button>
</div>
<button class="btn-icon" style="margin-left: 8px;">
<i class="fa-solid fa-microphone"></i>
</button>
</div>
<div class="header-right">
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="built-with-link">
Built with anycoder
</a>
<button class="btn-icon">
<i class="fa-solid fa-video"></i>
</button>
<button class="btn-icon">
<i class="fa-solid fa-bell"></i>
</button>
<div class="user-avatar">
<img src="https://picsum.photos/seed/user/100/100" alt="Avatar">
</div>
</div>
</header>
<!-- Sidebar -->
<aside class="sidebar" id="sidebar">
<a href="#" class="nav-item active" onclick="app.goHome()">
<i class="fa-solid fa-house"></i>
<span>Accueil</span>
</a>
<a href="#" class="nav-item">
<i class="fa-solid fa-fire"></i>
<span>Tendances</span>
</a>
<a href="#" class="nav-item">
<i class="fa-solid fa-music"></i>
<span>Musique</span>
</a>
<a href="#" class="nav-item">
<i class="fa-solid fa-gamepad"></i>
<span>Jeux vidéo</span>
</a>
<div class="nav-section-title">Mes Abonnements</div>
<a href="#" class="nav-item">
<i class="fa-solid fa-user-circle"></i>
<span>TechMaster</span>
</a>
<a href="#" class="nav-item">
<i class="fa-solid fa-user-circle"></i>
<span>NatureVibe</span>
</a>
<a href="#" class="nav-item">
<i class="fa-solid fa-user-circle"></i>
<span>CodingLife</span>
</a>
</aside>
<!-- Main Content -->
<main id="main-content">
<!-- HOME VIEW -->
<section id="home-view">
<div class="chips-container">
<div class="chip active">Tout</div>
<div class="chip">Jeux vidéo</div>
<div class="chip">Musique</div>
<div class="chip">Direct</div>
<div class="chip">Programmation</div>
<div class="chip">Nature</div>
<div class="chip">Cuisine</div>
<div class="chip">Actualités</div>
</div>
<div class="video-grid" id="video-grid">
<!-- Video cards injected by JS -->
</div>
</section>
<!-- WATCH VIEW -->
<section id="watch-view">
<div class="player-column">
<div class="video-wrapper">
<video id="main-player" controls>
<source src="" type="video/mp4">
Votre navigateur ne supporte pas la lecture vidéo.
</video>
</div>
<h1 class="watch-title" id="watch-title">Titre de la vidéo</h1>
<div class="watch-actions-bar">
<div class="channel-info-row">
<img src="" alt="" class="channel-icon" id="watch-channel-icon">
<div>
<h3 id="watch-channel-name">Nom de la chaîne</h3>
<span style="font-size: 0.8rem; color: #aaa;">120 k abonnés</span>
</div>
<button class="subscribe-btn" onclick="app.toggleSubscribe(this)">S'abonner</button>
</div>
<div class="actions-buttons">
<button class="action-chip" onclick="app.showToast('J\'aime cette vidéo')">
<i class="fa-regular fa-thumbs-up"></i> 12k
</button>
<button class="action-chip" onclick="app.showToast('Je n\'aime pas cette vidéo')">
<i class="fa-regular fa-thumbs-down"></i>
</button>
<button class="action-chip" onclick="app.showToast('Lien copié !')">
<i class="fa-solid fa-share"></i> Partager
</button>
</div>
</div>
<div class="description-box" id="watch-description">
<!-- Description injected here -->
</div>
<div class="comments-section">
<h3>142 Commentaires</h3>
<br>
<div class="comment">
<div class="user-avatar" style="width: 40px; height: 40px;">
<img src="https://picsum.photos/seed/c1/40/40" alt="User">
</div>
<div class="comment-body">
<h4>Jean Dupont <span style="color:#aaa; font-weight:400; font-size:0.75rem;">Il y a 2 heures</span></h4>
<p>Super vidéo, merci pour le contenu ! J'ai appris beaucoup de choses.</p>
</div>
</div>
<div class="comment">
<div class="user-avatar" style="width: 40px; height: 40px;">
<img src="https://picsum.photos/seed/c2/40/40" alt="User">
</div>
<div class="comment-body">
<h4>Sarah Connor <span style="color:#aaa; font-weight:400; font-size:0.75rem;">Il y a 5 heures</span></h4>
>La qualité est incroyable. Continue comme ça !</p>
</div>
</div>
</div>
</div>
<div class="recommendations-column" id="recommendations-list">
<!-- Recommendations injected by JS -->
</div>
</section>
</main>
<!-- Toast Container -->
<div id="toast-container"></div>
<script>
/**
* Application Logic
* Handles data, routing between Home and Watch views, and interactions.
*/
const app = {
// Mock Data: Videos
// Using Pexels Sample Videos for functionality
videos: [
{
id: 1,
title: "L'avenir de l'Intelligence Artificielle en 2024",
channel: "TechMaster",
views: "1.2 M de vues",
date: "il y a 2 jours",
duration: "12:34",
thumbnail: "https://picsum.photos/seed/tech1/400/225",
avatar: "https://picsum.photos/seed/avatar1/50/50",
description: "Découvrez comment l'IA va transformer notre quotidien dans cette analyse approfondie des dernières technologies.",
videoSrc: "https://videos.pexels.com/video-files/3129671/3129671-uhd_2560_1440_30fps.mp4"
},
{
id: 2,
title: "Relaxation : Sons de la forêt et pluie douce",
channel: "NatureVibe",
views: "850 k vues",
date: "il y a 1 semaine",
duration: "45:00",
thumbnail: "https://picsum.photos/seed/nature1/400/225",
avatar: "https://picsum.photos/seed/avatar2/50/50",
description: "Une vidéo pour se détendre et se concentrer. Enregistrement binaural haute qualité.",
videoSrc: "https://videos.pexels.com/video-files/855564/855564-hd_1920_1080_30fps.mp4"
},
{
id: 3,
title: "Apprendre le CSS Grid en 10 minutes",
channel: "CodeFast",
views: "45 k vues",
date: "il y a 4 heures",
duration: "10:05",
thumbnail: "https://picsum.photos/seed/code1/400/225",
avatar: "https://picsum.photos/seed/avatar3/50/50",
description: "Le guide ultime pour maîtriser les mises en page modernes avec CSS Grid.",
videoSrc: "https://videos.pexels.com/video-files/3129957/3129957-uhd_2560_1440_25fps.mp4"
},
{
id: 4,
title: "Voyage au Japon : Les rues de Tokyo",
channel: "TravelDiaries",
views: "2.5 M de vues",
date: "il y a 1 mois",
duration: "24:10",
thumbnail: "https://picsum.photos/seed/travel1/400/225",
avatar: "https://picsum.photos/seed/avatar4/50/50",
description: "Explorons la capitale japonaise, de Shinjuku à Akihabara. Une immersion culturelle totale.",
videoSrc: "https://videos.pexels.com/video-files/5752729/5752729-hd_1920_1080_25fps.mp4"
},
{
id: 5,
title: "Recette : Pâtes Carbonara Authentiques",
channel: "Chef Luigi",
views: "300 k vues",
date: "il y a 3 jours",
duration: "08:45",
thumbnail: "https://picsum.photos/seed/food1/400/225",
avatar: "https://picsum.photos/seed/avatar5/50/50",
description: "Oubliez la crème ! Voici la vraie recette romaine pour des pâtes parfaites.",
videoSrc: "https://videos.pexels.com/video-files/5497132/5497132-hd_1920_1080_25fps.mp4"
},
{
id: 6,
title: "Top 10 des Buts de l'Année",
channel: "SportCenter",
views: "5 M de vues",
date: "il y a 2 mois",
duration: "15:20",
thumbnail: "https://picsum.photos/seed/sport1/400/225",
avatar: "https://picsum.photos/seed/avatar6/50/50",
description: "Les moments les plus spectaculaires du monde sportif cette année.",
videoSrc: "https://videos.pexels.com/video-files/4763826/4763826-hd_1920_1080_24fps.mp4"
},
{
id: 7,
title: "Musique Lofi pour coder et travailler",
channel: "LofiGirl",
views: "10 vues en direct",
date: "En cours",
duration: "LIVE",
thumbnail: "https://picsum.photos/seed/music1/400/225",
avatar: "https://picsum.photos/seed/avatar7/50/50",
description: "Beats to relax/study to. Stream 24/7.",
videoSrc: "https://videos.pexels.com/video-files/6789143/6789143-hd_1920_1080_30fps.mp4"
},
{
id: 8,
title: "Review du nouveau Smartphone X",
channel: "GadgetsRev",
views: "600 k vues",
date: "il y a 5 jours",
duration: "18:30",
thumbnail: "https://picsum.photos/seed/gadget1/400/225",
avatar: "https://picsum.photos/seed/avatar8/50/50",
description: "Vaut-il vraiment son prix ? Tests de performance, autonomie et photo.",
videoSrc: "https://videos.pexels.com/video-files/853800/853800-hd_1920_1080_24fps.mp4"
}
],
/**
* Initialize the application
*/
init: function() {
this.renderHome();
this.setupEventListeners();
},
/**
* Render the Home Grid
*/
renderHome: function() {
const grid = document.getElementById('video-grid');
grid.innerHTML = this.videos.map(video => `
<div class="video-card" onclick="app.watchVideo(${video.id})">
<div class="thumbnail-container">
<img src="${video.thumbnail}" alt="${video.title}">
<div class="duration">${video.duration}</div>
</div>
<div class="video-info">
<img class="channel-icon" src="${video.avatar}" alt="${video.channel}">
<div class="video-details">
<h3 class="video-title">${video.title}</h3>
<div class="channel-name">${video.channel}</div>
<div class="video-meta">${video.views}${video.date}</div>
</div>
</div>
</div>
`).join('');
},
/**
* Switch to Watch View for a specific video
*/
watchVideo: function(id) {
const video = this.videos.find(v => v.id === id);
if (!video) return;
// Hide Home, Show Watch
document.getElementById('home-view').style.display = 'none';
document.getElementById('watch-view').style.display = 'flex';
document.getElementById('sidebar').style.transform = 'translateX(-100%)'; // Hide sidebar on mobile/tablet when watching
// Set Player Source
const player = document.getElementById('main-player');
player.src = video.videoSrc;
player.load();
player.play().catch(e => console.log("Auto-play prevented by browser"));
// Set Metadata
document.getElementById('watch-title').innerText = video.title;
document.getElementById('watch-channel-name').innerText = video.channel;
document.getElementById('watch-channel-icon').src = video.avatar;
document.getElementById('watch-description').innerText = video.description;
// Reset Subscribe Button
const subBtn = document.querySelector('.subscribe-btn');
subBtn.classList.remove('subscribed');
subBtn.innerText = "S'abonner";
// Render Recommendations (exclude current)
this.renderRecommendations(id);
// Scroll to top
window.scrollTo(0, 0);
},
/**
* Render Recommendations Sidebar
*/
renderRecommendations: function(currentId) {
const list = document.getElementById('recommendations-list');
const others = this.videos.filter(v => v.id !== currentId);
list.innerHTML = others.map(video => `
<div class="rec-video-card" onclick="app.watchVideo(${video.id})">
<div class="rec-thumbnail">
<img src="${video.thumbnail}" alt="${video.title}">
<div class="duration" style="font-size: 0.7rem; padding: 1px 3px;">${video.duration}</div>
</div>
<div class="rec-info">
<h4>${video.title}</h4>
<p>${video.channel}</p>
<p>${video.views}${video.date}</p>
</div>
</div>
`).join('');
},
/**
* Return to Home View
*/
goHome: function() {
// Stop Video
const player = document.getElementById('main-player');
player.pause();
player.src = "";
// Show Home, Hide Watch
document.getElementById('home-view').style.display = 'block';
document.getElementById('watch-view').style.display = 'none';
// Reset Sidebar visibility for desktop
if (window.innerWidth > 768) {
document.getElementById('sidebar').style.transform = 'translateX(0)';
}
},
/**
* Toggle Subscribe Button State
*/
toggleSubscribe: function(btn) {
if (btn.classList.contains('subscribed')) {
btn.classList.remove('subscribed');
btn.innerText = "S'abonner";
this.showToast("Abonnement annulé");
} else {
btn.classList.add('subscribed');
btn.innerText = "Abonné";
this.showToast("Abonnement réussi !");
}
},
/**
* Show a Toast Notification
*/
showToast: function(message) {
const container = document.getElementById('toast-container');
const toast = document.createElement('div');
toast.className = 'toast';
toast.innerText = message;
container.appendChild(toast);
// Remove after 3 seconds
setTimeout(() => {
toast.style.opacity = '0';
setTimeout(() => toast.remove(), 300);
}, 3000);
},
/**
* Setup Event Listeners
*/
setupEventListeners: function() {
// Mobile Menu Toggle
document.getElementById('menu-btn').addEventListener('click', () => {
const sidebar = document.getElementById('sidebar');
if (sidebar.style.transform === 'translateX(0px)') {
sidebar.style.transform = ''; // Revert to CSS default (media query dependent)
if(window.innerWidth <= 768) sidebar.style.transform = 'translateX(-100%)';
} else {
sidebar.style.transform = 'translateX(0px)';
}
});
// Search Functionality
document.getElementById('search-btn').addEventListener('click', () => {
const query = document.getElementById('search-input').value.toLowerCase();
if (!query) return;
const filtered = this.videos.filter(v =>
v.title.toLowerCase().includes(query) ||
v.channel.toLowerCase().includes(query)
);
const grid = document.getElementById('video-grid');
if (filtered.length > 0) {
this.goHome(); // Ensure we are on home view
grid.innerHTML = filtered.map(video => `
<div class="video-card" onclick="app.watchVideo(${video.id})">
<div class="thumbnail-container">
<img src="${video.thumbnail}" alt="${video.title}">
<div class="duration">${video.duration}</div>
</div>
<div class="video-info">
<img class="channel-icon" src="${video.avatar}" alt="${video.channel}">
<div class="video-details">
<h3 class="video-title">${video.title}</h3>
<div class="channel-name">${video.channel}</div>
<div class="video-meta">${video.views}${video.date}</div>
</div>
</div>
</div>
`).join('');
this.showToast(`${filtered.length} résultat(s) trouvé(s)`);
} else {
this.showToast("Aucune vidéo trouvée");
}
});
// Allow 'Enter' key for search
document.getElementById('search-input').addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
document.getElementById('search-btn').click();
}
});
}
};
// Start App
document.addEventListener('DOMContentLoaded', () => {
app.init();
});
</script>
</body>
</html>