This commit is contained in:
Broque Thomas 2025-08-23 10:14:38 -07:00
parent bb6be656e0
commit a78732fb08
2 changed files with 381 additions and 38 deletions

View file

@ -992,26 +992,69 @@ function displayDownloadsResults(results) {
if (isAlbum) {
const trackCount = result.tracks ? result.tracks.length : 0;
const totalSize = result.total_size ? `${(result.total_size / 1024 / 1024).toFixed(1)} MB` : 'Unknown size';
// Generate individual track items
let trackListHtml = '';
if (result.tracks && result.tracks.length > 0) {
result.tracks.forEach((track, trackIndex) => {
const trackSize = track.size ? `${(track.size / 1024 / 1024).toFixed(1)} MB` : 'Unknown size';
const trackBitrate = track.bitrate ? `${track.bitrate}kbps` : '';
trackListHtml += `
<div class="track-item">
<div class="track-item-info">
<div class="track-item-title">${escapeHtml(track.title || `Track ${trackIndex + 1}`)}</div>
<div class="track-item-details">
${track.track_number ? `${track.track_number}. ` : ''}${escapeHtml(track.artist || result.artist || 'Unknown Artist')} ${trackSize} ${escapeHtml(track.quality || 'Unknown')} ${trackBitrate}
</div>
</div>
<div class="track-item-actions">
<button onclick="downloadAlbumTrack(${index}, ${trackIndex})" class="track-download-btn"></button>
</div>
</div>
`;
});
}
html += `
<div class="search-result-item album-result">
<div class="result-info">
<strong>🎵 ${escapeHtml(result.album_title || result.title || 'Unknown Album')}</strong><br>
<span>by ${escapeHtml(result.artist || 'Unknown Artist')}</span><br>
<small>${trackCount} tracks ${escapeHtml(result.quality || 'Mixed')}</small>
<div class="album-result-card" data-album-index="${index}">
<div class="album-card-header" onclick="toggleAlbumExpansion(${index})">
<div class="album-expand-indicator"></div>
<div class="album-icon">💿</div>
<div class="album-info">
<div class="album-title">${escapeHtml(result.album_title || result.title || 'Unknown Album')}</div>
<div class="album-artist">by ${escapeHtml(result.artist || 'Unknown Artist')}</div>
<div class="album-details">
${trackCount} tracks ${totalSize} ${escapeHtml(result.quality || 'Mixed')}
</div>
<div class="album-uploader">Shared by ${escapeHtml(result.username || 'Unknown')}</div>
</div>
<div class="album-actions" onclick="event.stopPropagation()">
<button onclick="downloadAlbum(${index})" class="album-download-btn"> Download Album</button>
</div>
</div>
<div class="album-track-list" style="display: none;">
${trackListHtml}
</div>
<button onclick="downloadAlbum(${index})" class="download-btn"> Download Album</button>
</div>
`;
} else {
const sizeText = result.size ? `${(result.size / 1024 / 1024).toFixed(1)} MB` : 'Unknown size';
const bitrateText = result.bitrate ? `${result.bitrate}kbps` : '';
html += `
<div class="search-result-item track-result">
<div class="result-info">
<strong>${escapeHtml(result.title || 'Unknown Title')}</strong><br>
<span>by ${escapeHtml(result.artist || 'Unknown Artist')}</span><br>
<small>${sizeText} ${escapeHtml(result.quality || 'Unknown')} ${result.bitrate ? `${result.bitrate}kbps` : ''}</small>
<div class="track-result-card">
<div class="track-icon">🎵</div>
<div class="track-info">
<div class="track-title">${escapeHtml(result.title || 'Unknown Title')}</div>
<div class="track-artist">by ${escapeHtml(result.artist || 'Unknown Artist')}</div>
<div class="track-details">
${sizeText} ${escapeHtml(result.quality || 'Unknown')} ${bitrateText}
</div>
<div class="track-uploader">Shared by ${escapeHtml(result.username || 'Unknown')}</div>
</div>
<div class="track-actions">
<button onclick="downloadTrack(${index})" class="track-download-btn"> Download</button>
</div>
<button onclick="downloadTrack(${index})" class="download-btn"> Download</button>
</div>
`;
}
@ -1074,6 +1117,55 @@ async function downloadAlbum(index) {
}
}
function toggleAlbumExpansion(albumIndex) {
const albumCard = document.querySelector(`[data-album-index="${albumIndex}"]`);
if (!albumCard) return;
const trackList = albumCard.querySelector('.album-track-list');
const indicator = albumCard.querySelector('.album-expand-indicator');
if (trackList.style.display === 'none' || !trackList.style.display) {
// Expand
trackList.style.display = 'block';
indicator.textContent = '▼';
albumCard.classList.add('expanded');
} else {
// Collapse
trackList.style.display = 'none';
indicator.textContent = '▶';
albumCard.classList.remove('expanded');
}
}
async function downloadAlbumTrack(albumIndex, trackIndex) {
const results = window.currentSearchResults;
if (!results || !results[albumIndex] || !results[albumIndex].tracks || !results[albumIndex].tracks[trackIndex]) return;
const track = results[albumIndex].tracks[trackIndex];
try {
const response = await fetch('/api/download', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
...track,
result_type: 'track'
})
});
const data = await response.json();
if (data.success) {
showToast(`Download started: ${track.title}`, 'success');
} else {
showToast(`Track download failed: ${data.error}`, 'error');
}
} catch (error) {
console.error('Track download error:', error);
showToast('Failed to start track download', 'error');
}
}
async function loadArtistsData() {
try {
const response = await fetch(API.artists);
@ -1425,4 +1517,6 @@ window.selectResult = selectResult;
window.startStream = startStream;
window.startDownload = startDownload;
window.downloadTrack = downloadTrack;
window.downloadAlbum = downloadAlbum;
window.downloadAlbum = downloadAlbum;
window.toggleAlbumExpansion = toggleAlbumExpansion;
window.downloadAlbumTrack = downloadAlbumTrack;

View file

@ -2008,34 +2008,283 @@ body {
animation: modalFadeIn 0.3s ease-out;
}
/* Simple Downloads Results Styling */
.search-result-item {
background: rgba(255, 255, 255, 0.02);
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 8px;
padding: 12px;
margin-bottom: 8px;
/* GUI-Matching Search Results Styling */
/* Single Track Card (SearchResultItem) */
.track-result-card {
background: linear-gradient(to bottom,
rgba(48, 48, 52, 0.95),
rgba(38, 38, 42, 0.98));
border-radius: 18px;
border: 1px solid rgba(70, 70, 76, 0.5);
margin: 8px 4px;
padding: 16px;
display: flex;
justify-content: space-between;
align-items: center;
}
.search-result-item .result-info {
flex: 1;
}
.search-result-item .download-btn {
background: rgba(29, 185, 84, 0.1);
color: #1ed760;
border: 1px solid rgba(29, 185, 84, 0.3);
padding: 8px 16px;
border-radius: 6px;
cursor: pointer;
font-size: 12px;
gap: 16px;
transition: all 0.2s ease;
}
.search-result-item .download-btn:hover {
background: rgba(29, 185, 84, 0.2);
border-color: rgba(29, 185, 84, 0.5);
.track-result-card:hover {
background: linear-gradient(to bottom,
rgba(55, 55, 60, 0.98),
rgba(45, 45, 50, 1.0));
border: 1px solid rgba(29, 185, 84, 0.8);
}
.track-icon {
background: linear-gradient(to bottom right,
rgba(29, 185, 84, 0.3),
rgba(24, 156, 71, 0.2));
border-radius: 22px;
border: 2px solid rgba(29, 185, 84, 0.4);
font-size: 18px;
color: rgba(29, 185, 84, 1.0);
width: 44px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.track-info {
flex: 1;
min-width: 0;
}
.track-title {
font-size: 14px;
font-weight: bold;
color: #ffffff;
margin-bottom: 2px;
}
.track-artist {
font-size: 12px;
color: #b3b3b3;
margin-bottom: 2px;
}
.track-details {
font-size: 10px;
color: #888888;
margin-bottom: 2px;
}
.track-uploader {
font-size: 10px;
color: rgba(29, 185, 84, 1.0);
font-weight: 500;
}
.track-actions {
flex-shrink: 0;
}
.track-download-btn {
background: linear-gradient(to bottom,
rgba(29, 185, 84, 0.95),
rgba(24, 156, 71, 0.9));
border: 2px solid rgba(29, 185, 84, 0.3);
border-radius: 23px;
color: #000000;
font-size: 14px;
font-weight: bold;
padding: 8px 16px;
cursor: pointer;
transition: all 0.2s ease;
}
.track-download-btn:hover {
background: linear-gradient(to bottom,
rgba(30, 215, 96, 1.0),
rgba(25, 180, 80, 1.0));
}
/* Album Card (AlbumResultItem) */
.album-result-card {
background: linear-gradient(to bottom,
rgba(52, 52, 58, 0.95),
rgba(42, 42, 48, 0.98));
border-radius: 20px;
border: 1px solid rgba(75, 75, 82, 0.5);
margin: 8px 4px;
padding: 18px;
transition: all 0.2s ease;
}
.album-result-card:hover {
border: 1px solid rgba(29, 185, 84, 0.8);
}
.album-card-header {
display: flex;
align-items: center;
gap: 18px;
}
.album-icon {
font-size: 28px;
background: linear-gradient(to bottom right,
rgba(29, 185, 84, 0.2),
rgba(24, 156, 71, 0.15));
border-radius: 28px;
border: 2px solid rgba(29, 185, 84, 0.4);
width: 56px;
height: 56px;
display: flex;
align-items: center;
justify-content: center;
color: rgba(29, 185, 84, 1.0);
flex-shrink: 0;
}
.album-info {
flex: 1;
min-width: 0;
}
.album-title {
font-size: 16px;
font-weight: bold;
color: #ffffff;
margin-bottom: 3px;
}
.album-artist {
font-size: 13px;
color: #b3b3b3;
margin-bottom: 3px;
}
.album-details {
font-size: 11px;
color: #888888;
margin-bottom: 3px;
}
.album-uploader {
font-size: 11px;
color: rgba(29, 185, 84, 1.0);
font-weight: 500;
}
.album-actions {
flex-shrink: 0;
}
.album-download-btn {
background: linear-gradient(to bottom,
rgba(29, 185, 84, 0.95),
rgba(24, 156, 71, 0.9));
border: 2px solid rgba(29, 185, 84, 0.3);
border-radius: 23px;
color: #000000;
font-size: 15px;
font-weight: bold;
padding: 10px 20px;
cursor: pointer;
transition: all 0.2s ease;
}
.album-download-btn:hover {
background: linear-gradient(to bottom,
rgba(30, 215, 96, 1.0),
rgba(25, 180, 80, 1.0));
}
/* Album Expansion Functionality */
.album-card-header {
cursor: pointer;
position: relative;
}
.album-expand-indicator {
position: absolute;
left: -12px;
top: 50%;
transform: translateY(-50%);
font-size: 12px;
color: rgba(29, 185, 84, 0.8);
transition: transform 0.2s ease;
}
.album-result-card.expanded .album-expand-indicator {
transform: translateY(-50%) rotate(90deg);
}
/* Track List within Albums */
.album-track-list {
margin-top: 12px;
padding-top: 12px;
border-top: 1px solid rgba(75, 75, 82, 0.3);
}
/* Individual Track Items (TrackItem) */
.track-item {
background: rgba(40, 40, 40, 0.5);
border-radius: 8px;
border: 1px solid rgba(60, 60, 60, 0.3);
padding: 10px;
margin-bottom: 6px;
display: flex;
align-items: center;
justify-content: space-between;
transition: all 0.2s ease;
}
.track-item:hover {
background: rgba(50, 50, 50, 0.7);
border: 1px solid rgba(29, 185, 84, 0.5);
}
.track-item-info {
flex: 1;
min-width: 0;
}
.track-item-title {
font-size: 12px;
font-weight: bold;
color: #ffffff;
margin-bottom: 2px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.track-item-details {
font-size: 10px;
color: #888888;
}
.track-item-actions {
flex-shrink: 0;
margin-left: 8px;
}
.track-download-btn {
background: linear-gradient(to bottom,
rgba(29, 185, 84, 0.8),
rgba(24, 156, 71, 0.7));
border: 1px solid rgba(29, 185, 84, 0.4);
border-radius: 50%;
color: #000000;
font-size: 12px;
font-weight: bold;
width: 28px;
height: 28px;
cursor: pointer;
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
}
.track-download-btn:hover {
background: linear-gradient(to bottom,
rgba(30, 215, 96, 0.9),
rgba(25, 180, 80, 0.8));
border-color: rgba(29, 185, 84, 0.6);
}