Organized the differences between server and docker versions.

We are launching a docker version (server version) today so we want to just organize the repo
so its easier to navigate.
This commit is contained in:
2025-12-16 21:50:22 -05:00
parent b86f14a8f2
commit 28ff6ccc68
193 changed files with 23188 additions and 5 deletions

View File

@@ -0,0 +1,224 @@
<!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">
<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>
<link rel="stylesheet" href="/views/css/components/titlebar.css">
</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>
<div class="modal-overlay" id="desc-modal">
<div class="modal-content">
<button class="modal-close" onclick="closeModal()"></button>
<h2 class="modal-title">Synopsis</h2>
<div class="modal-text" id="full-description"></div>
</div>
</div>
<div class="modal-overlay" id="add-list-modal">
<div class="modal-content modal-list">
<button class="modal-close" onclick="closeAddToListModal()"></button>
<h2 class="modal-title" id="modal-title">Add to List</h2>
<div class="modal-body">
<div class="modal-fields-grid">
<div class="form-group">
<label>Status</label>
<select id="entry-status" class="form-input">
<option value="WATCHING">Watching</option>
<option value="COMPLETED">Completed</option>
<option value="PLANNING">Planning</option>
<option value="PAUSED">Paused</option>
<option value="DROPPED">Dropped</option>
<option value="REPEATING">Rewatching</option>
</select>
</div>
<div class="form-group">
<label>Episodes Watched</label>
<input type="number" id="entry-progress" class="form-input" min="0" placeholder="0">
</div>
<div class="form-group">
<label>Your Score (0-10)</label>
<input type="number" id="entry-score" class="form-input" min="0" max="10" step="0.1" placeholder="Optional">
</div>
<div class="form-group full-width">
<div class="date-group">
<div class="date-input-pair">
<label for="entry-start-date">Start Date</label>
<input type="date" id="entry-start-date" class="form-input">
</div>
<div class="date-input-pair">
<label for="entry-end-date">End Date</label>
<input type="date" id="entry-end-date" class="form-input">
</div>
</div>
</div>
<div class="form-group">
<label for="entry-repeat-count">Rewatch Count</label>
<input type="number" id="entry-repeat-count" class="form-input" min="0">
</div>
<div class="form-group notes-group">
<label for="entry-notes">Notes</label>
<textarea id="entry-notes" class="form-input notes-textarea" rows="4" placeholder="Personal notes..."></textarea>
</div>
<div class="form-group checkbox-group">
<input type="checkbox" id="entry-is-private" class="form-checkbox">
<label for="entry-is-private">Mark as Private</label>
</div>
</div>
</div>
<div class="modal-actions">
<button class="btn-danger" id="modal-delete-btn" onclick="deleteFromList()">Remove</button>
<button class="btn-secondary" onclick="closeAddToListModal()">Cancel</button>
<button class="btn-primary" onclick="saveToList()">Save Changes</button>
</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="hero-wrapper">
<div class="video-background">
<div id="player"></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 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>
</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>
</div>
<div class="episode-search-wrapper">
<input type="number" id="ep-search" class="episode-search-input" placeholder="Jump to Ep #" min="1">
</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>
</div>
</main>
</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>
<script src="/src/scripts/updateNotifier.js"></script>
<script src="/src/scripts/rpc-inapp.js"></script>
<script src="/src/scripts/auth-guard.js"></script>
<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>
</body>
</html>

View File

