Skip to content

Commit

Permalink
feat(project): support watchlists
Browse files Browse the repository at this point in the history
- Changed Alert, Modal and Dialog snapshots
- Review fixed
  • Loading branch information
“Anton committed Jun 14, 2022
1 parent 0124428 commit b506b52
Show file tree
Hide file tree
Showing 31 changed files with 196 additions and 61 deletions.
6 changes: 3 additions & 3 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ The eight-character Playlists IDs from the JW Player dashboard. These IDs popula

It is possible to use 'playlist', 'continue_watching' or 'favorites' as a type. With this, you can change the position of the shelves and turn on/off extra `continue_watching` and `favorites` shelves.

If you want to include `favorites` / `continue_watching` shelf, you should also add a corresponding playlist with `watchlist` type to features section (`features.favorites_list` and `features.continue_watching_list`). To exclude the shelves, remove a corresponding array item and a playlist in `features`.
If you want to include `favorites` / `continue_watching` shelf, you should also add a corresponding playlist with `watchlist` type to features section (`features.favoritesList` and `features.continueWatchingList`). To exclude the shelves, remove a corresponding array item and a playlist in `features`.

```
{
Expand Down Expand Up @@ -280,13 +280,13 @@ The eight-character Playlist ID of the Search playlist that you want to use to e

---

**features.favorites_list** (optional)
**features.favoritesList** (optional)

The eight-character Playlist ID of the Watchlist playlist that you want to use to populate the "Favorites" shelf in your site.

---

**features.continue_watching_list** (optional)
**features.continueWatchingList** (optional)

The eight-character Playlist ID of the Watchlist playlist that you want to use to populate the "Continue Watching" shelf in your site.

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,4 @@
"glob-parent": "^5.1.2",
"codeceptjs/**/ansi-regex": "^4.1.1"
}
}
}
12 changes: 11 additions & 1 deletion public/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
"type": "playlist",
"contentId": "JSKF03bk"
},
{
"enableText": true,
"type": "favorites"
},
{
"enableText": true,
"type": "continue_watching"
},
{
"enableText": true,
"type": "playlist",
Expand Down Expand Up @@ -36,7 +44,9 @@
],
"features": {
"recommendationsPlaylist": "IHBjjkSN",
"searchPlaylist": "D4soEviP"
"searchPlaylist": "D4soEviP",
"favoritesList": "34CFUkws",
"continueWatchingList": "IJvotI4w"
},
"styling": {
"backgroundColor": null,
Expand Down
18 changes: 10 additions & 8 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import QueryProvider from '#src/providers/QueryProvider';
import { restoreWatchHistory } from '#src/stores/WatchHistoryController';
import { initializeAccount } from '#src/stores/AccountController';
import { initializeFavorites } from '#src/stores/FavoritesController';
import { logDev } from '#src/utils/common';

import '#src/i18n/config';
import '#src/styles/main.scss';
Expand All @@ -27,27 +28,28 @@ class App extends Component {
}

async initializeServices(config: Config) {
if (config?.integrations?.cleeng?.id) {
await initializeAccount();
}

// We only request favorites and continue_watching data if these features are enabled
if (config?.features?.continue_watching_list) {
// We first initialize the account otherwise if we have favorites saved as externalData and in a local storage the sections may blink if data differs
if (config?.features?.continueWatchingList) {
await restoreWatchHistory();
}

if (config?.features?.favorites_list) {
if (config?.features?.favoritesList) {
await initializeFavorites();
}

if (config?.integrations?.cleeng?.id) {
await initializeAccount();
}
}

configLoadingHandler = (isLoading: boolean) => {
console.info(`Loading config: ${isLoading}`);
logDev(`Loading config: ${isLoading}`);
};

configErrorHandler = (error: Error) => {
this.setState({ error });
console.error('Error while loading the config.json:', error);
logDev('Error while loading the config.json:', error);
};

configValidationCompletedHandler = async (config: Config) => {
Expand Down
5 changes: 4 additions & 1 deletion src/components/Alert/Alert.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { render } from '@testing-library/react';

import Alert from './Alert';

vi.mock('../Dialog/Dialog', () => ({
default: 'div',
}));

describe('<Alert>', () => {
test('renders and matches snapshot', () => {
const { container } = render(<Alert body="Body" title="Title" open={true} onClose={vi.fn()} />);

expect(container).toMatchSnapshot();
});
});
26 changes: 25 additions & 1 deletion src/components/Alert/__snapshots__/Alert.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
// Vitest Snapshot v1

exports[`<Alert> > renders and matches snapshot 1`] = `<div />`;
exports[`<Alert> > renders and matches snapshot 1`] = `
<div>
<div
open=""
>
<h2
class="title"
>
Title
</h2>
<p
class="body"
>
Body
</p>
<button
class="button default outlined fullWidth"
>
<span>
alert.close
</span>
</button>
</div>
</div>
`;
4 changes: 4 additions & 0 deletions src/components/ConfirmationDialog/ConfirmationDialog.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { render } from '@testing-library/react';

import ConfirmationDialog from './ConfirmationDialog';

vi.mock('../Dialog/Dialog', () => ({
default: 'div',
}));

describe('<ConfirmationDialog>', () => {
test('renders and matches snapshot', () => {
const { container } = render(<ConfirmationDialog body="Body" title="Title" open={true} onConfirm={vi.fn()} onClose={vi.fn()} />);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
// Vitest Snapshot v1

exports[`<ConfirmationDialog> > renders and matches snapshot 1`] = `<div />`;
exports[`<ConfirmationDialog> > renders and matches snapshot 1`] = `
<div>
<div
open=""
>
<h2
class="title"
>
Title
</h2>
<p
class="body"
>
Body
</p>
<button
class="button confirmButton primary fullWidth"
>
<span>
confirmation_dialog.confirm
</span>
</button>
<button
class="button default outlined fullWidth"
>
<span>
confirmation_dialog.close
</span>
</button>
</div>
</div>
`;
4 changes: 4 additions & 0 deletions src/components/Dialog/Dialog.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { render } from '@testing-library/react';

import Dialog from './Dialog';

vi.mock('../Modal/Modal', () => ({
default: 'div',
}));

describe('<Dialog>', () => {
test('renders and matches snapshot', () => {
const { container } = render(
Expand Down
38 changes: 37 additions & 1 deletion src/components/Dialog/__snapshots__/Dialog.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
// Vitest Snapshot v1

exports[`<Dialog> > renders and matches snapshot 1`] = `<div />`;
exports[`<Dialog> > renders and matches snapshot 1`] = `
<div>
<div
open=""
>
<div
class="dialog"
>
<div
aria-label="close_modal"
class="iconButton modalCloseButton"
role="button"
tabindex="0"
>
<svg
aria-hidden="true"
class="icon"
focusable="false"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
/>
<path
d="M0 0h24v24H0z"
fill="none"
/>
</g>
</svg>
</div>
Dialog contents
</div>
</div>
</div>
`;
1 change: 1 addition & 0 deletions src/components/Payment/Payment.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ describe.skip('<Payment>', () => {
test('renders and matches snapshot', () => {
const { container } = render(
<Payment
accessModel="AVOD"
customer={customer as Customer}
transactions={transactions as Transaction[]}
activeSubscription={subscription as Subscription}
Expand Down
2 changes: 2 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export const VideoProgressMinMax = {

export const PLAYLIST_LIMIT = 25;

export const MAX_WATCHLIST_ITEMS_COUNT = 30;

export const ADYEN_TEST_CLIENT_KEY = 'test_I4OFGUUCEVB5TI222AS3N2Y2LY6PJM3K';

export const ADYEN_LIVE_CLIENT_KEY = 'live_BQDOFBYTGZB3XKF62GBYSLPUJ4YW2TPL';
1 change: 0 additions & 1 deletion src/constants/watchlist.ts

This file was deleted.

6 changes: 3 additions & 3 deletions src/containers/Cinema/Cinema.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ type Props = {
};

const Cinema: React.FC<Props> = ({ item, onPlay, onPause, onComplete, onUserActive, onUserInActive, feedId, isTrailer = false }: Props) => {
const { player, continue_watching_list } = useConfigStore(({ config }) => ({
const { player, continueWatchingList } = useConfigStore(({ config }) => ({
player: config.player,
continue_watching_list: config.features?.continue_watching_list,
continueWatchingList: config.features?.continueWatchingList,
}));
const playerElementRef = useRef<HTMLDivElement>(null);
const playerRef = useRef<JWPlayer>();
const loadingRef = useRef(false);
const seekToRef = useRef(-1);
const [libLoaded, setLibLoaded] = useState(!!window.jwplayer);
const scriptUrl = `https://content.jwplatform.com/libraries/${player}.js`;
const enableWatchHistory = continue_watching_list && !isTrailer;
const enableWatchHistory = continueWatchingList && !isTrailer;
const setPlayer = useOttAnalytics(item, feedId);
const handlePlaylistItemCallback = usePlaylistItemCallback();

