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

53
src/components/scrollingmenu/ScrollingMenu.tsx

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