Spaces:
Sleeping
Sleeping
AdityaAdaki
commited on
Commit
·
a8fd63c
1
Parent(s):
c2aa052
optimizations
Browse files- static/player.js +95 -76
static/player.js
CHANGED
|
@@ -3,10 +3,14 @@ let isPlaying = false;
|
|
| 3 |
let playlist = [];
|
| 4 |
let currentView = 'all';
|
| 5 |
let playlists = JSON.parse(localStorage.getItem('playlists')) || {};
|
| 6 |
-
let currentPlaylist = null;
|
| 7 |
let currentLyrics = null;
|
| 8 |
let isPlayingPlaylist = false;
|
| 9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
const audioPlayer = document.getElementById('audio-player');
|
| 11 |
const playBtn = document.getElementById('play-btn');
|
| 12 |
const prevBtn = document.getElementById('prev-btn');
|
|
@@ -19,6 +23,16 @@ const durationSpan = document.getElementById('duration');
|
|
| 19 |
// Add this constant at the top of the file
|
| 20 |
const DEFAULT_COVER = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgMjAwIDIwMCI+PHJlY3Qgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiIGZpbGw9IiNlOWVjZWYiLz48dGV4dCB4PSI1MCUiIHk9IjUwJSIgc3R5bGU9ImZvbnQtZmFtaWx5OiBBcmlhbDsgZm9udC1zaXplOiAyMHB4OyBmaWxsOiAjNmM3NTdkOyBkb21pbmFudC1iYXNlbGluZTogbWlkZGxlOyB0ZXh0LWFuY2hvcjogbWlkZGxlOyI+Tm8gQWxidW0gQXJ0PC90ZXh0Pjwvc3ZnPg==';
|
| 21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
// Fetch music structure from the server
|
| 23 |
fetch('/api/music-structure')
|
| 24 |
.then(response => response.json())
|
|
@@ -268,95 +282,110 @@ function switchView(view) {
|
|
| 268 |
}
|
| 269 |
}
|
| 270 |
|
|
|
|
| 271 |
function renderAlbumView() {
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
|
| 284 |
-
|
| 285 |
-
|
| 286 |
-
|
|
|
|
|
|
|
| 287 |
}
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
});
|
| 291 |
|
| 292 |
const container = document.getElementById('view-container');
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
|
|
|
|
|
|
|
| 296 |
<div class="album-card">
|
| 297 |
<div class="album-art-container">
|
| 298 |
<img class="album-art" src="${album.artwork}" onerror="this.src='${DEFAULT_COVER}'">
|
| 299 |
-
<button class="play-overlay" onclick="playAlbum('${
|
| 300 |
<i class="fas fa-play"></i>
|
| 301 |
</button>
|
| 302 |
</div>
|
| 303 |
-
<div class="album-info" onclick="showAlbumTracks('${
|
| 304 |
-
<h3>${
|
| 305 |
<p>${album.artist}</p>
|
| 306 |
<p>${album.tracks.length} tracks</p>
|
| 307 |
</div>
|
| 308 |
-
</div
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
|
| 312 |
}
|
| 313 |
|
|
|
|
| 314 |
function renderArtistView() {
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
| 328 |
-
|
| 329 |
-
|
|
|
|
|
|
|
| 330 |
}
|
| 331 |
-
}
|
| 332 |
-
}
|
| 333 |
|
| 334 |
const container = document.getElementById('view-container');
|
| 335 |
-
|
| 336 |
-
|
| 337 |
-
|
|
|
|
| 338 |
<div class="artist-card">
|
| 339 |
<div class="artist-art-container">
|
| 340 |
-
<img class="artist-image" src="${artist.artwork}" alt="${
|
| 341 |
-
<button class="play-overlay" onclick="playArtist('${
|
| 342 |
<i class="fas fa-play"></i>
|
| 343 |
</button>
|
| 344 |
</div>
|
| 345 |
-
<div class="artist-info" onclick="showArtistTracks('${
|
| 346 |
-
<h3>${
|
| 347 |
<p>${artist.tracks.length} tracks</p>
|
| 348 |
</div>
|
| 349 |
-
</div
|
| 350 |
-
|
| 351 |
-
|
| 352 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 353 |
}
|
| 354 |
|
| 355 |
function showAlbumTracks(albumName, artistName) {
|
| 356 |
-
const tracks =
|
| 357 |
-
track.metadata?.album === albumName &&
|
| 358 |
-
track.metadata?.artist === artistName
|
| 359 |
-
);
|
| 360 |
|
| 361 |
const container = document.getElementById('view-container');
|
| 362 |
const viewTitle = document.getElementById('view-title');
|
|
@@ -400,9 +429,7 @@ function showAlbumTracks(albumName, artistName) {
|
|
| 400 |
}
|
| 401 |
|
| 402 |
function showArtistTracks(artistName) {
|
| 403 |
-
const tracks =
|
| 404 |
-
track.metadata?.artist === artistName
|
| 405 |
-
);
|
| 406 |
renderTrackList(tracks, `Artist: ${artistName}`);
|
| 407 |
}
|
| 408 |
|
|
@@ -896,11 +923,7 @@ function showNotification(message) {
|
|
| 896 |
|
| 897 |
// Add these new functions to handle playing albums and artists
|
| 898 |
function playAlbum(albumName, artistName) {
|
| 899 |
-
const albumTracks =
|
| 900 |
-
track.metadata?.album === albumName &&
|
| 901 |
-
track.metadata?.artist === artistName
|
| 902 |
-
);
|
| 903 |
-
|
| 904 |
if (albumTracks.length > 0) {
|
| 905 |
currentPlaylist = {
|
| 906 |
name: albumName,
|
|
@@ -917,19 +940,15 @@ function playAlbum(albumName, artistName) {
|
|
| 917 |
}
|
| 918 |
|
| 919 |
function playArtist(artistName) {
|
| 920 |
-
const tracks =
|
| 921 |
-
track.metadata?.artist === artistName
|
| 922 |
-
);
|
| 923 |
if (tracks.length > 0) {
|
| 924 |
-
// Create a temporary playlist for the artist
|
| 925 |
currentPlaylist = {
|
| 926 |
name: artistName,
|
| 927 |
-
tracks: tracks
|
| 928 |
};
|
| 929 |
isPlayingPlaylist = true;
|
| 930 |
|
| 931 |
-
|
| 932 |
-
const mainPlaylistIndex = playlist.indexOf(tracks[0]);
|
| 933 |
if (mainPlaylistIndex !== -1) {
|
| 934 |
playTrack(mainPlaylistIndex);
|
| 935 |
showNotification(`Playing artist: ${artistName}`);
|
|
|
|
| 3 |
let playlist = [];
|
| 4 |
let currentView = 'all';
|
| 5 |
let playlists = JSON.parse(localStorage.getItem('playlists')) || {};
|
|
|
|
| 6 |
let currentLyrics = null;
|
| 7 |
let isPlayingPlaylist = false;
|
| 8 |
|
| 9 |
+
// Add these cache objects at the top of the file
|
| 10 |
+
const ALBUM_CACHE = new Map();
|
| 11 |
+
const ARTIST_CACHE = new Map();
|
| 12 |
+
let lastStructureUpdate = 0;
|
| 13 |
+
|
| 14 |
const audioPlayer = document.getElementById('audio-player');
|
| 15 |
const playBtn = document.getElementById('play-btn');
|
| 16 |
const prevBtn = document.getElementById('prev-btn');
|
|
|
|
| 23 |
// Add this constant at the top of the file
|
| 24 |
const DEFAULT_COVER = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgMjAwIDIwMCI+PHJlY3Qgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiIGZpbGw9IiNlOWVjZWYiLz48dGV4dCB4PSI1MCUiIHk9IjUwJSIgc3R5bGU9ImZvbnQtZmFtaWx5OiBBcmlhbDsgZm9udC1zaXplOiAyMHB4OyBmaWxsOiAjNmM3NTdkOyBkb21pbmFudC1iYXNlbGluZTogbWlkZGxlOyB0ZXh0LWFuY2hvcjogbWlkZGxlOyI+Tm8gQWxidW0gQXJ0PC90ZXh0Pjwvc3ZnPg==';
|
| 25 |
|
| 26 |
+
// Add this function to check if we need to rebuild caches
|
| 27 |
+
function shouldRebuildCaches() {
|
| 28 |
+
const now = Date.now();
|
| 29 |
+
if (now - lastStructureUpdate > 5000) { // Only rebuild every 5 seconds max
|
| 30 |
+
lastStructureUpdate = now;
|
| 31 |
+
return true;
|
| 32 |
+
}
|
| 33 |
+
return false;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
// Fetch music structure from the server
|
| 37 |
fetch('/api/music-structure')
|
| 38 |
.then(response => response.json())
|
|
|
|
| 282 |
}
|
| 283 |
}
|
| 284 |
|
| 285 |
+
// Optimize renderAlbumView
|
| 286 |
function renderAlbumView() {
|
| 287 |
+
if (shouldRebuildCaches()) {
|
| 288 |
+
ALBUM_CACHE.clear();
|
| 289 |
+
playlist.forEach(track => {
|
| 290 |
+
if (track.metadata) {
|
| 291 |
+
const albumName = track.metadata.album || 'Unknown Album';
|
| 292 |
+
const artistName = track.metadata.artist || 'Unknown Artist';
|
| 293 |
+
const albumKey = `${albumName}___${artistName}`;
|
| 294 |
+
|
| 295 |
+
if (!ALBUM_CACHE.has(albumKey)) {
|
| 296 |
+
ALBUM_CACHE.set(albumKey, {
|
| 297 |
+
name: albumName,
|
| 298 |
+
artist: artistName,
|
| 299 |
+
artwork: track.metadata.artwork || DEFAULT_COVER,
|
| 300 |
+
tracks: []
|
| 301 |
+
});
|
| 302 |
+
}
|
| 303 |
+
ALBUM_CACHE.get(albumKey).tracks.push(track);
|
| 304 |
}
|
| 305 |
+
});
|
| 306 |
+
}
|
|
|
|
| 307 |
|
| 308 |
const container = document.getElementById('view-container');
|
| 309 |
+
const albumsHtml = Array.from(ALBUM_CACHE.values())
|
| 310 |
+
.map(album => {
|
| 311 |
+
const escapedName = escapeHtml(album.name);
|
| 312 |
+
const escapedArtist = escapeHtml(album.artist);
|
| 313 |
+
return `
|
| 314 |
<div class="album-card">
|
| 315 |
<div class="album-art-container">
|
| 316 |
<img class="album-art" src="${album.artwork}" onerror="this.src='${DEFAULT_COVER}'">
|
| 317 |
+
<button class="play-overlay" onclick="playAlbum('${escapedName}','${escapedArtist}')">
|
| 318 |
<i class="fas fa-play"></i>
|
| 319 |
</button>
|
| 320 |
</div>
|
| 321 |
+
<div class="album-info" onclick="showAlbumTracks('${escapedName}','${escapedArtist}')">
|
| 322 |
+
<h3>${escapedName}</h3>
|
| 323 |
<p>${album.artist}</p>
|
| 324 |
<p>${album.tracks.length} tracks</p>
|
| 325 |
</div>
|
| 326 |
+
</div>`;
|
| 327 |
+
}).join('');
|
| 328 |
+
|
| 329 |
+
container.innerHTML = `<div class="album-grid">${albumsHtml}</div>`;
|
| 330 |
}
|
| 331 |
|
| 332 |
+
// Optimize renderArtistView
|
| 333 |
function renderArtistView() {
|
| 334 |
+
if (shouldRebuildCaches()) {
|
| 335 |
+
ARTIST_CACHE.clear();
|
| 336 |
+
playlist.forEach(track => {
|
| 337 |
+
if (track.metadata) {
|
| 338 |
+
const artistName = track.metadata.artist || 'Unknown Artist';
|
| 339 |
+
if (!ARTIST_CACHE.has(artistName)) {
|
| 340 |
+
ARTIST_CACHE.set(artistName, {
|
| 341 |
+
name: artistName,
|
| 342 |
+
artwork: track.metadata.artwork || DEFAULT_COVER,
|
| 343 |
+
tracks: []
|
| 344 |
+
});
|
| 345 |
+
}
|
| 346 |
+
const artist = ARTIST_CACHE.get(artistName);
|
| 347 |
+
artist.tracks.push(track);
|
| 348 |
+
if (!artist.artwork && track.metadata.artwork) {
|
| 349 |
+
artist.artwork = track.metadata.artwork;
|
| 350 |
+
}
|
| 351 |
}
|
| 352 |
+
});
|
| 353 |
+
}
|
| 354 |
|
| 355 |
const container = document.getElementById('view-container');
|
| 356 |
+
const artistsHtml = Array.from(ARTIST_CACHE.values())
|
| 357 |
+
.map(artist => {
|
| 358 |
+
const escapedName = escapeHtml(artist.name);
|
| 359 |
+
return `
|
| 360 |
<div class="artist-card">
|
| 361 |
<div class="artist-art-container">
|
| 362 |
+
<img class="artist-image" src="${artist.artwork}" onerror="this.src='${DEFAULT_COVER}'" alt="${escapedName}">
|
| 363 |
+
<button class="play-overlay" onclick="playArtist('${escapedName}')">
|
| 364 |
<i class="fas fa-play"></i>
|
| 365 |
</button>
|
| 366 |
</div>
|
| 367 |
+
<div class="artist-info" onclick="showArtistTracks('${escapedName}')">
|
| 368 |
+
<h3>${escapedName}</h3>
|
| 369 |
<p>${artist.tracks.length} tracks</p>
|
| 370 |
</div>
|
| 371 |
+
</div>`;
|
| 372 |
+
}).join('');
|
| 373 |
+
|
| 374 |
+
container.innerHTML = `<div class="artist-grid">${artistsHtml}</div>`;
|
| 375 |
+
}
|
| 376 |
+
|
| 377 |
+
// Optimize track filtering functions
|
| 378 |
+
function getAlbumTracks(albumName, artistName) {
|
| 379 |
+
const albumKey = `${albumName}___${artistName}`;
|
| 380 |
+
return ALBUM_CACHE.get(albumKey)?.tracks || [];
|
| 381 |
+
}
|
| 382 |
+
|
| 383 |
+
function getArtistTracks(artistName) {
|
| 384 |
+
return ARTIST_CACHE.get(artistName)?.tracks || [];
|
| 385 |
}
|
| 386 |
|
| 387 |
function showAlbumTracks(albumName, artistName) {
|
| 388 |
+
const tracks = getAlbumTracks(albumName, artistName);
|
|
|
|
|
|
|
|
|
|
| 389 |
|
| 390 |
const container = document.getElementById('view-container');
|
| 391 |
const viewTitle = document.getElementById('view-title');
|
|
|
|
| 429 |
}
|
| 430 |
|
| 431 |
function showArtistTracks(artistName) {
|
| 432 |
+
const tracks = getArtistTracks(artistName);
|
|
|
|
|
|
|
| 433 |
renderTrackList(tracks, `Artist: ${artistName}`);
|
| 434 |
}
|
| 435 |
|
|
|
|
| 923 |
|
| 924 |
// Add these new functions to handle playing albums and artists
|
| 925 |
function playAlbum(albumName, artistName) {
|
| 926 |
+
const albumTracks = getAlbumTracks(albumName, artistName);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 927 |
if (albumTracks.length > 0) {
|
| 928 |
currentPlaylist = {
|
| 929 |
name: albumName,
|
|
|
|
| 940 |
}
|
| 941 |
|
| 942 |
function playArtist(artistName) {
|
| 943 |
+
const tracks = getArtistTracks(artistName);
|
|
|
|
|
|
|
| 944 |
if (tracks.length > 0) {
|
|
|
|
| 945 |
currentPlaylist = {
|
| 946 |
name: artistName,
|
| 947 |
+
tracks: [...tracks]
|
| 948 |
};
|
| 949 |
isPlayingPlaylist = true;
|
| 950 |
|
| 951 |
+
const mainPlaylistIndex = playlist.findIndex(track => track.path === tracks[0].path);
|
|
|
|
| 952 |
if (mainPlaylistIndex !== -1) {
|
| 953 |
playTrack(mainPlaylistIndex);
|
| 954 |
showNotification(`Playing artist: ${artistName}`);
|