VideoController@update() now handles a replacement media file: if the
new file is audio the row is forced to type=music and, when the on-disk
type folder differs from the declared type (e.g. a video sitting under
users/{u}/videos/ that was later marked music), the media is relocated
into the canonical users/{u}/music/{slug}/tracks/{lang}-{id}/audio.ext
layout. Old primary file and stale meta.json are deleted from NAS; HLS
and slideshow caches are reset. The same relocation is applied by
replaceFile() so the mobile "Replace Media File" flow behaves the same.
Slide- and audio-track-management gates in update() also switched from
isAudioOnlyFile() (extension-based) to the declared type, so secondary
tracks and cover slides added mid-conversion are no longer silently
dropped. The edit modal now renders existing secondary tracks whenever
type=music regardless of the primary file extension.
Also carries an unrelated app.blade.php tweak: the mobile filter bar's
sticky reset moved from .yt-filter-bar to its wrapper, with padding
kept on the inner bar.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Removes the 12-chip cap on the language filter so every language that
appears in public content is listed (video 175 alone contributes 12).
The bar wrapper is now sticky and horizontally scrollable with chevron
buttons that appear only when the bar overflows in that direction, a
gradient fade behind each button, vertical-wheel → horizontal scroll
that hands off to the page at the edges, and sessionStorage-persisted
scroll position so navigation doesn't snap it back to the start.
Chip clicks are intercepted (only for /videos URLs; Trending/Shorts
still render different templates via a normal navigation) and swap
only the #filter-content region via fetch + DOMParser, updating
history.pushState, document.title, and active-chip state without a
full page reload. Modifier-clicks and middle-clicks fall through
to native "open in new tab" behaviour.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bundled pre-existing changes on the branch:
- Video merge: controller, service, admin merge modal, and a repair
console command; new video_redirects table (with source_folder)
so merged/moved videos keep resolving under their old keys.
- Default avatar SVG for users without a profile picture.
- Assorted view tweaks across profile, video actions/comments/insights,
admin layout, video-details, and the app layout.
- Small touch-ups in SuperAdminController, User model, NasSyncService.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lyrics pipeline (Whisper + Demucs + description alignment):
- New GenerateLyricsJob runs WhisperX with VAD filtering and forced word
alignment, writes per-track JSON to NAS.
- New DecorateLyricsJob calls the active LLM provider to bake one to
several emojis into each line (heavy decoration prompt).
- LyricsDescriptionParser strips heading content, section markers, and
emoji-decoration from a song's description while preserving every
language verbatim.
- correct_whisper_with_description aligner: strong-match anchors only,
vocal-region-aware gap-fill so missing verses land on actual singing.
- Owner UI for generate/regenerate/edit/delete in the player gear.
Admin pages:
- /admin/lyrics toggles for VAD, vocal gap-fill, Demucs, master
- /admin/gpu extracted GPU section, encoder picker, FFmpeg path
- /admin/backup extracted users-and-settings export/import
- /admin/settings now AI/LLM only with provider list and Test button
- /admin/nas-storage hosts NAS settings, repair, disable flow, browser
- Shared partials/settings-styles for a uniform look across pages.
Playlist view tracking:
- Migration adds playlists.view_count and playlist_views dedup table.
- Playlist::bumpViewIfNew increments per device with a one-hour window.
- Tracked from /playlists/{id}, /playlists/share/{token}, /ps/{token},
and /videos/{id}?playlist={token}. Dispatched after-response so it
never blocks the page render.
- Loading a playlist on the video page now runs one query instead of
the four the old getNextVideo/getPreviousVideo path triggered.
- View counts shown on every playlist card and the playlist hero.
Player polish:
- Floating mini-player is draggable, persists its position in
localStorage, clamps to viewport on resize.
- Mini disabled entirely on mobile (less than 768px).
- New gear-menu Mini Player toggle (persists in localStorage) lets the
user disable both scroll-activation and SPA-nav-activation.
- Close button keeps media playing when used on the player's own page.
- SPA navigator now swaps a #page-scripts container so per-page JS
(channel tabs, etc.) gets re-executed after content swaps.
Storage layout:
- Runtime data moved from /storage/* to /data/* and gitignored.
- /ml/venv, /ml/cache, /ml/__pycache__ excluded.
Co-Authored-By: Claude Opus 4.7 <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>
Users can now control which in-app and email notifications they receive
from their Settings tab on their channel page.
Bell (in-app) preferences:
- New comment on my video (default: on)
- Reply to my comment (default: on)
- Comment liked (default: on)
- Video liked (default: on)
- New subscriber (default: on)
- New video from channels I follow (default: on)
- New post from channels I follow (default: on)
- New user registration — super admins only (default: on)
Email preferences (same set plus):
- Comment liked (default: off — too noisy)
- Video liked (default: off — too noisy)
- New post from channels I follow (default: off)
- My video finished processing (default: on)
- Weekly activity digest every Monday (default: on)
- New user registration — super admins only (default: on)
Implementation:
- Migration: notification_preferences JSON column on users table
- User::notificationPref($key) helper with typed defaults
- All existing notification classes updated to check prefs in via()
- 4 new notification classes: NewSubscriberNotification,
VideoLikedNotification, NewPostNotification, WeeklyDigestNotification
- 8 new email views matching existing dark theme
- SendWeeklyDigest artisan command, scheduled every Monday 09:00
- NewSubscriberNotification wired into UserController::toggleSubscribe
- VideoLikedNotification wired into UserController::toggleLike
- NewPostNotification wired into PostController::store (to all subscribers)
- Bell renderer updated for new_subscriber, video_like, new_post types
- Preferences saved via AJAX (POST /settings/notifications) — instant
toggle with automatic revert on failure
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a new user registers, all super_admin users receive:
- A database notification shown in the bell (type: new_user), with the
new user's avatar and a link to their channel
- An email congratulating them with the new member's name, email,
join date, gender, and nationality, plus a View Profile CTA
Notification rendering in app.blade.php refactored into notifHref() and
notifThumb() helpers so new_user notifications link to /channel/{slug}
and show a circular avatar instead of a video thumbnail. Also fixed the
legacy /storage/thumbnails/ path to /media/thumbnails/ for video notifications.
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>
- 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
- Fixed bottom nav with 5 buttons: Home, Trending, Videos, History, Profile
- Shows only on mobile (≤768px)
- Fixed to bottom with proper padding for main content
- Uses Bootstrap Icons for navigation icons
- 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