- Add autoplay attribute to video player - Implement dynamic calculation of needed regular videos based on window height - Update video comments with Japanese content and remove default avatars
261 lines
9.5 KiB
JavaScript
261 lines
9.5 KiB
JavaScript
let videoDetails = {};
|
|
let comments = [];
|
|
let allVideos = [];
|
|
|
|
async function loadVideoData() {
|
|
try {
|
|
const response = await fetch('src/video.json');
|
|
const data = await response.json();
|
|
videoDetails = {};
|
|
allVideos = data.videos;
|
|
data.videos.forEach(video => {
|
|
videoDetails[video.id] = video;
|
|
});
|
|
comments = data.comments;
|
|
console.log('Video data loaded successfully:', allVideos.length, 'videos');
|
|
} catch (error) {
|
|
console.error('Failed to load video data:', error);
|
|
}
|
|
}
|
|
|
|
function getVideoIdFromUrl() {
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const id = urlParams.get('id');
|
|
return id ? parseInt(id) : 1;
|
|
}
|
|
|
|
function loadVideoInfo() {
|
|
const videoId = getVideoIdFromUrl();
|
|
console.log('Video ID:', videoId);
|
|
console.log('All videos:', allVideos.length);
|
|
|
|
const videoInfo = videoDetails[videoId];
|
|
console.log('Video info:', videoInfo);
|
|
|
|
if (videoInfo) {
|
|
document.getElementById('videoTitle').textContent = videoInfo.title;
|
|
document.getElementById('channelName').textContent = videoInfo.channel;
|
|
document.getElementById('channelSubscribers').textContent = videoInfo.subscribers;
|
|
document.getElementById('likeCount').textContent = videoInfo.likes;
|
|
document.getElementById('videoViews').textContent = videoInfo.views + ' views';
|
|
document.getElementById('videoUploadDate').textContent = videoInfo.uploadDate;
|
|
document.getElementById('videoDescription').textContent = videoInfo.description;
|
|
|
|
const channelAvatar = document.getElementById('channelAvatar');
|
|
if (videoInfo.channelAvatar && videoInfo.channelAvatar !== 'img/avatar/default.jpg') {
|
|
channelAvatar.innerHTML = `<img src="${videoInfo.channelAvatar}" alt="${videoInfo.channel}">`;
|
|
}
|
|
|
|
document.title = videoInfo.title + ' - YouTube Revived';
|
|
|
|
loadRelatedVideos(videoInfo);
|
|
}
|
|
|
|
renderComments();
|
|
}
|
|
|
|
function loadRelatedVideos(currentVideo) {
|
|
console.log('Loading related videos for:', currentVideo.title);
|
|
console.log('Current category:', currentVideo.category);
|
|
|
|
const currentCategory = currentVideo.category;
|
|
const currentId = currentVideo.id;
|
|
|
|
const shortsList = document.getElementById('shortsList');
|
|
const regularVideosList = document.getElementById('regularVideosList');
|
|
|
|
console.log('Shorts list element:', shortsList);
|
|
console.log('Regular videos list element:', regularVideosList);
|
|
|
|
shortsList.innerHTML = '';
|
|
regularVideosList.innerHTML = '';
|
|
|
|
const shorts = allVideos.filter(v => v.type === 'short' && v.id !== currentId);
|
|
const regularVideos = allVideos.filter(v => v.type === 'video' && v.id !== currentId);
|
|
|
|
console.log('Found shorts:', shorts.length);
|
|
console.log('Found regular videos:', regularVideos.length);
|
|
|
|
const sameCategoryShorts = shorts.filter(v => v.category === currentCategory);
|
|
const otherShorts = shorts.filter(v => v.category !== currentCategory);
|
|
|
|
const sameCategoryRegularVideos = regularVideos.filter(v => v.category === currentCategory);
|
|
const otherRegularVideos = regularVideos.filter(v => v.category !== currentCategory);
|
|
|
|
console.log('Same category shorts:', sameCategoryShorts.length);
|
|
console.log('Other shorts:', otherShorts.length);
|
|
console.log('Same category regular videos:', sameCategoryRegularVideos.length);
|
|
console.log('Other regular videos:', otherRegularVideos.length);
|
|
|
|
shuffleArray(otherShorts);
|
|
shuffleArray(otherRegularVideos);
|
|
|
|
const selectedShorts = [...sameCategoryShorts, ...otherShorts].slice(0, 3);
|
|
|
|
// Calculate needed regular videos based on page height
|
|
const calculateNeededVideos = () => {
|
|
const windowHeight = window.innerHeight;
|
|
const relatedSection = document.querySelector('.related-videos-section');
|
|
const shortsSection = document.querySelector('.shorts-section');
|
|
|
|
if (!relatedSection || !shortsSection) {
|
|
return 10; // Default to 10 if elements not found
|
|
}
|
|
|
|
const shortsHeight = shortsSection.offsetHeight;
|
|
const availableHeight = windowHeight - shortsHeight - 48; // 48px for padding/gap
|
|
|
|
// Estimate height per regular video item (including gap)
|
|
const estimatedVideoHeight = 100; // Average height of each video item
|
|
|
|
// Calculate needed videos
|
|
const neededVideos = Math.ceil(availableHeight / estimatedVideoHeight);
|
|
|
|
// Ensure we don't exceed available videos
|
|
const totalAvailableVideos = sameCategoryRegularVideos.length + otherRegularVideos.length;
|
|
return Math.min(neededVideos, totalAvailableVideos);
|
|
};
|
|
|
|
const neededVideosCount = calculateNeededVideos();
|
|
const selectedRegularVideos = [...sameCategoryRegularVideos, ...otherRegularVideos].slice(0, neededVideosCount);
|
|
|
|
console.log('Selected shorts:', selectedShorts.length);
|
|
console.log('Selected regular videos:', selectedRegularVideos.length, '(needed:', neededVideosCount, ')');
|
|
console.log('Window height:', window.innerHeight);
|
|
|
|
selectedShorts.forEach(short => {
|
|
const shortElement = document.createElement('div');
|
|
shortElement.className = 'short-item';
|
|
shortElement.innerHTML = `
|
|
<div class="short-thumbnail">
|
|
<img src="${short.thumbnail}" alt="${short.title}">
|
|
</div>
|
|
<div class="short-info">
|
|
<h4 class="short-title">${short.title}</h4>
|
|
<p class="short-channel">${short.channel}</p>
|
|
<p class="short-views">${short.views} views</p>
|
|
</div>
|
|
`;
|
|
shortElement.addEventListener('click', () => {
|
|
window.location.href = `video.html?id=${short.id}`;
|
|
});
|
|
shortsList.appendChild(shortElement);
|
|
});
|
|
|
|
selectedRegularVideos.forEach(video => {
|
|
const videoElement = document.createElement('div');
|
|
videoElement.className = 'regular-video-item';
|
|
videoElement.innerHTML = `
|
|
<div class="regular-video-thumbnail">
|
|
<img src="${video.thumbnail}" alt="${video.title}">
|
|
</div>
|
|
<div class="regular-video-info">
|
|
<h4 class="regular-video-title">${video.title}</h4>
|
|
<p class="regular-video-channel">${video.channel}</p>
|
|
<p class="regular-video-meta">${video.views} views • ${video.uploadDate}</p>
|
|
</div>
|
|
`;
|
|
videoElement.addEventListener('click', () => {
|
|
window.location.href = `video.html?id=${video.id}`;
|
|
});
|
|
regularVideosList.appendChild(videoElement);
|
|
});
|
|
}
|
|
|
|
function shuffleArray(array) {
|
|
for (let i = array.length - 1; i > 0; i--) {
|
|
const j = Math.floor(Math.random() * (i + 1));
|
|
[array[i], array[j]] = [array[j], array[i]];
|
|
}
|
|
}
|
|
|
|
function renderComments() {
|
|
const commentsList = document.getElementById('commentsList');
|
|
const commentsCount = document.getElementById('commentsCount');
|
|
|
|
commentsCount.textContent = comments.length + ' Comments';
|
|
commentsList.innerHTML = '';
|
|
|
|
comments.forEach(comment => {
|
|
const commentElement = document.createElement('div');
|
|
commentElement.className = 'comment-item';
|
|
commentElement.innerHTML = `
|
|
<div class="comment-avatar">
|
|
<i class="fas fa-user avatar-img"></i>
|
|
</div>
|
|
<div class="comment-content">
|
|
<div class="comment-header">
|
|
<span class="comment-author">${comment.author}</span>
|
|
<span class="comment-time">${comment.time}</span>
|
|
</div>
|
|
<p class="comment-text">${comment.content}</p>
|
|
<div class="comment-actions">
|
|
<button class="comment-action-btn">
|
|
<i class="fas fa-thumbs-up"></i>
|
|
</button>
|
|
<button class="comment-action-btn">
|
|
<i class="fas fa-thumbs-down"></i>
|
|
</button>
|
|
<button class="comment-action-btn">
|
|
<i class="fas fa-reply"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
commentsList.appendChild(commentElement);
|
|
});
|
|
}
|
|
|
|
async function initVideoPage() {
|
|
await loadVideoData();
|
|
loadVideoInfo();
|
|
setupEventListeners();
|
|
}
|
|
|
|
function setupEventListeners() {
|
|
const moreBtn = document.getElementById('moreBtn');
|
|
const moreDropdown = document.getElementById('moreDropdown');
|
|
|
|
if (moreBtn && moreDropdown) {
|
|
moreBtn.addEventListener('click', (e) => {
|
|
e.stopPropagation();
|
|
moreDropdown.classList.toggle('show');
|
|
});
|
|
|
|
document.addEventListener('click', () => {
|
|
moreDropdown.classList.remove('show');
|
|
});
|
|
}
|
|
|
|
const descriptionToggle = document.getElementById('descriptionToggle');
|
|
const videoDescription = document.getElementById('videoDescription');
|
|
|
|
if (descriptionToggle && videoDescription) {
|
|
descriptionToggle.addEventListener('click', () => {
|
|
videoDescription.classList.toggle('expanded');
|
|
const icon = descriptionToggle.querySelector('i');
|
|
if (videoDescription.classList.contains('expanded')) {
|
|
icon.classList.remove('fa-chevron-down');
|
|
icon.classList.add('fa-chevron-up');
|
|
} else {
|
|
icon.classList.remove('fa-chevron-up');
|
|
icon.classList.add('fa-chevron-down');
|
|
}
|
|
});
|
|
}
|
|
|
|
const subscribeBtn = document.getElementById('subscribeBtn');
|
|
if (subscribeBtn) {
|
|
subscribeBtn.addEventListener('click', () => {
|
|
subscribeBtn.classList.toggle('subscribed');
|
|
if (subscribeBtn.classList.contains('subscribed')) {
|
|
subscribeBtn.textContent = 'Subscribed';
|
|
} else {
|
|
subscribeBtn.textContent = 'Subscribe';
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', () => initVideoPage());
|