Skip to content

Commit

Permalink
feat(home): add lazy rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
royschut committed May 6, 2021
1 parent b54753f commit 3d1c954
Show file tree
Hide file tree
Showing 21 changed files with 487 additions and 315 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@
"pre-commit": "lint-staged && TZ=UTC yarn test --coverage --watchAll=false --ci --bail=1"
},
"dependencies": {
"@types/react-virtualized": "^9.21.11",
"classnames": "^2.3.1",
"memoize-one": "^5.2.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-query": "^3.13.10",
"react-router-dom": "^5.2.0",
"react-virtualized": "^9.22.3",
"tile-dock": "https://github.com/RCVZ/tile-dock-temp",
"yup": "^0.32.9"
},
Expand Down
2 changes: 1 addition & 1 deletion public/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"headerBackground": "#00DD00",
"enableCasting": true,
"enableSharing": true,
"dynamicBlur": false,
"dynamicBlur": true,
"posterFading": true
}
}
19 changes: 16 additions & 3 deletions src/components/Card/Card.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@

.card {
cursor: pointer;
transition: transform .2s ease-out,-webkit-transform .2s ease-out;
transition: transform 0.2s ease-out, -webkit-transform 0.2s ease-out;

&:hover {
transform: scale(1.05);
z-index: 10;
& .poster {
box-shadow: 0 0 0 3px var(--card-border-hover-color), 0 8px 10px rgb(0 0 0 / 14%), 0 3px 14px rgb(0 0 0 / 12%), 0 4px 5px rgb(0 0 0 / 20%);
box-shadow: 0 0 0 3px var(--card-border-hover-color), 0 8px 10px rgb(0 0 0 / 14%), 0 3px 14px rgb(0 0 0 / 12%),
0 4px 5px rgb(0 0 0 / 20%);
}
}
}
Expand All @@ -23,7 +24,7 @@
background-repeat: no-repeat;
background-size: cover;
border-radius: 4px;
transition: box-shadow .1s ease;
transition: box-shadow 0.1s ease;
box-shadow: 0 8px 10px rgb(0 0 0 / 14%), 0 3px 14px rgb(0 0 0 / 12%), 0 4px 5px rgb(0 0 0 / 20%);
}

Expand Down Expand Up @@ -63,3 +64,15 @@ $aspects: ((1, 1), (2, 1), (2, 3), (4, 3), (5, 3), (16, 9), (9, 16));
margin-bottom: 0px;
min-height: 19px;
}
.titleFeatured {
position: absolute;
display: flex;
bottom: 50%;
font-family: var(--body-alt-font-family);
color: var(--card-color);
font-weight: 700;
align-items: center;
width: 100%;
background: linear-gradient(to top, rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0));
padding: 12px;
}
26 changes: 14 additions & 12 deletions src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,40 @@
import React from 'react';
import React, { memo } from 'react';
import classNames from 'classnames';

import { formatDurationTag } from '../../utils/formatting';

import styles from './Card.module.scss';

type CardProps = {
onClick: (() => void);
onClick: () => void;
onHover: () => void;
title: string;
duration: number;
posterSource?: string;
posterAspect?: "1:1" | "2:1" | "2:3" | "4:3" | "5:3" | "16:9" | "9:16";
posterAspect?: '1:1' | '2:1' | '2:3' | '4:3' | '5:3' | '16:9' | '9:16';
featured: boolean;
};

function Card({
onClick,
onHover,
title,
duration,
posterSource,
posterAspect = "16:9",
posterAspect = '16:9',
featured = false,
}: CardProps): JSX.Element {
const posterClassNames = classNames(styles.poster, styles[`aspect${posterAspect.replace(':', '')}`])
const posterClassNames = classNames(styles.poster, styles[`aspect${posterAspect.replace(':', '')}`]);

return (
<div className={styles.card} onClick={onClick} role="button" aria-label={`Play ${title}`}>
<div
className={posterClassNames}
style={{ backgroundImage: `url(${posterSource})` }}
>
<div className={styles.card} onClick={onClick} onMouseEnter={onHover} role="button" aria-label={`Play ${title}`}>
<div className={posterClassNames} style={{ backgroundImage: `url(${posterSource})` }}>
{duration && <div className={styles.tag}>{formatDurationTag(duration)}</div>}
{featured && <div className={styles.titleFeatured}>{title}</div>}
</div>
<p className={styles.title}>{title}</p>
{!featured && <p className={styles.title}>{title}</p>}
</div>
);
}

export default Card;
export default memo(Card);
3 changes: 2 additions & 1 deletion src/components/Root/Root.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react';

import { mockWindowLocation, render } from '../../testUtils';
import { mockWindowLocation, mockMatchMedia, render } from '../../testUtils';

mockMatchMedia();
import Root from './Root';

