Clicking Create now opens a card-based chooser (Generic / Music / Sports)
before the upload modal; the chosen type is applied and its Content Type
dropdown is hidden as redundant.
Per type:
- Generic/Match show their fields inline in the modal (no card/popup);
Music keeps the track-card + Track Editor popup for multi-language tracks.
- "Language Track" wording stays music-only; a single Language field is now
available for generic/match too (mirrored on the mobile create page with
name-swapping so only the active picker submits).
Also unifies all modal controls (dropdowns, selects, inputs) to one larger,
red-accented dark style scoped to #uploadModal.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Storage structure
- All audio tracks (primary + per-language) now live in one folder per song with
unique lowercase names ({slug}-{lang}-{id}); no more tracks/ subfolder.
- Generated renders (download video + HLS) moved into the song's local-only cache/
subfolder, separated from source files (never synced to NAS, safe to wipe).
- tracks:reorganize artisan command (dry-run default) consolidates legacy files,
updates DB paths, and deletes orphans + empty folders.
- CLAUDE.md documents the canonical layout as a global rule (identical local + NAS).
Version-aware download & share
- Download MP3/Video and Share now act on the version being played; ?track={id}
is carried through share links and auto-selects audio + title + flag + about +
OG/meta on open.
GPU + visualizer
- Setting::gpuUsable() runs a cached health probe (nvidia-smi + nvenc smoke test,
256x144) before sending any encode to the GPU; falls back to CPU otherwise.
- Visualizer "Download Video" bakes in equal-width, cover-coloured, translucent
frequency bars; loop-filter rebuild makes generation ~25x faster.
Image cropper
- result-callback mode + per-song cover-slide cropper in upload/edit (modal + mobile).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduce per-video language support and multiple audio tracks
(VideoAudioTrack model + migrations for language, description, title),
a reusable language-select component, and a track-editor form. Bundle
the self-hosted flag-icons v7.2.3 library and a NAS auto-sync command.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
On mobile, entering fullscreen now also locks the screen orientation to
landscape via the Screen Orientation API. Exiting fullscreen unlocks it,
allowing the device to return to portrait. Applied to both the video
player and audio player. Gracefully ignored on browsers that don't
support screen.orientation.lock (e.g. iOS Safari).
Also includes the playlist auto-scroll fix (committed separately).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Three bugs in the Up Next / playlist SPA transition for music-type videos:
1. Title selector was '.audio-title' (doesn't exist) instead of '.video-title span'
2. Cover image only updated #audioCoverImg — missed when video has a slideshow
3. Slideshow SLIDE_URLS lived in a closed IIFE and couldn't be updated cross-video
Fix: always render both #audioCoverImg and #slideshowWrap in the DOM (toggle
display via inline style), hoist slideshow state variables outside the if-block,
and expose window._audioPlayerUpdate(d) that both recTransitionTo and
plTransitionTo call. The hook handles all cases: cover-to-cover, cover-to-slideshow,
slideshow-to-cover, slideshow-to-slideshow.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Autoplay toggle button in the Up Next header (defaults Off, persisted
in localStorage as ytpAutoplay_solo)
- When autoplay is On and video ends (_plOnVideoEnd hook), automatically
loads the first recommended video via SPA — no page refresh
- Clicking any recommended video uses recGoTo() → recTransitionTo()
instead of window.location.href: swaps video source, resets progress
bar, updates title, then background-swaps description, channel row,
comments, and the entire sidebar with fresh recommendations from the
next page
- First card gets a red ▶ indicator while autoplay is On so the user
can see what will play next
- Browser back/forward work via popstate
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add _ytpLoadSource(hlsUrl, mp4Url) to video-player component:
destroys old HLS instance, creates a new one with the new source,
then plays — browser retains autoplay permission since the <video>
element never leaves the page
- Add _ytpNavOverride hook: playlist overlay can replace navigateNext/
navigatePrev without modifying the component internals
- Add _plOnVideoEnd hook to 'ended' handler so the playlist overlay
can control autoplay/loop behavior independently
- Expose window._ytpHls for HLS instance lifecycle management
- Add hls_url + has_hls to /videos/{video}/player-data JSON endpoint
- Replace generic.blade.php playlist controls with full SPA system
identical in structure to music type: plTransitionTo, plSwapContent,
plAdj, plRender, plHighlight — no page refresh on track change
- Sidebar shows all playlist tracks; current track highlighted in red
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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 <noreply@anthropic.com>
Controls were only added to show.blade.php, but music/generic/match videos
render their own complete layouts with their own sidebars. Added the
pl-controls-bar to all three type views and the global CSS to app.blade.php.
- music: full standalone JS with shuffle/loop/autoplay + _plOnTrackEnd hook
- generic/match: syncs with video-player's existing ytpShuffleRow/ytpAutoplayRow toggles
- audio-player: ended handler now calls window._plOnTrackEnd if defined
- video-player: exposes window._ytpNav.next/prev for sidebar prev/next buttons
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Controls bar added to playlist sidebar header with:
- Prev/Next skip buttons (disabled when at bounds)
- Shuffle toggle (Fisher-Yates order stored in localStorage)
- Loop 3-state: off → loop all → loop one
- Autoplay toggle (default on, persists per playlist in localStorage)
All state is instant — no page reload on toggle.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- video-player: add userSeeking flag so mid-seek pause events are
suppressed; force-resume on 'seeked' if video was playing before seek;
guard player click handler against progCont clicks; e.preventDefault()
on touchend to stop synthetic click toggling play
- audio-player: apply identical seek fixes (same four changes)
- app layout: add floating mini-player that saves video state to
sessionStorage when bottom nav is tapped while a video is playing,
then restores playback on the next page via a floating overlay
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Installed p7h/nas-file-manager package via private VCS repo
- Published config/nas-file-manager.php with super_admin middleware restriction
- Added NAS env vars to .env.example
- Created admin/nas-storage page with connection info panel and file browser widget
- Added NAS Storage link to admin sidebar (super_admin only)
- Added SuperAdminController@nasStorage method and admin.nas-storage route
- Includes all accumulated branch changes: profile wall, 2FA, audit logs,
settings panel, country/phone/timezone components, posts, slideshow,
playlist shares, video downloads/shares, comment likes, notifications,
social links, and more
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add main_class yield to app.blade.php for proper CSS targeting
- Add upload-page-only upload-page-responsive classes to create view
- Now mobile upload (/videos/create) shows as full-width page, not modal
- Added authentication controllers (Login, Register)
- Added UserController for user profile management
- Added VideoController with full CRUD operations
- Added Video model with relationships (user, likes, views)
- Added User model enhancements (avatar, video relationships)
- Added database migrations for video_likes, video_views, user_avatar, video_visibility
- Added CompressVideoJob for video processing
- Added VideoUploaded mail notification
- Added authentication routes
- Updated web routes with video and user routes
- Added layout templates (app, plain, partials)
- Added user views (profile, settings, channel, history, liked)
- Added video views (create, edit, index, show)
- Added email templates