New main page way of browsing the courses
This commit is contained in:
@@ -680,55 +680,84 @@
|
||||
function loadLibrary() {
|
||||
const libraryCard = document.getElementById('library-card');
|
||||
if (!libraryCard) return;
|
||||
fetchLibraryLevel(null, document.getElementById('library-groups'), true);
|
||||
}
|
||||
|
||||
fetch('/library')
|
||||
function fetchLibraryLevel(path, container, isRoot) {
|
||||
const url = path ? `/library?path=${encodeURIComponent(path)}` : '/library';
|
||||
fetch(url)
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
document.getElementById('library-path-bar').textContent =
|
||||
`Scanning ${data.library_path}`;
|
||||
|
||||
const container = document.getElementById('library-groups');
|
||||
const groupNames = Object.keys(data.groups).sort((a, b) => a.localeCompare(b));
|
||||
|
||||
if (groupNames.length === 0) {
|
||||
const reason = (data.errors && data.errors.length)
|
||||
? data.errors.join(' ')
|
||||
: `No course folders found under ${data.library_path}.`;
|
||||
container.innerHTML = `<p style="color:#999;">${reason} You can still load a course by path below.</p>`;
|
||||
return;
|
||||
if (isRoot) {
|
||||
document.getElementById('library-path-bar').textContent =
|
||||
`Scanning ${data.library_path}`;
|
||||
}
|
||||
|
||||
container.innerHTML = groupNames.map((group, i) => `
|
||||
<div class="tree-item">
|
||||
<div class="tree-header directory" onclick="toggleTree(this)">
|
||||
<div class="tree-title">
|
||||
<span class="tree-icon">📁</span>
|
||||
<span class="tree-name">${group}</span>
|
||||
<span class="tree-stats">${data.groups[group].length} course${data.groups[group].length === 1 ? '' : 's'}</span>
|
||||
</div>
|
||||
<button class="tree-toggle">▶</button>
|
||||
</div>
|
||||
<div class="tree-content">
|
||||
${data.groups[group].map(course => `
|
||||
<div class="lesson-item"
|
||||
onclick="loadCoursePath('${course.path.replace(/'/g, "\\'")}')">
|
||||
<div class="lesson-title">
|
||||
<span class="lesson-icon">🎓</span>
|
||||
<span>${course.name}</span>
|
||||
</div>
|
||||
<span class="lesson-meta">${course.media_files} media file${course.media_files === 1 ? '' : 's'}</span>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
renderLibraryLevel(data, container, isRoot);
|
||||
})
|
||||
.catch(() => {
|
||||
document.getElementById('library-groups').innerHTML =
|
||||
container.innerHTML =
|
||||
'<p style="color:#ff6b6b;">Could not reach the library scanner.</p>';
|
||||
});
|
||||
}
|
||||
|
||||
function renderLibraryLevel(data, container, isRoot) {
|
||||
if (!data.items || data.items.length === 0) {
|
||||
const reason = (data.errors && data.errors.length)
|
||||
? data.errors.join(' ')
|
||||
: (isRoot ? `No course folders found under ${data.library_path}.` : 'No courses in here.');
|
||||
container.innerHTML = `<p style="color:#999; padding: 6px 0;">${reason}${isRoot ? ' You can still load a course by path below.' : ''}</p>`;
|
||||
return;
|
||||
}
|
||||
|
||||
container.innerHTML = data.items.map(item => {
|
||||
if (item.type === 'course') {
|
||||
return `
|
||||
<div class="lesson-item"
|
||||
onclick="loadCoursePath('${item.path.replace(/'/g, "\\'")}')">
|
||||
<div class="lesson-title">
|
||||
<span class="lesson-icon">🎓</span>
|
||||
<span>${item.name}</span>
|
||||
</div>
|
||||
<span class="lesson-meta">${item.media_files} media file${item.media_files === 1 ? '' : 's'}</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
return `
|
||||
<div class="tree-item">
|
||||
<div class="tree-header directory" onclick="toggleLibraryDir(this, '${item.path.replace(/'/g, "\\'")}')">
|
||||
<div class="tree-title">
|
||||
<span class="tree-icon">📁</span>
|
||||
<span class="tree-name">${item.name}</span>
|
||||
</div>
|
||||
<button class="tree-toggle">▶</button>
|
||||
</div>
|
||||
<div class="tree-content" data-loaded="false"></div>
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function toggleLibraryDir(headerEl, path) {
|
||||
const content = headerEl.nextElementSibling;
|
||||
const toggle = headerEl.querySelector('.tree-toggle');
|
||||
if (!content || !content.classList.contains('tree-content')) return;
|
||||
|
||||
if (content.classList.contains('expanded')) {
|
||||
content.classList.remove('expanded');
|
||||
toggle.textContent = '▶';
|
||||
return;
|
||||
}
|
||||
|
||||
content.classList.add('expanded');
|
||||
toggle.textContent = '▼';
|
||||
|
||||
if (content.dataset.loaded === 'true') return; // already fetched this branch
|
||||
|
||||
content.innerHTML = '<p style="color:#999; padding: 6px 0;">Loading...</p>';
|
||||
content.dataset.loaded = 'true';
|
||||
fetchLibraryLevel(path, content, false);
|
||||
}
|
||||
|
||||
function loadCoursePath(path) {
|
||||
fetch('/load_course', {
|
||||
method: 'POST',
|
||||
|
||||
Reference in New Issue
Block a user