Merge pull request #8 from mkelvers/copilot/add-button-to-disable-autoplay
Add autoplay toggle button to video player
This commit is contained in:
@@ -81,6 +81,7 @@ const initPlayer = (): void => {
|
||||
const forwardBtn = container.querySelector('[data-forward]') as HTMLButtonElement
|
||||
const fullscreenBtn = container.querySelector('[data-fullscreen]') as HTMLButtonElement
|
||||
const skipSegmentBtn = container.querySelector('[data-skip]') as HTMLButtonElement
|
||||
const autoplayBtn = document.querySelector('[data-autoplay]') as HTMLButtonElement
|
||||
const subtitleText = container.querySelector('[data-subtitle-text]') as HTMLElement
|
||||
|
||||
const streamURL = container.getAttribute('data-stream-url') || '/watch/proxy/stream'
|
||||
@@ -176,6 +177,21 @@ const initPlayer = (): void => {
|
||||
|
||||
const skipLabel = (segmentType: string): string => segmentType === 'ed' ? 'Skip outro' : 'Skip intro'
|
||||
|
||||
const isAutoplayEnabled = (): boolean => localStorage.getItem('mal:autoplay-enabled') !== 'false'
|
||||
|
||||
const updateAutoplayButton = (): void => {
|
||||
if (!autoplayBtn) return
|
||||
const enabled = isAutoplayEnabled()
|
||||
const label = enabled ? 'Autoplay: On' : 'Autoplay: Off'
|
||||
autoplayBtn.title = label
|
||||
autoplayBtn.classList.remove('opacity-40', 'opacity-50')
|
||||
if (!enabled) autoplayBtn.classList.add('opacity-50')
|
||||
const lastChild = autoplayBtn.lastChild
|
||||
if (lastChild && lastChild.nodeType === Node.TEXT_NODE) {
|
||||
lastChild.textContent = label
|
||||
}
|
||||
}
|
||||
|
||||
const timelineBounds = (): { start: number, end: number, duration: number } => {
|
||||
const duration = Number.isFinite(video.duration) && video.duration > 0 ? video.duration : 0
|
||||
|
||||
@@ -803,6 +819,8 @@ const goToNextEpisode = (): void => {
|
||||
return
|
||||
}
|
||||
|
||||
if (!isAutoplayEnabled()) return
|
||||
|
||||
const nextEpisode = currentEpisodeNumber + 1
|
||||
markEpisodeTransition(nextEpisode)
|
||||
|
||||
@@ -862,7 +880,9 @@ const loadNextEpisodeInPlace = async (animeID: number, nextEpisode: number): Pro
|
||||
}
|
||||
|
||||
video.load()
|
||||
video.play().catch(() => {})
|
||||
if (isAutoplayEnabled()) {
|
||||
video.play().catch(() => {})
|
||||
}
|
||||
|
||||
parsedSegments = (data.segments || [])
|
||||
.map((segment: SkipSegment) => {
|
||||
@@ -1036,6 +1056,12 @@ const loadNextEpisodeInPlace = async (animeID: number, nextEpisode: number): Pro
|
||||
modeDub?.addEventListener('click', toggleDub)
|
||||
modeSub?.addEventListener('click', toggleSub)
|
||||
|
||||
autoplayBtn?.addEventListener('click', () => {
|
||||
localStorage.setItem('mal:autoplay-enabled', isAutoplayEnabled() ? 'false' : 'true')
|
||||
updateAutoplayButton()
|
||||
showControls()
|
||||
})
|
||||
|
||||
subtitleSelect?.addEventListener('change', async () => {
|
||||
const selected = subtitleSelect.value
|
||||
if (selected === 'none') {
|
||||
@@ -1142,6 +1168,7 @@ const loadNextEpisodeInPlace = async (animeID: number, nextEpisode: number): Pro
|
||||
updatePlayPauseIcons(false)
|
||||
syncVolumeUI()
|
||||
updateSkipButton(0)
|
||||
updateAutoplayButton()
|
||||
showControls()
|
||||
|
||||
playerInitialized = true
|
||||
|
||||
@@ -39,7 +39,19 @@ templ WatchPage(anime jikan.Anime, data shared.WatchPageData) {
|
||||
hx-boost="true"
|
||||
>
|
||||
@watch.VideoPlayer(data, anime.DisplayTitle())
|
||||
<div class="flex flex-wrap items-center justify-between gap-2 sm:justify-end">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<button
|
||||
data-autoplay
|
||||
class="inline-flex h-8 items-center gap-1.5 bg-(--panel-soft) px-2 text-xs text-(--text) hover:bg-(--panel)"
|
||||
title="Autoplay: On"
|
||||
>
|
||||
<svg class="h-3.5 w-3.5 shrink-0" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<polygon points="5 6 16 12 5 18" fill="currentColor" stroke="none"></polygon>
|
||||
<line x1="19" y1="6" x2="19" y2="18" stroke="currentColor" stroke-width="2" stroke-linecap="round"></line>
|
||||
</svg>
|
||||
Autoplay: On
|
||||
</button>
|
||||
<div class="ml-auto flex flex-wrap items-center gap-2">
|
||||
if shared.CanGoPrevEpisode(data.CurrentEpisode) {
|
||||
<a
|
||||
href={ templ.URL(shared.EpisodeWithOffsetURL(anime.MalID, data.CurrentEpisode, -1)) }
|
||||
@@ -75,6 +87,7 @@ templ WatchPage(anime jikan.Anime, data shared.WatchPageData) {
|
||||
anime.Airing,
|
||||
)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<section>
|
||||
<h3 class="mb-3 text-lg font-semibold tracking-wide text-(--text)">
|
||||
|
||||
Reference in New Issue
Block a user