-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(favorites): implement favorites store and hooks
- Loading branch information
1 parent
9a8bd5f
commit 1032cdb
Showing
13 changed files
with
149 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ module.exports = { | |
'playlist', | ||
'videodetail', | ||
'search', | ||
'favorites', | ||
], | ||
], | ||
}, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,6 +67,7 @@ The allowed scopes are: | |
- playlist | ||
- videodetail | ||
- search | ||
- favorites | ||
|
||
### Subject | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const API_BASE_URL = 'https://content.jwplatform.com'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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="M12.1,18.55L12,18.65L11.89,18.55C7.14,14.24 4,11.39 4,8.5C4,6.5 5.5,5 7.5,5C9.04,5 10.54,6 11.07,7.36H12.93C13.46,6 14.96,5 16.5,5C18.5,5 20,6.5 20,8.5C20,11.39 16.86,14.24 12.1,18.55M16.5,3C14.76,3 13.09,3.81 12,5.08C10.91,3.81 9.24,3 7.5,3C4.42,3 2,5.41 2,8.5C2,12.27 5.4,15.36 10.55,20.03L12,21.35L13.45,20.03C18.6,15.36 22,12.27 22,8.5C22,5.41 19.58,3 16.5,3Z" /> | ||
</g>, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import type { Playlist, PlaylistItem } from '../../types/playlist'; | ||
import { API_BASE_URL } from '../config'; | ||
|
||
/** | ||
* Get playlist by id | ||
* @param {string} id | ||
* @param relatedMediaId | ||
*/ | ||
export const getPlaylistById = (id: string, relatedMediaId?: string) : Promise<Playlist | undefined> => { | ||
const relatedQuery = relatedMediaId ? `?related_media_id=${relatedMediaId}` : ''; | ||
|
||
return fetch(`${API_BASE_URL}/v2/playlists/${id}${relatedQuery}`) | ||
.then((res) => res.json()); | ||
}; | ||
|
||
/** | ||
* Get search playlist | ||
* @param {string} playlistId | ||
* @param {string} query | ||
*/ | ||
export const getSearchPlaylist = (playlistId: string, query: string) : Promise<Playlist | undefined> => { | ||
return fetch(`${API_BASE_URL}/v2/playlists/${playlistId}?search=${encodeURIComponent(query)}`) | ||
.then((res) => res.json()); | ||
}; | ||
|
||
/** | ||
* Get media by id | ||
* @param {string} id | ||
*/ | ||
export const getMediaById = (id: string): Promise<PlaylistItem | undefined> => { | ||
return fetch(`${API_BASE_URL}/v2/media/${id}`) | ||
.then((res) => res.json() as Promise<Playlist>) | ||
.then(data => data.playlist[0]); | ||
}; | ||
|
||
/** | ||
* Gets multiple media items by the given ids. Filters out items that don't exist. | ||
* @param {string[]} ids | ||
*/ | ||
export const getMediaByIds = async (ids: string[]): Promise<PlaylistItem[]> => { | ||
// @todo this should be updated when it will become possible to request multiple media items in a single request | ||
const responses = await Promise.all(ids.map(id => getMediaById(id))); | ||
|
||
function notEmpty<Value> (value: Value | null | undefined): value is Value { | ||
return value !== null && value !== undefined; | ||
} | ||
|
||
return responses.filter(notEmpty); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,65 @@ | ||
import { Store } from 'pullstate'; | ||
|
||
type Favorite = { | ||
mediaId: string; | ||
}; | ||
import type { PlaylistItem } from '../../types/playlist'; | ||
import * as persist from '../utils/persist'; | ||
import type { Favorite } from '../../types/favorite'; | ||
import { getMediaByIds } from '../services/api.service'; | ||
|
||
type FavoritesStore = { | ||
favorites: Favorite[]; | ||
favorites: PlaylistItem[]; | ||
}; | ||
|
||
export const FavoritesStore = new Store<FavoritesStore>({ | ||
favorites: [{ mediaId: '' }], | ||
const PERSIST_KEY_FAVORITES = `favorites${window.configId ? `-${window.configId}` : ''}`; | ||
|
||
export const favoritesStore = new Store<FavoritesStore>({ | ||
favorites: [], | ||
}); | ||
|
||
export const initializeFavorites = async () => { | ||
const savedFavorites: Favorite[] | null = persist.getItem(PERSIST_KEY_FAVORITES) as Favorite[] | null; | ||
|
||
if (savedFavorites) { | ||
const favoritesPlaylist = await getMediaByIds(savedFavorites.map(({ mediaid }) => mediaid)); | ||
|
||
favoritesStore.update((state) => { | ||
state.favorites = favoritesPlaylist; | ||
}); | ||
} | ||
|
||
return favoritesStore.subscribe(state => state.favorites, (favorites) => { | ||
persist.setItem(PERSIST_KEY_FAVORITES, favorites.map(playlistItem => ({ | ||
mediaid: playlistItem.mediaid, | ||
title: playlistItem.title, | ||
tags: playlistItem.tags, | ||
duration: playlistItem.duration, | ||
}) as Favorite)); | ||
}); | ||
}; | ||
|
||
type SaveItemFn = (item: PlaylistItem) => void; | ||
type RemoveItemFn = (item: PlaylistItem) => void; | ||
type HasItemFn = (item: PlaylistItem) => boolean; | ||
|
||
export const useFavorites = (): { saveItem: SaveItemFn, removeItem: RemoveItemFn, hasItem: HasItemFn } => { | ||
const favorites = favoritesStore.useState((s) => s.favorites); | ||
|
||
const saveItem = (item: PlaylistItem) => { | ||
favoritesStore.update((s, o) => { | ||
if (!o.favorites.some(current => current.mediaid === item.mediaid)) { | ||
s.favorites.push(item); | ||
} | ||
}); | ||
}; | ||
|
||
const removeItem = (item: PlaylistItem) => { | ||
favoritesStore.update((s) => { | ||
s.favorites = s.favorites.filter(current => current.mediaid !== item.mediaid); | ||
}); | ||
}; | ||
|
||
const hasItem = (item: PlaylistItem) => { | ||
return favorites.some(current => current.mediaid === item.mediaid); | ||
}; | ||
|
||
return { saveItem, removeItem, hasItem }; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export type Favorite = { | ||
mediaid: string; | ||
title: string; | ||
tags: string; | ||
duration: number; | ||
}; |