Skip to content

Commit

Permalink
Merge pull request #11 from Videodock/fix/playlist
Browse files Browse the repository at this point in the history
Fix/playlist
  • Loading branch information
ChristiaanScheermeijer authored May 7, 2021
2 parents bb6b501 + c9eaa29 commit c980657
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 35 deletions.
11 changes: 8 additions & 3 deletions src/components/Dropdown/Dropdown.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ import * as React from 'react';
import { render } from '@testing-library/react';

import Dropdown from './Dropdown';

const options = ['x', 'y', 'z'];

describe('<Dropdown>', () => {
it('renders dropdown', () => {
const { getByText } = render(
<Dropdown name="categories" value="aa" defaultLabel="bb" options={options} setValue={(event) => event} />,
<Dropdown
name="categories"
value="aa"
defaultLabel="bb"
options={options}
onClick={(event: React.SyntheticEvent) => event}
onChange={(event: React.SyntheticEvent) => event}
/>,
);
const dropdown = getByText(/bb/i);
expect(document.body.contains(dropdown));
Expand Down
25 changes: 14 additions & 11 deletions src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
import React from 'react';
import React, { SyntheticEvent } from 'react';
import classNames from 'classnames';

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

type DropdownProps = {
type Props = {
name: string;
value: string;
defaultLabel: string;
options: string[];
setValue: (value: string) => void;
optionsStyle?: string;
onClick: (event: SyntheticEvent) => void;
onChange: (event: React.ChangeEvent<HTMLSelectElement>) => void;
};

function Dropdown({ name, value, defaultLabel, options, setValue }: DropdownProps) {
const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => setValue(event.target.value);

const Dropdown: React.FC<Props> = ({ name, value, defaultLabel, options, onClick, onChange, optionsStyle }: Props) => {
return (
<div className={styles.dropdown}>
<select className={styles.select} name={name} value={value} onChange={handleChange}>
<option value="">{defaultLabel}</option>
<select className={styles.select} name={name} value={value} onClick={onClick} onChange={onChange}>
<option className={classNames(styles.option, optionsStyle)} value="">
{defaultLabel}
</option>
{options.map((option) => (
<option className={styles.option} key={option} value={option}>
<option className={classNames(styles.option, optionsStyle)} key={option} value={option}>
{option}
</option>
))}
</select>
<span className="focus"></span>
<span className="focus" />
</div>
);
}
};

export default Dropdown;
2 changes: 1 addition & 1 deletion src/components/DynamicBlur/DynamicBlur.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import DynamicBlur from './DynamicBlur';

describe('<DynamicBlur>', () => {
test('renders and matches snapshot', () => {
const { container } = render(<DynamicBlur />);
const { container } = render(<DynamicBlur url="/" />);

expect(container).toMatchSnapshot();
});
Expand Down
4 changes: 2 additions & 2 deletions src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ const Header: React.FC<Props> = ({ headerType = 'static', onMenuButtonClick, pla
</div>
{logoSrc && <Logo src={logoSrc} />}
<nav className={styles.nav} aria-label="menu">
<ButtonLink className={styles.buttonLink} label="Home" to="/" />
<ButtonLink label="Home" to="/" />
{playlistMenuItems}
<ButtonLink className={styles.buttonLink} label="Settings" to="/u" />
<ButtonLink label="Settings" to="/u" />
</nav>
<div className={styles.search}></div>
</div>
Expand Down
63 changes: 45 additions & 18 deletions src/screens/Playlist/Playlist.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,65 @@
import React, { useState } from 'react';
import type { RouteComponentProps } from 'react-router-dom';
import type { GridCellProps } from 'react-virtualized';

import VirtualizedGrid from '../../components/VirtualizedGrid/VirtualizedGrid';
import usePlaylist from '../../hooks/usePlaylist';
import { getCategoriesFromPlaylist, filterPlaylistCategory } from '../../utils/collection';
import { getCategoriesFromPlaylist, filterPlaylistCategory, chunk } from '../../utils/collection';
import Card from '../../components/Card/Card';
import Dropdown from '../../components/Dropdown/Dropdown';
import CardGrid from '../../components/CardGrid/CardGrid';
import Dropdown from '../../components/Filter/Filter';
import useBreakpoint, { Breakpoint } from '../../hooks/useBreakpoint';

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

// TEMP DATA
const playlistId = 'sR5VypYk';
const cols = {
[Breakpoint.xs]: 2,
[Breakpoint.sm]: 2,
[Breakpoint.md]: 2,
[Breakpoint.lg]: 4,
[Breakpoint.xl]: 5,
};

type PlaylistDestructuredArguments = {
mediaid: string;
title: string;
duration: number;
image: string;
type PlaylistRouteParams = {
id: string;
};

function Playlist() {
const { isLoading, error, data: { title, playlist } = {} } = usePlaylist(playlistId);
function Playlist({
match: {
params: { id },
},
}: RouteComponentProps<PlaylistRouteParams>) {
const { isLoading, error, data: { title, playlist } = {} } = usePlaylist(id);
const [filter, setFilter] = useState<string>('');
const breakpoint: Breakpoint = useBreakpoint();

if (isLoading) return <p>Loading...</p>;

if (error) return <p>No playlist found...</p>;
if (error || !playlist) return <p>No playlist found...</p>;

const categories = getCategoriesFromPlaylist(playlist);
const filteredPlaylist = filterPlaylistCategory(playlist, filter);

const playlistRows = chunk(filteredPlaylist, cols[breakpoint]);

const cellRenderer = ({ columnIndex, key, rowIndex, style }: GridCellProps) => {
if (!playlistRows[rowIndex][columnIndex]) return;

const { mediaid: mediaId, title, duration, image, seriesId } = playlistRows[rowIndex][columnIndex];

return (
<div className={styles.wrapper} style={style} key={key}>
<Card
key={mediaId}
title={title}
duration={duration}
posterSource={image}
seriesId={seriesId}
onClick={() => ''}
/>
</div>
);
};

return (
<div className={styles.playlist}>
<header className={styles.header}>
Expand All @@ -38,11 +69,7 @@ function Playlist() {
)}
</header>
<main>
<CardGrid>
{filteredPlaylist.map(({ mediaid: mediaId, title, duration, image }: PlaylistDestructuredArguments) => (
<Card key={mediaId} title={title} duration={duration} posterSource={image} onClick={() => ''} />
))}
</CardGrid>
<VirtualizedGrid rowCount={playlistRows.length} cellRenderer={cellRenderer} spacing={30} />
</main>
</div>
);
Expand Down

0 comments on commit c980657

Please sign in to comment.