SPA playlist transitions — no page refresh on track change

- Add GET /videos/{video}/player-data JSON endpoint returning stream URL,
  cover, slides, title, duration (used by client-side SPA transitions)
- Replace music playlist JS with full SPA system: plTransitionTo() swaps
  audio.src in-place (preserving browser autoplay permission), updates
  cover art, resets progress bar, then background-fetches the new page
  to swap #vdbWrap (description) and #ytcSection (comments) via DOMParser
- plSwapContent() re-runs the YTC comments IIFE after swapping innerHTML
  so comments load correctly for the new video
- Prev/next/shuffle/loop/autoplay controls now computed dynamically from
  PL_VIDEOS array — buttons stay correct after each SPA transition
- Sidebar shows ALL playlist tracks (removed @if filter); current track
  highlighted in red; clicking any card triggers SPA transition
- Browser back/forward handled via popstate + history.pushState

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
ghassanandClaude Sonnet 4.6 committed 2026-05-16 12:12:22 +03:00
1 parent 99f71c54e5
commit da02425aeb
3 files changed
+186 -48

No files matched your search

+1
View File
@@ -45,6 +45,7 @@ Route::get('/videos/{video}/download-mp3', [VideoController::class, 'downloadMp3
Route::post('/videos/{video}/slideshow/generate', [VideoController::class, 'slideshowGenerate'])->name('videos.slideshow.generate');
Route::get('/videos/{video}/slideshow/progress', [VideoController::class, 'slideshowProgress'])->name('videos.slideshow.progress');
Route::get('/videos/{video}/recommendations', [VideoController::class, 'recommendations'])->name('videos.recommendations');
Route::get('/videos/{video}/player-data', [VideoController::class, 'playerData'])->name('videos.playerData');
Route::post('/videos/{video}/share', [VideoController::class, 'recordShare'])->name('videos.recordShare');
Route::get('/videos/{video}/og-image', [VideoController::class, 'ogImage'])->name('videos.ogImage');
Route::get('/s/{token}', [VideoController::class, 'accessShare'])->name('share.access');