Merge pull request #26 from JulienMaille/fav-lib

many ui small improvements
This commit is contained in:
Julien 2025-12-27 14:13:59 +01:00 committed by GitHub
commit a85262a25a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 88 additions and 38 deletions

View file

@ -137,14 +137,14 @@
<h2 class="section-title">Recent Albums</h2>
<div class="card-grid" id="home-recent-albums"></div>
</section>
<section class="content-section">
<h2 class="section-title">Recent Playlists</h2>
<div class="card-grid" id="home-recent-playlists"></div>
</section>
<section class="content-section">
<h2 class="section-title">Recent Artists</h2>
<div class="card-grid" id="home-recent-artists"></div>
</section>
<section class="content-section">
<h2 class="section-title">Recent Playlists</h2>
<div class="card-grid" id="home-recent-playlists"></div>
</section>
</div>
<div id="page-search" class="page">
@ -172,7 +172,7 @@
<div id="page-library" class="page">
<h2 class="section-title">Your Library</h2>
<div class="search-tabs">
<button class="search-tab active" data-tab="tracks">Liked Songs</button>
<button class="search-tab active" data-tab="tracks">Liked Tracks</button>
<button class="search-tab" data-tab="albums">Albums</button>
<button class="search-tab" data-tab="artists">Artists</button>
<button class="search-tab" data-tab="playlists">Playlists</button>

View file

@ -354,7 +354,7 @@ export async function handleTrackAction(action, item, player, api, lyricsManager
const container = itemEl.parentElement;
itemEl.remove();
if (container && container.children.length === 0) {
const msg = type === 'track' ? 'No liked songs yet.' : `No liked ${type}s yet.`;
const msg = type === 'track' ? 'No liked tracks yet.' : `No liked ${type}s yet.`;
container.innerHTML = `<div class="placeholder-text">${msg}</div>`;
}
} else if (added && !itemEl && ui && type === 'track') {
@ -427,7 +427,14 @@ export function initializeTrackInteractions(player, api, mainContent, contextMen
e.stopPropagation();
const trackItem = menuBtn.closest('.track-item');
if (trackItem && !trackItem.dataset.queueIndex) {
contextTrack = trackDataStore.get(trackItem);
const clickedTrack = trackDataStore.get(trackItem);
if (contextMenu.style.display === 'block' && contextTrack && clickedTrack && contextTrack.id === clickedTrack.id) {
contextMenu.style.display = 'none';
return;
}
contextTrack = clickedTrack;
if (contextTrack) {
await updateContextMenuLikeState(contextMenu, contextTrack);
const rect = menuBtn.getBoundingClientRect();

View file

@ -454,31 +454,16 @@ export class UIRenderer {
async renderLibraryPage() {
this.showPage('library');
const playlistsContainer = document.getElementById('library-playlists-container');
const tracksContainer = document.getElementById('library-tracks-container');
const albumsContainer = document.getElementById('library-albums-container');
const artistsContainer = document.getElementById('library-artists-container');
// Render Favorites
const likedPlaylists = await db.getFavorites('playlist');
if (likedPlaylists.length) {
playlistsContainer.innerHTML = likedPlaylists.map(p => this.createPlaylistCardHTML(p)).join('');
likedPlaylists.forEach(playlist => {
const el = playlistsContainer.querySelector(`[data-playlist-id="${playlist.uuid}"]`);
if (el) {
trackDataStore.set(el, playlist);
this.updateLikeState(el, 'playlist', playlist.uuid);
}
});
} else {
playlistsContainer.innerHTML = createPlaceholder('No liked playlists yet.');
}
const playlistsContainer = document.getElementById('library-playlists-container');
const likedTracks = await db.getFavorites('track');
if (likedTracks.length) {
this.renderListWithTracks(tracksContainer, likedTracks, true);
} else {
tracksContainer.innerHTML = createPlaceholder('No liked songs yet.');
tracksContainer.innerHTML = createPlaceholder('No liked tracks yet.');
}
const likedAlbums = await db.getFavorites('album');
@ -508,6 +493,20 @@ export class UIRenderer {
} else {
artistsContainer.innerHTML = createPlaceholder('No liked artists yet.');
}
const likedPlaylists = await db.getFavorites('playlist');
if (likedPlaylists.length) {
playlistsContainer.innerHTML = likedPlaylists.map(p => this.createPlaylistCardHTML(p)).join('');
likedPlaylists.forEach(playlist => {
const el = playlistsContainer.querySelector(`[data-playlist-id="${playlist.uuid}"]`);
if (el) {
trackDataStore.set(el, playlist);
this.updateLikeState(el, 'playlist', playlist.uuid);
}
});
} else {
playlistsContainer.innerHTML = createPlaceholder('No liked playlists yet.');
}
}
async renderHomePage() {
@ -528,7 +527,7 @@ export class UIRenderer {
}
});
} else {
albumsContainer.innerHTML = createPlaceholder("You haven't viewed any albums yet. Search for music to get started!");
albumsContainer.innerHTML = createPlaceholder("You haven't viewed any albums yet.");
}
if (recents.artists.length) {
@ -541,7 +540,7 @@ export class UIRenderer {
}
});
} else {
artistsContainer.innerHTML = createPlaceholder("You haven't viewed any artists yet. Search for music to get started!");
artistsContainer.innerHTML = createPlaceholder("You haven't viewed any artists yet.");
}
if (playlistsContainer) {
@ -555,7 +554,7 @@ export class UIRenderer {
}
});
} else {
playlistsContainer.innerHTML = createPlaceholder("You haven't viewed any playlists yet. Search for music to get started!");
playlistsContainer.innerHTML = createPlaceholder("You haven't viewed any playlists yet.");
}
}
}

