Fix search, branding, header centering, and card-based feed layout
- Search box now fills navbar center with max-width 400px - Dropdown items have more padding (p-4) and hover contrast - Branding uses cross-browser gradient text with visible tagline - Navbar centers tabs + search together in navbar-center - Feed redesigned as responsive card grid (cover-centered, details below) - Cards show large cover art with aspect-ratio:1, fallback SVG on 404 - Artist name, title, type badge, and date positioned under cover
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
{#if entries.isEmpty()}
|
{#if entries.isEmpty()}
|
||||||
<div class="bg-base-100 shadow-xl rounded-box p-10 text-center border border-base-300">
|
<div class="bg-base-100 shadow-xl rounded-box p-12 text-center border border-base-300">
|
||||||
<svg class="icon-lg" style="margin:0 auto 0.75rem;color:var(--bc);opacity:0.15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
<svg class="icon-lg" style="margin:0 auto 0.75rem;color:var(--bc);opacity:0.15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/>
|
<circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/>
|
||||||
<path d="M9 18V5l12-2v13"/><path d="M9 9l12-2"/>
|
<path d="M9 18V5l12-2v13"/><path d="M9 9l12-2"/>
|
||||||
@@ -8,46 +8,40 @@
|
|||||||
<p style="font-size:0.875rem;color:var(--bc);opacity:0.4;margin-top:0.25rem">Add artists to your collection to see their releases here</p>
|
<p style="font-size:0.875rem;color:var(--bc);opacity:0.4;margin-top:0.25rem">Add artists to your collection to see their releases here</p>
|
||||||
</div>
|
</div>
|
||||||
{#else}
|
{#else}
|
||||||
<div class="overflow-x-auto rounded-box border border-base-300">
|
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:1rem">
|
||||||
<table class="table table-pin-rows">
|
{#for entry in entries}
|
||||||
<thead>
|
<a href="https://musicbrainz.org/release-group/{entry.mbid}"
|
||||||
<tr style="background:color-mix(in srgb, var(--b2) 80%, transparent)">
|
target="_blank" rel="noopener noreferrer"
|
||||||
<th style="width:5rem">Cover</th>
|
class="bg-base-100 shadow-md rounded-box border border-base-300 overflow-hidden"
|
||||||
<th>Artist</th>
|
style="text-decoration:none;transition:transform 0.15s,box-shadow 0.15s;display:flex;flex-direction:column"
|
||||||
<th>Release</th>
|
onmouseover="this.style.transform='translateY(-2px)';this.style.boxShadow='0 8px 24px rgba(0,0,0,0.2)'"
|
||||||
<th>Type</th>
|
onmouseout="this.style.transform='';this.style.boxShadow=''">
|
||||||
<th style="width:7rem">Date</th>
|
<div style="aspect-ratio:1;overflow:hidden;background:var(--b2)">
|
||||||
</tr>
|
<img src="https://coverartarchive.org/release-group/{entry.mbid}/front-250"
|
||||||
</thead>
|
alt="Cover for {entry.title}"
|
||||||
<tbody>
|
style="width:100%;height:100%;object-fit:cover;display:block"
|
||||||
{#for entry in entries}
|
loading="lazy"
|
||||||
<tr style="transition:background 0.15s" onmouseover="this.style.background='color-mix(in srgb, var(--b2) 50%, transparent)'" onmouseout="this.style.background=''">
|
onerror="this.parentElement.innerHTML='<div style=\'display:flex;align-items:center;justify-content:center;height:100%;color:var(--bc);opacity:0.15\'><svg width=\'48\' height=\'48\' viewBox=\'0 0 24 24\' fill=\'none\' stroke=\'currentColor\' stroke-width=\'1.5\'><circle cx=\'6\' cy=\'18\' r=\'3\'/><circle cx=\'18\' cy=\'16\' r=\'3\'/><path d=\'M9 18V5l12-2v13\'/><path d=\'M9 9l12-2\'/></svg></div>'">
|
||||||
<td>
|
</div>
|
||||||
<a href="https://musicbrainz.org/release-group/{entry.mbid}" target="_blank" rel="noopener noreferrer">
|
<div style="padding:0.65rem 0.75rem;flex:1;display:flex;flex-direction:column;gap:0.2rem">
|
||||||
<img src="https://coverartarchive.org/release-group/{entry.mbid}/front-250" alt="Cover" class="cover-img" loading="lazy" onerror="this.style.display='none'">
|
<div style="font-size:0.75rem;font-weight:500;color:var(--bc);opacity:0.55;text-transform:uppercase;letter-spacing:0.05em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">{entry.artistName}</div>
|
||||||
</a>
|
<div style="font-size:0.85rem;font-weight:600;color:var(--bc);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;line-height:1.3">{entry.title}</div>
|
||||||
</td>
|
<div style="margin-top:auto;padding-top:0.35rem;display:flex;align-items:center;gap:0.4rem;flex-wrap:wrap">
|
||||||
<td><span style="font-weight:500">{entry.artistName}</span></td>
|
{#if entry.primaryType == 'Album'}
|
||||||
<td>
|
<span class="badge badge-primary badge-xs">Album</span>
|
||||||
<a href="https://musicbrainz.org/release-group/{entry.mbid}" target="_blank" rel="noopener noreferrer" class="link link-hover" style="font-weight:500">
|
{#else if entry.primaryType == 'Single'}
|
||||||
{entry.title}
|
<span class="badge badge-secondary badge-xs">Single</span>
|
||||||
</a>
|
{#else if entry.primaryType == 'EP'}
|
||||||
</td>
|
<span class="badge badge-accent badge-xs">EP</span>
|
||||||
<td>
|
{#else}
|
||||||
{#if entry.primaryType == 'Album'}
|
<span class="badge badge-ghost badge-xs">{entry.primaryType}</span>
|
||||||
<span class="badge badge-primary badge-sm">Album</span>
|
{/if}
|
||||||
{#else if entry.primaryType == 'Single'}
|
{#if entry.firstReleaseDate}
|
||||||
<span class="badge badge-secondary badge-sm">Single</span>
|
<span style="font-size:0.7rem;color:var(--bc);opacity:0.45">{entry.firstReleaseDate}</span>
|
||||||
{#else if entry.primaryType == 'EP'}
|
{/if}
|
||||||
<span class="badge badge-accent badge-sm">EP</span>
|
</div>
|
||||||
{#else}
|
</div>
|
||||||
<span class="badge badge-ghost badge-sm">{entry.primaryType}</span>
|
</a>
|
||||||
{/if}
|
{/for}
|
||||||
</td>
|
|
||||||
<td style="font-size:0.875rem;color:var(--bc);opacity:0.5">{entry.firstReleaseDate}</td>
|
|
||||||
</tr>
|
|
||||||
{/for}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
<div class="bg-base-100 shadow-xl border border-base-300 rounded-box mt-1" style="max-height:18rem;overflow-y:auto">
|
<div class="bg-base-100 shadow-xl border border-base-300 rounded-box mt-1" style="max-height:24rem;overflow-y:auto">
|
||||||
{#if artists.isEmpty()}
|
{#if artists.isEmpty()}
|
||||||
<div class="p-4 text-sm text-center" style="color:var(--bc);opacity:0.5">No artists found</div>
|
<div class="p-6 text-sm text-center" style="color:var(--bc);opacity:0.5">No artists found</div>
|
||||||
{#else}
|
{#else}
|
||||||
{#for artist in artists}
|
{#for artist in artists}
|
||||||
<div class="search-dropdown-item p-3 border-b border-base-200" style="display:flex;align-items:center;justify-content:space-between">
|
<div class="p-4 border-b border-base-200 last:border-b-0" style="display:flex;align-items:center;justify-content:space-between;transition:background 0.15s" onmouseover="this.style.background='color-mix(in srgb, var(--p) 8%, transparent)'" onmouseout="this.style.background=''">
|
||||||
<div class="flex-1 min-w-0 mr-2">
|
<div class="flex-1 min-w-0 mr-3">
|
||||||
<div style="display:flex;align-items:center;gap:0.5rem">
|
<div style="display:flex;align-items:center;gap:0.5rem;margin-bottom:0.25rem">
|
||||||
<span style="font-weight:600;font-size:0.875rem">{artist.name}</span>
|
<span style="font-weight:600;font-size:0.9rem">{artist.name}</span>
|
||||||
{#if artist.type}
|
{#if artist.type}
|
||||||
<span class="badge badge-ghost badge-xs">{artist.type}</span>
|
<span class="badge badge-ghost badge-xs">{artist.type}</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#if artist.disambiguation}
|
{#if artist.disambiguation}
|
||||||
<div style="font-size:0.75rem;color:var(--bc);opacity:0.5;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">{artist.disambiguation}</div>
|
<div style="font-size:0.8rem;color:var(--bc);opacity:0.55;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-bottom:0.15rem">{artist.disambiguation}</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if artist.area}
|
{#if artist.area}
|
||||||
<div style="font-size:0.75rem;color:var(--bc);opacity:0.4">{artist.area}</div>
|
<div style="font-size:0.75rem;color:var(--bc);opacity:0.4">{artist.area}</div>
|
||||||
@@ -20,12 +20,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div style="flex-shrink:0">
|
<div style="flex-shrink:0">
|
||||||
{#if artist.alreadyTracked}
|
{#if artist.alreadyTracked}
|
||||||
<span class="badge badge-success badge-sm gap-1">
|
<span class="badge badge-success badge-sm gap-1" style="padding:0.3rem 0.6rem">
|
||||||
<svg class="icon-xs" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><polyline points="20 6 9 17 4 12"/></svg>
|
<svg class="icon-xs" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><polyline points="20 6 9 17 4 12"/></svg>
|
||||||
Added
|
Added
|
||||||
</span>
|
</span>
|
||||||
{#else}
|
{#else}
|
||||||
<button class="btn btn-primary btn-xs"
|
<button class="btn btn-primary btn-sm"
|
||||||
|
style="min-height:0;height:2rem;padding:0 0.75rem"
|
||||||
hx-post="/api/artists/{artist.mbid}/track"
|
hx-post="/api/artists/{artist.mbid}/track"
|
||||||
hx-target="#search-results"
|
hx-target="#search-results"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
|
|||||||
@@ -7,20 +7,23 @@
|
|||||||
<link href="https://cdn.jsdelivr.net/npm/daisyui@4/dist/full.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/daisyui@4/dist/full.min.css" rel="stylesheet">
|
||||||
<script src="https://unpkg.com/htmx.org@2/dist/htmx.min.js"></script>
|
<script src="https://unpkg.com/htmx.org@2/dist/htmx.min.js"></script>
|
||||||
<style>
|
<style>
|
||||||
#search-wrapper { position: relative; width: 280px; }
|
#search-wrapper { position: relative; width: 100%; max-width: 400px; }
|
||||||
@media (min-width: 768px) { #search-wrapper { width: 320px; } }
|
|
||||||
@media (min-width: 1024px) { #search-wrapper { width: 384px; } }
|
|
||||||
#search-results {
|
#search-results {
|
||||||
position: absolute; top: 100%; left: 0; right: 0; z-index: 50;
|
position: absolute; top: 100%; left: 0; right: 0; z-index: 50;
|
||||||
}
|
}
|
||||||
main { max-width: 1024px; margin: 0 auto; padding: 1.5rem 1rem; }
|
main { max-width: 1100px; margin: 0 auto; padding: 1.5rem 1rem; }
|
||||||
@media (min-width: 640px) { main { padding: 1.5rem 1.5rem; } }
|
.brand-icon { width: 28px; height: 28px; flex-shrink: 0; }
|
||||||
.brand-icon { width: 28px; height: 28px; }
|
.icon-sm { width: 16px; height: 16px; flex-shrink: 0; }
|
||||||
.icon-sm { width: 16px; height: 16px; }
|
.icon-xs { width: 12px; height: 12px; flex-shrink: 0; }
|
||||||
.icon-xs { width: 12px; height: 12px; }
|
.icon-lg { width: 48px; height: 48px; flex-shrink: 0; }
|
||||||
.icon-lg { width: 48px; height: 48px; }
|
.brand-text {
|
||||||
.cover-img { width: 64px; height: 64px; object-fit: cover; border-radius: 8px; }
|
font-size: 1.25rem;
|
||||||
.search-dropdown-item:hover { background: color-mix(in srgb, var(--p) 10%, transparent); }
|
font-weight: 800;
|
||||||
|
background: linear-gradient(135deg, var(--p), var(--a));
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
@@ -37,27 +40,23 @@
|
|||||||
<body class="min-h-screen bg-base-200">
|
<body class="min-h-screen bg-base-200">
|
||||||
<div class="navbar bg-base-100 shadow-lg px-4">
|
<div class="navbar bg-base-100 shadow-lg px-4">
|
||||||
<div class="navbar-start">
|
<div class="navbar-start">
|
||||||
<div class="flex items-center gap-2">
|
<a href="/" class="flex items-center gap-2 no-underline">
|
||||||
<a href="/" class="flex items-center gap-2 no-underline">
|
<svg class="brand-icon text-primary" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<svg class="brand-icon text-primary" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/>
|
||||||
<circle cx="6" cy="18" r="3"/>
|
<path d="M9 18V5l12-2v13"/><path d="M9 9l12-2"/>
|
||||||
<circle cx="18" cy="16" r="3"/>
|
</svg>
|
||||||
<path d="M9 18V5l12-2v13"/>
|
<div>
|
||||||
<path d="M9 9l12-2"/>
|
<div class="brand-text">DiscDrop</div>
|
||||||
</svg>
|
<div class="text-xs leading-none" style="color:var(--bc);opacity:0.5">Release Groups Feed</div>
|
||||||
<div>
|
|
||||||
<div class="text-xl font-bold" style="background:linear-gradient(135deg,var(--p),var(--a));-webkit-background-clip:text;-webkit-text-fill-color:transparent">DiscDrop</div>
|
|
||||||
<div class="text-xs text-base-content/50 leading-none" style="display:none">Release Groups Feed</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<div class="tabs tabs-box ml-2 hidden sm:flex">
|
|
||||||
<a href="/" class="tab tab-sm {#if activeTab == 'releases'}tab-active{/if}">Releases</a>
|
|
||||||
<a href="/artists" class="tab tab-sm {#if activeTab == 'artists'}tab-active{/if}">Artists</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="navbar-center">
|
<div class="navbar-center flex-1 justify-center">
|
||||||
|
<div class="tabs tabs-box hidden sm:flex mr-4">
|
||||||
|
<a href="/" class="tab tab-sm {#if activeTab == 'releases'}tab-active{/if}">Releases</a>
|
||||||
|
<a href="/artists" class="tab tab-sm {#if activeTab == 'artists'}tab-active{/if}">Artists</a>
|
||||||
|
</div>
|
||||||
<div id="search-wrapper">
|
<div id="search-wrapper">
|
||||||
<form hx-get="/api/artists/search"
|
<form hx-get="/api/artists/search"
|
||||||
hx-target="#search-results"
|
hx-target="#search-results"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{#include layouts/base}
|
{#include layouts/base}
|
||||||
{#page-content}
|
{#page-content}
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:1.25rem">
|
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;flex-wrap:wrap;gap:0.75rem">
|
||||||
<h2 style="font-size:1.5rem;font-weight:700">📡 Releases</h2>
|
<h2 style="font-size:1.5rem;font-weight:700">📡 Releases</h2>
|
||||||
<div style="display:flex;gap:0.5rem">
|
<div style="display:flex;gap:0.5rem">
|
||||||
<a href="/feed/rss.xml" class="btn btn-primary btn-sm gap-2">
|
<a href="/feed/rss.xml" class="btn btn-primary btn-sm gap-2">
|
||||||
|
|||||||
Reference in New Issue
Block a user