feat: Enhance sidebar functionality and favorite albums feature

- Updated GitHub workflows to include additional metadata in labels for Docker images.
- Modified Dockerfile to copy README.md into the app directory for documentation purposes.
- Added favorite albums functionality in the album page, allowing users to mark albums as favorites.
- Improved AudioPlayer component to save playback position more frequently.
- Refactored sidebar component to include a favorites section and improved navigation.
- Introduced useFavoriteAlbums hook to manage favorite albums state and local storage.
- Updated settings page to allow users to toggle sidebar visibility.
This commit is contained in:
2025-07-09 21:39:16 +00:00
committed by GitHub
parent 53bbbe1801
commit 4cc59b4c1f
9 changed files with 488 additions and 240 deletions

View File

@@ -52,6 +52,7 @@ const SettingsPage = () => {
// Sidebar settings
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
const [sidebarVisible, setSidebarVisible] = useState(true);
// Initialize client-side state after hydration
useEffect(() => {
@@ -80,6 +81,13 @@ const SettingsPage = () => {
setSidebarCollapsed(savedSidebarCollapsed === 'true');
}
const savedSidebarVisible = localStorage.getItem('sidebar-visible');
if (savedSidebarVisible !== null) {
setSidebarVisible(savedSidebarVisible === 'true');
} else {
setSidebarVisible(true); // Default to visible
}
// Load Last.fm credentials
const storedCredentials = localStorage.getItem('lastfm-credentials');
if (storedCredentials) {
@@ -232,6 +240,24 @@ const SettingsPage = () => {
}
};
const handleSidebarVisibilityToggle = (visible: boolean) => {
setSidebarVisible(visible);
if (isClient) {
localStorage.setItem('sidebar-visible', visible.toString());
}
toast({
title: visible ? "Sidebar Shown" : "Sidebar Hidden",
description: visible
? "Sidebar is now visible"
: "Sidebar is now hidden",
});
// Trigger a custom event to notify the sidebar component
if (typeof window !== 'undefined') {
window.dispatchEvent(new CustomEvent('sidebar-visibility-toggle', { detail: { visible } }));
}
};
const handleLastFmAuth = () => {
if (!lastFmCredentials.apiKey) {
toast({
@@ -527,25 +553,25 @@ const SettingsPage = () => {
</CardHeader>
<CardContent className="space-y-6">
<div className="space-y-2">
<Label htmlFor="sidebar-mode">Sidebar Mode</Label>
<Label htmlFor="sidebar-visibility">Sidebar Visibility</Label>
<Select
value={sidebarCollapsed ? "collapsed" : "expanded"}
onValueChange={(value) => handleSidebarToggle(value === "collapsed")}
value={sidebarVisible ? "visible" : "hidden"}
onValueChange={(value) => handleSidebarVisibilityToggle(value === "visible")}
>
<SelectTrigger id="sidebar-mode">
<SelectTrigger id="sidebar-visibility">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="expanded">Expanded (with labels)</SelectItem>
<SelectItem value="collapsed">Collapsed (icons only)</SelectItem>
<SelectItem value="visible">Visible</SelectItem>
<SelectItem value="hidden">Hidden</SelectItem>
</SelectContent>
</Select>
</div>
<div className="text-sm text-muted-foreground space-y-2">
<p><strong>Expanded:</strong> Shows full navigation labels</p>
<p><strong>Collapsed:</strong> Shows only icons with tooltips</p>
<p className="mt-3"><strong>Note:</strong> You can also toggle the sidebar using the collapse button in the sidebar.</p>
<p><strong>Visible:</strong> Sidebar is always shown with icon navigation</p>
<p><strong>Hidden:</strong> Sidebar is completely hidden for maximum space</p>
<p className="mt-3"><strong>Note:</strong> The sidebar now shows only icons with tooltips on hover for a cleaner interface.</p>
</div>
</CardContent>
</Card>