Skip to content

Commit

Permalink
Merge branch 'develop' into feat/continue-watching-shelf
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristiaanScheermeijer authored Jun 16, 2021
2 parents 6312cc3 + 81ce7b7 commit de271a8
Show file tree
Hide file tree
Showing 12 changed files with 196 additions and 13 deletions.
4 changes: 4 additions & 0 deletions src/components/Button/Button.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,9 @@
height: 20px;
width: 20px;
fill: currentColor;
@include responsive.tablet-only() {
width: 18px;
height: 18px;
}
}
}
4 changes: 2 additions & 2 deletions src/components/Video/Video.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@
.otherButtons {
display: flex;
justify-content: center;
width: 100%;
> button {
margin-right: 8px;
width: 33%;
width: 100%;
}
> button:last-child {
margin-right: 0px;
Expand All @@ -78,7 +79,6 @@
> button:first-child {
margin-bottom: 8px;
margin-right: 0px;
width: 100%;
}
> button:not(:first-child) {
flex: 1;
Expand Down
15 changes: 14 additions & 1 deletion src/components/Video/Video.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,20 @@ describe('<Video>', () => {
title: 'Test item title',
tracks: [],
} as PlaylistItem;
const { container } = render(<Video item={item} startPlay={() => null} goBack={() => null} poster="fading" play isFavorited={false} onFavoriteButtonClick={jest.fn()}/>);
const { container } = render(
<Video
item={item}
startPlay={jest.fn()}
goBack={jest.fn()}
poster="fading"
play
hasShared={false}
onShareClick={jest.fn()}
enableSharing
isFavorited={false}
onFavoriteButtonClick={jest.fn()}
/>,
);

expect(container).toMatchSnapshot();
});
Expand Down
23 changes: 16 additions & 7 deletions src/components/Video/Video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import useBreakpoint, { Breakpoint } from '../../hooks/useBreakpoint';
import Favorite from '../../icons/Favorite';
import PlayTrailer from '../../icons/PlayTrailer';
import Share from '../../icons/Share';
import Check from '../../icons/Check';
import ArrowLeft from '../../icons/ArrowLeft';
import Play from '../../icons/Play';
import Button from '../Button/Button';
Expand All @@ -28,6 +29,9 @@ type Props = {
isFavorited: boolean;
onFavoriteButtonClick: () => void;
poster: Poster;
enableSharing: boolean;
hasShared: boolean;
onShareClick: () => void;
relatedShelf?: JSX.Element;
};

Expand All @@ -37,9 +41,12 @@ const Video: React.FC<Props> = ({
startPlay,
goBack,
poster,
relatedShelf,
enableSharing,
hasShared,
onShareClick,
isFavorited,
onFavoriteButtonClick,
relatedShelf,
}: Props) => {
const [isPlaying, setIsPlaying] = useState<boolean>(false);
const [mouseActive, setMouseActive] = useState(false);
Expand Down Expand Up @@ -102,12 +109,14 @@ const Video: React.FC<Props> = ({
onClick={onFavoriteButtonClick}
color={isFavorited ? 'primary' : 'default'}
/>
<Button
label={t('video:share')}
aria-label={t('video:share_video')}
startIcon={<Share />}
onClick={() => null}
/>
{enableSharing && (
<Button
label={hasShared ? t('video:copied_url') : t('video:share')}
startIcon={hasShared ? <Check /> : <Share />}
onClick={onShareClick}
active={hasShared}
/>
)}
</div>
</div>
<div
Expand Down
1 change: 0 additions & 1 deletion src/components/Video/__snapshots__/Video.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ exports[`<Video> renders and matches snapshot 1`] = `
</span>
</button>
<button
aria-label="video:share_video"
class="button default outlined"
>
<div
Expand Down
95 changes: 95 additions & 0 deletions src/containers/Video/Video.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { useHistory, useLocation } from 'react-router';
import React, { useContext, useState } from 'react';
import type { Config } from 'types/Config';
import type { PlaylistItem } from 'types/playlist';

import { copyToClipboard } from '../../utils/dom';
import useBlurImageUpdater from '../../hooks/useBlurImageUpdater';
import { ConfigContext } from '../../providers/ConfigProvider';
import VideoComponent from '../../components/Video/Video';
import { cardUrl, videoUrl } from '../../utils/formatting';
import usePlaylist from '../../hooks/usePlaylist';
import Shelf from '../Shelf/Shelf';
import { useFavorites } from '../../stores/FavoritesStore';

export type VideoType = 'movie' | 'series';

export type VideoProps = {
playlistId: string;
videoType: VideoType;
episodeId?: string | null;
mediaId?: string | null;
};

const Video = ({ playlistId, videoType, episodeId, mediaId }: VideoProps): JSX.Element => {
const history = useHistory();
const location = useLocation();
const { hasItem, saveItem, removeItem } = useFavorites();
const play = new URLSearchParams(location.search).get('play') === '1';
const config: Config = useContext(ConfigContext);
const [hasShared, setHasShared] = useState<boolean>(false);
const enableSharing: boolean = config.options.enableSharing === true;
const posterFading: boolean = config.options.posterFading === true;

const { isLoading, error, data: { playlist } = { playlist: [] } } = usePlaylist(playlistId);

const updateBlurImage = useBlurImageUpdater(playlist);

const getMovieItem = () => playlist.find((item) => item.mediaid === mediaId);
const getSeriesItem = () => playlist[0];
const item = videoType === 'movie' ? getMovieItem() : getSeriesItem();
const isFavorited = !!item && hasItem(item);

const startPlay = () => item && history.push(videoUrl(item, playlistId, true));
const goBack = () => item && history.push(videoUrl(item, playlistId, false));

const onCardClick = (item: PlaylistItem) => history.push(cardUrl(item));
const onCardHover = (item: PlaylistItem) => updateBlurImage(item.image);

const onShareClick = (): void => {
if (!item) return;

if (typeof navigator.share === 'function') {
navigator.share({ title: item.title, text: item.description, url: window.location.href });
} else {
copyToClipboard(window.location.href);
}
setHasShared(true);
setTimeout(() => setHasShared(false), 2000);
};

//temp:
console.info({ episodeId });

if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error loading list</p>;
if (!playlist) return <p>List not found</p>;
if (!item) return <p>Can not find medium</p>;

return (
<VideoComponent
item={item}
play={play}
startPlay={startPlay}
goBack={goBack}
poster={posterFading ? 'fading' : 'normal'}
enableSharing={enableSharing}
hasShared={hasShared}
onShareClick={onShareClick}
isFavorited={isFavorited}
onFavoriteButtonClick={() => (isFavorited ? removeItem(item) : saveItem(item))}
relatedShelf={
config.recommendationsPlaylist ? (
<Shelf
playlistId={config.recommendationsPlaylist}
onCardClick={onCardClick}
onCardHover={onCardHover}
relatedMediaId={item.mediaid}
/>
) : undefined
}
/>
);
};

export default Video;
1 change: 1 addition & 0 deletions src/i18n/locales/en_US/video.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
"share_video": "Share this video",
"start_watching": "Start watching",
"trailer": "Trailer",
"copied_url": "Copied url",
"watch_trailer": "Watch the trailer"
}
1 change: 1 addition & 0 deletions src/i18n/locales/nl_NL/video.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
"share_video": "",
"start_watching": "",
"trailer": "",
"copied_url": "",
"watch_trailer": ""
}
10 changes: 10 additions & 0 deletions src/icons/Check.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';

import createIcon from './Icon';

export default createIcon(
'0 0 24 24',
<g>
<path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" />
</g>,
);
21 changes: 20 additions & 1 deletion src/screens/Movie/Movie.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useContext } from 'react';
import React, { useContext, useState } from 'react';
import type { RouteComponentProps } from 'react-router-dom';
import { useHistory } from 'react-router';
import { Helmet } from 'react-helmet';
Expand All @@ -11,6 +11,7 @@ import type { PlaylistItem } from '../../../types/playlist';
import VideoComponent from '../../components/Video/Video';
import Shelf from '../../containers/Shelf/Shelf';
import useMedia from '../../hooks/useMedia';
import { copyToClipboard } from '../../utils/dom';

type MovieRouteParams = {
id: string;
Expand All @@ -31,6 +32,9 @@ const Movie = ({
const play = searchParams.get('play') === '1';
const posterFading: boolean = config ? config.options.posterFading === true : false;

const [hasShared, setHasShared] = useState<boolean>(false);
const enableSharing: boolean = config.options.enableSharing === true;

useBlurImageUpdater(item);

const isFavorited = !!item && hasItem(item);
Expand All @@ -40,6 +44,18 @@ const Movie = ({

const onCardClick = (item: PlaylistItem) => history.push(cardUrl(item));

const onShareClick = (): void => {
if (!item) return;

if (typeof navigator.share === 'function') {
navigator.share({ title: item.title, text: item.description, url: window.location.href });
} else {
copyToClipboard(window.location.href);
}
setHasShared(true);
setTimeout(() => setHasShared(false), 2000);
};

if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error loading list</p>;
if (!item) return <p>Can not find medium</p>;
Expand Down Expand Up @@ -76,6 +92,9 @@ const Movie = ({
startPlay={startPlay}
goBack={goBack}
poster={posterFading ? 'fading' : 'normal'}
enableSharing={enableSharing}
hasShared={hasShared}
onShareClick={onShareClick}
isFavorited={isFavorited}
onFavoriteButtonClick={() => (isFavorited ? removeItem(item) : saveItem(item))}
relatedShelf={
Expand Down
21 changes: 20 additions & 1 deletion src/screens/Series/Series.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useContext, useEffect, useMemo } from 'react';
import React, { useContext, useEffect, useMemo, useState } from 'react';
import type { RouteComponentProps } from 'react-router-dom';
import { useHistory } from 'react-router';
import { Helmet } from 'react-helmet';
Expand All @@ -12,6 +12,7 @@ import VideoComponent from '../../components/Video/Video';
import Shelf from '../../containers/Shelf/Shelf';
import useMedia from '../../hooks/useMedia';
import usePlaylist from '../../hooks/usePlaylist';
import { copyToClipboard } from '../../utils/dom';

type SeriesRouteParams = {
id: string;
Expand Down Expand Up @@ -40,6 +41,9 @@ const Series = (
}
}, [history, searchParams, seriesPlaylist]);

const [hasShared, setHasShared] = useState<boolean>(false);
const enableSharing: boolean = config.options.enableSharing === true;

const { hasItem, saveItem, removeItem } = useFavorites();
const play = searchParams.get('play') === '1';
const posterFading: boolean = config ? config.options.posterFading === true : false;
Expand All @@ -52,6 +56,18 @@ const Series = (

const onCardClick = (item: PlaylistItem) => history.push(cardUrl(item));

const onShareClick = (): void => {
if (!item) return;

if (typeof navigator.share === 'function') {
navigator.share({ title: item.title, text: item.description, url: window.location.href });
} else {
copyToClipboard(window.location.href);
}
setHasShared(true);
setTimeout(() => setHasShared(false), 2000);
};

if (isLoading || playlistIsLoading) return <p>Loading...</p>;
if (error || playlistError) return <p>Error loading list</p>;
if (!seriesPlaylist || !item) return <p>Can not find medium</p>;
Expand Down Expand Up @@ -84,6 +100,9 @@ const Series = (
startPlay={startPlay}
goBack={goBack}
poster={posterFading ? 'fading' : 'normal'}
enableSharing={enableSharing}
hasShared={hasShared}
onShareClick={onShareClick}
isFavorited={isFavorited}
onFavoriteButtonClick={() => isFavorited ? removeItem(item) : saveItem(item)}
relatedShelf={
Expand Down
13 changes: 13 additions & 0 deletions src/utils/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,16 @@ export const addScript = (src: string, callback: () => void): void => {
script.onerror = (error) => console.info('Error loading external script', error);
document.body.appendChild(script);
};

export const copyToClipboard = (value: string): void => {
const inputc = document.createElement('input');
inputc.style.zIndex = '-10';
inputc.style.position = 'absolute';
inputc.style.left = '-1000';
inputc.value = value;
document.body.appendChild(inputc);
inputc.select();
document.execCommand('copy');
inputc.blur();
document.body.removeChild(inputc);
};

0 comments on commit de271a8

Please sign in to comment.