Browse Source

Improve ScrollingMenu component

- Add prop to remove scrollbar
- Add custom scroll function
master
jeffvli 3 years ago
committed by Jeff
parent
commit
c5caa18aeb
  1. 4
      src/components/dashboard/Dashboard.tsx
  2. 53
      src/components/scrollingmenu/ScrollingMenu.tsx
  3. 44
      src/shared/utils.ts

4
src/components/dashboard/Dashboard.tsx

@ -169,6 +169,7 @@ const Dashboard = () => {
{newestAlbums && recentAlbums && randomAlbums && ( {newestAlbums && recentAlbums && randomAlbums && (
<> <>
<ScrollingMenu <ScrollingMenu
noScrollbar
title="Recently Played" title="Recently Played"
data={recentAlbums} data={recentAlbums}
cardTitle={{ cardTitle={{
@ -193,6 +194,7 @@ const Dashboard = () => {
/> />
<ScrollingMenu <ScrollingMenu
noScrollbar
title="Recently Added" title="Recently Added"
data={newestAlbums} data={newestAlbums}
cardTitle={{ cardTitle={{
@ -217,6 +219,7 @@ const Dashboard = () => {
/> />
<ScrollingMenu <ScrollingMenu
noScrollbar
title="Random" title="Random"
data={randomAlbums} data={randomAlbums}
cardTitle={{ cardTitle={{
@ -241,6 +244,7 @@ const Dashboard = () => {
/> />
<ScrollingMenu <ScrollingMenu
noScrollbar
title="Most Played" title="Most Played"
data={frequentAlbums} data={frequentAlbums}
cardTitle={{ cardTitle={{

53
src/components/scrollingmenu/ScrollingMenu.tsx

@ -3,19 +3,17 @@ import settings from 'electron-settings';
import styled from 'styled-components'; import styled from 'styled-components';
import { ButtonGroup, ButtonToolbar, FlexboxGrid, Icon } from 'rsuite'; import { ButtonGroup, ButtonToolbar, FlexboxGrid, Icon } from 'rsuite';
import Card from '../card/Card'; import Card from '../card/Card';
import { SectionTitleWrapper, SectionTitle, StyledIconButton } from '../shared/styled'; import { SectionTitleWrapper, SectionTitle, StyledButton } from '../shared/styled';
import { useAppSelector } from '../../redux/hooks'; import { useAppSelector } from '../../redux/hooks';
import { smoothScroll } from '../../shared/utils';
const ScrollMenuContainer = styled.div` const ScrollMenuContainer = styled.div<{ $noScrollbar?: boolean }>`
margin-bottom: 25px;
overflow-x: auto; overflow-x: auto;
white-space: nowrap; white-space: nowrap;
::-webkit-scrollbar { ::-webkit-scrollbar {
height: 10px; height: ${(props) => (props.$noScrollbar ? '0px' : '10px')};
} }
scroll-behavior: smooth;
`; `;
const ScrollingMenu = ({ const ScrollingMenu = ({
@ -26,6 +24,7 @@ const ScrollingMenu = ({
onClickTitle, onClickTitle,
type, type,
handleFavorite, handleFavorite,
noScrollbar,
}: any) => { }: any) => {
const cacheImages = Boolean(settings.getSync('cacheImages')); const cacheImages = Boolean(settings.getSync('cacheImages'));
const misc = useAppSelector((state) => state.misc); const misc = useAppSelector((state) => state.misc);
@ -35,7 +34,7 @@ const ScrollingMenu = ({
return ( return (
<> <>
<SectionTitleWrapper> <SectionTitleWrapper>
<FlexboxGrid justify="space-between"> <FlexboxGrid justify="space-between" style={{ alignItems: 'flex-end' }}>
<FlexboxGrid.Item> <FlexboxGrid.Item>
<SectionTitle <SectionTitle
tabIndex={0} tabIndex={0}
@ -53,22 +52,36 @@ const ScrollingMenu = ({
{data.length > 0 && ( {data.length > 0 && (
<ButtonToolbar> <ButtonToolbar>
<ButtonGroup> <ButtonGroup>
<StyledIconButton <StyledButton
size="sm"
appearance="subtle" appearance="subtle"
icon={<Icon icon="arrow-left" />}
onClick={() => { onClick={() => {
scrollContainerRef.current.scrollLeft -= smoothScroll(
config.lookAndFeel.gridView.cardSize * 5; 400,
scrollContainerRef.current,
scrollContainerRef.current.scrollLeft -
config.lookAndFeel.gridView.cardSize * 5,
'scrollLeft'
);
}} }}
/> >
<StyledIconButton <Icon icon="arrow-left" />
</StyledButton>
<StyledButton
size="sm"
appearance="subtle" appearance="subtle"
icon={<Icon icon="arrow-right" />}
onClick={() => { onClick={() => {
scrollContainerRef.current.scrollLeft += smoothScroll(
config.lookAndFeel.gridView.cardSize * 5; 400,
scrollContainerRef.current,
scrollContainerRef.current.scrollLeft +
config.lookAndFeel.gridView.cardSize * 5,
'scrollLeft'
);
}} }}
/> >
<Icon icon="arrow-right" />
</StyledButton>
</ButtonGroup> </ButtonGroup>
</ButtonToolbar> </ButtonToolbar>
)} )}
@ -76,14 +89,16 @@ const ScrollingMenu = ({
</FlexboxGrid> </FlexboxGrid>
</SectionTitleWrapper> </SectionTitleWrapper>
<ScrollMenuContainer ref={scrollContainerRef}> <ScrollMenuContainer ref={scrollContainerRef} $noScrollbar={noScrollbar}>
{data.map((item: any) => ( {data.map((item: any) => (
<span key={item.id} style={{ display: 'inline-block' }}> <span key={item.id} style={{ display: 'inline-block' }}>
<Card <Card
itemId={item.id} itemId={item.id}
title={item[cardTitle.property] || item.title} title={item[cardTitle.property] || item.title}
subtitle={ subtitle={
cardSubtitle.unit typeof cardSubtitle === 'string'
? cardSubtitle
: cardSubtitle.unit
? `${item[cardSubtitle.property]}${cardSubtitle.unit}` ? `${item[cardSubtitle.property]}${cardSubtitle.unit}`
: item[cardSubtitle.property] : item[cardSubtitle.property]
} }

44
src/shared/utils.ts

@ -567,3 +567,47 @@ export const writeOBSFiles = (filePath: string, data: any) => {
}); });
} }
}; };
// From https://gist.github.com/andjosh/6764939#gistcomment-3564498
const easeInOutQuad = (
currentTime: number,
start: number,
change: number,
duration: number
): number => {
let newCurrentTime = currentTime;
newCurrentTime /= duration / 2;
if (newCurrentTime < 1) {
return (change / 2) * newCurrentTime * newCurrentTime + start;
}
newCurrentTime -= 1;
return (-change / 2) * (newCurrentTime * (newCurrentTime - 2) - 1) + start;
};
// From https://gist.github.com/andjosh/6764939#gistcomment-3564498
export const smoothScroll = (
duration: number,
element: HTMLElement,
to: number,
property: 'scrollTop' | 'scrollLeft'
): void => {
const start = element[property];
const change = to - start;
const startDate = new Date().getTime();
const animateScroll = () => {
const currentDate = new Date().getTime();
const currentTime = currentDate - startDate;
element[property] = easeInOutQuad(currentTime, start, change, duration);
if (currentTime < duration) {
requestAnimationFrame(animateScroll);
} else {
element[property] = to;
}
};
animateScroll();
};

Loading…
Cancel
Save