Skip to content

Commit

Permalink
feat: 다름 사람의 플리에서 비디오를 내 플리에 추가할때 중복된 비디오가 추가되지 않도록 수정 (#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
HSjjs98 committed Sep 18, 2024
1 parent 55bdfee commit b7aaf7b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 16 deletions.
24 changes: 19 additions & 5 deletions src/components/playlist/Playlists.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import theme from '@/styles/theme';
import { PlaylistModel } from '@/types/playlist';

interface PlaylistListProps {
playlists: PlaylistModel[];
playlists: (PlaylistModel & { containsVideo?: boolean })[];
customStyle?: SerializedStyles;
customVideoStyle?: SerializedStyles;
isColumn?: boolean;
onPlaylistClick?: (playlistId: string, title: string) => void;
onPlaylistClick?: (playlistId: string, title: string, containsVideo: boolean) => void;
disabledPlaylists?: boolean;
}

const Playlists: React.FC<PlaylistListProps> = ({
Expand All @@ -22,6 +23,7 @@ const Playlists: React.FC<PlaylistListProps> = ({
customVideoStyle,
onPlaylistClick,
isColumn = true,
disabledPlaylists = false,
}) => {
const currentUser = useAuth();

Expand All @@ -31,12 +33,19 @@ const Playlists: React.FC<PlaylistListProps> = ({
{playlists.length > 0 &&
playlists
.filter(({ isPublic, userId }) => isPublic || userId === currentUser?.uid)
.map(({ playlistId, title, videos, isPublic }) => (
.map(({ playlistId, title, videos, isPublic, containsVideo }) => (
<div
data-testid="playlist-item"
key={`playlist-${playlistId}`}
css={itemStyle(isColumn)}
onClick={() => (onPlaylistClick ? onPlaylistClick(playlistId, title) : null)}
css={[
itemStyle(isColumn),
disabledPlaylists && containsVideo && disabledPlaylistStyle,
]}
onClick={() =>
onPlaylistClick && !containsVideo
? onPlaylistClick(playlistId, title, !!containsVideo)
: null
}
>
<VideoThumbnail
url={videos[0]?.thumbnailUrl}
Expand Down Expand Up @@ -99,4 +108,9 @@ const itemStyle = (isColumn: boolean) => css`
}
`;

const disabledPlaylistStyle = css`
opacity: 0.5;
pointer-events: none;
`;

export default Playlists;
45 changes: 34 additions & 11 deletions src/pages/SelectPli.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from 'react';
import { useState, useMemo } from 'react';

import { css } from '@emotion/react';
import { HiOutlineBookmark, HiOutlinePlay } from 'react-icons/hi2';
Expand All @@ -21,6 +21,7 @@ import { useAddVideosToMyPlaylist } from '@/hooks/useVideoToPlaylist';
import SelectVideoPage from '@/pages/SelectVideo';
import { useToastStore } from '@/stores/toastStore';
import theme from '@/styles/theme';
import { PlaylistModel, VideoModel } from '@/types/playlist';
import { makeVideoObj } from '@/utils/video';

const tabs = [
Expand Down Expand Up @@ -59,20 +60,32 @@ const SelectPliPage: React.FC<SelectPliPageProps> = ({
close: closeSelectVideoModal,
} = useModalWithOverlay('selectVideoModal', 'selectPli');

const isVideoInPlaylist = useMemo(() => {
return (playlist: PlaylistModel) =>
playlist.videos.some((video: VideoModel) => video.videoId === videoObj.videoId);
}, [videoObj.videoId]);

const filteredPlaylists = useMemo(() => {
return (myPlaylists || []).map((playlist) => ({
...playlist,
containsVideo: isVideoInPlaylist(playlist),
}));
}, [myPlaylists, isVideoInPlaylist]);

const handleAddPlaylist = (title: string, isPublic: boolean) => {
addPlaylistMutation.mutate({ title, isPublic });
addToast('새로운 플리를 추가했습니다.');
};

const handlePlaylistClick = (playlistId: string, title: string) => {
const handlePlaylistClick = (playlistId: string, title: string, containsVideo: boolean) => {
if (type === 'fromPli') {
setSelectedPlaylistId(playlistId);
openSelectVideoModal();
} else if (type === 'byLink') {
if (onSelectPlaylist) {
onSelectPlaylist(playlistId, title);
}
} else if (videoId) {
} else if (videoId && !containsVideo) {
addVideoToPlaylistMutation.mutate(
{ playlistId, videos: [videoObj] },
{
Expand All @@ -85,7 +98,7 @@ const SelectPliPage: React.FC<SelectPliPageProps> = ({
},
},
);
} else {
} else if (!containsVideo) {
navigate(`${PATH.PLAYLIST}/${playlistId}`);
}
};
Expand All @@ -112,8 +125,6 @@ const SelectPliPage: React.FC<SelectPliPageProps> = ({
return <p>{error.message}</p>;
}

const filteredPlaylists = myPlaylists?.filter((playlist) => playlist.videos.length > 0) || [];

return (
<>
<div css={selectPliStyle}>
Expand All @@ -139,31 +150,38 @@ const SelectPliPage: React.FC<SelectPliPageProps> = ({
onAddPlaylist={handleAddPlaylist}
/>
<Playlists
playlists={myPlaylists || []}
playlists={filteredPlaylists}
customStyle={playlistStyle}
customVideoStyle={videoStyle}
onPlaylistClick={handlePlaylistClick}
onPlaylistClick={(id, title, containsVideo) =>
handlePlaylistClick(id, title, containsVideo)
}
isColumn={false}
disabledPlaylists={!type && videoId ? true : false}
/>
</>
) : (
<TabMenu tabs={tabs} activeTabId={activeTab} onTabChange={setActiveTab}>
<TabContent id="my" activeTabId={activeTab}>
<Playlists
playlists={filteredPlaylists || []}
playlists={filteredPlaylists.filter((playlist) => playlist.videos.length > 0)}
customStyle={playlistStyle}
customVideoStyle={videoStyle}
onPlaylistClick={handlePlaylistClick}
onPlaylistClick={(id, title, containsVideo) =>
handlePlaylistClick(id, title, containsVideo)
}
isColumn={false}
disabledPlaylists={false}
/>
</TabContent>
<TabContent id="subscribe" activeTabId={activeTab}>
<Playlists
playlists={subscribedPlaylists || []}
customStyle={playlistStyle}
customVideoStyle={videoStyle}
onPlaylistClick={handlePlaylistClick}
onPlaylistClick={(id, title) => handlePlaylistClick(id, title, false)}
isColumn={false}
disabledPlaylists={false}
/>
</TabContent>
</TabMenu>
Expand Down Expand Up @@ -214,6 +232,11 @@ const playlistStyle = css`
margin-left: 12px;
}
}
.disabled-playlist {
opacity: 0.5;
pointer-events: none;
}
`;

const videoStyle = css`
Expand Down

0 comments on commit b7aaf7b

Please sign in to comment.