-
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(signing): add playlist and media entitlement using a service
- Loading branch information
1 parent
7b0b0ae
commit e93a655
Showing
19 changed files
with
248 additions
and
101 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 |
---|---|---|
|
@@ -22,6 +22,7 @@ module.exports = { | |
'menu', | ||
'payment', | ||
'e2e', | ||
'signing', | ||
], | ||
], | ||
}, | ||
|
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,31 @@ | ||
import React, { useCallback, useLayoutEffect, useRef } from 'react'; | ||
|
||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
/** | ||
* The `useEventCallback` hook can be compared to the `useCallback` hook but without dependencies. It is a "shortcut" | ||
* to prevent re-renders based on callback changes due to dependency changes. This can be useful to improve the | ||
* performance or to prevent adding/removing event listeners to third-party libraries such as JW Player. | ||
* | ||
* @see {https://reactjs.org/docs/hooks-faq.html#how-to-avoid-passing-callbacks-down} | ||
* | ||
* @param {function} [callback] | ||
*/ | ||
const useEventCallback = <T extends (...args: any[]) => unknown>(callback?: T): T => { | ||
const fnRef = useRef(() => { | ||
throw new Error('Callback called in render'); | ||
}) as unknown as React.MutableRefObject<T | undefined>; | ||
|
||
useLayoutEffect(() => { | ||
fnRef.current = callback; | ||
}, [callback]); | ||
|
||
// @ts-ignore | ||
// ignore since we just want to pass all arguments to the callback function (which we don't know) | ||
return useCallback((...args) => { | ||
if (typeof fnRef.current === 'function') { | ||
return fnRef.current(...args); | ||
} | ||
}, []); | ||
}; | ||
|
||
export default useEventCallback; |
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,14 +1,35 @@ | ||
import { UseBaseQueryResult, useQuery } from 'react-query'; | ||
|
||
import { getMediaById } from '../services/api.service'; | ||
import { getDRMMediaById, getMediaById } from '../services/api.service'; | ||
|
||
import type { PlaylistItem } from '#types/playlist'; | ||
import { getPublicToken } from '#src/services/entitlement.service'; | ||
import { useAccountStore } from '#src/stores/AccountStore'; | ||
import { useConfigStore } from '#src/stores/ConfigStore'; | ||
|
||
export type UseMediaResult<TData = PlaylistItem, TError = unknown> = UseBaseQueryResult<TData, TError>; | ||
|
||
export default function useMedia(mediaId: string, enabled: boolean = true): UseMediaResult { | ||
return useQuery(['media', mediaId], () => getMediaById(mediaId), { | ||
enabled: !!mediaId && enabled, | ||
keepPreviousData: true, | ||
}); | ||
const jwt = useAccountStore((store) => store.auth?.jwt); | ||
const signingConfig = useConfigStore((store) => store.config.contentSigningService); | ||
|
||
return useQuery( | ||
['media', mediaId], | ||
async () => { | ||
const drmEnabled = !!signingConfig?.host && !!signingConfig?.drmEnabled && !!signingConfig?.drmPolicyId; | ||
|
||
if (drmEnabled && signingConfig?.drmEnabled && signingConfig?.drmPolicyId) { | ||
const { host, drmPolicyId } = signingConfig; | ||
const token = await getPublicToken(host, 'media', mediaId, drmPolicyId, {}, jwt); | ||
|
||
return getDRMMediaById(mediaId, signingConfig.drmPolicyId, token); | ||
} | ||
|
||
return getMediaById(mediaId); | ||
}, | ||
{ | ||
enabled: !!mediaId && enabled, | ||
keepPreviousData: true, | ||
}, | ||
); | ||
} |
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,24 +1,59 @@ | ||
import { UseBaseQueryResult, useQuery } from 'react-query'; | ||
|
||
import { generatePlaylistPlaceholder } from '../utils/collection'; | ||
import { getPlaylistById } from '../services/api.service'; | ||
import { getDRMPlaylistById, getPlaylistById } from '../services/api.service'; | ||
|
||
import type { Playlist } from '#types/playlist'; | ||
import type { Playlist, PlaylistParams } from '#types/playlist'; | ||
import { useConfigStore } from '#src/stores/ConfigStore'; | ||
import { getPublicToken } from '#src/services/entitlement.service'; | ||
import { useAccountStore } from '#src/stores/AccountStore'; | ||
|
||
const placeholderData = generatePlaylistPlaceholder(30); | ||
|
||
export type UsePlaylistResult<TData = Playlist, TError = unknown> = UseBaseQueryResult<TData, TError>; | ||
|
||
export default function usePlaylist( | ||
const filterRelatedMediaItem = (playlist: Playlist | undefined, relatedMediaId?: string): Playlist | undefined => { | ||
if (playlist?.playlist && relatedMediaId) { | ||
playlist.playlist = playlist.playlist.filter((playlistItem) => playlistItem.mediaid !== relatedMediaId); | ||
} | ||
|
||
return playlist; | ||
}; | ||
|
||
export default function usePlaylist ( | ||
playlistId: string, | ||
relatedMediaId?: string, | ||
params: PlaylistParams = {}, | ||
enabled: boolean = true, | ||
usePlaceholderData: boolean = true, | ||
limit?: number, | ||
): UsePlaylistResult { | ||
return useQuery(['playlist', playlistId, relatedMediaId], () => getPlaylistById(playlistId, relatedMediaId, limit), { | ||
enabled: !!playlistId && enabled, | ||
placeholderData: usePlaceholderData ? placeholderData : undefined, | ||
retry: false, | ||
}); | ||
const jwt = useAccountStore((store) => store.auth?.jwt); | ||
const signingConfig = useConfigStore((store) => store.config.contentSigningService); | ||
|
||
return useQuery( | ||
['playlist', playlistId, params], | ||
async () => { | ||
const drmEnabled = !!signingConfig?.host && !!signingConfig?.drmEnabled && !!signingConfig?.drmPolicyId; | ||
|
||
if (drmEnabled && signingConfig?.drmEnabled && signingConfig?.drmPolicyId) { | ||
const { host, drmPolicyId } = signingConfig; | ||
const token = await getPublicToken(host, 'playlist', playlistId, jwt, params, drmPolicyId); | ||
|
||
const playlist = await getDRMPlaylistById(playlistId, signingConfig.drmPolicyId, { | ||
...params, | ||
token, | ||
}); | ||
|
||
return filterRelatedMediaItem(playlist, params.related_media_id); | ||
} | ||
|
||
const playlist = await getPlaylistById(playlistId, {}).then(filterRelatedMediaItem); | ||
|
||
return filterRelatedMediaItem(playlist, params.related_media_id); | ||
}, | ||
{ | ||
enabled: !!playlistId && enabled, | ||
placeholderData: usePlaceholderData ? placeholderData : undefined, | ||
retry: false, | ||
}, | ||
); | ||
} |
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,34 @@ | ||
import { useCallback } from 'react'; | ||
|
||
import { getMediaToken } from '../services/entitlement.service'; | ||
import { useAccountStore } from '../stores/AccountStore'; | ||
import { useConfigStore } from '../stores/ConfigStore'; | ||
|
||
import { getDRMMediaById, getMediaById } from '#src/services/api.service'; | ||
import type { PlaylistItem } from '#types/playlist'; | ||
|
||
export const usePlaylistItemCallback = () => { | ||
const { auth } = useAccountStore(({ auth, subscription }) => ({ auth, subscription })); | ||
const signingConfig = useConfigStore((state) => state.config?.contentSigningService); | ||
|
||
return useCallback( | ||
async (item: PlaylistItem) => { | ||
const jwt = auth?.jwt; | ||
const signingEnabled = !!signingConfig?.host; | ||
const drmEnabled = signingEnabled && signingConfig?.drmEnabled && signingConfig?.drmPolicyId; | ||
|
||
if (!signingConfig && !signingEnabled) return item; | ||
|
||
// if signing is enabled, we need to sign the media item first. Assuming that the media item given to the player | ||
// isn't signed. An alternative way is to | ||
const { host, drmPolicyId } = signingConfig; | ||
|
||
const token = await getMediaToken({ host, drmPolicyId, id: item.mediaid, jwt, params: {} }); | ||
|
||
if (drmEnabled && drmPolicyId) return getDRMMediaById(item.mediaid, drmPolicyId, token); | ||
|
||
return await getMediaById(item.mediaid, token); | ||
}, | ||
[auth], | ||
); | ||
}; |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
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
Oops, something went wrong.