Expand Down
2 changes: 2 additions & 0 deletions src/i18n/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ i18n
caches: ['localStorage'],
},
});

export default i18n;
3 changes: 2 additions & 1 deletion src/i18n/locales/en_US/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
"sign_in": "Sign in",
"sign_up": "Sign up",
"slide_left": "Slide left",
"slide_right": "Slide right"
"slide_right": "Slide right",
"default_site_name": "My OTT Application"
}
3 changes: 2 additions & 1 deletion src/i18n/locales/nl_NL/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
"sign_in": "",
"sign_up": "",
"slide_left": "",
"slide_right": ""
"slide_right": "",
"default_site_name": ""
}
6 changes: 5 additions & 1 deletion src/i18n/locales/nl_NL/video.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,9 @@
"trailer": "",
"video_not_found": "",
"watch_trailer": "",
"share_video": ""
"share_video": "",
"favorites_warning": {
"title": "",
"body": ""
}
}
11 changes: 4 additions & 7 deletions src/screens/Movie/Movie.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ import { addConfigParamToUrl } from '#src/utils/configOverride';
import { removeItem, saveItem } from '#src/stores/FavoritesController';
import usePlaylist from '#src/hooks/usePlaylist';
import useEntitlement from '#src/hooks/useEntitlement';
import useToggle from '#src/hooks/useToggle';
import StartWatchingButton from '#src/containers/StartWatchingButton/StartWatchingButton';
import { MAX_WATCHLIST_ITEMS_COUNT } from '#src/constants/watchlist';
import { MAX_WATCHLIST_ITEMS_COUNT } from '#src/config';

