full enhance of anime page and player.

This commit is contained in:
2025-12-31 02:05:10 +01:00
parent a4ff19c3d7
commit 2afb9742b1
23 changed files with 3900 additions and 4443 deletions

View File

@@ -1,17 +1,21 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="/public/assets/waifuboards.ico" type="image/x-icon">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="/public/assets/waifuboards.ico" type="image/x-icon" />
<title>WaifuBoard</title>
<link rel="stylesheet" href="/views/css/globals.css">
<link rel="stylesheet" href="/views/css/components/anilist-modal.css">
<link rel="stylesheet" href="/views/css/components/hero.css">
<link rel="stylesheet" href="/views/css/anime/anime.css">
<link rel="stylesheet" href="/views/css/components/updateNotifier.css">
<script src="/src/scripts/titlebar.js"></script>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<link rel="stylesheet" href="https://cdn.plyr.io/3.7.8/plyr.css" />
<script src="https://cdn.plyr.io/3.7.8/plyr.js"></script>
<link rel="stylesheet" href="/views/css/globals.css" />
<link rel="stylesheet" href="/views/css/components/anilist-modal.css" />
<link rel="stylesheet" href="/views/css/anime/anime.css" />
<link rel="stylesheet" href="/views/css/anime/player.css" />
<link rel="stylesheet" href="/views/css/components/titlebar.css">
<script src="/src/scripts/titlebar.js"></script>
</head>
<body>
<div id="titlebar">
@@ -20,137 +24,158 @@
<span class="app-title">WaifuBoard</span>
</div>
<div class="title-right">
<button class="min"></button>
<button class="min"></button>
<button class="max">🗖</button>
<button class="close"></button>
</div>
</div>
<a href="/anime" class="back-btn">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<path d="M19 12H5"/><path d="M12 19l-7-7 7-7"/>
</svg>
Back
</a>
<div class="modal-overlay" id="desc-modal">
<div class="modal-content">
<button class="modal-close" onclick="closeModal()"></button>
<button class="modal-close" onclick="closeDescriptionModal()"></button>
<h2 class="modal-title">Synopsis</h2>
<div class="modal-text" id="full-description"></div>
</div>
</div>
<a href="/anime" class="back-btn">
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path d="M15 19l-7-7 7-7"/></svg>
Back to Home
</a>
<div class="top-media-wrapper" id="top-media-wrapper">
<div class="hero-wrapper">
<div class="video-background">
<div id="player"></div>
<div class="hero-wrapper" id="hero-wrapper">
<div class="video-background"><div id="trailer-player"></div></div>
<div class="hero-overlay"></div>
</div>
<div class="hero-overlay"></div>
</div>
<div class="content-container">
<aside class="sidebar">
<div class="poster-card">
<img id="poster" src="" alt="">
</div>
<div class="info-grid">
<div class="info-item">
<h4>Format</h4>
<span id="format">--</span>
</div>
<div class="info-item">
<h4>Episodes</h4>
<span id="episodes">--</span>
</div>
<div class="info-item">
<h4>Status</h4>
<span id="status">--</span>
</div>
<div class="info-item">
<h4>Season</h4>
<span id="season">--</span>
</div>
<div class="info-item">
<h4>Studio</h4>
<span id="studio">--</span>
</div>
</div>
<div class="info-grid">
<div class="info-item">
<h4>Main Characters</h4>
<div class="character-list" id="char-list"></div>
</div>
</div>
</aside>
<main class="main-content">
<div class="anime-header">
<h1 class="anime-title" id="title">Loading...</h1>
<div class="meta-row">
<div class="pill extension-pill" id="extension-pill" style="display: none; background: #8b5cf6;"></div>
<div class="pill" id="local-pill" style="display: none; background: #8b5cf6;"></div>
<div class="pill score" id="score">--% Score</div>
<div class="pill" id="year">----</div>
<div class="pill" id="genres">Action</div>
</div>
<div class="action-row">
<button class="btn-watch" id="watch-btn">
<svg width="24" height="24" fill="currentColor" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg>
Start Watching
</button>
<button class="btn-secondary" id="add-to-list-btn" onclick="openAddToListModal()">+ Add to List</button>
</div>
</div>
<div class="description-box">
<div id="description-preview"></div>
<button id="read-more-btn" class="read-more-btn" style="display: none;" onclick="openModal()">
Read More
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M19 9l-7 7-7-7"/></svg>
<div class="player-wrapper" id="player-wrapper" style="display: none;">
<div class="player-container">
<button id="prev-ep-btn" class="side-nav-btn left" title="Previous Episode">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 18l-6-6 6-6"/></svg>
</button>
</div>
<div class="episodes-section">
<div class="episodes-header-row">
<div class="section-title" style="margin:0; border:none; padding:0;">
<h2 style="font-size: 1.8rem; border-left: 4px solid #8b5cf6; padding-left: 1rem;">Episodes</h2>
<button id="next-ep-btn" class="side-nav-btn right" title="Next Episode">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18l6-6-6-6"/></svg>
</button>
<div class="player-header">
<div class="header-left">
<button class="btn-icon-glass" id="close-player-btn" title="Close Player">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 12H5"/><path d="M12 19l-7-7 7-7"/></svg>
</button>
<div class="episode-info">
<span class="ep-label">Watching</span>
<span id="player-episode-title" class="ep-title">Episode 1</span>
</div>
</div>
<div class="episode-search-wrapper">
<input type="number" id="ep-search" class="episode-search-input" placeholder="Jump to Ep #" min="1">
<div class="header-right">
<div class="settings-group">
<div class="sd-toggle" id="sd-toggle" data-state="sub">
<div class="sd-bg"></div>
<div class="sd-option active" id="opt-sub">Sub</div>
<div class="sd-option" id="opt-dub">Dub</div>
</div>
<select id="server-select" class="glass-select" style="display:none;"></select>
<select id="extension-select" class="glass-select"></select>
</div>
</div>
</div>
<div class="episodes-grid" id="episodes-grid"></div>
<div class="pagination-controls" id="pagination-controls">
<button class="page-btn" id="prev-page" onclick="changePage(-1)">Previous</button>
<span class="page-info" id="page-info">Page 1 of 1</span>
<button class="page-btn" id="next-page" onclick="changePage(1)">Next</button>
<div class="video-frame">
<video id="player" controls crossorigin playsinline></video>
<div id="player-loading" class="player-loading-overlay">
<div class="spinner"></div>
<p id="player-loading-text">Loading Stream...</p>
</div>
</div>
</div>
</main>
</div>
</div>
<div id="updateToast" class="hidden">
<p>Update available: <span id="latestVersionDisplay">v1.x</span></p>
<a id="downloadButton" href="https://git.waifuboard.app/ItsSkaiya/WaifuBoard/releases" target="_blank">
Click To Download
</a>
</div>
<div class="content-container" id="main-content">
<div class="anime-header">
<h1 class="anime-title" id="title">Loading...</h1>
<div class="hero-meta-info">
<span id="local-pill" class="pill-local" style="display:none;">Local</span>
<span id="extension-pill" class="pill-local" style="background:#8b5cf6; display:none;">Ext</span>
<span id="score">--% Score</span><span id="year">----</span><span id="format">--</span><span id="episodes">-- Ep</span>
</div>
<div class="hero-description-mini" id="description-preview"></div>
<div class="hero-tags" id="genres"></div>
<script src="/src/scripts/updateNotifier.js"></script>
<script src="/src/scripts/rpc-inapp.js"></script>
<script src="/src/scripts/auth-guard.js"></script>
<div class="action-row">
<button class="btn-watch" id="watch-btn">
<svg width="20" height="20" viewBox="0 0 24 24" fill="black"><path d="M8 5v14l11-7z"/></svg>
Start Watching
</button>
<button class="btn-add-list" id="add-to-list-btn">+ Add to List</button>
</div>
</div>
<div class="main-layout">
<aside class="poster-section">
<div class="poster-card"><img id="poster" src="" alt="Poster"></div>
<div class="metadata-sidebar">
<div class="meta-item-side"><span>Status</span><p id="status">--</p></div>
<div class="meta-item-side"><span>Season</span><p id="season">--</p></div>
<div class="meta-item-side"><span>Studio</span><p id="studio">--</p></div>
</div>
</aside>
<div class="content-column">
<section class="episodes-section">
<div class="episodes-header-row">
<h2>Episodes</h2>
<input type="number" id="ep-search" class="episode-search-input" placeholder="Jump to...">
</div>
<div id="episodes-grid" class="episodes-grid"></div>
<div class="pagination-controls" id="pagination-controls">
<button class="page-btn" id="prev-page">Previous</button>
<span class="page-info" id="page-info">Page 1 of 1</span>
<button class="page-btn" id="next-page">Next</button>
</div>
</section>
<div id="relations-section" style="display:none; margin-top: 3rem;">
<h3 class="subsection-title">Relations</h3>
<div class="relations-horizontal" id="relations-grid"></div>
</div>
</div>
</div>
<section class="content-section">
<h2 class="subsection-title">Characters</h2>
<div class="characters-grid" id="char-list"></div>
<button id="show-more-chars" class="btn-show-more" style="display: none;">Show Full Cast</button>
</section>
<section class="content-section">
<h2 class="subsection-title">Recommended</h2>
<div class="carousel-wrapper">
<button class="scroll-btn left" onclick="scrollRecommendations(-1)"></button>
<div class="carousel" id="recommendations-grid"></div>
<button class="scroll-btn right" onclick="scrollRecommendations(1)"></button>
</div>
</section>
</div>
<script src="/src/scripts/utils/auth-utils.js"></script>
<script src="/src/scripts/utils/notification-utils.js"></script>
<script src="/src/scripts/utils/url-utils.js"></script>
<script src="/src/scripts/utils/pagination-manager.js"></script>
<script src="/src/scripts/utils/media-metadata-utils.js"></script>
<script src="/src/scripts/utils/youtube-player-utils.js"></script>
<script src="/src/scripts/utils/list-modal-manager.js"></script>
<script src="/src/scripts/anime/anime.js"></script>
<script src="/src/scripts/anime/player.js"></script>
<script src="/src/scripts/anime/entry.js"></script>
</body>
</html>

