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:
@@ -5,7 +5,8 @@ import { Menu } from "@/app/components/menu";
|
||||
import { Sidebar } from "@/app/components/sidebar";
|
||||
import { useNavidrome } from "@/app/components/NavidromeContext";
|
||||
import { AudioPlayer } from "./AudioPlayer";
|
||||
import { Toaster } from "@/components/ui/toaster"
|
||||
import { Toaster } from "@/components/ui/toaster";
|
||||
import { useFavoriteAlbums } from "@/hooks/use-favorite-albums";
|
||||
|
||||
interface IhateserversideProps {
|
||||
children: React.ReactNode;
|
||||
@@ -18,12 +19,15 @@ const Ihateserverside: React.FC<IhateserversideProps> = ({ children }) => {
|
||||
const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false);
|
||||
const [isClient, setIsClient] = useState(false);
|
||||
const { playlists } = useNavidrome();
|
||||
const { favoriteAlbums, removeFavoriteAlbum } = useFavoriteAlbums();
|
||||
|
||||
// Handle client-side hydration
|
||||
useEffect(() => {
|
||||
setIsClient(true);
|
||||
const savedCollapsed = localStorage.getItem('sidebar-collapsed') === 'true';
|
||||
const savedVisible = localStorage.getItem('sidebar-visible') !== 'false'; // Default to true
|
||||
setIsSidebarCollapsed(savedCollapsed);
|
||||
setIsSidebarVisible(savedVisible);
|
||||
}, []);
|
||||
|
||||
const toggleSidebarCollapse = () => {
|
||||
@@ -34,6 +38,14 @@ const Ihateserverside: React.FC<IhateserversideProps> = ({ children }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const toggleSidebarVisibility = () => {
|
||||
const newVisible = !isSidebarVisible;
|
||||
setIsSidebarVisible(newVisible);
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.setItem('sidebar-visible', newVisible.toString());
|
||||
}
|
||||
};
|
||||
|
||||
const handleTransitionEnd = () => {
|
||||
if (!isSidebarVisible) {
|
||||
setIsSidebarHidden(true); // This will fully hide the sidebar after transition
|
||||
@@ -53,7 +65,7 @@ const Ihateserverside: React.FC<IhateserversideProps> = ({ children }) => {
|
||||
}}
|
||||
>
|
||||
<Menu
|
||||
toggleSidebar={() => setIsSidebarVisible(!isSidebarVisible)}
|
||||
toggleSidebar={toggleSidebarVisibility}
|
||||
isSidebarVisible={isSidebarVisible}
|
||||
toggleStatusBar={() => setIsStatusBarVisible(!isStatusBarVisible)}
|
||||
isStatusBarVisible={isStatusBarVisible}
|
||||
@@ -62,15 +74,19 @@ const Ihateserverside: React.FC<IhateserversideProps> = ({ children }) => {
|
||||
|
||||
{/* Main Content Area */}
|
||||
<div className="flex-1 flex overflow-hidden w-full">
|
||||
<div className="w-64 shrink-0 border-r transition-all duration-200">
|
||||
<Sidebar
|
||||
playlists={playlists}
|
||||
className="h-full overflow-y-auto"
|
||||
collapsed={false}
|
||||
onToggle={toggleSidebarCollapse}
|
||||
onTransitionEnd={handleTransitionEnd}
|
||||
/>
|
||||
</div>
|
||||
{isSidebarVisible && (
|
||||
<div className="w-16 shrink-0 border-r transition-all duration-200">
|
||||
<Sidebar
|
||||
playlists={playlists}
|
||||
className="h-full overflow-y-auto"
|
||||
collapsed={true}
|
||||
visible={isSidebarVisible}
|
||||
favoriteAlbums={favoriteAlbums}
|
||||
onToggle={toggleSidebarCollapse}
|
||||
onTransitionEnd={handleTransitionEnd}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex-1 overflow-y-auto min-w-0">
|
||||
<div>{children}</div>
|
||||
</div>
|
||||
@@ -93,7 +109,7 @@ const Ihateserverside: React.FC<IhateserversideProps> = ({ children }) => {
|
||||
}}
|
||||
>
|
||||
<Menu
|
||||
toggleSidebar={() => setIsSidebarVisible(!isSidebarVisible)}
|
||||
toggleSidebar={toggleSidebarVisibility}
|
||||
isSidebarVisible={isSidebarVisible}
|
||||
toggleStatusBar={() => setIsStatusBarVisible(!isStatusBarVisible)}
|
||||
isStatusBarVisible={isStatusBarVisible}
|
||||
@@ -101,22 +117,25 @@ const Ihateserverside: React.FC<IhateserversideProps> = ({ children }) => {
|
||||
</div>
|
||||
|
||||
{/* Main Content Area */}
|
||||
<div className="flex-1 flex overflow-hidden w-full">
|
||||
{isSidebarVisible && (
|
||||
<div className={`${isSidebarCollapsed ? 'w-16' : 'w-64'} shrink-0 border-r transition-all duration-200`}>
|
||||
<Sidebar
|
||||
playlists={playlists}
|
||||
className="h-full overflow-y-auto"
|
||||
collapsed={isSidebarCollapsed}
|
||||
onToggle={toggleSidebarCollapse}
|
||||
onTransitionEnd={handleTransitionEnd}
|
||||
/>
|
||||
<div className="flex-1 flex overflow-hidden w-full">
|
||||
{isSidebarVisible && (
|
||||
<div className="w-16 shrink-0 border-r transition-all duration-200">
|
||||
<Sidebar
|
||||
playlists={playlists}
|
||||
className="h-full overflow-y-auto"
|
||||
collapsed={true}
|
||||
visible={isSidebarVisible}
|
||||
favoriteAlbums={favoriteAlbums}
|
||||
onToggle={toggleSidebarCollapse}
|
||||
onTransitionEnd={handleTransitionEnd}
|
||||
onRemoveFavoriteAlbum={removeFavoriteAlbum}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex-1 overflow-y-auto min-w-0">
|
||||
<div>{children}</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex-1 overflow-y-auto min-w-0">
|
||||
<div>{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Floating Audio Player */}
|
||||
{isStatusBarVisible && (
|
||||
|
||||
Reference in New Issue
Block a user