Skip to content

Commit

Permalink
feat(favorites): add favorites shelf
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristiaanScheermeijer committed Jun 14, 2021
1 parent 8da119b commit 15ff11c
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 14 deletions.
32 changes: 32 additions & 0 deletions src/containers/FavoritesShelf/FavoritesShelf.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import type { PlaylistItem } from 'types/playlist';

import ShelfComponent from '../../components/Shelf/Shelf';
import { favoritesStore } from '../../stores/FavoritesStore';

type FavoritesShelfProps = {
playlistId: string;
onCardClick: (playlistItem: PlaylistItem) => void;
onCardHover: (playlistItem: PlaylistItem) => void;
featured?: boolean;
};

const Shelf = ({ playlistId, onCardClick, onCardHover, featured = false }: FavoritesShelfProps): JSX.Element => {
const favoritesPlaylist = favoritesStore.useState(s => s.favorites);
const continueWatchingPlaylist = favoritesStore.useState(s => s.favorites);

const playlist = playlistId === 'favorites' ? favoritesPlaylist : continueWatchingPlaylist;

return (
<ShelfComponent
loading={false}
error={null}
playlist={playlist}
onCardClick={onCardClick}
onCardHover={onCardHover}
featured={featured}
/>
);
};

export default Shelf;
2 changes: 1 addition & 1 deletion src/providers/QueryProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';

const queryClient = new QueryClient();
export const queryClient = new QueryClient();

type QueryProviderProps = {
children: JSX.Element;
Expand Down
4 changes: 3 additions & 1 deletion src/screens/Home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import scrollbarSize from '../../utils/dom';
import { cardUrl } from '../../utils/formatting';

import styles from './Home.module.scss';
import FavoritesShelf from '../../containers/FavoritesShelf/FavoritesShelf';

type rowData = {
index: number;
Expand Down Expand Up @@ -49,14 +50,15 @@ const Home = (): JSX.Element => {

const onCardClick = (playlistItem: PlaylistItem) => history.push(cardUrl(playlistItem, contentItem.playlistId));
const onCardHover = (playlistItem: PlaylistItem) => updateBlurImage(playlistItem.image);
const ShelfComponent = contentItem.playlistId === 'favorites' ? FavoritesShelf : Shelf;

return (
<div
key={key}
style={style}
className={classNames(styles.shelfContainer, { [styles.featured]: contentItem.featured })}
>
<Shelf
<ShelfComponent
key={contentItem.playlistId}
playlistId={contentItem.playlistId}
onCardClick={onCardClick}
Expand Down
12 changes: 12 additions & 0 deletions src/services/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ const loadConfig = async (configLocation: string) => {

const data = await response.json();

addFavoritesShelf(data);

if (data.version) {
return parseDeprecatedConfig(data);
}
Expand All @@ -71,6 +73,16 @@ const loadConfig = async (configLocation: string) => {
}
};

/**
* Add the favorites shelf if not already defined
* @param {Config} data
*/
const addFavoritesShelf = (data: Config) => {
if (!data.content.some(row => row.playlistId === 'favorites')) {
data.content.push({ playlistId: 'favorites' });
}
};

/**
* Serialize deprecated config to v3 config
* @param {Object} config
Expand Down
30 changes: 18 additions & 12 deletions src/stores/FavoritesStore.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,39 @@
import { Store } from 'pullstate';

import type { PlaylistItem } from '../../types/playlist';
import type { Playlist, PlaylistItem } from '../../types/playlist';
import * as persist from '../utils/persist';
import type { Favorite } from '../../types/favorite';
import { getMediaByIds } from '../services/api.service';
import { queryClient } from '../providers/QueryProvider';

type FavoritesStore = {
favorites: PlaylistItem[];
favorites: Playlist;
};

const PERSIST_KEY_FAVORITES = `favorites${window.configId ? `-${window.configId}` : ''}`;

export const favoritesStore = new Store<FavoritesStore>({
favorites: [],
favorites: {
title: 'Favorites',
playlist: [],
},
});

export const initializeFavorites = async () => {
const savedFavorites: Favorite[] | null = persist.getItem(PERSIST_KEY_FAVORITES) as Favorite[] | null;
const savedItems: Favorite[] | null = persist.getItem(PERSIST_KEY_FAVORITES) as Favorite[] | null;

if (savedFavorites) {
const favoritesPlaylist = await getMediaByIds(savedFavorites.map(({ mediaid }) => mediaid));
if (savedItems) {
const playlistItems = await getMediaByIds(savedItems.map(({ mediaid }) => mediaid));

favoritesStore.update((state) => {
state.favorites = favoritesPlaylist;
state.favorites.playlist = playlistItems;
});
}

return favoritesStore.subscribe(state => state.favorites, (favorites) => {
persist.setItem(PERSIST_KEY_FAVORITES, favorites.map(playlistItem => ({
queryClient.setQueryData(['playlist', 'favorites', undefined], () => favorites);

persist.setItem(PERSIST_KEY_FAVORITES, favorites.playlist.map(playlistItem => ({
mediaid: playlistItem.mediaid,
title: playlistItem.title,
tags: playlistItem.tags,
Expand All @@ -45,20 +51,20 @@ export const useFavorites = (): { saveItem: SaveItemFn, removeItem: RemoveItemFn

const saveItem = (item: PlaylistItem) => {
favoritesStore.update((s, o) => {
if (!o.favorites.some(current => current.mediaid === item.mediaid)) {
s.favorites.push(item);
if (!o.favorites.playlist.some(current => current.mediaid === item.mediaid)) {
s.favorites.playlist.unshift(item);
}
});
};

const removeItem = (item: PlaylistItem) => {
favoritesStore.update((s) => {
s.favorites = s.favorites.filter(current => current.mediaid !== item.mediaid);
s.favorites.playlist = s.favorites.playlist.filter(current => current.mediaid !== item.mediaid);
});
};

const hasItem = (item: PlaylistItem) => {
return favorites.some(current => current.mediaid === item.mediaid);
return favorites.playlist.some(current => current.mediaid === item.mediaid);
};

return { saveItem, removeItem, hasItem };
Expand Down

0 comments on commit 15ff11c

Please sign in to comment.