🐛 fix: CodeRabbit review (library search, covers, likes, layout classes, clear-btn, styles) and lint workflow; keep scroll on list/grid toggle

Made-with: Cursor
This commit is contained in:
Thiago Vinícius 2026-03-27 18:20:11 -03:00
parent 2e92a34b00
commit 5be3d39b1b
4 changed files with 30 additions and 14 deletions

View file

@ -19,6 +19,7 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 1
ref: ${{ github.head_ref || github.ref }}
- name: Setup Bun
uses: oven-sh/setup-bun@v1
@ -55,7 +56,6 @@ jobs:
commit_message: 'style: auto-fix linting issues'
commit_user_name: 'github-actions[bot]'
commit_user_email: 'github-actions[bot]@users.noreply.github.com'
only_if_changed: true
- name: Run HTML Lint
run: bun run lint:html

View file

@ -1458,10 +1458,12 @@ export async function handleTrackAction(
const layout = localStorage.getItem('libraryLikedTracksView') || 'list';
const tempDiv = document.createElement('div');
if (layout === 'grid') {
tracksContainer.className = 'card-grid';
tracksContainer.classList.remove('track-list');
tracksContainer.classList.add('card-grid');
tempDiv.innerHTML = ui.createTrackCardHTML(item);
} else {
tracksContainer.className = 'track-list';
tracksContainer.classList.remove('card-grid');
tracksContainer.classList.add('track-list');
const index = tracksContainer.children.length;
tempDiv.innerHTML = ui.createTrackItemHTML(item, index, true, false, false, true);
}
@ -1470,7 +1472,7 @@ export async function handleTrackAction(
if (newEl) {
tracksContainer.appendChild(newEl);
trackDataStore.set(newEl, item);
ui.updateLikeState(newEl, item.type === 'video' ? 'video' : 'track', item.id);
ui.updateLikeState(newEl, 'track', item.id);
const likedToolbar = document.getElementById('library-liked-tracks-toolbar');
if (likedToolbar) likedToolbar.style.display = 'flex';
const shuffleBtn = document.getElementById('shuffle-liked-tracks-btn');

View file

@ -738,13 +738,18 @@ export class UIRenderer {
videoCoverCandidate && (typeof videoCoverCandidate === 'string' || typeof videoCoverCandidate === 'number')
? this.api.getVideoCoverUrl(videoCoverCandidate)
: null;
const cover = video.image || video.cover;
const coverFallback = video.image || video.cover;
const coverPrimitive =
coverFallback != null &&
(typeof coverFallback === 'string' || typeof coverFallback === 'number')
? coverFallback
: null;
let imageHTML;
if (videoCoverUrl) {
imageHTML = `<img src="${videoCoverUrl}" alt="${escapeHtml(video.title)}" class="card-image" loading="lazy">`;
} else if (cover) {
imageHTML = this.getCoverHTML(cover, escapeHtml(video.title));
} else if (coverPrimitive) {
imageHTML = this.getCoverHTML(coverPrimitive, escapeHtml(video.title));
} else {
imageHTML = `<div class="card-image video-icon-placeholder" style="display: flex; align-items: center; justify-content: center; background: var(--secondary); aspect-ratio: 16/9; width: 100%;">${SVG_PLAY(48, { style: 'opacity: 0.7;' })}</div>`;
}
@ -843,18 +848,20 @@ export class UIRenderer {
const oldListener = clearBtn._clearListener;
if (oldListener) clearBtn.removeEventListener('click', oldListener);
// Toggle visibility based on input value
const oldToggle = inputElement._searchClearToggleListener;
if (oldToggle) inputElement.removeEventListener('input', oldToggle);
const toggleVisibility = () => {
clearBtn.style.display = inputElement.value.trim() ? 'flex' : 'none';
};
// Clear input on click
const clearListener = () => {
inputElement.value = '';
inputElement.dispatchEvent(new Event('input'));
inputElement.focus();
};
inputElement._searchClearToggleListener = toggleVisibility;
inputElement.addEventListener('input', toggleVisibility);
clearBtn._clearListener = clearListener;
clearBtn.addEventListener('click', clearListener);
@ -1718,6 +1725,7 @@ export class UIRenderer {
}
showPage(pageId) {
const previousPage = this.currentPage;
this.currentPage = pageId;
document.querySelectorAll('.page').forEach((page) => {
page.classList.toggle('active', page.id === `page-${pageId}`);
@ -1730,7 +1738,10 @@ export class UIRenderer {
);
});
document.querySelector('.main-content').scrollTop = 0;
const mainContent = document.querySelector('.main-content');
if (mainContent && previousPage !== pageId) {
mainContent.scrollTop = 0;
}
// Clear artist context when navigating away from artist page
if (pageId !== 'artist') {
@ -1809,7 +1820,8 @@ export class UIRenderer {
if (viewGridBtn) viewGridBtn.classList.toggle('active', likedViewLayout === 'grid');
if (likedViewLayout === 'grid') {
tracksContainer.className = 'card-grid';
tracksContainer.classList.remove('track-list');
tracksContainer.classList.add('card-grid');
tracksContainer.innerHTML = likedTracks.map((t) => this.createTrackCardHTML(t)).join('');
likedTracks.forEach((track) => {
const el = tracksContainer.querySelector(`[data-track-id="${track.id}"]`);
@ -1820,7 +1832,8 @@ export class UIRenderer {
}
});
} else {
tracksContainer.className = 'track-list';
tracksContainer.classList.remove('card-grid');
tracksContainer.classList.add('track-list');
this.renderListWithTracks(tracksContainer, likedTracks, true, false, false, true);
}
this.setupLibraryLikedTracksSearch(tracksContainer);
@ -1828,7 +1841,8 @@ export class UIRenderer {
if (likedToolbar) likedToolbar.style.display = 'none';
if (shuffleBtn) shuffleBtn.style.display = 'none';
if (downloadBtn) downloadBtn.style.display = 'none';
tracksContainer.className = 'track-list';
tracksContainer.classList.remove('card-grid');
tracksContainer.classList.add('track-list');
tracksContainer.innerHTML = createPlaceholder('No liked tracks yet.');
}

View file

@ -2419,7 +2419,7 @@ body.multi-select-mode .track-item:hover {
}
.track-row-like-btn.active {
color: var(--highlight);
color: #ef4444;
}
.track-item-duration {