feat: queue improvements, system browser links (v1.4.5)

- Queue: year added to now-playing meta, cover enlarged to 90px + top-aligned, default width 340px
- Artist pages: Last.fm/Wikipedia open in system browser with button label feedback
- README: AUR badge + install section, Nord theme mention, in-app browser bullet removed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Psychotoxical
2026-03-17 21:19:07 +01:00
parent d4e44199e9
commit 18199a1f8a
14 changed files with 51 additions and 32 deletions
+1 -1
View File
@@ -73,7 +73,7 @@ function AppShell() {
const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(() => {
return localStorage.getItem('psysonic_sidebar_collapsed') === 'true';
});
const [queueWidth, setQueueWidth] = useState(300);
const [queueWidth, setQueueWidth] = useState(340);
const [isDraggingQueue, setIsDraggingQueue] = useState(false);
useEffect(() => {
+3 -1
View File
@@ -316,7 +316,9 @@ export default function QueuePanel() {
style={{ cursor: currentTrack.albumId ? 'pointer' : 'default' }}
onClick={() => currentTrack.albumId && navigate(`/album/${currentTrack.albumId}`)}
>{currentTrack.album}</div>
{currentTrack.year && (
<div className="queue-current-sub">{currentTrack.year}</div>
)}
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: '6px' }}>
<div className="queue-current-tech">
{currentTrack.bitRate && currentTrack.suffix ? (
+2
View File
@@ -120,6 +120,7 @@ const enTranslation = {
favorite: 'Favorite',
albumCount_one: '{{count}} Album',
albumCount_other: '{{count}} Albums',
openedInBrowser: 'Opened in browser',
},
favorites: {
title: 'Favorites',
@@ -539,6 +540,7 @@ const deTranslation = {
favorite: 'Als Favorit',
albumCount_one: '{{count}} Album',
albumCount_other: '{{count}} Alben',
openedInBrowser: 'Im Browser geöffnet',
},
favorites: {
title: 'Favoriten',
+11 -15
View File
@@ -1,10 +1,10 @@
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { getArtist, getArtistInfo, getTopSongs, getSimilarSongs2, SubsonicArtist, SubsonicAlbum, SubsonicSong, SubsonicArtistInfo, buildCoverArtUrl, coverArtCacheKey, star, unstar } from '../api/subsonic';
import AlbumCard from '../components/AlbumCard';
import CachedImage from '../components/CachedImage';
import { ArrowLeft, Users, ExternalLink, Star, Play, Shuffle, Radio } from 'lucide-react';
import { WebviewWindow } from '@tauri-apps/api/webviewWindow';
import { open } from '@tauri-apps/plugin-shell';
import { usePlayerStore } from '../store/playerStore';
import { useTranslation } from 'react-i18next';
@@ -50,6 +50,7 @@ export default function ArtistDetail() {
const [loading, setLoading] = useState(true);
const [radioLoading, setRadioLoading] = useState(false);
const [isStarred, setIsStarred] = useState(false);
const [openedLink, setOpenedLink] = useState<string | null>(null);
const playTrack = usePlayerStore(state => state.playTrack);
const enqueue = usePlayerStore(state => state.enqueue);
@@ -77,15 +78,10 @@ export default function ArtistDetail() {
});
}, [id]);
const openLink = (url: string, title: string) => {
const label = `browser_${Date.now()}`;
new WebviewWindow(label, {
url,
title,
width: 1100,
height: 780,
center: true,
});
const openLink = (url: string, key: string) => {
open(url);
setOpenedLink(key);
setTimeout(() => setOpenedLink(null), 2500);
};
const toggleStar = async () => {
@@ -192,14 +188,14 @@ export default function ArtistDetail() {
{(info?.lastFmUrl || artist.name) && (
<div className="artist-detail-links">
{info?.lastFmUrl && (
<button className="artist-ext-link" onClick={() => openLink(info.lastFmUrl!, `${artist.name} — Last.fm`)}>
<button className="artist-ext-link" onClick={() => openLink(info.lastFmUrl!, 'lastfm')}>
<LastfmIcon size={14} />
Last.fm
{openedLink === 'lastfm' ? t('artistDetail.openedInBrowser') : 'Last.fm'}
</button>
)}
<button className="artist-ext-link" onClick={() => openLink(wikiUrl, `${artist.name} — Wikipedia`)}>
<button className="artist-ext-link" onClick={() => openLink(wikiUrl, 'wiki')}>
<ExternalLink size={14} />
Wikipedia
{openedLink === 'wiki' ? t('artistDetail.openedInBrowser') : 'Wikipedia'}
</button>
</div>
)}
+3 -3
View File
@@ -478,15 +478,15 @@
padding: var(--space-3) var(--space-4);
display: flex;
flex-direction: row;
align-items: center;
align-items: flex-start;
gap: var(--space-3);
flex-shrink: 0;
border-bottom: 1px solid var(--border-subtle);
}
.queue-current-cover {
width: 72px;
height: 72px;
width: 90px;
height: 90px;
flex-shrink: 0;
border-radius: var(--radius-md);
overflow: hidden;