52 Commits

Author SHA1 Message Date
ghassan
6e7d5d178a Fix SPA transitions: title, cover image, and slideshow not updating
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>
2026-05-16 23:02:21 +03:00
ghassan
2c0888088d Fix Up Next SPA: add playerData to auth except list
VideoController constructor applied auth middleware to all methods
not in the except list. playerData was missing, causing guest
requests to get 401 → SPA fallback to window.location.href → page refresh.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 14:27:13 +03:00
ghassan
07cee7b481 Fix video autoplay: register MANIFEST_PARSED before loadSource, use loadedmetadata for MP4/native-HLS
The MANIFEST_PARSED listener was registered after loadSource/attachMedia,
so cached manifests could fire the event before the listener was set —
meaning tryAutoplay never ran. Fix: register the listener first, then
call loadSource. Also switch MP4 and native-HLS paths to play on
loadedmetadata (not immediately after load()) which is the earliest
safe moment to call play(). Belt-and-suspenders canplay fallback now
also explicitly mutes before calling play().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 14:07:23 +03:00
ghassan
e74862a24d Fix video autoplay on page load — trigger play on MANIFEST_PARSED
Previously, play() was only called from the canplay listener which can
fire too late or be missed with HLS.js. Now also triggers on
Hls.Events.MANIFEST_PARSED (the earliest reliable point), and calls
play() directly after video.load() for MP4/native-HLS paths. Also
fixes _ytpLoadSource (SPA transitions) to use the same pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 13:58:24 +03:00
ghassan
4f275de15f SPA transitions + autoplay for match type; add no-refresh rule to CLAUDE.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 13:45:16 +03:00
ghassan
5960c6e7b1 Add Up Next autoplay controls + SPA transitions to music type
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 13:35:41 +03:00
ghassan
d73f877d18 Add SPA autoplay + no-refresh clicks to Up Next recommendations
- 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>
2026-05-16 13:29:01 +03:00
ghassan
77e7b950be SPA playlist transitions for generic (video) type
- 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>
2026-05-16 13:16:25 +03:00
ghassan
da02425aeb 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 <noreply@anthropic.com>
2026-05-16 12:12:22 +03:00
ghassan
99f71c54e5 Fix playlist controls: add to type-specific views (music, generic, match)
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>
2026-05-16 11:45:33 +03:00
ghassan
05db0e128a Add playlist controls: prev/next, shuffle, loop, autoplay toggle
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>
2026-05-16 11:16:42 +03:00
ghassan
c160242dbc WIP: storage-fix-local-nas work before playlist controls feature
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 11:15:20 +03:00
ghassan
6b3ab5b65e Use NAS as primary storage — direct upload when enabled
When NAS storage is enabled, uploaded files go directly to the NAS share
(users/{username}/videos/{title-slug}/) with no permanent local copy kept.
Thumbnails and video are fetched from NAS on demand for streaming/playback.
When NAS is disabled, files are organised into the same directory schema
in local storage.

- VideoController: branch upload flow on NAS enabled/disabled
- NasSyncService: add uploadDirectToNas() for direct NAS writes,
  organizeLocalFiles() for local NAS-schema, localVideoDir() resolver,
  deleteLocalAssets() for post-sync cleanup
- GenerateHlsJob: download from NAS via ensureLocalCopy() when local
  file is absent (NAS-primary mode); clean up temp after HLS generation
- CompressVideoJob: place compressed file alongside original (any dir)
- Video/VideoSlide models: localVideoPath(), localThumbnailPath(),
  thumbnailStorageKey(), localPath(), storageKey() helpers for
  format-agnostic path resolution (old flat paths + new NAS-schema paths)
- MediaController: serve thumbnails from NAS-mirrored paths with NAS fallback
- SuperAdminController: use model path helpers for file deletion
- NasFreeLocalStorage: scan new users/ tree in addition to legacy flat dirs
- Settings: rename "NAS Storage Sync" tab to "NAS Storage", update description

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 17:17:07 +03:00
ghassan
296d605864 Add nas:free-local command to remove local files already on NAS
Scans all videos that still have a local file, checks NAS for meta.json
(written last in syncVideo, so its presence confirms a complete push),
then removes the local copy if confirmed.

Usage:
  php artisan nas:free-local --dry-run   # preview
  php artisan nas:free-local --force     # delete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 01:59:47 +03:00
ghassan
0b75acec89 Make NAS the primary storage when enabled (not a mirror)
When NAS sync is enabled:
- Audio uploads: pushed to NAS via NasSyncVideoJob, local file deleted immediately after
- Video uploads: processed locally (ffprobe, compress, HLS), then at the end of
  GenerateHlsJob the final compressed file is re-synced to NAS and the local copy removed
- stream() and download(): if local file is missing, pull from NAS into a local
  stream cache (storage/app/nas_cache/videos/) and serve from there with full
  byte-range support — so seeking still works over NAS-sourced files

When NAS is disabled:
- Upload, stream, and download all use local storage exclusively (no change)

