Skip to content

Commit 3bff757

Browse files
committed
feat(video): ✨ added video player modal
1 parent e31c026 commit 3bff757

File tree

6 files changed

+123
-31
lines changed

6 files changed

+123
-31
lines changed

src/icons/actionIcons/playIcon.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
1+
import { type PointerEvent } from "react";
2+
13
const PlayIcon = ({
24
className,
35
size = "40",
6+
onClick,
7+
onPointerDown,
48
}: {
59
className: string;
10+
onClick?: () => void;
11+
onPointerDown?: (event: PointerEvent) => void;
612
size?: string;
713
}) => (
814
<svg
915
className={className}
1016
height={size}
1117
id="play"
18+
onClick={onClick}
19+
onPointerDown={onPointerDown}
1220
viewBox="0 0 256 256"
1321
width={size}
1422
>

src/pageComponents/dashboard/cardSection/index.tsx

+51-29
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import DefaultUserIcon from "../../../icons/user/defaultUserIcon";
2727
import {
2828
useLoadersStore,
2929
useMiscellaneousStore,
30+
useModalStore,
3031
} from "../../../store/componentStore";
3132
import {
3233
type BookmarkViewDataTypes,
@@ -59,6 +60,7 @@ import {
5960
import "node_modules/video-react/dist/video-react.css";
6061

6162
import PlayIcon from "../../../icons/actionIcons/playIcon";
63+
import VideoModal from "../modals/videoModal";
6264

6365
import ListBox from "./listBox";
6466

@@ -120,6 +122,12 @@ const CardSection = ({
120122
const toggleIsSearchLoading = useLoadersStore(
121123
(state) => state.toggleIsSearchLoading,
122124
);
125+
const toggleShowVideoModal = useModalStore(
126+
(state) => state.toggleShowVideoModal,
127+
);
128+
const setSelectedVideoId = useMiscellaneousStore(
129+
(state) => state.setSelectedVideoId,
130+
);
123131

124132
const categoryData = queryClient.getQueryData([CATEGORIES_KEY, userId]) as {
125133
data: CategoriesData[];
@@ -436,6 +444,8 @@ const CardSection = ({
436444
width: number,
437445
type: string,
438446
) => {
447+
const isVideo = isBookmarkVideo(type);
448+
439449
const imgClassName = classNames({
440450
"min-h-[48px] min-w-[80px] max-h-[48px] max-w-[80px] object-cover rounded":
441451
cardTypeCondition === "list",
@@ -455,6 +465,7 @@ const CardSection = ({
455465
});
456466

457467
const figureClassName = classNames({
468+
relative: isVideo,
458469
"mr-3": cardTypeCondition === "list",
459470
"h-[48px] w-[80px] ": cardTypeCondition === "list",
460471
"w-full h-[194px] ": cardTypeCondition === "card",
@@ -530,19 +541,27 @@ const CardSection = ({
530541
return null;
531542
};
532543

533-
const isVideo = isBookmarkVideo(type);
534-
535-
// const playSvgClassName = classNames({
536-
// absolute: true,
537-
// "top-[43%] left-[43%]":
538-
// cardTypeCondition === "moodboard" || cardTypeCondition === "card",
539-
// "top-[13%] left-[27%]": cardTypeCondition === "list",
540-
// });
544+
const playSvgClassName = classNames({
545+
"hover:fill-slate-500 transition ease-in-out delay-50": true,
546+
absolute: true,
547+
"top-[43%] left-[43%]":
548+
cardTypeCondition === "moodboard" || cardTypeCondition === "card",
549+
"top-[13%] left-[27%]": cardTypeCondition === "list",
550+
});
541551

542552
return (
543553
!isNull(imgLogic()) && (
544554
<figure className={figureClassName}>
545-
{/* {isVideo ? <PlayIcon className={playSvgClassName} /> : null}{" "} */}
555+
{isVideo && (
556+
<PlayIcon
557+
className={playSvgClassName}
558+
onClick={() => {
559+
toggleShowVideoModal();
560+
setSelectedVideoId(id);
561+
}}
562+
onPointerDown={(event) => event.stopPropagation()}
563+
/>
564+
)}
546565
{isVideo ? null : null} {imgLogic()}
547566
</figure>
548567
)
@@ -795,27 +814,30 @@ const CardSection = ({
795814
});
796815

797816
return (
798-
<div
799-
className={listWrapperClass}
800-
// style={{ height: "calc(100vh - 270px)"}}
801-
>
802-
<ListBox
803-
aria-label="Categories"
804-
bookmarksColumns={bookmarksColumns}
805-
bookmarksList={bookmarksList}
806-
cardTypeCondition={cardTypeCondition}
807-
isPublicPage={isPublicPage}
808-
onBulkBookmarkDelete={onBulkBookmarkDelete}
809-
onCategoryChange={onCategoryChange}
810-
selectionMode="multiple"
817+
<>
818+
<div
819+
className={listWrapperClass}
820+
// style={{ height: "calc(100vh - 270px)"}}
811821
>
812-
{renderSortByCondition()?.map((item) => (
813-
<Item key={item?.id} textValue={item?.id?.toString()}>
814-
{renderBookmarkCardTypes(item)}
815-
</Item>
816-
))}
817-
</ListBox>
818-
</div>
822+
<ListBox
823+
aria-label="Categories"
824+
bookmarksColumns={bookmarksColumns}
825+
bookmarksList={bookmarksList}
826+
cardTypeCondition={cardTypeCondition}
827+
isPublicPage={isPublicPage}
828+
onBulkBookmarkDelete={onBulkBookmarkDelete}
829+
onCategoryChange={onCategoryChange}
830+
selectionMode="multiple"
831+
>
832+
{renderSortByCondition()?.map((item) => (
833+
<Item key={item?.id} textValue={item?.id?.toString()}>
834+
{renderBookmarkCardTypes(item)}
835+
</Item>
836+
))}
837+
</ListBox>
838+
</div>
839+
<VideoModal listData={listData} />
840+
</>
819841
);
820842
};
821843

src/pageComponents/dashboard/cardSection/option.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,12 @@ const Option = ({
9393
onClick={(event) => {
9494
event.preventDefault();
9595
// open on single click
96-
if (isPublicPage || isVideo) {
96+
if (isPublicPage) {
9797
window.open(url, "_blank");
9898
}
9999

100100
// open on double click
101-
if (event.detail === 2 && !isPublicPage && !isTrashPage && !isVideo) {
101+
if (event.detail === 2 && !isPublicPage && !isTrashPage) {
102102
window.open(url, "_blank");
103103
}
104104
}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { useEffect } from "react";
2+
import find from "lodash/find";
3+
4+
import Modal from "../../../components/modal";
5+
import {
6+
useMiscellaneousStore,
7+
useModalStore,
8+
} from "../../../store/componentStore";
9+
import { type SingleListData } from "../../../types/apiTypes";
10+
11+
const VideoModal = ({ listData }: { listData: SingleListData[] }) => {
12+
const showVideoModal = useModalStore((state) => state.showVideoModal);
13+
const toggleShowVideoModal = useModalStore(
14+
(state) => state.toggleShowVideoModal,
15+
);
16+
const selectedVideoId = useMiscellaneousStore(
17+
(state) => state.selectedVideoId,
18+
);
19+
const setSelectedVideoId = useMiscellaneousStore(
20+
(state) => state.setSelectedVideoId,
21+
);
22+
23+
useEffect(() => {
24+
if (!showVideoModal) {
25+
setSelectedVideoId(null);
26+
}
27+
}, [setSelectedVideoId, showVideoModal]);
28+
29+
const selectedVideoData = find(
30+
listData,
31+
(item) => selectedVideoId === item?.id,
32+
);
33+
34+
return (
35+
<Modal
36+
open={showVideoModal}
37+
setOpen={() => toggleShowVideoModal()}
38+
wrapperClassName="w-[65.4%] h-[82%] rounded-2xl outline-none"
39+
>
40+
{/* eslint-disable-next-line jsx-a11y/media-has-caption */}
41+
<video
42+
className="h-full w-full rounded-2xl"
43+
controls
44+
src={selectedVideoData?.url}
45+
/>
46+
</Modal>
47+
);
48+
};
49+
50+
export default VideoModal;

src/store/componentStore.ts

+8
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ export const useModalStore = create<ModalStoreState>((set) => ({
3333
set((state) => ({
3434
showSettingsModal: !state.showSettingsModal,
3535
})),
36+
showVideoModal: false,
37+
toggleShowVideoModal: () =>
38+
set((state) => ({
39+
showVideoModal: !state.showVideoModal,
40+
})),
3641
}));
3742

3843
export const useLoadersStore = create<LoadersStoreState>((set) => ({
@@ -74,4 +79,7 @@ export const useMiscellaneousStore = create<MiscellaneousStoreState>((set) => ({
7479
setCurrentSettingsPage: (
7580
value: MiscellaneousStoreState["currentSettingsPage"],
7681
) => set(() => ({ currentSettingsPage: value })),
82+
selectedVideoId: null,
83+
setSelectedVideoId: (value: number | null) =>
84+
set(() => ({ selectedVideoId: value })),
7785
}));

src/types/componentStoreTypes.ts

+4
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ export type ModalStoreState = {
44
showDeleteBookmarkWarningModal: boolean;
55
showSettingsModal: boolean;
66
showShareCategoryModal: boolean;
7+
showVideoModal: boolean;
78
toggleShareCategoryModal: () => void;
89
toggleShowAddBookmarkShortcutModal: () => void;
910
toggleShowClearTrashWarningModal: () => void;
1011
toggleShowDeleteBookmarkWarningModal: () => void;
1112
toggleShowSettingsModal: () => void;
13+
toggleShowVideoModal: () => void;
1214
};
1315

1416
export type LoadersStoreState = {
@@ -26,13 +28,15 @@ export type MiscellaneousStoreState = {
2628
currentSettingsPage: "change-email" | "delete" | "main";
2729
isCardDragging: boolean;
2830
searchText: string;
31+
selectedVideoId: number | null;
2932
setAddScreenshotBookmarkId: (value: number | undefined) => void;
3033
setCurrentBookmarkView: (value: BookmarksViewTypes) => void;
3134
setCurrentSettingsPage: (
3235
value: MiscellaneousStoreState["currentSettingsPage"],
3336
) => void;
3437
setIsCardDragging: (value: boolean) => void;
3538
setSearchText: (value: string) => void;
39+
setSelectedVideoId: (id: number | null) => void;
3640
setShareCategoryId: (id: number | undefined) => void;
3741
setShowSidePane: (value: boolean) => void;
3842
shareCategoryId: number | undefined;

0 commit comments

Comments
 (0)