diff --git a/src/components/Publish/EditPlaylist/EditPlaylist.tsx b/src/components/Publish/EditPlaylist/EditPlaylist.tsx index 52a4c5e..335d4a3 100644 --- a/src/components/Publish/EditPlaylist/EditPlaylist.tsx +++ b/src/components/Publish/EditPlaylist/EditPlaylist.tsx @@ -44,6 +44,7 @@ import { } from "../../../state/features/videoSlice.ts"; import ImageUploader from "../../common/ImageUploader.tsx"; import { categories, subCategories } from "../../../constants/Categories.ts"; +import { ratings } from "../../../constants/Ratings.ts"; import { Playlists } from "../../Playlists/Playlists.tsx"; import { PlaylistListEdit } from "../PlaylistListEdit/PlaylistListEdit.tsx"; import { TextEditor } from "../../common/TextEditor/TextEditor.tsx"; @@ -90,6 +91,8 @@ export const EditPlaylist = () => { useState(null); const [selectedSubCategoryVideos, setSelectedSubCategoryVideos] = useState(null); + const [selectedRatingVideos, setSelectedRatingVideos] = + useState(null); const isNew = useMemo(() => { return editVideoProperties?.mode === "new"; @@ -121,8 +124,8 @@ export const EditPlaylist = () => { // // Split the extracted string into key-value pairs // const keyValuePairs = extractedString.split(";"); - // // Initialize variables to hold the category and subcategory values - // let category, subcategory; + // // Initialize variables to hold the category, subcategory, and rating values + // let category, subcategory, rating; // // Loop through each key-value pair // keyValuePairs.forEach((pair) => { @@ -133,6 +136,8 @@ export const EditPlaylist = () => { // category = value; // } else if (key === "subcategory") { // subcategory = value; + // } else if (key === "rating") { + // rating = value; // } // }); @@ -146,6 +151,11 @@ export const EditPlaylist = () => { // setSelectedCategoryVideos(selectedOption || null); // } + // if(rating){ + // const selectedOption = ratings.find((option) => option.id === +rating); + // setSelectedRatingVideos(selectedOption || null); + // } + // } // }, [editVideoProperties]); @@ -206,6 +216,13 @@ export const EditPlaylist = () => { setSelectedSubCategoryVideos(selectedOption || null); } + if (editVideoProperties?.rating) { + const selectedOption = ratings.find( + option => option.id === +editVideoProperties.rating + ); + setSelectedRatingVideos(selectedOption || null); + } + if (editVideoProperties?.videos) { checkforPlaylist(editVideoProperties?.videos); } @@ -219,6 +236,7 @@ export const EditPlaylist = () => { setPlaylistData(null); setSelectedCategoryVideos(null); setSelectedSubCategoryVideos(null); + setSelectedRatingVideos(null); setCoverImage(""); dispatch(setEditPlaylist(null)); }; @@ -229,6 +247,7 @@ export const EditPlaylist = () => { if (!description) throw new Error("Please enter a description"); if (!coverImage) throw new Error("Please select cover image"); if (!selectedCategoryVideos) throw new Error("Please select a category"); + if (!selectedRatingVideos) throw new Error("Please select a rating"); if (!editVideoProperties) return; if (!userAddress) throw new Error("Unable to locate user address"); @@ -257,6 +276,7 @@ export const EditPlaylist = () => { } const category = selectedCategoryVideos.id; const subcategory = selectedSubCategoryVideos?.id || ""; + const rating = selectedRatingVideos.id; const videoStructured = playlistData.videos.map(item => { const descriptionVid = item?.metadata?.description; @@ -303,6 +323,7 @@ export const EditPlaylist = () => { commentsId: commentsId, category, subcategory, + rating, }; const codes = videoStructured @@ -310,8 +331,8 @@ export const EditPlaylist = () => { .slice(0, 10) .join(""); let metadescription = - `**category:${category};subcategory:${subcategory};${codes}**` + - stringDescription.slice(0, 120); + `**category:${category};subcategory:${subcategory};rating:${rating};${codes}**` + + stringDescription.slice(0, 110); const crowdfundObjectToBase64 = await objectToBase64(playlistObject); // Description is obtained from raw data @@ -417,6 +438,13 @@ export const EditPlaylist = () => { ); setSelectedSubCategoryVideos(selectedOption || null); }; + const handleOptionRatingChangeVideos = ( + event: SelectChangeEvent + ) => { + const optionId = event.target.value; + const selectedOption = ratings.find(option => option.id === +optionId); + setSelectedRatingVideos(selectedOption || null); + }; const removeVideo = index => { const copyData = structuredClone(playlistData); @@ -497,6 +525,21 @@ export const EditPlaylist = () => { )} + + Select a Rating + + {!coverImage ? ( diff --git a/src/components/Publish/EditVideo/EditVideo.tsx b/src/components/Publish/EditVideo/EditVideo.tsx index a5fa0cc..785a471 100644 --- a/src/components/Publish/EditVideo/EditVideo.tsx +++ b/src/components/Publish/EditVideo/EditVideo.tsx @@ -47,6 +47,7 @@ import { } from "../../../state/features/videoSlice.ts"; import ImageUploader from "../../common/ImageUploader.tsx"; import { categories, subCategories } from "../../../constants/Categories.ts"; +import { ratings } from "../../../constants/Ratings.ts"; import { MultiplePublish } from "../MultiplePublish/MultiplePublishAll.tsx"; import { TextEditor } from "../../common/TextEditor/TextEditor.tsx"; import { extractTextFromHTML } from "../../common/TextEditor/utils.ts"; @@ -96,6 +97,8 @@ export const EditVideo = () => { useState(null); const [selectedSubCategoryVideos, setSelectedSubCategoryVideos] = useState(null); + const [selectedRatingVideos, setSelectedRatingVideos] = + useState(null); const [imageExtracts, setImageExtracts] = useState([]); const { getRootProps, getInputProps } = useDropzone({ @@ -148,8 +151,8 @@ export const EditVideo = () => { // // Split the extracted string into key-value pairs // const keyValuePairs = extractedString.split(";"); - // // Initialize variables to hold the category and subcategory values - // let category, subcategory; + // // Initialize variables to hold the category, subcategory, and rating values + // let category, subcategory, rating; // // Loop through each key-value pair // keyValuePairs.forEach((pair) => { @@ -160,6 +163,8 @@ export const EditVideo = () => { // category = value; // } else if (key === "subcategory") { // subcategory = value; + // } else if (key === "rating") { + // rating = value; // } // }); @@ -173,6 +178,11 @@ export const EditVideo = () => { // setSelectedCategoryVideos(selectedOption || null); // } + // if(rating){ + // const selectedOption = ratings.find((option) => option.id === +rating); + // setSelectedRatingVideos(selectedOption || null); + // } + // } // }, [editVideoProperties]); @@ -204,6 +214,13 @@ export const EditVideo = () => { ]?.find(option => option.id === +editVideoProperties.subcategory); setSelectedSubCategoryVideos(selectedOption || null); } + + if (editVideoProperties?.rating) { + const selectedOption = ratings.find( + option => option.id === +editVideoProperties.rating + ); + setSelectedRatingVideos(selectedOption || null); + } } }, [editVideoProperties]); @@ -223,6 +240,7 @@ export const EditVideo = () => { if (!description) throw new Error("Please enter a description"); if (!coverImage) throw new Error("Please select cover image"); if (!selectedCategoryVideos) throw new Error("Please select a category"); + if (!selectedRatingVideos) throw new Error("Please select a rating"); if (!editVideoProperties) return; if (!userAddress) throw new Error("Unable to locate user address"); let errorMsg = ""; @@ -251,6 +269,7 @@ export const EditVideo = () => { let listOfPublishes = []; const category = selectedCategoryVideos.id; const subcategory = selectedSubCategoryVideos?.id || ""; + const rating = selectedRatingVideos.id; const fullDescription = extractTextFromHTML(description); let fileExtension = "mp4"; @@ -282,14 +301,15 @@ export const EditVideo = () => { commentsId: editVideoProperties.commentsId, category, subcategory, + rating, code: editVideoProperties.code, videoType: file?.type || "video/mp4", filename: `${alphanumericString.trim()}.${fileExtension}`, }; let metadescription = - `**category:${category};subcategory:${subcategory};code:${editVideoProperties.code}**` + - description.slice(0, 150); + `**category:${category};subcategory:${subcategory};rating:${rating};code:${editVideoProperties.code}**` + + description.slice(0, 140); const crowdfundObjectToBase64 = await objectToBase64(videoObject); // Description is obtained from raw data @@ -374,6 +394,13 @@ export const EditVideo = () => { ); setSelectedSubCategoryVideos(selectedOption || null); }; + const handleOptionRatingChangeVideos = ( + event: SelectChangeEvent + ) => { + const optionId = event.target.value; + const selectedOption = ratings.find(option => option.id === +optionId); + setSelectedRatingVideos(selectedOption || null); + }; const onFramesExtracted = async imgs => { try { @@ -493,6 +520,21 @@ export const EditVideo = () => { )} + + Select a Rating + + {file && ( { const [playlistDescription, setPlaylistDescription] = useState(""); const [selectedCategory, setSelectedCategory] = useState(null); const [selectedSubCategory, setSelectedSubCategory] = useState(null); + const [selectedRating, setSelectedRating] = useState(null); const [selectedCategoryVideos, setSelectedCategoryVideos] = useState(null); const [selectedSubCategoryVideos, setSelectedSubCategoryVideos] = useState(null); + const [selectedRatingVideos, setSelectedRatingVideos] = + useState(null); const [playlistSetting, setPlaylistSetting] = useState(null); const [publishes, setPublishes] = useState(null); @@ -208,6 +212,7 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => { if (!playlistDescription) throw new Error("Please enter a description"); if (!playlistCoverImage) throw new Error("Please select cover image"); if (!selectedCategory) throw new Error("Please select a category"); + if (!selectedRating) throw new Error("Please select a rating"); } if (files?.length === 0) throw new Error("Please select at least one file"); @@ -248,6 +253,7 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => { : publish.description; const category = selectedCategoryVideos.id; const subcategory = selectedSubCategoryVideos?.id || ""; + const rating = selectedRatingVideos.id; const coverImage = isCheckSameCoverImage ? coverImageForAll : publish.coverImage; @@ -301,14 +307,15 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => { commentsId: `${QTUBE_VIDEO_BASE}_cm_${id}`, category, subcategory, + rating, code, videoType: file?.type || "video/mp4", filename: `${alphanumericString.trim()}.${fileExtension}`, }; let metadescription = - `**category:${category};subcategory:${subcategory};code:${code}**` + - fullDescription.slice(0, 150); + `**category:${category};subcategory:${subcategory};rating:${rating};code:${code}**` + + fullDescription.slice(0, 140); const crowdfundObjectToBase64 = await objectToBase64(videoObject); // Description is obtained from raw data @@ -347,6 +354,7 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => { const stringDescription = extractTextFromHTML(description); const category = selectedCategory.id; const subcategory = selectedSubCategory?.id || ""; + const rating = selectedRating.id; const coverImage = playlistCoverImage; const sanitizeTitle = title .replace(/[^a-zA-Z0-9\s-]/g, "") @@ -385,6 +393,7 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => { commentsId: `${QTUBE_PLAYLIST_BASE}_cm_${id}`, category, subcategory, + rating, }; const codes = videos @@ -393,8 +402,8 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => { .join(""); let metadescription = - `**category:${category};subcategory:${subcategory};${codes}**` + - stringDescription.slice(0, 120); + `**category:${category};subcategory:${subcategory};rating:${rating};${codes}**` + + stringDescription.slice(0, 110); const crowdfundObjectToBase64 = await objectToBase64(playlistObject); // Description is obtained from raw data @@ -448,8 +457,8 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => { .join(""); let metadescription = - `**category:${playlistObject.category};subcategory:${playlistObject.subcategory};${codes}**` + - playlistObject.description.slice(0, 120); + `**category:${playlistObject.category};subcategory:${playlistObject.subcategory};rating:${playlistObject.rating};${codes}**` + + playlistObject.description.slice(0, 110); const crowdfundObjectToBase64 = await objectToBase64(playlistObject); // Description is obtained from raw data @@ -531,6 +540,11 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => { ); setSelectedSubCategory(selectedOption || null); }; + const handleOptionRatingChange = (event: SelectChangeEvent) => { + const optionId = event.target.value; + const selectedOption = ratings.find(option => option.id === +optionId); + setSelectedRating(selectedOption || null); + }; const handleOptionCategoryChangeVideos = ( event: SelectChangeEvent @@ -549,6 +563,13 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => { ); setSelectedSubCategoryVideos(selectedOption || null); }; + const handleOptionRatingChangeVideos = ( + event: SelectChangeEvent + ) => { + const optionId = event.target.value; + const selectedOption = ratings.find(option => option.id === +optionId); + setSelectedRatingVideos(selectedOption || null); + }; const next = () => { try { @@ -557,6 +578,7 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => { if (files?.length === 0) throw new Error("Please select at least one file"); if (!selectedCategoryVideos) throw new Error("Please select a category"); + if (!selectedRatingVideos) throw new Error("Please select a rating"); files.forEach(file => { if (!file.title) throw new Error("Please enter a title"); if (!isCheckTitleByFile && !file.description) @@ -786,6 +808,21 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => { )} + + Select a Rating + + )} @@ -1203,6 +1240,21 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => { )} + + Select a Rating + + )} @@ -1297,8 +1349,10 @@ export const PublishVideo = ({ editId, editContent }: NewCrowdfundProps) => { setSelectedCategory(null); setCoverImageForAll(null); setSelectedSubCategory(null); + setSelectedRating(null); setSelectedCategoryVideos(null); setSelectedSubCategoryVideos(null); + setSelectedRatingVideos(null); setPlaylistSetting(null); dispatch( setNotification({ diff --git a/src/constants/Ratings.ts b/src/constants/Ratings.ts new file mode 100644 index 0000000..6487095 --- /dev/null +++ b/src/constants/Ratings.ts @@ -0,0 +1,5 @@ +export const ratings = [ + { id: 1, name: "General" }, + // Add more or edit as needed + { id: 99, name: "NSFW" }, +]; diff --git a/src/hooks/useFetchVideos.tsx b/src/hooks/useFetchVideos.tsx index d9de1db..f685d16 100644 --- a/src/hooks/useFetchVideos.tsx +++ b/src/hooks/useFetchVideos.tsx @@ -157,6 +157,7 @@ export const useFetchVideos = () => { title: video?.metadata?.title, category: video?.metadata?.category, categoryName: video?.metadata?.categoryName, + rating: video?.metadata?.rating, tags: video?.metadata?.tags || [], description: video?.metadata?.description, created: video?.created, @@ -193,6 +194,7 @@ export const useFetchVideos = () => { name?: string; category?: string; subcategory?: string; + rating?: string; keywords?: string; contentType?: ContentType; }; @@ -201,6 +203,7 @@ export const useFetchVideos = () => { name: "", category: "", subcategory: "", + rating: "", keywords: "", contentType: "videos", }; @@ -218,6 +221,7 @@ export const useFetchVideos = () => { name = "", category = "", subcategory = "", + rating = "", keywords = "", contentType = filters.contentType, }: FilterType = resetFilters ? emptyFilters : filters; @@ -247,6 +251,11 @@ export const useFetchVideos = () => { `&description=category:${category};subcategory:${subcategory}`; } } + if (rating) { + defaultUrl += (category ? ';' : '&description=') + `rating:${rating}`; + } else { + defaultUrl += (category ? ';' : '&description=') + `rating:1;`; + } if (keywords) { defaultUrl = defaultUrl + `&query=${keywords}`; } @@ -287,6 +296,7 @@ export const useFetchVideos = () => { service: video?.service, category: video?.metadata?.category, categoryName: video?.metadata?.categoryName, + rating: video?.metadata?.rating, tags: video?.metadata?.tags || [], description: video?.metadata?.description, created: video?.created, @@ -351,6 +361,7 @@ export const useFetchVideos = () => { title: video?.metadata?.title, category: video?.metadata?.category, categoryName: video?.metadata?.categoryName, + rating: video?.metadata?.rating, tags: video?.metadata?.tags || [], description: video?.metadata?.description, created: video?.created, diff --git a/src/pages/ContentPages/PlaylistContent/PlaylistContent.tsx b/src/pages/ContentPages/PlaylistContent/PlaylistContent.tsx index 2dce472..33b58b6 100644 --- a/src/pages/ContentPages/PlaylistContent/PlaylistContent.tsx +++ b/src/pages/ContentPages/PlaylistContent/PlaylistContent.tsx @@ -171,6 +171,7 @@ export const PlaylistContent = () => { title: resourceData?.metadata?.title, category: resourceData?.metadata?.category, categoryName: resourceData?.metadata?.categoryName, + rating: resourceData?.metadata?.rating, tags: resourceData?.metadata?.tags || [], description: resourceData?.metadata?.description, created: resourceData?.created, @@ -226,6 +227,7 @@ export const PlaylistContent = () => { title: resourceData?.metadata?.title, category: resourceData?.metadata?.category, categoryName: resourceData?.metadata?.categoryName, + rating: resourceData?.metadata?.rating, tags: resourceData?.metadata?.tags || [], description: resourceData?.metadata?.description, created: resourceData?.created, diff --git a/src/pages/ContentPages/VideoContent/VideoContent.tsx b/src/pages/ContentPages/VideoContent/VideoContent.tsx index 451fbb9..5524672 100644 --- a/src/pages/ContentPages/VideoContent/VideoContent.tsx +++ b/src/pages/ContentPages/VideoContent/VideoContent.tsx @@ -255,6 +255,7 @@ export const VideoContent = () => { title: resourceData?.metadata?.title, category: resourceData?.metadata?.category, categoryName: resourceData?.metadata?.categoryName, + rating: resourceData?.metadata?.rating, tags: resourceData?.metadata?.tags || [], description: resourceData?.metadata?.description, created: resourceData?.created, diff --git a/src/pages/Home/Home.tsx b/src/pages/Home/Home.tsx index 558669b..b80d6a9 100644 --- a/src/pages/Home/Home.tsx +++ b/src/pages/Home/Home.tsx @@ -31,6 +31,7 @@ import { SubtitleContainer } from "./Home-styles"; import { changeSelectedCategoryVideos, changeSelectedSubCategoryVideos, + changeSelectedRatingVideos, changefilterName, changefilterSearch, } from "../../state/features/videoSlice"; @@ -40,6 +41,7 @@ import { VideoListType, } from "../../state/features/persistSlice.ts"; import { categories, subCategories } from "../../constants/Categories.ts"; +import { ratings } from "../../constants/Ratings.ts"; import { ListSuperLikeContainer } from "../../components/common/ListSuperLikes/ListSuperLikeContainer.tsx"; import { TabContext, TabList, TabPanel } from "@mui/lab"; import VideoList from "./VideoList.tsx"; @@ -107,6 +109,13 @@ export const Home = ({ mode }: HomeProps) => { dispatch(changeSelectedSubCategoryVideos(payload)); }; + const selectedRatingVideos = useSelector( + (state: RootState) => state.video.selectedRatingVideos + ) || { id: 1, name: "General" }; + const setSelectedRatingVideos = payload => { + dispatch(changeSelectedRatingVideos(payload)); + }; + const dispatch = useDispatch(); const filteredVideos = useSelector( (state: RootState) => state.video.filteredVideos @@ -131,6 +140,7 @@ export const Home = ({ mode }: HomeProps) => { name: filterName, category: selectedCategoryVideos?.id, subcategory: selectedSubCategoryVideos?.id, + rating: selectedRatingVideos?.id, keywords: filterSearch, contentType: filterType, }, @@ -149,6 +159,7 @@ export const Home = ({ mode }: HomeProps) => { filterName, selectedCategoryVideos, selectedSubCategoryVideos, + selectedRatingVideos, filterSearch, filterType, tabValue, @@ -172,6 +183,7 @@ export const Home = ({ mode }: HomeProps) => { name: "", category: "", subcategory: "", + rating: "", keywords: "", contentType: filterType, }, @@ -240,6 +252,7 @@ export const Home = ({ mode }: HomeProps) => { setFilterName(""); setSelectedCategoryVideos(null); setSelectedSubCategoryVideos(null); + setSelectedRatingVideos({ id: 1, name: "General" }); ReactDOM.flushSync(() => { getVideosHandler(true, true); @@ -263,6 +276,13 @@ export const Home = ({ mode }: HomeProps) => { ); setSelectedSubCategoryVideos(selectedOption || null); }; + const handleOptionRatingChangeVideos = ( + event: SelectChangeEvent + ) => { + const optionId = event.target.value; + const selectedOption = ratings.find(option => option.id === +optionId); + setSelectedRatingVideos(selectedOption || null); + }; const handleInputKeyDown = (event: any) => { if (event.key === "Enter") { @@ -444,6 +464,58 @@ export const Home = ({ mode }: HomeProps) => { + + + + + + Rating + + + + + + Videos diff --git a/src/pages/Home/VideoListComponentLevel.tsx b/src/pages/Home/VideoListComponentLevel.tsx index f84f42d..dd7fe0e 100644 --- a/src/pages/Home/VideoListComponentLevel.tsx +++ b/src/pages/Home/VideoListComponentLevel.tsx @@ -68,6 +68,7 @@ export const VideoListComponentLevel = ({ mode }: VideoListProps) => { title: video?.metadata?.title, category: video?.metadata?.category, categoryName: video?.metadata?.categoryName, + rating: video?.metadata?.rating, tags: video?.metadata?.tags || [], description: video?.metadata?.description, created: video?.created, diff --git a/src/state/features/videoSlice.ts b/src/state/features/videoSlice.ts index 19e685c..1679e7a 100644 --- a/src/state/features/videoSlice.ts +++ b/src/state/features/videoSlice.ts @@ -13,6 +13,7 @@ interface GlobalState { filterName: string; selectedCategoryVideos: any; selectedSubCategoryVideos: any; + selectedRatingVideos: any; editVideoProperties: any; editPlaylistProperties: any; filteredSubscriptionList: SubscriptionData[]; @@ -30,6 +31,7 @@ const initialState: GlobalState = { filterName: "", selectedCategoryVideos: null, selectedSubCategoryVideos: null, + selectedRatingVideos: null, editVideoProperties: null, editPlaylistProperties: null, filteredSubscriptionList: [], @@ -45,6 +47,7 @@ export interface Video { id: string; category?: string; categoryName?: string; + rating?: string; tags?: string[]; updated?: number | string; isValid?: boolean; @@ -74,6 +77,9 @@ export const videoSlice = createSlice({ changeSelectedSubCategoryVideos: (state, action) => { state.selectedSubCategoryVideos = action.payload; }, + changeSelectedRatingVideos: (state, action) => { + state.selectedRatingVideos = action.payload; + }, setCountNewVideos: (state, action) => { state.countNewVideos = action.payload; }, @@ -202,6 +208,7 @@ export const { changefilterName, changeSelectedCategoryVideos, changeSelectedSubCategoryVideos, + changeSelectedRatingVideos, blockUser, setEditVideo, setEditPlaylist,