diff --git a/static/app.css b/static/app.css
index 138fb9b..925e3c2 100644
--- a/static/app.css
+++ b/static/app.css
@@ -13,6 +13,9 @@ body {
}
/* Header styles */
.site-header {
+ position: sticky;
+ top: 0;
+ z-index: 1000;
display: flex;
align-items: center;
padding: 10px 20px;
@@ -74,10 +77,15 @@ li {
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
+/* mouse symbol for links */
+li.directory-item, li.file-item,
+li.directory-item a, li.file-item a {
+ cursor: pointer;
+}
+
/* Directory Items (in a list) */
.directory-item {
padding: 15px;
- /* Use flex for list items if needed */
}
/* Grid Layout for Directories */
@@ -100,23 +108,19 @@ li {
grid-template-columns: 1fr auto;
align-items: center;
margin: 10px 0;
- padding: 15px;
+ padding: 15px 10px;
background-color: #fff;
border-radius: 5px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
/* Link Styles */
-a.directory-link,
+.directory-link,
a.play-file {
color: #34495e;
text-decoration: none;
word-break: break-all;
}
-a.directory-link:hover,
-a.play-file:hover {
- color: #34495e;
-}
a.show-transcript {
text-decoration: none;
color: #34495e;
diff --git a/static/app.js b/static/app.js
index e984a2a..0a824de 100644
--- a/static/app.js
+++ b/static/app.js
@@ -20,50 +20,39 @@ function renderContent(data) {
// Render breadcrumbs, directories (grid view when appropriate), and files.
let breadcrumbHTML = '';
data.breadcrumbs.forEach((crumb, index) => {
- breadcrumbHTML += `${crumb.name}`;
+ breadcrumbHTML += `${crumb.name}`;
if (index < data.breadcrumbs.length - 1) {
breadcrumbHTML += `>`;
}
});
document.getElementById('breadcrumbs').innerHTML = breadcrumbHTML;
- // Render directories.
+ // Build the HTML for directories and files.
let contentHTML = '';
if (data.directories.length > 0) {
contentHTML += '
';
}
- // Render files.
if (data.files.length > 0) {
contentHTML += '';
data.files.forEach((file, idx) => {
let symbol = '📄';
if (file.file_type === 'music') {
symbol = '🔊';
- // Add each music file to currentMusicFiles with its index.
currentMusicFiles.push({ path: file.path, index: idx });
} else if (file.file_type === 'image') {
symbol = '🖼️';
}
- // Add a data-index attribute for music files.
const indexAttr = file.file_type === 'music' ? ` data-index="${currentMusicFiles.length - 1}"` : '';
contentHTML += `-
- ${symbol} ${file.name.replace('.mp3', '')}`;
+ ${symbol} ${file.name.replace('.mp3', '')}`;
if (file.has_transcript) {
contentHTML += `📄`;
}
@@ -72,7 +61,35 @@ function renderContent(data) {
contentHTML += '
';
}
+ // Insert the generated HTML into a container in the DOM.
document.getElementById('content').innerHTML = contentHTML;
+
+ // Now attach the event listeners for directories.
+ document.querySelectorAll('li.directory-item').forEach(li => {
+ li.addEventListener('click', function(e) {
+ // Only trigger if the click did not start on an .
+ if (!e.target.closest('a')) {
+ const anchor = li.querySelector('a.directory-link');
+ if (anchor) {
+ anchor.click();
+ }
+ }
+ });
+ });
+
+ // Now attach the event listeners for files.
+ document.querySelectorAll('li.file-item').forEach(li => {
+ li.addEventListener('click', function(e) {
+ // Only trigger if the click did not start on an .
+ if (!e.target.closest('a')) {
+ const anchor = li.querySelector('a.play-file');
+ if (anchor) {
+ anchor.click();
+ }
+ }
+ });
+ });
+
// Update global variable for gallery images (only image files).
currentGalleryImages = data.files
.filter(f => f.file_type === 'image')
diff --git a/static/audioplayer.js b/static/audioplayer.js
index d96c932..657e9b0 100644
--- a/static/audioplayer.js
+++ b/static/audioplayer.js
@@ -101,7 +101,9 @@ function updateTimeInfo() {
audio.ontimeupdate = function() {
changeTimelinePosition();
updateTimeInfo();
- if ('mediaSession' in navigator && typeof navigator.mediaSession.setPositionState === 'function') {
+ if ('mediaSession' in navigator &&
+ typeof navigator.mediaSession.setPositionState === 'function' &&
+ !isNaN(audio.duration)) {
navigator.mediaSession.setPositionState({
duration: audio.duration,
playbackRate: audio.playbackRate,
@@ -112,7 +114,9 @@ audio.ontimeupdate = function() {
// --- Also update media session on play (in case timeupdate lags) ---
audio.onplay = function() {
- if ('mediaSession' in navigator && typeof navigator.mediaSession.setPositionState === 'function') {
+ if ('mediaSession' in navigator &&
+ typeof navigator.mediaSession.setPositionState === 'function' &&
+ !isNaN(audio.duration)) {
navigator.mediaSession.setPositionState({
duration: audio.duration,
playbackRate: audio.playbackRate,