Skip to content

Commit

Permalink
feat(menu): support media type for menu (#610)
Browse files Browse the repository at this point in the history
* feat(menu): support media type for menu

* feat(menu): fix lint fail

* feat(menu): code cleanup, rename types to include media

* feat(menu): add use case for playlist explicitly

* feat(menu): return empty string for default case

* feat(menu): rename constant
  • Loading branch information
CarinaDraganJW authored Sep 19, 2024
1 parent 20ddad5 commit 80acd7f
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 30 deletions.
3 changes: 2 additions & 1 deletion packages/common/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,10 @@ export const EPG_TYPE = {
viewNexa: 'viewnexa',
} as const;

export const PLAYLIST_TYPE = {
export const APP_CONFIG_ITEM_TYPE = {
playlist: 'playlist',
continue_watching: 'continue_watching',
favorites: 'favorites',
content_list: 'content_list',
media: 'media',
} as const;
20 changes: 20 additions & 0 deletions packages/common/src/utils/urlFormatting.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { AppMenuType } from '@jwp/ott-common/types/config';

import type { PlaylistItem } from '../../types/playlist';
import { PATH_MEDIA, PATH_PLAYLIST, PATH_CONTENT_LIST } from '../paths';
import { logWarn } from '../logger';
import { APP_CONFIG_ITEM_TYPE } from '../constants';

import { getLegacySeriesPlaylistIdFromEpisodeTags, getSeriesPlaylistIdFromCustomParams } from './media';

Expand Down Expand Up @@ -117,6 +120,10 @@ export const mediaURL = ({
);
};

export const singleMediaURL = (id: string, title?: string) => {
return createPath(PATH_MEDIA, { id, title: title ? slugify(title) : undefined });
};

export const playlistURL = (id: string, title?: string) => {
return createPath(PATH_PLAYLIST, { id, title: title ? slugify(title) : undefined });
};
Expand All @@ -125,6 +132,19 @@ export const contentListURL = (id: string, title?: string) => {
return createPath(PATH_CONTENT_LIST, { id, title: title ? slugify(title) : undefined });
};

export const determinePath = ({ type, contentId }: { type: AppMenuType | undefined; contentId: string }) => {
switch (type) {
case APP_CONFIG_ITEM_TYPE.content_list:
return contentListURL(contentId);
case APP_CONFIG_ITEM_TYPE.media:
return singleMediaURL(contentId);
case APP_CONFIG_ITEM_TYPE.playlist:
return playlistURL(contentId);
default:
return '';
}
};

export const liveChannelsURL = (playlistId: string, channelId?: string, play = false) => {
return createPath(
PATH_PLAYLIST,
Expand Down
14 changes: 8 additions & 6 deletions packages/common/types/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { PLAYLIST_TYPE } from '../src/constants';
import type { APP_CONFIG_ITEM_TYPE } from '../src/constants';

import type { AdScheduleUrls, AdDeliveryMethod } from './ad-schedule';

Expand Down Expand Up @@ -43,22 +43,22 @@ export type Drm = {
defaultPolicyId: string;
};

export type PlaylistType = keyof typeof PLAYLIST_TYPE;

export type PlaylistMenuType = Extract<PlaylistType, 'playlist' | 'content_list'>;
export type AppContentType = keyof typeof APP_CONFIG_ITEM_TYPE;
export type AppMenuType = Extract<AppContentType, 'playlist' | 'content_list' | 'media'>;
export type AppShelfType = Extract<AppContentType, 'playlist' | 'content_list' | 'continue_watching' | 'favorites'>;

export type Content = {
contentId?: string;
title?: string;
type: PlaylistType;
type: AppShelfType;
featured?: boolean;
backgroundColor?: string | null;
};

export type Menu = {
label: string;
contentId: string;
type?: PlaylistMenuType;
type?: AppMenuType;
filterTags?: string;
};

Expand All @@ -78,11 +78,13 @@ export type Cleeng = {
yearlyOffer?: string | null;
useSandbox?: boolean;
};

export type JWP = {
clientId?: string | null;
assetId?: number | null;
useSandbox?: boolean;
};

export type Features = {
recommendationsPlaylist?: string | null;
searchPlaylist?: string | null;
Expand Down
12 changes: 6 additions & 6 deletions packages/hooks-react/src/usePlaylist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { generatePlaylistPlaceholder } from '@jwp/ott-common/src/utils/collectio
import { isScheduledOrLiveMedia } from '@jwp/ott-common/src/utils/liveEvent';
import { isTruthyCustomParamValue } from '@jwp/ott-common/src/utils/common';
import type { ApiError } from '@jwp/ott-common/src/utils/api';
import type { PlaylistMenuType } from '@jwp/ott-common/types/config';
import { PLAYLIST_TYPE } from '@jwp/ott-common/src/constants';
import type { AppMenuType } from '@jwp/ott-common/types/config';
import { APP_CONFIG_ITEM_TYPE } from '@jwp/ott-common/src/constants';
import { useConfigStore } from '@jwp/ott-common/src/stores/ConfigStore';

const placeholderData = generatePlaylistPlaceholder(30);
Expand All @@ -21,7 +21,7 @@ export const getPlaylistQueryOptions = ({
params = {},
queryClient,
}: {
type: PlaylistMenuType;
type: AppMenuType;
contentId: string | undefined;
siteId: string;
enabled: boolean;
Expand All @@ -35,7 +35,7 @@ export const getPlaylistQueryOptions = ({
enabled: !!contentId && enabled,
queryKey: ['playlist', type, contentId, params],
queryFn: async () => {
if (type === PLAYLIST_TYPE.playlist) {
if (type === APP_CONFIG_ITEM_TYPE.playlist) {
const playlist = await apiService.getPlaylistById(contentId, params);

// This pre-caches all playlist items and makes navigating a lot faster.
Expand All @@ -44,7 +44,7 @@ export const getPlaylistQueryOptions = ({
});

return playlist;
} else if (type === PLAYLIST_TYPE.content_list) {
} else if (type === APP_CONFIG_ITEM_TYPE.content_list) {
const contentList = await apiService.getContentList({ siteId, id: contentId });

return contentList;
Expand All @@ -67,7 +67,7 @@ export default function usePlaylist(
params: GetPlaylistParams = {},
enabled: boolean = true,
usePlaceholderData: boolean = true,
type: PlaylistMenuType = PLAYLIST_TYPE.playlist,
type: AppMenuType = APP_CONFIG_ITEM_TYPE.playlist,
) {
const queryClient = useQueryClient();
const siteId = useConfigStore((state) => state.config.siteId);
Expand Down
4 changes: 2 additions & 2 deletions packages/hooks-react/src/usePlaylists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { PersonalShelf, PersonalShelves, PLAYLIST_LIMIT } from '@jwp/ott-common/
import { useFavoritesStore } from '@jwp/ott-common/src/stores/FavoritesStore';
import { useWatchHistoryStore } from '@jwp/ott-common/src/stores/WatchHistoryStore';
import { useConfigStore } from '@jwp/ott-common/src/stores/ConfigStore';
import type { Content, PlaylistMenuType, PlaylistType } from '@jwp/ott-common/types/config';
import type { Content, AppContentType, AppMenuType } from '@jwp/ott-common/types/config';
import type { Playlist } from '@jwp/ott-common/types/playlist';
import { useQueries, useQueryClient } from 'react-query';

Expand All @@ -15,7 +15,7 @@ type UsePlaylistResult = {
isPlaceholderData?: boolean;
}[];

const isPlaylistType = (type: PlaylistType): type is PlaylistMenuType => !PersonalShelves.some((pType) => pType === type);
const isPlaylistType = (type: AppContentType): type is AppMenuType => !PersonalShelves.some((pType) => pType === type);

const usePlaylists = (content: Content[], rowsToLoad: number | undefined = undefined) => {
const page_limit = PLAYLIST_LIMIT.toString();
Expand Down
4 changes: 2 additions & 2 deletions packages/ui-react/src/components/Shelf/Shelf.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import classNames from 'classnames';
import { useTranslation } from 'react-i18next';
import { CYCLE_MODE_RESTART, type RenderControl, type RenderPagination, TileSlider } from '@videodock/tile-slider';
import type { Playlist, PlaylistItem } from '@jwp/ott-common/types/playlist';
import type { AccessModel, PlaylistType } from '@jwp/ott-common/types/config';
import type { AccessModel, AppContentType } from '@jwp/ott-common/types/config';
import { isLocked } from '@jwp/ott-common/src/utils/entitlements';
import { mediaURL } from '@jwp/ott-common/src/utils/urlFormatting';
import { PersonalShelf } from '@jwp/ott-common/src/constants';
Expand Down Expand Up @@ -39,7 +39,7 @@ export const ShelfIdentifier = Symbol(`SHELF`);

export type ShelfProps = {
playlist: Playlist;
type: PlaylistType;
type: AppContentType;
onCardHover?: (playlistItem: PlaylistItem) => void;
watchHistory?: { [key: string]: number };
enableTitle?: boolean;
Expand Down
5 changes: 2 additions & 3 deletions packages/ui-react/src/containers/Layout/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import { Outlet } from 'react-router';
import { shallow } from '@jwp/ott-common/src/utils/compare';
import { useConfigStore } from '@jwp/ott-common/src/stores/ConfigStore';
import { unicodeToChar } from '@jwp/ott-common/src/utils/common';
import { contentListURL, playlistURL } from '@jwp/ott-common/src/utils/urlFormatting';
import { determinePath } from '@jwp/ott-common/src/utils/urlFormatting';
import env from '@jwp/ott-common/src/env';
import { useUIStore } from '@jwp/ott-common/src/stores/UIStore';
import { PLAYLIST_TYPE } from '@jwp/ott-common/src/constants';

import Header from '../../components/Header/Header';
import Footer from '../../components/Footer/Footer';
Expand Down Expand Up @@ -51,7 +50,7 @@ const Layout = () => {
{ label: t('home'), to: '/' },
...menu.map(({ label, contentId, type }) => ({
label,
to: type === PLAYLIST_TYPE.content_list ? contentListURL(contentId) : playlistURL(contentId),
to: determinePath({ type, contentId }),
})),
];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { contentListURL, playlistURL } from '@jwp/ott-common/src/utils/urlFormatting';
import { useUIStore } from '@jwp/ott-common/src/stores/UIStore';
import { useConfigStore } from '@jwp/ott-common/src/stores/ConfigStore';
import useOpaqueId from '@jwp/ott-hooks-react/src/useOpaqueId';
import { useLocation, useNavigate } from 'react-router';
import { ACCESS_MODEL, PLAYLIST_TYPE } from '@jwp/ott-common/src/constants';
import { ACCESS_MODEL } from '@jwp/ott-common/src/constants';
import { useAccountStore } from '@jwp/ott-common/src/stores/AccountStore';
import { determinePath } from '@jwp/ott-common/src/utils/urlFormatting';

import Button from '../../components/Button/Button';
import Sidebar from '../../components/Sidebar/Sidebar';
Expand Down Expand Up @@ -84,7 +84,7 @@ const SidebarContainer = () => {
</li>
{menu.map(({ contentId, type, label }) => (
<li key={contentId}>
<MenuButton label={label} to={type === PLAYLIST_TYPE.content_list ? contentListURL(contentId) : playlistURL(contentId)} />
<MenuButton label={label} to={determinePath({ type, contentId })} />
</li>
))}
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import React from 'react';
import { useParams } from 'react-router';
import { useTranslation } from 'react-i18next';
import type { Playlist } from '@jwp/ott-common/types/playlist';
import { PLAYLIST_TYPE, PLAYLIST_CONTENT_TYPE } from '@jwp/ott-common/src/constants';
import { APP_CONFIG_ITEM_TYPE, PLAYLIST_CONTENT_TYPE } from '@jwp/ott-common/src/constants';
import { ScreenMap } from '@jwp/ott-common/src/utils/ScreenMap';
import usePlaylist from '@jwp/ott-hooks-react/src/usePlaylist';
import type { PlaylistMenuType } from '@jwp/ott-common/types/config';
import type { AppMenuType } from '@jwp/ott-common/types/config';

import Loading from '../Loading/Loading';
import ErrorPage from '../../components/ErrorPage/ErrorPage';
Expand All @@ -24,7 +24,7 @@ playlistScreenMap.registerByContentType(PlaylistLiveChannels, PLAYLIST_CONTENT_T
// register content list screens
contentScreenMap.registerDefault(PlaylistGrid);

const PlaylistScreenRouter = ({ type }: { type: PlaylistMenuType }) => {
const PlaylistScreenRouter = ({ type }: { type: AppMenuType }) => {
const params = useParams();
const id = params.id || '';

Expand All @@ -43,7 +43,7 @@ const PlaylistScreenRouter = ({ type }: { type: PlaylistMenuType }) => {
return <ErrorPage title={t('empty_shelves_heading')} message={t('empty_shelves_description')} />;
}

const Screen = type === PLAYLIST_TYPE.content_list ? contentScreenMap.getScreen(data) : playlistScreenMap.getScreen(data);
const Screen = type === APP_CONFIG_ITEM_TYPE.content_list ? contentScreenMap.getScreen(data) : playlistScreenMap.getScreen(data);

return <Screen data={data} isLoading={isFetching} />;
};
Expand Down
6 changes: 3 additions & 3 deletions platforms/web/src/containers/AppRoutes/AppRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import MediaScreenRouter from '@jwp/ott-ui-react/src/pages/ScreenRouting/MediaSc
import PlaylistScreenRouter from '@jwp/ott-ui-react/src/pages/ScreenRouting/PlaylistScreenRouter';
import Layout from '@jwp/ott-ui-react/src/containers/Layout/Layout';
import { PATH_ABOUT, PATH_CONTENT_LIST, PATH_LEGACY_SERIES, PATH_MEDIA, PATH_PLAYLIST, PATH_SEARCH, PATH_USER } from '@jwp/ott-common/src/paths';
import { PLAYLIST_TYPE } from '@jwp/ott-common/src/constants';
import { APP_CONFIG_ITEM_TYPE } from '@jwp/ott-common/src/constants';

import RoutesContainer from '#src/containers/RoutesContainer/RoutesContainer';

Expand All @@ -24,8 +24,8 @@ export default function AppRoutes() {
<Route element={<RoutesContainer />}>
<Route element={<Layout />} errorElement={<RootErrorPage />}>
<Route index element={<Home />} />
<Route path={PATH_PLAYLIST} element={<PlaylistScreenRouter type={PLAYLIST_TYPE.playlist} />} />
<Route path={PATH_CONTENT_LIST} element={<PlaylistScreenRouter type={PLAYLIST_TYPE.content_list} />} />
<Route path={PATH_PLAYLIST} element={<PlaylistScreenRouter type={APP_CONFIG_ITEM_TYPE.playlist} />} />
<Route path={PATH_CONTENT_LIST} element={<PlaylistScreenRouter type={APP_CONFIG_ITEM_TYPE.content_list} />} />
<Route path={PATH_MEDIA} element={<MediaScreenRouter />} />
<Route path={PATH_LEGACY_SERIES} element={<LegacySeries />} />
<Route path={PATH_SEARCH} element={<Search />} />
Expand Down

0 comments on commit 80acd7f

Please sign in to comment.