diff --git a/index.php b/index.php
index ca5dd62..7d97f75 100644
--- a/index.php
+++ b/index.php
@@ -639,7 +639,8 @@
const state = {
currentType: 'videos',
currentFile: null,
- filesData: null
+ filesData: null,
+ currentItemEl: null
};
// Initialize
@@ -766,6 +767,72 @@
}
}
+ function setActiveFileItem(fileItemEl) {
+ // Clear existing "active" state
+ document.querySelectorAll('.file-item').forEach(f => f.classList.remove('active'));
+
+ // Set new "active"
+ if (fileItemEl) {
+ fileItemEl.classList.add('active');
+ fileItemEl.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
+ }
+
+ state.currentItemEl = fileItemEl || null;
+ }
+
+ /**
+ * Finds the "next" file-item in UI order, preferring the same folder/div
+ * the current item is in. If there's no next sibling, it walks up the DOM
+ * and continues searching.
+ */
+ function findNextFileItem(currentEl) {
+ if (!currentEl) return null;
+
+ // 1) Prefer "next siblings" within the same container
+ let n = currentEl.nextElementSibling;
+ while (n) {
+ if (n.classList && n.classList.contains('file-item')) return n;
+ n = n.nextElementSibling;
+ }
+
+ // 2) If none, walk upward and look for the next file-item after the
+ // parent container (e.g., next folder section)
+ let parent = currentEl.parentElement;
+ while (parent) {
+ // Stop at the file browser root
+ if (parent.id === 'fileBrowser') break;
+
+ let pNext = parent.nextElementSibling;
+ while (pNext) {
+ // If the next sibling is a file-item, play it
+ if (pNext.classList && pNext.classList.contains('file-item')) return pNext;
+
+ // If it's a folder, search inside it for the first file-item
+ const inside = pNext.querySelector && pNext.querySelector('.file-item');
+ if (inside) return inside;
+
+ pNext = pNext.nextElementSibling;
+ }
+
+ parent = parent.parentElement;
+ }
+
+ // No next item found
+ return null;
+ }
+
+ function playNextItem() {
+ const next = findNextFileItem(state.currentItemEl);
+ if (!next) {
+ console.log('Reached end of list; no next item.');
+ return;
+ }
+
+ // Trigger the same behavior as clicking it
+ next.click();
+ }
+
+
function renderFileTree(files, container = document.getElementById('fileBrowser'), depth = 0) {
if (depth === 0) {
container.innerHTML = '';
@@ -801,11 +868,15 @@
const icon = state.currentType === 'videos' ? '🎬' : '🎵';
fileItem.innerHTML = `${icon}${name}`;
- fileItem.addEventListener('click', () => {
- playFile(content, name);
- document.querySelectorAll('.file-item').forEach(f => f.classList.remove('active'));
- fileItem.classList.add('active');
- });
+ fileItem.dataset.path = content;
+ fileItem.dataset.name = name;
+
+ fileItem.addEventListener('click', () => {
+ // Play and mark active
+ playFile(content, name, fileItem);
+ setActiveFileItem(fileItem);
+ });
+
container.appendChild(fileItem);
}
@@ -876,7 +947,7 @@
}
- function playFile(path, name) {
+ function playFile(path, name, sourceItemEl = null) {
const playerContainer = document.getElementById('playerContainer');
const nowPlaying = document.getElementById('nowPlaying');
const nowPlayingTitle = document.getElementById('nowPlayingTitle');
@@ -891,6 +962,11 @@
mediaElement.controls = true;
mediaElement.autoplay = true;
+ // Keep track of which UI element launched playback (used for "next")
+ if (sourceItemEl) {
+ state.currentItemEl = sourceItemEl;
+ }
+
if (isVideo) {
// Some browsers only populate audioTracks after metadata is available
mediaElement.addEventListener('loadedmetadata', () => {
@@ -928,6 +1004,12 @@
mediaElement.addEventListener('canplay', () => {
console.log('Media ready to play:', name);
});
+
+ mediaElement.addEventListener('ended', () => {
+ // Auto-advance to next item when current finishes
+ playNextItem();
+ });
+
// URL encode the path properly
const encodedPath = encodeURIComponent(path);