AdityaAdaki commited on
Commit
a8fd63c
·
1 Parent(s): c2aa052

optimizations

Browse files
Files changed (1) hide show
  1. 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
- const albums = {};
273
- playlist.forEach(track => {
274
- if (track.metadata) {
275
- // Create a unique key combining album name and artist to prevent mixing different albums
276
- const albumName = track.metadata.album || 'Unknown Album';
277
- const artistName = track.metadata.artist || 'Unknown Artist';
278
- const albumKey = `${albumName}___${artistName}`;
279
-
280
- if (!albums[albumKey]) {
281
- albums[albumKey] = {
282
- name: albumName,
283
- artist: artistName,
284
- artwork: track.metadata.artwork || DEFAULT_COVER,
285
- tracks: []
286
- };
 
 
287
  }
288
- albums[albumKey].tracks.push(track);
289
- }
290
- });
291
 
292
  const container = document.getElementById('view-container');
293
- container.innerHTML = `
294
- <div class="album-grid">
295
- ${Object.values(albums).map(album => `
 
 
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('${escapeHtml(album.name)}', '${escapeHtml(album.artist)}')">
300
  <i class="fas fa-play"></i>
301
  </button>
302
  </div>
303
- <div class="album-info" onclick="showAlbumTracks('${escapeHtml(album.name)}', '${escapeHtml(album.artist)}')">
304
- <h3>${escapeHtml(album.name)}</h3>
305
  <p>${album.artist}</p>
306
  <p>${album.tracks.length} tracks</p>
307
  </div>
308
- </div>
309
- `).join('')}
310
- </div>
311
- `;
312
  }
313
 
 
314
  function renderArtistView() {
315
- const artists = {};
316
- playlist.forEach(track => {
317
- if (track.metadata) {
318
- const artistName = track.metadata.artist || 'Unknown Artist';
319
- if (!artists[artistName]) {
320
- artists[artistName] = {
321
- name: artistName,
322
- artwork: track.metadata.artwork || DEFAULT_COVER,
323
- tracks: []
324
- };
325
- }
326
- artists[artistName].tracks.push(track);
327
- // Use the first track's artwork as artist image if we don't have it yet
328
- if (!artists[artistName].artwork && track.metadata.artwork) {
329
- artists[artistName].artwork = track.metadata.artwork;
 
 
330
  }
331
- }
332
- });
333
 
334
  const container = document.getElementById('view-container');
335
- container.innerHTML = `
336
- <div class="artist-grid">
337
- ${Object.values(artists).map(artist => `
 
338
  <div class="artist-card">
339
  <div class="artist-art-container">
340
- <img class="artist-image" src="${artist.artwork}" alt="${artist.name}">
341
- <button class="play-overlay" onclick="playArtist('${artist.name}')">
342
  <i class="fas fa-play"></i>
343
  </button>
344
  </div>
345
- <div class="artist-info" onclick="showArtistTracks('${artist.name}')">
346
- <h3>${artist.name}</h3>
347
  <p>${artist.tracks.length} tracks</p>
348
  </div>
349
- </div>
350
- `).join('')}
351
- </div>
352
- `;
 
 
 
 
 
 
 
 
 
 
353
  }
354
 
355
  function showAlbumTracks(albumName, artistName) {
356
- const tracks = playlist.filter(track =>
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 = playlist.filter(track =>
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 = playlist.filter(track =>
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 = playlist.filter(track =>
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
- // Play the first track
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}`);