@@ -0,0 +1,265 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WaifuBoard</title>
<link rel="stylesheet" href="/views/css/globals.css">
<link rel="stylesheet" href="/views/css/components/navbar.css">
<link rel="stylesheet" href="/views/css/components/hero.css">
<link rel="stylesheet" href="/views/css/components/anilist-modal.css">
<link rel="stylesheet" href="/views/css/components/updateNotifier.css">
<link rel="stylesheet" href="/views/css/components/titlebar.css">
<link rel="icon" href="/public/assets/waifuboards.ico" type="image/x-icon">
<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>
<nav class="navbar" id="navbar">
<a href="#" class="nav-brand">
<div class="brand-icon">
<img src="/public/assets/waifuboards.ico" alt="WF Logo">
</div>
WaifuBoard
</a>
<div class="nav-center">
<button class="nav-button active">Anime</button>
<button class="nav-button" onclick="window.location.href='/books'">Books</button>
<button class="nav-button" onclick="window.location.href='/gallery'">Gallery</button>
<button class="nav-button" onclick="window.location.href='/schedule'">Schedule</button>
<button class="nav-button" onclick="window.location.href='/my-list'">My List</button>
<button class="nav-button" onclick="window.location.href='/marketplace'">Marketplace</button>
</div>
<div class="nav-right">
<div class="search-wrapper">
<svg class="search-icon" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<circle cx="11" cy="11" r="8"/>
<path d="M21 21l-4.35-4.35"/>
</svg>
<input type="text" class="search-input" id="search-input" placeholder="Search anime..." autocomplete="off">
<div class="search-results" id="search-results"></div>
</div>
<div class="nav-user" id="nav-user" style="display:none;">
<div class="user-avatar-btn">
<img id="nav-avatar" src="/public/assets/waifuboards.ico" alt="avatar">
<div class="online-indicator"></div>
</div>
<div class="nav-dropdown" id="nav-dropdown">
<div class="dropdown-header">
<img id="dropdown-avatar" src="/public/assets/waifuboards.ico" alt="avatar" class="dropdown-avatar">
<div class="dropdown-user-info">
<div class="dropdown-username" id="nav-username"></div>
</div>
</div>
<a href="/my-list" class="dropdown-item">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
<polyline points="17 21 17 13 7 13 7 21"/>
<polyline points="7 3 7 8 15 8"/>
</svg>
<span>My List</span>
</a>
<button class="dropdown-item logout-item" id="nav-logout">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>
<polyline points="16 17 21 12 16 7"/>
<line x1="21" y1="12" x2="9" y2="12"/>
</svg>
<span>Logout</span>
</button>
</div>
</div>
</div>
</nav>
<div class="hero-wrapper">
<div class="hero-background">
<img id="hero-bg-media" alt="">
<div id="player" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 120vw; height: 120vh; pointer-events: none; opacity: 0; transition: opacity 1s;"></div>
</div>
<div class="hero-vignette"></div>
<div class="hero-content">
<div class="hero-poster-card">
<div class="skeleton poster-skeleton" id="hero-poster-skeleton"></div>
<img id="hero-poster" alt="" style="display: none;" onload="this.style.display='block'; document.getElementById('hero-poster-skeleton').style.display='none'">
</div>
<div class="hero-text">
<div id="hero-loading-ui">
<div class="skeleton title-skeleton"></div>
<div class="skeleton text-skeleton" style="width: 40%"></div>
<div class="skeleton text-skeleton" style="width: 100%; height: 4em;"></div>
</div>
<div id="hero-real-ui" style="display: none;">
<h1 class="hero-title" id="hero-title"></h1>
<div class="hero-meta">
<span class="score-badge" id="hero-score"></span>
<span id="hero-year"></span>
<span id="hero-type"></span>
</div>
<p class="hero-desc" id="hero-desc"></p>
<div class="hero-buttons">
<button class="btn-primary" id="watch-btn">Watch Now</button>
<button class="btn-blur">+ Add to List</button>
</div>
</div>
</div>
</div>
</div>
<div class="modal-overlay" id="add-list-modal">
<div class="modal-content modal-list">
<button class="modal-close" onclick="closeAddToListModal()"></button>
<h2 class="modal-title" id="modal-title">Add to List</h2>
<div class="modal-body">
<div class="modal-fields-grid">
<div class="form-group">
<label>Status</label>
<select id="entry-status" class="form-input">
<option value="WATCHING">Watching/Reading</option>
<option value="COMPLETED">Completed</option>
<option value="PLANNING">Planning</option>
<option value="PAUSED">Paused</option>
<option value="DROPPED">Dropped</option>
<option value="REPEATING">Rewatching</option>
</select>
</div>
<div class="form-group">
<label>Episodes Watched</label>
<input type="number" id="entry-progress" class="form-input" min="0" placeholder="0">
</div>
<div class="form-group">
<label>Your Score (0-10)</label>
<input type="number" id="entry-score" class="form-input" min="0" max="10" step="0.1" placeholder="Optional">
</div>
<div class="form-group full-width">
<div class="date-group">
<div class="date-input-pair">
<label for="entry-start-date">Start Date</label>
<input type="date" id="entry-start-date" class="form-input">
</div>
<div class="date-input-pair">
<label for="entry-end-date">End Date</label>
<input type="date" id="entry-end-date" class="form-input">
</div>
</div>
</div>
<div class="form-group">
<label for="entry-repeat-count">Rewatch Count</label>
<input type="number" id="entry-repeat-count" class="form-input" min="0">
</div>
<div class="form-group notes-group">
<label for="entry-notes">Notes</label>
<textarea id="entry-notes" class="form-input notes-textarea" rows="4" placeholder="Personal notes..."></textarea>
</div>
<div class="form-group checkbox-group">
<input type="checkbox" id="entry-is-private" class="form-checkbox">
<label for="entry-is-private">Mark as Private</label>
</div>
</div>
</div>
<div class="modal-actions">
<button class="btn-danger" id="modal-delete-btn" onclick="deleteFromList()">Remove</button>
<button class="btn-secondary" onclick="closeAddToListModal()">Cancel</button>
<button class="btn-primary" onclick="saveToList()">Save Changes</button>
</div>
</div>
</div>
<main>
<section class="section">
<div class="section-header">
<div class="section-title">Continue watching</div>
</div>
<div class="carousel-wrapper">
<button class="scroll-btn left" onclick="scrollCarousel('my-status', -1)"></button>
<div class="carousel" id="my-status">
<div class="card"><div class="card-img-wrap skeleton"></div></div>
<div class="card"><div class="card-img-wrap skeleton"></div></div>
<div class="card"><div class="card-img-wrap skeleton"></div></div>
<div class="card"><div class="card-img-wrap skeleton"></div></div>
</div>
<button class="scroll-btn right" onclick="scrollCarousel('my-status', 1)"></button>
</div>
</section>
<section class="section">
<div class="section-header"><div class="section-title">Trending This Season</div></div>
<div class="carousel-wrapper">
<button class="scroll-btn left" onclick="scrollCarousel('trending', -1)"></button>
<div class="carousel" id="trending">
<div class="card"><div class="card-img-wrap skeleton"></div></div>
<div class="card"><div class="card-img-wrap skeleton"></div></div>
<div class="card"><div class="card-img-wrap skeleton"></div></div>
<div class="card"><div class="card-img-wrap skeleton"></div></div>
</div>
<button class="scroll-btn right" onclick="scrollCarousel('trending', 1)"></button>
</div>
</section>
<section class="section">
<div class="section-header"><div class="section-title">Top Airing Now</div></div>
<div class="carousel-wrapper">
<button class="scroll-btn left" onclick="scrollCarousel('top-airing', -1)"></button>
<div class="carousel" id="top-airing">
<div class="card"><div class="card-img-wrap skeleton"></div></div>
<div class="card"><div class="card-img-wrap skeleton"></div></div>
<div class="card"><div class="card-img-wrap skeleton"></div></div>
<div class="card"><div class="card-img-wrap skeleton"></div></div>
</div>
<button class="scroll-btn right" onclick="scrollCarousel('top-airing', 1)"></button>
</div>
</section>
</main>
<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/utils/auth-utils.js"></script>
<script src="/src/scripts/utils/notification-utils.js"></script>
<script src="/src/scripts/utils/search-manager.js"></script>
<script src="/src/scripts/utils/list-modal-manager.js"></script>
<script src="/src/scripts/utils/continue-watching-manager.js"></script>
<script src="/src/scripts/utils/youtube-player-utils.js"></script>
<script src="/src/scripts/anime/animes.js"></script>
<script src="/src/scripts/updateNotifier.js"></script>
<script src="/src/scripts/rpc-inapp.js"></script>
<script src="/src/scripts/auth-guard.js"></script>
</body>
</html>

View File

@@ -0,0 +1,197 @@
<!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>