type MovieRouteParams = {
id: string;
Expand All @@ -36,7 +37,7 @@ const Movie = ({ match, location }: RouteComponentProps<MovieRouteParams>): JSX.
const { t } = useTranslation('video');
const [hasShared, setHasShared] = useState<boolean>(false);
const [playTrailer, setPlayTrailer] = useState<boolean>(false);
const [isFavoritesWarningShown, setIsFavoritesWarningShown] = useState(false);
const [isFavoritesWarningShown, onFavoritesWarningToggle] = useToggle();

// Routing
const history = useHistory();
Expand All @@ -51,7 +52,7 @@ const Movie = ({ match, location }: RouteComponentProps<MovieRouteParams>): JSX.

const posterFading: boolean = styling?.posterFading === true;
const enableSharing: boolean = features?.enableSharing === true;
const isFavoritesEnabled: boolean = Boolean(features?.favorites_list);
const isFavoritesEnabled: boolean = Boolean(features?.favoritesList);

// Media
const { isLoading, error, data: item } = useMedia(id);
Expand All @@ -70,10 +71,6 @@ const Movie = ({ match, location }: RouteComponentProps<MovieRouteParams>): JSX.
const { isEntitled } = useEntitlement(item);

// Handlers
const onFavoritesWarningToggle = useCallback(() => {
setIsFavoritesWarningShown(!isFavoritesWarningShown);
}, [setIsFavoritesWarningShown, isFavoritesWarningShown]);

const onFavoriteButtonClick = useCallback(() => {
if (!item) {
return;
Expand Down
2 changes: 2 additions & 0 deletions src/screens/Series/Series.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const Series = ({ match, location }: RouteComponentProps<SeriesRouteParams>): JS
const { styling, features, siteName } = config;
const posterFading: boolean = styling?.posterFading === true;
const enableSharing: boolean = features?.enableSharing === true;
const isFavoritesEnabled: boolean = Boolean(features?.favoritesList);

// Media
const { isLoading, error, data: item } = useMedia(episodeId);
Expand Down Expand Up @@ -160,6 +161,7 @@ const Series = ({ match, location }: RouteComponentProps<SeriesRouteParams>): JS
onTrailerClick={() => setPlayTrailer(true)}
onTrailerClose={() => setPlayTrailer(false)}
isFavorited={isFavorited}
isFavoritesEnabled={isFavoritesEnabled}
onFavoriteButtonClick={() => (isFavorited ? removeItem(item) : saveItem(item))}
startWatchingButton={<StartWatchingButton item={item} />}
isSeries
Expand Down
Loading

0 comments on commit b506b52

Please sign in to comment.