fix: use consistent icons in search results (#451)

replaced text characters (♪, ◉, ◫, #) with actual SVG icons
matching those used elsewhere in the app:
- track: music note icon (same as player placeholder)
- artist: person icon (same as TrackItem/TrackInfo)
- album: record icon (same as TrackItem/TrackInfo)
- tag: label icon (same as tag detail page)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>

authored by zzstoatzz.io Claude and committed by GitHub 325c739a c5d4e46a

Changed files
+41 -16
frontend
src
lib
components
+41 -16
frontend/src/lib/components/SearchModal.svelte
··· 56 56 } 57 57 } 58 58 59 - function getResultIcon(type: SearchResult['type']): string { 60 - switch (type) { 61 - case 'track': 62 - return '♪'; 63 - case 'artist': 64 - return '◉'; 65 - case 'album': 66 - return '◫'; 67 - case 'tag': 68 - return '#'; 69 - } 70 - } 71 - 72 59 function getResultImage(result: SearchResult): string | null { 73 60 switch (result.type) { 74 61 case 'track': ··· 178 165 loading="lazy" 179 166 onerror={(e) => ((e.currentTarget as HTMLImageElement).style.display = 'none')} 180 167 /> 181 - <span class="result-icon-fallback">{getResultIcon(result.type)}</span> 182 - {:else} 183 - {getResultIcon(result.type)} 168 + <!-- fallback icon shown if image fails to load --> 169 + <span class="result-icon-fallback"> 170 + {#if result.type === 'track'} 171 + <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"> 172 + <path d="M9 18V5l12-2v13"></path> 173 + <circle cx="6" cy="18" r="3"></circle> 174 + <circle cx="18" cy="16" r="3"></circle> 175 + </svg> 176 + {:else if result.type === 'artist'} 177 + <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"> 178 + <circle cx="8" cy="5" r="3" fill="none" /> 179 + <path d="M3 14c0-2.5 2-4.5 5-4.5s5 2 5 4.5" stroke-linecap="round" /> 180 + </svg> 181 + {:else if result.type === 'album'} 182 + <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"> 183 + <rect x="2" y="2" width="12" height="12" fill="none" /> 184 + <circle cx="8" cy="8" r="2.5" fill="currentColor" stroke="none" /> 185 + </svg> 186 + {/if} 187 + </span> 188 + {:else if result.type === 'track'} 189 + <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"> 190 + <path d="M9 18V5l12-2v13"></path> 191 + <circle cx="6" cy="18" r="3"></circle> 192 + <circle cx="18" cy="16" r="3"></circle> 193 + </svg> 194 + {:else if result.type === 'artist'} 195 + <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"> 196 + <circle cx="8" cy="5" r="3" fill="none" /> 197 + <path d="M3 14c0-2.5 2-4.5 5-4.5s5 2 5 4.5" stroke-linecap="round" /> 198 + </svg> 199 + {:else if result.type === 'album'} 200 + <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"> 201 + <rect x="2" y="2" width="12" height="12" fill="none" /> 202 + <circle cx="8" cy="8" r="2.5" fill="currentColor" stroke="none" /> 203 + </svg> 204 + {:else if result.type === 'tag'} 205 + <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 206 + <path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"></path> 207 + <line x1="7" y1="7" x2="7.01" y2="7"></line> 208 + </svg> 184 209 {/if} 185 210 </span> 186 211 <div class="result-content">