View file

@ -530,8 +530,8 @@ body.has-page-background .track-item:hover {
.card-like-btn {
position: absolute;
top: 0.5rem;
right: 0.5rem;
top: 2%;
right: 2%;
background: rgba(0, 0, 0, 0.25) !important;
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
@ -947,6 +947,20 @@ body.has-page-background .track-item:hover {
flex-shrink: 0;
}
#like-album-btn,
#like-playlist-btn,
#like-artist-btn {
width: auto;
height: auto;
padding: 0.875rem;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
flex-shrink: 0;
aspect-ratio: 1/1;
}
.btn-secondary {
padding: 0.5rem 1rem;
background-color: var(--secondary);
@ -1379,6 +1393,7 @@ input:checked + .slider::before {
filter: var(--cover-filter);
z-index: -1;
background-image: var(--bg-image);
transition: background-image var(--transition);
}
.fullscreen-cover-content {
@ -2296,13 +2311,33 @@ input:checked + .slider::before {
.detail-header-actions {
width: auto;
margin-top: 0.5em;
display: flex;
align-items: center;
gap: 0.5rem;
}
.detail-header-actions .btn-primary {
width: auto;
padding: 0.5rem;
width: 40px;
height: 40px;
padding: 0;
border-radius: 50%;
aspect-ratio: 1/1;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
#like-album-btn,
#like-playlist-btn,
#like-artist-btn {
width: 40px;
height: 40px;
padding: 0;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.detail-header-actions .btn-primary span {
@ -2669,6 +2704,11 @@ input:checked + .slider::before {
}
@media (hover: none) and (pointer: coarse) {
.main-content {
padding: var(--spacing-sm);
grid-area: main;
}
.progress-bar,
.volume-bar {
height: 8px;
@ -2688,20 +2728,23 @@ input:checked + .slider::before {
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
.track-item,
.queue-track-item {
padding: var(--spacing-md) var(--spacing-sm);
button {
min-height: 36px;
min-width: 36px;
}
button {
min-height: 44px;
min-width: 44px;
.track-item {
grid-template-columns: 32px 1fr 40px 36px;
}
.player-controls .buttons button {
min-height: 36px;
min-width: 36px;
}
.card-like-btn {
opacity: 1;
}
}
@supports (padding-top: env(safe-area-inset-top)) {
@ -3161,3 +3204,4 @@ input:checked + .slider::before {
padding-top: max(1.5rem, env(titlebar-area-height, 0));
}
}