HLS segments are intentionally kept local: they are small, generated on-demand,
and serving them via per-segment SMB round-trips would hurt playback performance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 01:56:55 +03:00
ghassan
d1441b213a Fix progress bar seek pausing playback + add persistent mini-player
- 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>
2026-05-14 01:45:20 +03:00
ghassan
615e7efd7c Redesign NAS file manager to match admin dark theme
- Published package views to resources/views/vendor/nas-file-manager/
- Rewrote file-manager.blade.php using admin CSS variables (--bg, --bg-card,
  --border, --text, --brand, etc.) and Bootstrap Icons instead of Tailwind/SVGs
- Replaced accordion wrapper with flat tab bar matching .adm-* tab pattern
- Dialogs use --bg-card2, --border-light, and .adm-btn classes
- Removed Tailwind CDN and brand color overrides from nas-storage.blade.php

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 13:50:41 +03:00
ghassan
8a00bcecac Simplify NAS storage page — let package Connection tab own the UI
Removed the manual connection summary card now that the package widget
has a built-in Connection tab with a live test button and form fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 13:46:00 +03:00
ghassan
69ae56331a Update p7h/nas-file-manager to latest (adds Connection tab)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 13:43:54 +03:00
ghassan
0b2e95ea65 Add NAS file manager integration and all pending platform changes
- 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>
2026-05-13 13:24:32 +03:00
ghassan
d44490dfe0 latest update with cron job for deleting orphan videos 2026-04-05 03:49:50 +03:00
ghassan
2a562b99f1 latest update 2026-04-05 03:30:22 +03:00
ghassan
64eadfaf56 converted comment section and the cannel info and the action buttons to components 2026-03-21 03:22:30 +03:00
ghassan
84fcbd84dc latest update 2026-03-21 02:24:27 +03:00
ghassan
3b09f4baed all is working great 2026-03-15 04:55:18 +03:00
ghassan
f850f40f78 all is working great 2026-03-15 04:06:35 +03:00
ghassan
69f5df163a update the match view 2026-03-12 03:59:52 +03:00
ghassan
062c0e896f latest update 2026-03-11 11:21:33 +03:00
ghassan
9ad842dcd5 Add trending videos page with YouTube-style algorithm
- Trending algorithm based on:
  - Recent views (last 48h): 70% weight
  - View velocity (views/hour): 15% weight
  - Recency bonus: 10% weight
  - Like count: 5% weight
- Excludes videos older than 10 days
- Filter options: Today/This Week/This Month
- Added route, controller method, and view
- Updated nav to link to trending page
2026-03-03 21:30:44 +03:00
ghassan
59870862db Add mobile responsive admin dashboard
- Hamburger menu toggle for mobile sidebar
- Slide-in sidebar overlay on mobile
- Responsive stats cards (2 per row tablet, 1 per row mobile)
- Touch-friendly targets (44px minimum)
- Table scroll wrapper for horizontal scroll
- Responsive typography and spacing
- Close sidebar on nav click and resize
2026-03-03 21:24:27 +03:00
ghassan
3f40316d53 Style cancel button to match upload button 2026-03-03 21:14:40 +03:00
ghassan
c2bac73984 Add spacing between video type and privacy selectors 2026-03-03 21:03:15 +03:00
ghassan
148bf6f45e Fix upload page: header HTML, cancel button, close button 2026-03-03 21:02:37 +03:00
ghassan
4b7b58e8cc Remove upload page header: title and subtitle 2026-03-03 20:55:04 +03:00
ghassan
f78e1f6d4a Fix: Convert upload modal to full page layout 2026-03-03 20:51:50 +03:00
ghassan
c2180e556d Fix: Remove red header, use dark theme for upload page 2026-03-03 20:33:51 +03:00
ghassan
0b893025a5 Remove red header from upload page 2026-03-03 20:31:47 +03:00
ghassan
98f55af8d7 Fix mobile upload page - full page not modal
- 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
2026-03-03 19:58:34 +03:00
ghassan
79bcd95d36 Hide header upload button on mobile - use bottom nav instead 2026-03-03 19:51:13 +03:00
ghassan
9ed7fb47b9 Fix bottom nav: change Videos button to Upload with auth check 2026-03-03 19:40:31 +03:00
ghassan
76b4796ab2 Fix: channels.show route not found - changed to channel 2026-03-03 19:28:13 +03:00
ghassan
e0e6c803a9 Add YouTube-style mobile bottom navigation bar
- 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
2026-03-03 19:19:40 +03:00
ghassan
94a73cc74d Add mobile bottom action bar for video detail page 2026-03-03 19:12:45 +03:00
ghassan
1888f77886 Improve mobile responsiveness - touch targets, better grids, smaller screens 2026-03-03 18:51:53 +03:00
ghassan
a28023c29b admin panel added and comments are working and likes are working 2026-03-03 17:36:19 +03:00
ghassan
72e9439727 made the video cards components 2026-03-02 02:16:28 +03:00
ghassan
3aa49d638d latest update my Video Platform is working Great 2026-02-26 22:35:52 +03:00
ghassan
dcdcafe0ba latest update my Video Platform is working Great 2026-02-26 21:29:52 +03:00
ghassan
eb707c1ee1 update latest 2026-02-25 02:12:56 +00:00
ghassan
b38f1a93bb latest update youtube replica 2026-02-25 00:47:59 +00:00