View File

@@ -1,197 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WaifuBoard Watch</title>
<link rel="stylesheet" href="/views/css/globals.css">
<link rel="stylesheet" href="/views/css/anime/watch.css">
<link rel="stylesheet" href="/views/css/components/updateNotifier.css">
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<link rel="stylesheet" href="https://cdn.plyr.io/3.7.8/plyr.css" />
<script src="https://cdn.plyr.io/3.7.8/plyr.js"></script>
<link rel="icon" href="/public/assets/waifuboards.ico">
<link rel="stylesheet" href="/views/css/components/titlebar.css">
<script src="/src/scripts/titlebar.js"></script>
</head>
<body>
<div id="titlebar"> <div class="title-left">
<img class="app-icon" src="/public/assets/waifuboards.ico" alt=""/>
<span class="app-title">WaifuBoard</span>
</div>
<div class="title-right">
<button class="min"></button>
<button class="max">🗖</button>
<button class="close"></button>
</div>
</div>
<header class="top-bar">
<a href="#" id="back-link" class="back-btn">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24">
<path d="M15 19l-7-7 7-7"/>
</svg>
<span>Back to Series</span>
</a>
</header>
<div class="ui-scale-wrapper">
<main class="watch-container">
<section class="anime-details">
<div class="details-container">
<div class="details-cover">
<img id="detail-cover-image" src="" alt="Anime Cover" class="cover-image">
</div>
<div class="details-content">
<h1 id="anime-title-details">Loading...</h1>
<div class="details-meta">
<span id="detail-format" class="meta-badge">--</span>
<span id="detail-season" class="meta-badge">--</span>
<span id="detail-score" class="meta-badge meta-score">--</span>
</div>
<br>
<p id="detail-description" class="details-description">Loading description...</p>
</div>
</div>
</section>
<section class="player-section">
<div class="player-toolbar">
<div class="control-group">
<div class="sd-toggle" id="sd-toggle" data-state="sub" onclick="toggleAudioMode()">
<div class="sd-bg"></div>
<div class="sd-option active" id="opt-sub">Sub</div>
<div class="sd-option" id="opt-dub">Dub</div>
</div>
</div>
<div class="control-group">
<select id="server-select" class="source-select" onchange="loadStream()" style="display:none;">
<option value="">Server...</option>
</select>
<select id="extension-select" class="source-select" onchange="onExtensionChange()">
<option value="" disabled selected>Source...</option>
</select>
</div>
</div>
<div class="video-container">
<video id="player" controls crossorigin playsinline></video>
<div id="loading-overlay" class="loading-overlay">
<div class="spinner"></div>
<p id="loading-text">Select a source...</p>
</div>
</div>
<div class="episode-controls">
<div class="episode-info">
<h1 id="anime-title-details2">Loading...</h1>
<p id="episode-label">Episode --</p>
</div>
<div class="navigation-buttons">
<button class="nav-btn prev-btn" id="prev-btn"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M15 19l-7-7 7-7"/></svg><span>Previous</span></button>
<button class="nav-btn next-btn" id="next-btn"><span>Next</span><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 5l7 7-7 7"/></svg></button>
</div>
</div>
<div class="episode-carousel-compact">
<div class="carousel-header">
<h2>Episodes</h2>
<div class="carousel-nav">
<button class="carousel-arrow-mini" id="ep-prev-mini"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><path d="M15 18l-6-6 6-6"/></svg></button>
<button class="carousel-arrow-mini" id="ep-next-mini"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><path d="M9 6l6 6-6 6"/></svg></button>
</div>
</div>
<div id="episode-carousel" class="episode-carousel-compact-list">
</div>
</div>
</section>
</main>
</div>
<script src="../../src/scripts/anime/player.js"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
const carousel = document.getElementById('episode-carousel');
if (!carousel) return;
const prevBtn = document.getElementById('ep-prev-mini');
const nextBtn = document.getElementById('ep-next-mini');
const scrollAmount = 150;
prevBtn?.addEventListener('click', () => {
carousel.scrollBy({ left: -scrollAmount, behavior: 'smooth' });
});
nextBtn?.addEventListener('click', () => {
carousel.scrollBy({ left: scrollAmount, behavior: 'smooth' });
});
const updateArrows = () => {
if (!prevBtn || !nextBtn) return;
prevBtn.style.opacity = carousel.scrollLeft <= 10 ? '0.3' : '1';
prevBtn.style.pointerEvents = carousel.scrollLeft <= 10 ? 'none' : 'auto';
const atEnd = carousel.scrollLeft + carousel.clientWidth >= carousel.scrollWidth - 10;
nextBtn.style.opacity = atEnd ? '0.3' : '1';
nextBtn.style.pointerEvents = atEnd ? 'none' : 'auto';
};
carousel.addEventListener('scroll', updateArrows);
window.addEventListener('resize', updateArrows);
const observer = new MutationObserver((mutations, obs) => {
updateArrows();
obs.disconnect();
});
observer.observe(carousel, { childList: true });
});
document.addEventListener('DOMContentLoaded', () => {
const expandBtn = document.getElementById('expand-characters-btn');
const characterList = document.getElementById('characters-list');
const btnText = expandBtn?.querySelector('span');
if (!expandBtn || !characterList) return;
expandBtn.addEventListener('click', () => {
const isExpanded = expandBtn.getAttribute('data-expanded') === 'true';
if (isExpanded) {
characterList.classList.remove('expanded');
expandBtn.setAttribute('data-expanded', 'false');
if (btnText) btnText.innerText = 'Show All';
} else {
characterList.classList.add('expanded');
expandBtn.setAttribute('data-expanded', 'true');
if (btnText) btnText.innerText = 'Show Less';
}
});
});
</script>
<div id="updateToast" class="hidden">
<p>Update available: <span id="latestVersionDisplay">v1.x</span></p>
<a
id="downloadButton"
href="https://git.waifuboard.app/ItsSkaiya/WaifuBoard/releases"
target="_blank"
>
Click To Download
</a>
</div>
<script src="/src/scripts/updateNotifier.js"></script>
<script src="/src/scripts/auth-guard.js"></script>
</body>
</html>