Chunked video upload, persistent track order, per-track playlist entries

Chunked uploads: bypass Cloudflare's 100 MB request cap by slicing the
video/audio into 8 MB chunks and reassembling server-side before the
normal store flow runs.

Track reorder: audio tracks gain a `position` column so a user's edit-
modal ordering survives reload. `Video::audioTracks()` now orders by
position, `promote_track_id` remembers the swapped row, and freshly
uploaded tracks append to the end.

Playlist per-track pinning: `playlist_videos.audio_track_id` remembers
which language the user pinned when adding a song. Same song with a
different track becomes a separate row (Spotify-style duplicates).
Player-data exposes `active_stream_url` + `active_track_id`, sidebar
cards render `?track=` from the pivot, and both `plTransitionTo` and
initial-load code activate the corresponding language option.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
ghassanandClaude Opus 4.7 committed 2026-07-31 02:42:25 +03:00
1 parent af276f2cd1
commit ba8ab11ce4
12 files changed
+547 -49

No files matched your search

@@ -980,6 +980,14 @@ document.getElementById('edit-form').addEventListener('submit', function(e) {
// Append delete IDs
_editDeleteTrackIds.forEach(id => formData.append('delete_track_ids[]', id));
// Ordered list of track IDs as displayed. Index 0 is the primary slot;
// "primary" is the sentinel for the original primary track row, since
// the primary isn't a video_audio_tracks row of its own.
Array.from(document.querySelectorAll('#edit-tc-list > .um-track-card')).forEach(card => {
const val = (card.id === 'edit-tc-t1-card') ? 'primary' : (card.dataset.trackId || '');
if (val) formData.append('track_order[]', val);
});
// ── Log tracker: dump the exact track-related payload being submitted ──────
(function () {
const promoteId = document.getElementById('edit-promote-track-id')?.value || '(none)';