Share-YouTube / script.js
Taf2023's picture
Upload 6 files
5565235 verified
// API Base URL
const API_BASE_URL = '/api';
// DOM Elements
const shareForm = document.getElementById('shareForm');
const linksContainer = document.getElementById('linksContainer');
const loadingSpinner = document.getElementById('loadingSpinner');
const successMessage = document.getElementById('successMessage');
const successText = document.getElementById('successText');
// Initialize app
document.addEventListener('DOMContentLoaded', function() {
loadLinks();
// Handle form submission
shareForm.addEventListener('submit', handleShareSubmit);
});
// Handle share form submission
async function handleShareSubmit(e) {
e.preventDefault();
const formData = new FormData(shareForm);
const data = {
name: formData.get('name'),
note: formData.get('note'),
youtube_link: formData.get('youtube_link')
};
// Validate YouTube URL
if (!isValidYouTubeURL(data.youtube_link)) {
alert('กรุณากรอกลิงก์ YouTube ที่ถูกต้อง');
return;
}
try {
showLoading(true);
const response = await fetch(`${API_BASE_URL}/posts`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error('เกิดข้อผิดพลาดในการแชร์');
}
const result = await response.json();
// Show success message
showSuccessMessage('แชร์สำเร็จ!');
// Clear form
shareForm.reset();
// Reload links
await loadLinks();
} catch (error) {
console.error('Error sharing link:', error);
alert('เกิดข้อผิดพลาดในการแชร์: ' + error.message);
} finally {
showLoading(false);
}
}
// Load all shared links
async function loadLinks() {
try {
showLoading(true);
const response = await fetch(`${API_BASE_URL}/posts`);
if (!response.ok) {
throw new Error('ไม่สามารถโหลดลิงก์ได้');
}
const links = await response.json();
displayLinks(links);
} catch (error) {
console.error('Error loading links:', error);
linksContainer.innerHTML = `
<div style="text-align: center; color: #666; padding: 20px;">
<i class="fas fa-exclamation-triangle"></i>
<p>ไม่สามารถโหลดลิงก์ได้: ${error.message}</p>
</div>
`;
} finally {
showLoading(false);
}
}
// Display links in the container
function displayLinks(links) {
if (links.length === 0) {
linksContainer.innerHTML = `
<div style="text-align: center; color: #666; padding: 40px;">
<i class="fab fa-youtube" style="font-size: 3rem; margin-bottom: 15px;"></i>
<p>ยังไม่มีลิงก์ที่แชร์</p>
<p>เป็นคนแรกที่แชร์ลิงก์ YouTube!</p>
</div>
`;
return;
}
linksContainer.innerHTML = links.map(link => createLinkCard(link)).join('');
// Add event listeners for like and comment buttons
addLinkEventListeners();
}
// Create HTML for a single link card
function createLinkCard(link) {
const videoId = extractYouTubeVideoId(link.youtube_link);
const embedUrl = videoId ? `https://www.youtube.com/embed/${videoId}` : '';
const timeAgo = getTimeAgo(new Date(link.created_at));
return `
<div class="link-card" data-link-id="${link.id}">
<div class="link-header">
<span class="user-name">
<i class="fas fa-user"></i> ${escapeHtml(link.name)}
</span>
<span class="timestamp">${timeAgo}</span>
</div>
<div class="link-note">
${escapeHtml(link.note)}
</div>
${embedUrl ? `
<div class="youtube-embed">
<iframe src="${embedUrl}"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
</div>
` : `
<div class="youtube-link">
<a href="${link.youtube_link}" target="_blank" rel="noopener noreferrer">
<i class="fab fa-youtube"></i> ดูวิดีโอใน YouTube
</a>
</div>
`}
<div class="link-actions">
<button class="action-btn like-btn" data-link-id="${link.id}">
<i class="fas fa-heart"></i>
<span class="like-count">${link.likes}</span>
</button>
<button class="action-btn comment-btn" data-link-id="${link.id}">
<i class="fas fa-comment"></i>
คอมเมนต์
</button>
</div>
<div class="comments-section" id="comments-${link.id}" style="display: none;">
<div class="comment-form">
<input type="text" placeholder="เขียนคอมเมนต์..." class="comment-input">
<button type="button" class="add-comment-btn" data-link-id="${link.id}">
<i class="fas fa-paper-plane"></i>
</button>
</div>
<div class="comments-list" id="comments-list-${link.id}">
<!-- Comments will be loaded here -->
</div>
</div>
</div>
`;
}
// Add event listeners for link interactions
function addLinkEventListeners() {
// Like buttons
document.querySelectorAll('.like-btn').forEach(btn => {
btn.addEventListener('click', handleLike);
});
// Comment buttons
document.querySelectorAll('.comment-btn').forEach(btn => {
btn.addEventListener('click', toggleComments);
});
// Add comment buttons
document.querySelectorAll('.add-comment-btn').forEach(btn => {
btn.addEventListener('click', handleAddComment);
});
// Enter key for comment input
document.querySelectorAll('.comment-input').forEach(input => {
input.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
const linkId = this.closest('.comments-section').id.split('-')[1];
const btn = document.querySelector(`.add-comment-btn[data-link-id="${linkId}"]`);
btn.click();
}
});
});
}
// Handle like button click
async function handleLike(e) {
const linkId = e.currentTarget.dataset.linkId;
const likeBtn = e.currentTarget;
const likeCount = likeBtn.querySelector('.like-count');
try {
const response = await fetch(`${API_BASE_URL}/posts/${linkId}/like`, {
method: 'POST'
});
if (!response.ok) {
throw new Error('ไม่สามารถถูกใจได้');
}
const result = await response.json();
likeCount.textContent = result.likes;
// Add visual feedback
likeBtn.classList.add('liked');
setTimeout(() => likeBtn.classList.remove('liked'), 1000);
} catch (error) {
console.error('Error liking post:', error);
alert('เกิดข้อผิดพลาดในการถูกใจ');
}
}
// Toggle comments section
async function toggleComments(e) {
const linkId = e.currentTarget.dataset.linkId;
const commentsSection = document.getElementById(`comments-${linkId}`);
if (commentsSection.style.display === 'none') {
commentsSection.style.display = 'block';
await loadComments(linkId);
} else {
commentsSection.style.display = 'none';
}
}
// Load comments for a specific link
async function loadComments(linkId) {
try {
const response = await fetch(`${API_BASE_URL}/posts/${linkId}/comments`);
if (!response.ok) {
throw new Error('ไม่สามารถโหลดคอมเมนต์ได้');
}
const comments = await response.json();
const commentsList = document.getElementById(`comments-list-${linkId}`);
if (comments.length === 0) {
commentsList.innerHTML = '<p style="text-align: center; color: #666; padding: 10px;">ยังไม่มีคอมเมนต์</p>';
} else {
commentsList.innerHTML = comments.map(comment => `
<div class="comment">
<div class="comment-author">
<i class="fas fa-user"></i> ${escapeHtml(comment.name)}
</div>
<div class="comment-text">${escapeHtml(comment.comment)}</div>
</div>
`).join('');
}
} catch (error) {
console.error('Error loading comments:', error);
}
}
// Handle add comment
async function handleAddComment(e) {
const linkId = e.currentTarget.dataset.linkId;
const commentsSection = document.getElementById(`comments-${linkId}`);
const commentInput = commentsSection.querySelector('.comment-input');
const commentText = commentInput.value.trim();
if (!commentText) {
alert('กรุณาเขียนคอมเมนต์');
return;
}
// Simple name prompt (in real app, you'd have user authentication)
const name = prompt('กรุณากรอกชื่อของคุณ:');
if (!name) return;
try {
const response = await fetch(`${API_BASE_URL}/posts/${linkId}/comments`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: name,
comment: commentText
})
});
if (!response.ok) {
throw new Error('ไม่สามารถเพิ่มคอมเมนต์ได้');
}
// Clear input
commentInput.value = '';
// Reload comments
await loadComments(linkId);
showSuccessMessage('เพิ่มคอมเมนต์สำเร็จ!');
} catch (error) {
console.error('Error adding comment:', error);
alert('เกิดข้อผิดพลาดในการเพิ่มคอมเมนต์');
}
}
// Utility functions
function isValidYouTubeURL(url) {
const youtubeRegex = /^(https?:\/\/)?(www\.)?(youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)[a-zA-Z0-9_-]{11}/;
return youtubeRegex.test(url);
}
function extractYouTubeVideoId(url) {
const regex = /(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([a-zA-Z0-9_-]{11})/;
const match = url.match(regex);
return match ? match[1] : null;
}
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
function getTimeAgo(date) {
const now = new Date();
const diffInSeconds = Math.floor((now - date) / 1000);
if (diffInSeconds < 60) return 'เมื่อสักครู่';
if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)} นาทีที่แล้ว`;
if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)} ชั่วโมงที่แล้ว`;
return `${Math.floor(diffInSeconds / 86400)} วันที่แล้ว`;
}
function showLoading(show) {
loadingSpinner.style.display = show ? 'block' : 'none';
}
function showSuccessMessage(message) {
successText.textContent = message;
successMessage.style.display = 'flex';
setTimeout(() => {
successMessage.style.display = 'none';
}, 3000);
}