Separate sidebar icons to new component

- Fixes react render issue
This commit is contained in:
jeffvli 2023-10-17 05:46:42 -07:00
parent 3675146f1f
commit cbeb4ab7d8
3 changed files with 109 additions and 173 deletions

View file

@ -1,42 +1,16 @@
import { Group, UnstyledButton } from '@mantine/core'; import { Group, UnstyledButton } from '@mantine/core';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { IconType } from 'react-icons'; import { RiArrowLeftSLine, RiArrowRightSLine, RiMenuFill } from 'react-icons/ri';
import { import { NavLink, useNavigate } from 'react-router-dom';
RiUserVoiceLine,
RiMenuFill,
RiFolder3Line,
RiPlayListLine,
RiAlbumLine,
RiHome6Line,
RiMusic2Line,
RiHome6Fill,
RiAlbumFill,
RiMusic2Fill,
RiUserVoiceFill,
RiFlag2Fill,
RiFolder3Fill,
RiPlayListFill,
RiSearchLine,
RiSearchFill,
RiPlayFill,
RiPlayLine,
RiSettings2Fill,
RiSettings2Line,
RiFlag2Line,
RiArrowLeftSLine,
RiArrowRightSLine,
} from 'react-icons/ri';
import { generatePath, NavLink, useNavigate } from 'react-router-dom';
import styled from 'styled-components'; import styled from 'styled-components';
import { LibraryItem } from '/@/renderer/api/types';
import { DropdownMenu, ScrollArea } from '/@/renderer/components'; import { DropdownMenu, ScrollArea } from '/@/renderer/components';
import { CollapsedSidebarButton } from '/@/renderer/features/sidebar/components/collapsed-sidebar-button';
import { CollapsedSidebarItem } from '/@/renderer/features/sidebar/components/collapsed-sidebar-item'; import { CollapsedSidebarItem } from '/@/renderer/features/sidebar/components/collapsed-sidebar-item';
import { SidebarIcon } from '/@/renderer/features/sidebar/components/sidebar-icon';
import { AppMenu } from '/@/renderer/features/titlebar/components/app-menu'; import { AppMenu } from '/@/renderer/features/titlebar/components/app-menu';
import { AppRoute } from '/@/renderer/router/routes';
import { SidebarItemType, useGeneralSettings, useWindowSettings } from '/@/renderer/store'; import { SidebarItemType, useGeneralSettings, useWindowSettings } from '/@/renderer/store';
import { Platform } from '/@/renderer/types'; import { Platform } from '/@/renderer/types';
import { CollapsedSidebarButton } from '/@/renderer/features/sidebar/components/collapsed-sidebar-button';
const SidebarContainer = styled(motion.div)<{ $windowBarStyle: Platform }>` const SidebarContainer = styled(motion.div)<{ $windowBarStyle: Platform }>`
display: flex; display: flex;
@ -49,65 +23,18 @@ const SidebarContainer = styled(motion.div)<{ $windowBarStyle: Platform }>`
user-select: none; user-select: none;
`; `;
const sidebarItemMap = {
[AppRoute.HOME]: {
activeIcon: RiHome6Fill,
icon: RiHome6Line,
},
[AppRoute.LIBRARY_ALBUMS]: {
activeIcon: RiAlbumFill,
icon: RiAlbumLine,
},
[AppRoute.LIBRARY_ALBUM_ARTISTS]: {
activeIcon: RiUserVoiceFill,
icon: RiUserVoiceLine,
},
[AppRoute.PLAYLISTS]: {
activeIcon: RiPlayListFill,
icon: RiPlayListLine,
},
[AppRoute.LIBRARY_SONGS]: {
activeIcon: RiMusic2Fill,
icon: RiMusic2Line,
},
[AppRoute.LIBRARY_FOLDERS]: {
activeIcon: RiFolder3Fill,
icon: RiFolder3Line,
},
[AppRoute.LIBRARY_GENRES]: {
activeIcon: RiFlag2Fill,
icon: RiFlag2Line,
},
[generatePath(AppRoute.SEARCH, { itemType: LibraryItem.SONG })]: {
activeIcon: RiSearchFill,
icon: RiSearchLine,
},
[AppRoute.SETTINGS]: {
activeIcon: RiSettings2Fill,
icon: RiSettings2Line,
},
[AppRoute.NOW_PLAYING]: {
activeIcon: RiPlayFill,
icon: RiPlayLine,
},
};
export const CollapsedSidebar = () => { export const CollapsedSidebar = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const { windowBarStyle } = useWindowSettings(); const { windowBarStyle } = useWindowSettings();
const { sidebarItems, sidebarCollapsedNavigation } = useGeneralSettings(); const { sidebarItems, sidebarCollapsedNavigation } = useGeneralSettings();
const sidebarItemsWithRoute: (SidebarItemType & { const sidebarItemsWithRoute: SidebarItemType[] = useMemo(() => {
activeIcon: IconType;
icon: IconType;
})[] = useMemo(() => {
if (!sidebarItems) return []; if (!sidebarItems) return [];
const items = sidebarItems const items = sidebarItems
.filter((item) => !item.disabled) .filter((item) => !item.disabled)
.map((item) => ({ .map((item) => ({
...item, ...item,
...sidebarItemMap[item.route as keyof typeof sidebarItemMap],
})); }));
return items; return items;
@ -157,9 +84,20 @@ export const CollapsedSidebar = () => {
{sidebarItemsWithRoute.map((item) => ( {sidebarItemsWithRoute.map((item) => (
<CollapsedSidebarItem <CollapsedSidebarItem
key={item.id} key={item.id}
activeIcon={<item.activeIcon size="25" />} activeIcon={
<SidebarIcon
active
route={item.route}
size="25"
/>
}
component={NavLink} component={NavLink}
icon={<item.icon size="25" />} icon={
<SidebarIcon
route={item.route}
size="25"
/>
}
label={item.label} label={item.label}
route={item.route} route={item.route}
to={item.route} to={item.route}

View file

@ -0,0 +1,68 @@
import {
RiAlbumFill,
RiAlbumLine,
RiFlag2Fill,
RiFlag2Line,
RiFolder3Fill,
RiFolder3Line,
RiHome6Fill,
RiHome6Line,
RiMusic2Fill,
RiMusic2Line,
RiPlayFill,
RiPlayLine,
RiPlayListFill,
RiPlayListLine,
RiSearchFill,
RiSearchLine,
RiSettings2Fill,
RiSettings2Line,
RiUserVoiceFill,
RiUserVoiceLine,
} from 'react-icons/ri';
import { AppRoute } from '/@/renderer/router/routes';
import { generatePath } from 'react-router';
import { LibraryItem } from '/@/renderer/api/types';
interface SidebarIconProps {
active?: boolean;
route: string;
size?: string;
}
export const SidebarIcon = ({ active, route, size }: SidebarIconProps) => {
switch (route) {
case AppRoute.HOME:
if (active) return <RiHome6Fill size={size} />;
return <RiHome6Line size={size} />;
case AppRoute.LIBRARY_ALBUMS:
if (active) return <RiAlbumFill size={size} />;
return <RiAlbumLine size={size} />;
case AppRoute.LIBRARY_ARTISTS:
if (active) return <RiUserVoiceFill size={size} />;
return <RiUserVoiceLine size={size} />;
case AppRoute.PLAYLISTS:
if (active) return <RiPlayListFill size={size} />;
return <RiPlayListLine size={size} />;
case AppRoute.LIBRARY_SONGS:
if (active) return <RiMusic2Fill size={size} />;
return <RiMusic2Line size={size} />;
case AppRoute.LIBRARY_FOLDERS:
if (active) return <RiFolder3Fill size={size} />;
return <RiFolder3Line size={size} />;
case AppRoute.LIBRARY_GENRES:
if (active) return <RiFlag2Fill size={size} />;
return <RiFlag2Line size={size} />;
case generatePath(AppRoute.SEARCH, { itemType: LibraryItem.SONG }):
if (active) return <RiSearchFill size={size} />;
return <RiSearchLine size={size} />;
case AppRoute.SETTINGS:
if (active) return <RiSettings2Fill size={size} />;
return <RiSettings2Line size={size} />;
case AppRoute.NOW_PLAYING:
if (active) return <RiPlayFill size={size} />;
return <RiPlayLine size={size} />;
default:
return <RiHome6Line size={size} />;
}
};

View file

@ -1,45 +1,20 @@
import { MouseEvent, useMemo } from 'react';
import { Box, Center, Divider, Group, Stack } from '@mantine/core'; import { Box, Center, Divider, Group, Stack } from '@mantine/core';
import { closeAllModals, openModal } from '@mantine/modals'; import { closeAllModals, openModal } from '@mantine/modals';
import { AnimatePresence, motion } from 'framer-motion'; import { AnimatePresence, motion } from 'framer-motion';
import { IconType } from 'react-icons'; import { MouseEvent, useMemo } from 'react';
import { import { RiAddFill, RiArrowDownSLine, RiDiscLine, RiListUnordered } from 'react-icons/ri';
RiAddFill, import { Link, useLocation } from 'react-router-dom';
RiAlbumFill,
RiAlbumLine,
RiArrowDownSLine,
RiDiscLine,
RiFlag2Fill,
RiFlagLine,
RiFolder3Fill,
RiFolder3Line,
RiHome6Fill,
RiHome6Line,
RiListUnordered,
RiMusic2Fill,
RiMusic2Line,
RiPlayLine,
RiSearchFill,
RiUserVoiceFill,
RiUserVoiceLine,
RiSearchLine,
RiPlayFill,
RiSettings2Line,
RiSettings2Fill,
RiPlayListLine,
RiPlayListFill,
} from 'react-icons/ri';
import { generatePath, Link, useLocation } from 'react-router-dom';
import styled from 'styled-components'; import styled from 'styled-components';
import { import {
SidebarItemType, SidebarItemType,
useGeneralSettings, useGeneralSettings,
useWindowSettings, useWindowSettings,
} from '../../../store/settings.store'; } from '../../../store/settings.store';
import { LibraryItem, PlaylistListSort, ServerType, SortOrder } from '/@/renderer/api/types'; import { PlaylistListSort, ServerType, SortOrder } from '/@/renderer/api/types';
import { Button, MotionStack, Spinner, Tooltip } from '/@/renderer/components'; import { Button, MotionStack, Spinner, Tooltip } from '/@/renderer/components';
import { CreatePlaylistForm, usePlaylistList } from '/@/renderer/features/playlists'; import { CreatePlaylistForm, usePlaylistList } from '/@/renderer/features/playlists';
import { ActionBar } from '/@/renderer/features/sidebar/components/action-bar'; import { ActionBar } from '/@/renderer/features/sidebar/components/action-bar';
import { SidebarIcon } from '/@/renderer/features/sidebar/components/sidebar-icon';
import { SidebarItem } from '/@/renderer/features/sidebar/components/sidebar-item'; import { SidebarItem } from '/@/renderer/features/sidebar/components/sidebar-item';
import { SidebarPlaylistList } from '/@/renderer/features/sidebar/components/sidebar-playlist-list'; import { SidebarPlaylistList } from '/@/renderer/features/sidebar/components/sidebar-playlist-list';
import { useContainerQuery } from '/@/renderer/hooks'; import { useContainerQuery } from '/@/renderer/hooks';
@ -92,49 +67,6 @@ const SidebarImage = styled.img`
background: var(--placeholder-bg); background: var(--placeholder-bg);
`; `;
const sidebarItemMap = {
[AppRoute.HOME]: {
activeIcon: RiHome6Fill,
icon: RiHome6Line,
},
[AppRoute.LIBRARY_ALBUMS]: {
activeIcon: RiAlbumFill,
icon: RiAlbumLine,
},
[AppRoute.LIBRARY_ALBUM_ARTISTS]: {
activeIcon: RiUserVoiceFill,
icon: RiUserVoiceLine,
},
[AppRoute.PLAYLISTS]: {
activeIcon: RiPlayListFill,
icon: RiPlayListLine,
},
[AppRoute.LIBRARY_SONGS]: {
activeIcon: RiMusic2Fill,
icon: RiMusic2Line,
},
[AppRoute.LIBRARY_FOLDERS]: {
activeIcon: RiFolder3Fill,
icon: RiFolder3Line,
},
[AppRoute.LIBRARY_GENRES]: {
activeIcon: RiFlag2Fill,
icon: RiFlagLine,
},
[generatePath(AppRoute.SEARCH, { itemType: LibraryItem.SONG })]: {
activeIcon: RiSearchFill,
icon: RiSearchLine,
},
[AppRoute.SETTINGS]: {
activeIcon: RiSettings2Fill,
icon: RiSettings2Line,
},
[AppRoute.NOW_PLAYING]: {
activeIcon: RiPlayFill,
icon: RiPlayLine,
},
};
export const Sidebar = () => { export const Sidebar = () => {
const location = useLocation(); const location = useLocation();
const sidebar = useSidebarStore(); const sidebar = useSidebarStore();
@ -180,17 +112,13 @@ export const Sidebar = () => {
const { sidebarItems } = useGeneralSettings(); const { sidebarItems } = useGeneralSettings();
const sidebarItemsWithRoute: (SidebarItemType & { const sidebarItemsWithRoute: SidebarItemType[] = useMemo(() => {
activeIcon: IconType;
icon: IconType;
})[] = useMemo(() => {
if (!sidebarItems) return []; if (!sidebarItems) return [];
const items = sidebarItems const items = sidebarItems
.filter((item) => !item.disabled) .filter((item) => !item.disabled)
.map((item) => ({ .map((item) => ({
...item, ...item,
...sidebarItemMap[item.route as keyof typeof sidebarItemMap],
})); }));
return items; return items;
@ -214,21 +142,23 @@ export const Sidebar = () => {
sx={{ maxHeight: showImage ? `calc(100% - ${sidebar.leftWidth})` : '100%' }} sx={{ maxHeight: showImage ? `calc(100% - ${sidebar.leftWidth})` : '100%' }}
> >
<Stack spacing={0}> <Stack spacing={0}>
{sidebarItemsWithRoute.map((item) => ( {sidebarItemsWithRoute.map((item) => {
return (
<SidebarItem <SidebarItem
key={`sidebar-${item.route}`} key={`sidebar-${item.route}`}
to={item.route} to={item.route}
> >
<Group spacing="sm"> <Group spacing="sm">
{location.pathname === item.route ? ( <SidebarIcon
<item.activeIcon size="1.1em" /> active={location.pathname === item.route}
) : ( route={item.route}
<item.icon size="1.1em" /> size="1.1em"
)} />
{item.label} {item.label}
</Group> </Group>
</SidebarItem> </SidebarItem>
))} );
})}
</Stack> </Stack>
<Divider <Divider
mx="1rem" mx="1rem"