Merge pull request #26 from JulienMaille/fav-lib
many ui small improvements
This commit is contained in:
commit
a85262a25a
4 changed files with 88 additions and 38 deletions
10
index.html
10
index.html
|
|
@ -137,14 +137,14 @@
|
||||||
<h2 class="section-title">Recent Albums</h2>
|
<h2 class="section-title">Recent Albums</h2>
|
||||||
<div class="card-grid" id="home-recent-albums"></div>
|
<div class="card-grid" id="home-recent-albums"></div>
|
||||||
</section>
|
</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">
|
<section class="content-section">
|
||||||
<h2 class="section-title">Recent Artists</h2>
|
<h2 class="section-title">Recent Artists</h2>
|
||||||
<div class="card-grid" id="home-recent-artists"></div>
|
<div class="card-grid" id="home-recent-artists"></div>
|
||||||
</section>
|
</section>
|
||||||
|
<section class="content-section">
|
||||||
|
<h2 class="section-title">Recent Playlists</h2>
|
||||||
|
<div class="card-grid" id="home-recent-playlists"></div>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="page-search" class="page">
|
<div id="page-search" class="page">
|
||||||
|
|
@ -172,7 +172,7 @@
|
||||||
<div id="page-library" class="page">
|
<div id="page-library" class="page">
|
||||||
<h2 class="section-title">Your Library</h2>
|
<h2 class="section-title">Your Library</h2>
|
||||||
<div class="search-tabs">
|
<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="albums">Albums</button>
|
||||||
<button class="search-tab" data-tab="artists">Artists</button>
|
<button class="search-tab" data-tab="artists">Artists</button>
|
||||||
<button class="search-tab" data-tab="playlists">Playlists</button>
|
<button class="search-tab" data-tab="playlists">Playlists</button>
|
||||||
|
|
|
||||||
11
js/events.js
11
js/events.js
|
|
@ -354,7 +354,7 @@ export async function handleTrackAction(action, item, player, api, lyricsManager
|
||||||
const container = itemEl.parentElement;
|
const container = itemEl.parentElement;
|
||||||
itemEl.remove();
|
itemEl.remove();
|
||||||
if (container && container.children.length === 0) {
|
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>`;
|
container.innerHTML = `<div class="placeholder-text">${msg}</div>`;
|
||||||
}
|
}
|
||||||
} else if (added && !itemEl && ui && type === 'track') {
|
} else if (added && !itemEl && ui && type === 'track') {
|
||||||
|
|
@ -427,7 +427,14 @@ export function initializeTrackInteractions(player, api, mainContent, contextMen
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const trackItem = menuBtn.closest('.track-item');
|
const trackItem = menuBtn.closest('.track-item');
|
||||||
if (trackItem && !trackItem.dataset.queueIndex) {
|
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) {
|
if (contextTrack) {
|
||||||
await updateContextMenuLikeState(contextMenu, contextTrack);
|
await updateContextMenuLikeState(contextMenu, contextTrack);
|
||||||
const rect = menuBtn.getBoundingClientRect();
|
const rect = menuBtn.getBoundingClientRect();
|
||||||
|
|
|
||||||
39
js/ui.js
39
js/ui.js
|
|
@ -454,31 +454,16 @@ export class UIRenderer {
|
||||||
async renderLibraryPage() {
|
async renderLibraryPage() {
|
||||||
this.showPage('library');
|
this.showPage('library');
|
||||||
|
|
||||||
const playlistsContainer = document.getElementById('library-playlists-container');
|
|
||||||
const tracksContainer = document.getElementById('library-tracks-container');
|
const tracksContainer = document.getElementById('library-tracks-container');
|
||||||
const albumsContainer = document.getElementById('library-albums-container');
|
const albumsContainer = document.getElementById('library-albums-container');
|
||||||
const artistsContainer = document.getElementById('library-artists-container');
|
const artistsContainer = document.getElementById('library-artists-container');
|
||||||
|
const playlistsContainer = document.getElementById('library-playlists-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 likedTracks = await db.getFavorites('track');
|
const likedTracks = await db.getFavorites('track');
|
||||||
if (likedTracks.length) {
|
if (likedTracks.length) {
|
||||||
this.renderListWithTracks(tracksContainer, likedTracks, true);
|
this.renderListWithTracks(tracksContainer, likedTracks, true);
|
||||||
} else {
|
} else {
|
||||||
tracksContainer.innerHTML = createPlaceholder('No liked songs yet.');
|
tracksContainer.innerHTML = createPlaceholder('No liked tracks yet.');
|
||||||
}
|
}
|
||||||
|
|
||||||
const likedAlbums = await db.getFavorites('album');
|
const likedAlbums = await db.getFavorites('album');
|
||||||
|
|
@ -508,6 +493,20 @@ export class UIRenderer {
|
||||||
} else {
|
} else {
|
||||||
artistsContainer.innerHTML = createPlaceholder('No liked artists yet.');
|
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() {
|
async renderHomePage() {
|
||||||
|
|
@ -528,7 +527,7 @@ export class UIRenderer {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} 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) {
|
if (recents.artists.length) {
|
||||||
|
|
@ -541,7 +540,7 @@ export class UIRenderer {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} 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) {
|
if (playlistsContainer) {
|
||||||
|
|
@ -555,7 +554,7 @@ export class UIRenderer {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} 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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
66
styles.css
66
styles.css
|
|
@ -530,8 +530,8 @@ body.has-page-background .track-item:hover {
|
||||||
|
|
||||||
.card-like-btn {
|
.card-like-btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0.5rem;
|
top: 2%;
|
||||||
right: 0.5rem;
|
right: 2%;
|
||||||
background: rgba(0, 0, 0, 0.25) !important;
|
background: rgba(0, 0, 0, 0.25) !important;
|
||||||
backdrop-filter: blur(8px);
|
backdrop-filter: blur(8px);
|
||||||
-webkit-backdrop-filter: blur(8px);
|
-webkit-backdrop-filter: blur(8px);
|
||||||
|
|
@ -947,6 +947,20 @@ body.has-page-background .track-item:hover {
|
||||||
flex-shrink: 0;
|
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 {
|
.btn-secondary {
|
||||||
padding: 0.5rem 1rem;
|
padding: 0.5rem 1rem;
|
||||||
background-color: var(--secondary);
|
background-color: var(--secondary);
|
||||||
|
|
@ -1379,6 +1393,7 @@ input:checked + .slider::before {
|
||||||
filter: var(--cover-filter);
|
filter: var(--cover-filter);
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
background-image: var(--bg-image);
|
background-image: var(--bg-image);
|
||||||
|
transition: background-image var(--transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-cover-content {
|
.fullscreen-cover-content {
|
||||||
|
|
@ -2296,13 +2311,33 @@ input:checked + .slider::before {
|
||||||
.detail-header-actions {
|
.detail-header-actions {
|
||||||
width: auto;
|
width: auto;
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.detail-header-actions .btn-primary {
|
.detail-header-actions .btn-primary {
|
||||||
width: auto;
|
width: 40px;
|
||||||
padding: 0.5rem;
|
height: 40px;
|
||||||
|
padding: 0;
|
||||||
border-radius: 50%;
|
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 {
|
.detail-header-actions .btn-primary span {
|
||||||
|
|
@ -2669,6 +2704,11 @@ input:checked + .slider::before {
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (hover: none) and (pointer: coarse) {
|
@media (hover: none) and (pointer: coarse) {
|
||||||
|
.main-content {
|
||||||
|
padding: var(--spacing-sm);
|
||||||
|
grid-area: main;
|
||||||
|
}
|
||||||
|
|
||||||
.progress-bar,
|
.progress-bar,
|
||||||
.volume-bar {
|
.volume-bar {
|
||||||
height: 8px;
|
height: 8px;
|
||||||
|
|
@ -2688,20 +2728,23 @@ input:checked + .slider::before {
|
||||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.track-item,
|
button {
|
||||||
.queue-track-item {
|
min-height: 36px;
|
||||||
padding: var(--spacing-md) var(--spacing-sm);
|
min-width: 36px;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
.track-item {
|
||||||
min-height: 44px;
|
grid-template-columns: 32px 1fr 40px 36px;
|
||||||
min-width: 44px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.player-controls .buttons button {
|
.player-controls .buttons button {
|
||||||
min-height: 36px;
|
min-height: 36px;
|
||||||
min-width: 36px;
|
min-width: 36px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card-like-btn {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@supports (padding-top: env(safe-area-inset-top)) {
|
@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));
|
padding-top: max(1.5rem, env(titlebar-area-height, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue