feat: Add reusable video modal component with Alist-style UI
This commit is contained in:
61
templates/anime_downloader/components/video_modal.html
Normal file
61
templates/anime_downloader/components/video_modal.html
Normal file
@@ -0,0 +1,61 @@
|
||||
<!-- Video Modal Component for Anime Downloader -->
|
||||
<!-- Usage: include 'anime_downloader/components/video_modal.html' in your template -->
|
||||
|
||||
<!-- Video.js CDN -->
|
||||
<link href="https://vjs.zencdn.net/8.10.0/video-js.css" rel="stylesheet" />
|
||||
<script src="https://vjs.zencdn.net/8.10.0/video.min.js"></script>
|
||||
|
||||
<!-- Video Player Modal -->
|
||||
<div class="modal fade" id="videoModal" tabindex="-1" role="dialog" aria-labelledby="videoModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl" role="document">
|
||||
<div class="modal-content" style="background: #0f172a; border-radius: 12px;">
|
||||
<div class="modal-header" style="border-bottom: 1px solid rgba(255,255,255,0.1);">
|
||||
<h5 class="modal-title" id="videoModalLabel" style="color: #f1f5f9;">비디오 플레이어</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" style="color: #f1f5f9;">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body" style="padding: 0;">
|
||||
<div class="video-container" style="position: relative; overflow: hidden; background: #000;">
|
||||
<video id="video-player" class="video-js vjs-big-play-centered vjs-theme-fantasy" controls preload="auto" playsinline webkit-playsinline style="width: 100%; height: auto; max-height: 80vh;">
|
||||
<p class="vjs-no-js">JavaScript가 필요합니다.</p>
|
||||
</video>
|
||||
<!-- 화면 꽉 채우기 토글 버튼 (모바일용) -->
|
||||
<button id="btn-video-zoom" class="video-zoom-btn" title="화면 비율 조절">
|
||||
<i class="fa fa-expand"></i>
|
||||
</button>
|
||||
</div>
|
||||
<!-- 플레이리스트 컨트롤 UI (Alist 스타일) -->
|
||||
<div class="playlist-controls">
|
||||
<!-- 에피소드 선택 드롭다운 + 자동 다음 토글 -->
|
||||
<div class="episode-selector-row">
|
||||
<div class="episode-dropdown-wrapper">
|
||||
<select id="episode-dropdown" class="episode-dropdown">
|
||||
<!-- JavaScript에서 옵션 동적 생성 -->
|
||||
</select>
|
||||
<svg class="dropdown-arrow" viewBox="0 0 15 15" aria-hidden="true">
|
||||
<path d="M4.93179 5.43179C4.75605 5.60753 4.75605 5.89245 4.93179 6.06819C5.10753 6.24392 5.39245 6.24392 5.56819 6.06819L7.49999 4.13638L9.43179 6.06819C9.60753 6.24392 9.89245 6.24392 10.0682 6.06819C10.2439 5.89245 10.2439 5.60753 10.0682 5.43179L7.81819 3.18179C7.73379 3.0974 7.61933 3.04999 7.49999 3.04999C7.38064 3.04999 7.26618 3.0974 7.18179 3.18179L4.93179 5.43179ZM10.0682 9.56819C10.2439 9.39245 10.2439 9.10753 10.0682 8.93179C9.89245 8.75606 9.60753 8.75606 9.43179 8.93179L7.49999 10.8636L5.56819 8.93179C5.39245 8.75606 5.10753 8.75606 4.93179 8.93179C4.75605 9.10753 4.75605 9.39245 4.93179 9.56819L7.18179 11.8182C7.35753 11.9939 7.64245 11.9939 7.81819 11.8182L10.0682 9.56819Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<label class="auto-next-toggle">
|
||||
<input type="checkbox" id="auto-next-checkbox" checked>
|
||||
<span class="toggle-label">자동 다음</span>
|
||||
<span class="toggle-switch"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- 외부 플레이어 버튼 -->
|
||||
<div class="external-players">
|
||||
<div class="external-players-grid" id="external-player-buttons">
|
||||
<!-- 버튼들은 JavaScript에서 동적 생성 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<link rel="stylesheet" href="{{ url_for('.static', filename='css/video_modal.css') }}"/>
|
||||
<script src="{{ url_for('.static', filename='js/video_modal.js') }}"></script>
|
||||
Reference in New Issue
Block a user