describe('<Root />', () => {
Expand Down
25 changes: 3 additions & 22 deletions src/components/Root/Root.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,8 @@
import React, { FC } from 'react';
import { Route, Switch } from 'react-router-dom';

import Playlist from '../../screens/Playlist/Playlist';
import Home from '../../screens/Home/Home';

// Mock screens

const PlaylistScreen = () => {
return (
<>
<span>PlaylistScreen</span>
</>
);
};
const Settings = () => {
return (
<>
<span>Settings</span>{' '}
</>
);
};

// Mock screens

type Props = {
error?: Error | null;
};
Expand All @@ -34,8 +15,8 @@ const Root: FC<Props> = ({ error }: Props) => {
return (
<Switch>
<Route path="/" component={Home} exact />
<Route path="/p/:id" component={PlaylistScreen} exact />
<Route path="/u" component={Settings} exact />
<Route path="/p/:id" component={Playlist} exact />
<Route path="/u" component={() => <span>Settings</span>} exact />
</Switch>
);
};
Expand Down
34 changes: 34 additions & 0 deletions src/components/Shelf/Shelf.module.scss
Original file line number Diff line number Diff line change
@@ -1,2 +1,36 @@
@use '../../styles/variables';
@use '../../styles/theme';

.Shelf {
margin: 0px 56px;
}

.title {
overflow: hidden;
font-family: var(--body-font-family);
color: var(--card-color);
font-weight: 700;
width: 100%;
text-overflow: ellipsis;
white-space: nowrap;
}

.arrowButton {
position: absolute;
background: none;
color: white;
border: none;
font-size: 2em;
font-weight: 400;
font-variant: normal;
line-height: 1;
-webkit-font-smoothing: antialiased;
z-index: 1;
cursor: pointer;
}
.arrowLeft {
left: -30px;
}
.arrowRight {
right: -30px;
}
11 changes: 5 additions & 6 deletions src/components/Shelf/Shelf.test.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import React from 'react';
import { render, screen } from '@testing-library/react';

import Shelf from './Shelf';
// import React from 'react';
// import { render, screen } from '@testing-library/react';
// import Shelf from './Shelf';

describe('FeaturedShelf Component tests', () => {
test.skip('dummy test', () => {
render(<Shelf title="test" playlist={[]} featured></Shelf>);
expect(screen.getByText('hello world')).toBeInTheDocument();
// render(<Shelf title="test" playlist={[]} featured></Shelf>);
// expect(screen.getByText('hello world')).toBeInTheDocument();
});
});
119 changes: 43 additions & 76 deletions src/components/Shelf/Shelf.tsx
Original file line number Diff line number Diff line change
@@ -1,100 +1,67 @@
import React, { useContext } from 'react';
import type { Config } from 'types/Config';
import React from 'react';
import type { Playlist, PlaylistItem } from 'types/playlist';
import classNames from 'classnames';

import { ConfigContext } from '../../providers/configProvider';
import Card from '../Card/Card';
import TileDock from '../TileDock/TileDock';
import useBreakpoint, { Breakpoint } from '../../hooks/useBreakpoint';

import styles from './Shelf.module.scss';

export type Image = {
src: string;
type: string;
width: number;
const tileBreakpoints = {
[Breakpoint.xs]: 1,
[Breakpoint.sm]: 3,
[Breakpoint.md]: 4,
[Breakpoint.lg]: 5,
[Breakpoint.xl]: 6,
};

export type ShelfProps = {
title: string;
playlist: string[];
playlist: Playlist | undefined;
onCardClick: (playlistItem: PlaylistItem) => void;
onCardHover: (playlistItem: PlaylistItem) => void;
featured?: boolean;
};

export type Source = {
file: string;
type: string;
};

export type Track = {
file: string;
kind: string;
label: string;
};
const Shelf: React.FC<ShelfProps> = ({ playlist, onCardClick, onCardHover, featured = false }: ShelfProps) => {
const breakpoint: Breakpoint = useBreakpoint();
const tilesToShow: number = featured ? 1 : tileBreakpoints[breakpoint];

export type Item = {
description: string;
duration: number;
feedid: string;
image: string;
images: Image[];
junction_id: string;
link: string;
mediaid: string;
pubdate: number;
sources: Source[];
tags: string;
title: string;
tracks: Track[];
variations: Record<string, unknown>;
};

const Shelf: React.FC<ShelfProps> = ({
title,
playlist,
featured = false,
}: ShelfProps) => {
const config: Config = useContext(ConfigContext);

console.info(config);
if (!playlist) return null;

return (
<div className={styles['Shelf']}>
<p>
Playlist {title} {featured}
</p>
{!featured && <h2 className={styles['title']}>{playlist.title}</h2>}
<TileDock
items={playlist}
tilesToShow={6}
tileHeight={300}
cycleMode={'endless'}
items={playlist.playlist}
tilesToShow={tilesToShow}
cycleMode={'restart'}
transitionTime="0.3s"
spacing={3}
spacing={12}
renderLeftControl={(handleClick) => (
<button onClick={handleClick}>Left</button>
<button className={classNames(styles['arrowButton'], styles['arrowLeft'])} onClick={handleClick}>
&lt;
</button>
)}
renderRightControl={(handleClick) => (
<button onClick={handleClick}>Right</button>
)}
renderTile={(item: unknown) => {
<button className={classNames(styles['arrowButton'], styles['arrowRight'])} onClick={handleClick}>
&gt;
</button>
)}
renderTile={(item) => {
const playlistItem = item as PlaylistItem;
return (
<div
style={{
background: 'white',
width: '100%',
height: '100%',
overflow: 'hidden',
}}
>
<div
style={{
width: '100%',
height: '100%',
background: `url('${
(item as Item).images[0]?.src
}') center / cover no-repeat`,
}}
>
</div>
</div>
)}}
<Card
key={playlistItem.mediaid}
title={playlistItem.title}
duration={playlistItem.duration}
posterSource={playlistItem.image}
onClick={() => onCardClick(playlistItem)}
onHover={() => onCardHover(playlistItem)}
featured={featured}
/>
);
}}
/>
</div>
);
Expand Down
1 change: 0 additions & 1 deletion src/components/TileDock/TileDock.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.tileDock {
overflow: hidden;
position: relative;
}
.tileDock ul {
Expand Down
Loading

0 comments on commit 3d1c954

Please sign in to comment.