- Created complete documentation in docs/ directory - Added PROJECT_OVERVIEW.md with feature highlights and getting started guide - Added ARCHITECTURE.md with system design and technical details - Added SECURITY.md with comprehensive security implementation guide - Added DEVELOPMENT.md with development workflows and best practices - Added DEPLOYMENT.md with production deployment instructions - Added API.md with complete REST API documentation - Added CONTRIBUTING.md with contribution guidelines - Added CHANGELOG.md with version history and migration notes - Reorganized all documentation files into docs/ directory for better organization - Updated README.md with proper documentation links and quick navigation - Enhanced project structure with professional documentation standards
256 lines
14 KiB
Smarty
256 lines
14 KiB
Smarty
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>{if $file_title}{$file_title} - EasyStream{else}Watch Video - EasyStream{/if}</title>
|
|
<link rel="stylesheet" href="{$main_url}/f_templates/tpl_frontend/css/player.css">
|
|
<style>
|
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 0; background: #0f0f0f; color: #fff; }
|
|
.header { background: #212121; border-bottom: 1px solid #333; padding: 1rem 0; }
|
|
.header-content { max-width: 1200px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; padding: 0 20px; }
|
|
.logo { font-size: 1.5rem; font-weight: bold; color: #ff0000; text-decoration: none; }
|
|
.nav { display: flex; gap: 2rem; }
|
|
.nav a { color: #fff; text-decoration: none; padding: 0.5rem 1rem; border-radius: 4px; transition: all 0.2s; }
|
|
.nav a:hover { background: #333; }
|
|
.player-container { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
|
.video-player { background: #000; border-radius: 8px; overflow: hidden; margin-bottom: 1rem; position: relative; }
|
|
.video-info { background: #212121; padding: 1.5rem; border-radius: 8px; margin-bottom: 1rem; }
|
|
.video-title { font-size: 1.5rem; font-weight: 600; margin: 0 0 1rem 0; line-height: 1.3; }
|
|
.video-meta { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 1rem; margin-bottom: 1rem; }
|
|
.video-stats { display: flex; align-items: center; gap: 1rem; color: #aaa; }
|
|
.video-actions { display: flex; gap: 0.5rem; }
|
|
.action-btn { background: #333; color: #fff; border: none; padding: 0.5rem 1rem; border-radius: 20px; cursor: pointer; display: flex; align-items: center; gap: 0.5rem; transition: all 0.2s; }
|
|
.action-btn:hover { background: #555; }
|
|
.action-btn.liked { background: #065fd4; }
|
|
.channel-info { display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem; }
|
|
.channel-avatar { width: 40px; height: 40px; border-radius: 50%; }
|
|
.channel-details h3 { margin: 0; font-size: 1rem; }
|
|
.channel-details p { margin: 0; color: #aaa; font-size: 0.875rem; }
|
|
.subscribe-btn { background: #cc0000; color: white; border: none; padding: 0.5rem 1rem; border-radius: 20px; cursor: pointer; font-weight: 500; }
|
|
.subscribe-btn:hover { background: #aa0000; }
|
|
.subscribe-btn.subscribed { background: #333; }
|
|
.video-description { color: #ccc; line-height: 1.5; }
|
|
.sidebar { background: #212121; border-radius: 8px; padding: 1rem; }
|
|
.related-videos { display: grid; gap: 1rem; }
|
|
.related-video { display: flex; gap: 1rem; padding: 0.5rem; border-radius: 4px; transition: background 0.2s; cursor: pointer; }
|
|
.related-video:hover { background: #333; }
|
|
.related-thumbnail { width: 120px; height: 68px; border-radius: 4px; object-fit: cover; }
|
|
.related-info h4 { margin: 0 0 0.25rem 0; font-size: 0.875rem; line-height: 1.2; }
|
|
.related-info p { margin: 0; color: #aaa; font-size: 0.75rem; }
|
|
.comments-section { background: #212121; border-radius: 8px; padding: 1.5rem; margin-top: 1rem; }
|
|
.comments-header { margin-bottom: 1.5rem; }
|
|
.comment-form { margin-bottom: 2rem; }
|
|
.comment-input { width: 100%; background: #333; border: 1px solid #555; color: #fff; padding: 0.75rem; border-radius: 4px; resize: vertical; min-height: 80px; }
|
|
.comment-actions { display: flex; gap: 0.5rem; margin-top: 0.5rem; }
|
|
.comment-btn { background: #065fd4; color: white; border: none; padding: 0.5rem 1rem; border-radius: 4px; cursor: pointer; }
|
|
.comment-btn:hover { background: #0a5bc4; }
|
|
.comment-btn.cancel { background: #333; }
|
|
.comment { margin-bottom: 1rem; }
|
|
.comment-header { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem; }
|
|
.comment-avatar { width: 24px; height: 24px; border-radius: 50%; }
|
|
.comment-author { font-weight: 500; font-size: 0.875rem; }
|
|
.comment-time { color: #aaa; font-size: 0.75rem; }
|
|
.comment-text { color: #ccc; line-height: 1.4; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<header class="header">
|
|
<div class="header-content">
|
|
<a href="{$main_url}" class="logo">🎬 EasyStream</a>
|
|
<nav class="nav">
|
|
<a href="{$main_url}">Home</a>
|
|
<a href="{$main_url}/videos">Videos</a>
|
|
<a href="{$main_url}/broadcasts">Live</a>
|
|
<a href="{$main_url}/upload">Upload</a>
|
|
{if $smarty.session.USER_ID}
|
|
<a href="{$main_url}/account">Account</a>
|
|
{else}
|
|
<a href="{$main_url}/signin">Sign In</a>
|
|
{/if}
|
|
</nav>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="player-container">
|
|
<div style="display: grid; grid-template-columns: 1fr 350px; gap: 20px;">
|
|
<div class="main-content">
|
|
<!-- Video Player Area -->
|
|
<div class="video-player">
|
|
{generate_html type="view_layout" bullet_id="ct-bullet1" entry_id="ct-entry-details1" section="view" bb="0"}
|
|
</div>
|
|
|
|
<!-- Video Information -->
|
|
<div class="video-info">
|
|
<h1 class="video-title">{if $file_title}{$file_title}{else}Video Title{/if}</h1>
|
|
|
|
<div class="video-meta">
|
|
<div class="video-stats">
|
|
<span>{if $file_views}{$file_views|number_format} views{else}0 views{/if}</span>
|
|
<span>•</span>
|
|
<span>{if $upload_date}{$upload_date|date_format:"%b %d, %Y"}{else}Recently uploaded{/if}</span>
|
|
</div>
|
|
|
|
<div class="video-actions">
|
|
{if $file_rating eq "1"}
|
|
<button class="action-btn like-btn" data-action="like">
|
|
👍 <span class="like-count">{if $file_like}{$file_like|number_format}{else}0{/if}</span>
|
|
</button>
|
|
<button class="action-btn dislike-btn" data-action="dislike">
|
|
👎 <span class="dislike-count">{if $file_dislike}{$file_dislike|number_format}{else}0{/if}</span>
|
|
</button>
|
|
{/if}
|
|
|
|
{if $file_social_sharing eq "1"}
|
|
<button class="action-btn share-btn">
|
|
📤 Share
|
|
</button>
|
|
{/if}
|
|
|
|
{if $file_favorites eq "1"}
|
|
<button class="action-btn save-btn">
|
|
💾 Save
|
|
</button>
|
|
{/if}
|
|
|
|
{if $file_watchlist eq "1"}
|
|
<button class="action-btn watchlist-btn">
|
|
🕒 Watch Later
|
|
</button>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Channel Information -->
|
|
<div class="channel-info">
|
|
<img src="{if $usr_photo}{$usr_photo}{else}{$main_url}/f_templates/tpl_frontend/img/default-avatar.png{/if}"
|
|
alt="{if $usr_dname}{$usr_dname}{else}{$usr_user}{/if}" class="channel-avatar">
|
|
<div class="channel-details">
|
|
<h3>{if $usr_dname}{$usr_dname}{elseif $ch_title}{$ch_title}{else}{$usr_user}{/if}</h3>
|
|
<p>{if $usr_subscribers}{$usr_subscribers|number_format} subscribers{else}No subscribers yet{/if}</p>
|
|
</div>
|
|
<div style="margin-left: auto;">
|
|
{if $smarty.session.USER_ID and $smarty.session.USER_ID neq $usr_id}
|
|
<button class="subscribe-btn" data-user-id="{$usr_id}">
|
|
{if $user_issub}Subscribed{else}Subscribe{/if}
|
|
</button>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Video Description -->
|
|
{if $file_description}
|
|
<div class="video-description">
|
|
<p>{$file_description|nl2br}</p>
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
|
|
<!-- Comments Section -->
|
|
{if $file_comments eq "1"}
|
|
<div class="comments-section">
|
|
<div class="comments-header">
|
|
<h3>{if $file_comment_count}{$file_comment_count|number_format} Comments{else}0 Comments{/if}</h3>
|
|
</div>
|
|
|
|
{if $smarty.session.USER_ID}
|
|
<div class="comment-form">
|
|
<textarea class="comment-input" placeholder="Add a comment..." id="comment-text"></textarea>
|
|
<div class="comment-actions">
|
|
<button class="comment-btn cancel" onclick="document.getElementById('comment-text').value=''; this.parentElement.parentElement.style.display='none';">Cancel</button>
|
|
<button class="comment-btn" onclick="postComment()">Comment</button>
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
|
|
<div id="comments-list">
|
|
<!-- Comments will be loaded here -->
|
|
<div class="comment">
|
|
<div class="comment-header">
|
|
<img src="{$main_url}/f_templates/tpl_frontend/img/default-avatar.png" alt="User" class="comment-avatar">
|
|
<span class="comment-author">Sample User</span>
|
|
<span class="comment-time">2 hours ago</span>
|
|
</div>
|
|
<div class="comment-text">
|
|
This is a sample comment to show the layout. Comments will be loaded dynamically.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
|
|
<!-- Sidebar with Related Videos -->
|
|
<div class="sidebar">
|
|
<h3 style="margin: 0 0 1rem 0;">Up Next</h3>
|
|
<div class="related-videos" id="related-videos">
|
|
<!-- Related videos will be loaded here -->
|
|
<div class="related-video">
|
|
<img src="{$main_url}/f_templates/tpl_frontend/img/default-thumb.jpg" alt="Related Video" class="related-thumbnail">
|
|
<div class="related-info">
|
|
<h4>Sample Related Video</h4>
|
|
<p>Channel Name</p>
|
|
<p>1.2M views • 3 days ago</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Enhanced video player interactions
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Like/Dislike functionality
|
|
document.querySelectorAll('.like-btn, .dislike-btn').forEach(btn => {
|
|
btn.addEventListener('click', function() {
|
|
const action = this.dataset.action;
|
|
// Add AJAX call to existing EasyStream like system
|
|
console.log('Action:', action);
|
|
});
|
|
});
|
|
|
|
// Subscribe functionality
|
|
const subscribeBtn = document.querySelector('.subscribe-btn');
|
|
if (subscribeBtn) {
|
|
subscribeBtn.addEventListener('click', function() {
|
|
const userId = this.dataset.userId;
|
|
// Add AJAX call to existing EasyStream subscription system
|
|
console.log('Subscribe to user:', userId);
|
|
});
|
|
}
|
|
|
|
// Comment form interactions
|
|
const commentInput = document.getElementById('comment-text');
|
|
if (commentInput) {
|
|
commentInput.addEventListener('focus', function() {
|
|
this.parentElement.querySelector('.comment-actions').style.display = 'flex';
|
|
});
|
|
}
|
|
|
|
// Load related videos and comments via existing EasyStream system
|
|
loadRelatedVideos();
|
|
loadComments();
|
|
});
|
|
|
|
function loadRelatedVideos() {
|
|
// Integration with existing EasyStream related videos system
|
|
// This would call the existing VView::sideColumn() method
|
|
}
|
|
|
|
function loadComments() {
|
|
// Integration with existing EasyStream comments system
|
|
// This would call the existing VComments::browseComment() method
|
|
}
|
|
|
|
function postComment() {
|
|
const text = document.getElementById('comment-text').value;
|
|
if (text.trim()) {
|
|
// Integration with existing EasyStream comment posting
|
|
// This would call the existing VComments::postComment() method
|
|
console.log('Posting comment:', text);
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |