diff --git a/src/components/EditVideo/EditVideo.tsx b/src/components/EditVideo/EditVideo.tsx index 5a1f6b6..3a03fb6 100644 --- a/src/components/EditVideo/EditVideo.tsx +++ b/src/components/EditVideo/EditVideo.tsx @@ -47,7 +47,7 @@ import { } from "../../state/features/videoSlice"; import ImageUploader from "../common/ImageUploader"; import { QTUBE_VIDEO_BASE, categories, subCategories } from "../../constants"; -import { MultiplePublish } from "../common/MultiplePublish/MultiplePublish"; +import { MultiplePublish } from "../common/MultiplePublish/MultiplePublishAll"; import { TextEditor } from "../common/TextEditor/TextEditor"; import { extractTextFromHTML } from "../common/TextEditor/utils"; import { toBase64 } from "../UploadVideo/UploadVideo"; @@ -81,7 +81,7 @@ export const EditVideo = () => { const editVideoProperties = useSelector( (state: RootState) => state.video.editVideoProperties ); - const [publishes, setPublishes] = useState([]); + const [publishes, setPublishes] = useState(null); const [isOpenMultiplePublish, setIsOpenMultiplePublish] = useState(false); const [videoPropertiesToSetToRedux, setVideoPropertiesToSetToRedux] = useState(null); @@ -325,7 +325,11 @@ export const EditVideo = () => { listOfPublishes.push(requestBodyVideo); } - setPublishes(listOfPublishes); + const multiplePublish = { + action: "PUBLISH_MULTIPLE_QDN_RESOURCES", + resources: [...listOfPublishes], + }; + setPublishes(multiplePublish); setIsOpenMultiplePublish(true); setVideoPropertiesToSetToRedux({ ...editVideoProperties, @@ -599,6 +603,18 @@ export const EditVideo = () => { {isOpenMultiplePublish && ( { + setIsOpenMultiplePublish(false); + setPublishes(null) + if(messageNotification){ + dispatch( + setNotification({ + msg: messageNotification, + alertType: 'error' + }) + ) + } + }} onSubmit={() => { setIsOpenMultiplePublish(false); const clonedCopy = structuredClone(videoPropertiesToSetToRedux); diff --git a/src/components/UploadVideo/UploadVideo.tsx b/src/components/UploadVideo/UploadVideo.tsx index c281090..4a1fa5c 100644 --- a/src/components/UploadVideo/UploadVideo.tsx +++ b/src/components/UploadVideo/UploadVideo.tsx @@ -51,7 +51,7 @@ import { categories, subCategories, } from "../../constants"; -import { MultiplePublish } from "../common/MultiplePublish/MultiplePublish"; +import { MultiplePublish } from "../common/MultiplePublish/MultiplePublishAll"; import { CrowdfundSubTitle, CrowdfundSubTitleRow, @@ -124,7 +124,7 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => { useState(null); const [playlistSetting, setPlaylistSetting] = useState(null); - const [publishes, setPublishes] = useState([]); + const [publishes, setPublishes] = useState(null); const [isCheckTitleByFile, setIsCheckTitleByFile] = useState(false) const [isCheckSameCoverImage, setIsCheckSameCoverImage] = useState(false) const [isCheckDescriptionIsTitle, setIsCheckDescriptionIsTitle] = useState(false) @@ -456,8 +456,11 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => { throw new Error("cannot get playlist data"); } } - - setPublishes(listOfPublishes); + const multiplePublish = { + action: "PUBLISH_MULTIPLE_QDN_RESOURCES", + resources: [...listOfPublishes], + }; + setPublishes(multiplePublish); setIsOpenMultiplePublish(true); } catch (error: any) { let notificationObj: any = null; @@ -1206,6 +1209,18 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => { {isOpenMultiplePublish && ( { + setIsOpenMultiplePublish(false); + setPublishes(null) + if(messageNotification){ + dispatch( + setNotification({ + msg: messageNotification, + alertType: 'error' + }) + ) + } + }} onSubmit={() => { setIsOpenMultiplePublish(false); setIsOpen(false); diff --git a/src/components/common/ListSuperLikes/ListSuperLikes.tsx b/src/components/common/ListSuperLikes/ListSuperLikes.tsx index 2c9806a..8c3a46b 100644 --- a/src/components/common/ListSuperLikes/ListSuperLikes.tsx +++ b/src/components/common/ListSuperLikes/ListSuperLikes.tsx @@ -70,7 +70,7 @@ export default function ListSuperLikes({ superlikes }) { }}> { - const theme = useTheme(); - const listOfSuccessfulPublishesRef = useRef([]) - const [listOfSuccessfulPublishes, setListOfSuccessfulPublishes] = useState< - any[] - >([]); - const [currentlyInPublish, setCurrentlyInPublish] = useState(null); - const hasStarted = useRef(false); - const publish = useCallback(async (pub: any) => { - await qortalRequest(pub); - }, []); - const [isPublishing, setIsPublishing] = useState(true) - - const handlePublish = useCallback( - async (pub: any) => { - try { - setCurrentlyInPublish(pub?.identifier); - - await publish(pub); - - setListOfSuccessfulPublishes((prev: any) => [...prev, pub?.identifier]); - listOfSuccessfulPublishesRef.current = [...listOfSuccessfulPublishesRef.current, pub?.identifier] - } catch (error) { - console.log({ error }); - await new Promise((res) => { - setTimeout(() => { - res(); - }, 5000); - }); - // await handlePublish(pub); - } - }, - [publish] - ); - - const startPublish = useCallback( - async (pubs: any) => { - setIsPublishing(true) - const filterPubs = pubs.filter((pub)=> !listOfSuccessfulPublishesRef.current.includes(pub.identifier)) - for (const pub of filterPubs) { - await handlePublish(pub); - - } - - if(listOfSuccessfulPublishesRef.current.length === pubs.length){ - onSubmit() - } - setIsPublishing(false) - }, - [handlePublish, onSubmit, listOfSuccessfulPublishes, publishes] - ); - - useEffect(() => { - if (publishes && !hasStarted.current) { - hasStarted.current = true; - startPublish(publishes); - } - }, [startPublish, publishes, listOfSuccessfulPublishes]); - - - return ( - - - {publishes.map((publish: any) => { - return ( - - {publish?.title} - {publish?.identifier === currentlyInPublish ? ( - - ) : listOfSuccessfulPublishes.includes(publish.identifier) ? ( - - ) : ( - - )} - - ); - })} - {!isPublishing && listOfSuccessfulPublishes.length !== publishes.length && ( - <> - Some files were not published. Please try again. It's important that all the files get published. Maybe wait a couple minutes if the error keeps occurring - - - )} - - - - ); -}; diff --git a/src/components/common/MultiplePublish/MultiplePublishAll.tsx b/src/components/common/MultiplePublish/MultiplePublishAll.tsx new file mode 100644 index 0000000..bba4059 --- /dev/null +++ b/src/components/common/MultiplePublish/MultiplePublishAll.tsx @@ -0,0 +1,211 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { + Box, + Button, + CircularProgress, + Modal, + Typography, + useTheme, +} from "@mui/material"; +import React, { useCallback, useEffect, useState, useRef } from "react"; +import { CircleSVG } from "../../../assets/svgs/CircleSVG"; +import { EmptyCircleSVG } from "../../../assets/svgs/EmptyCircleSVG"; +import { styled } from "@mui/system"; + +interface Publish { + resources: any[]; + action: string; +} + +interface MultiplePublishProps { + publishes: Publish; + isOpen: boolean; + onSubmit: ()=> void + onError: (message?: string)=> void +} +export const MultiplePublish = ({ publishes, isOpen, onSubmit, onError}: MultiplePublishProps) => { + const theme = useTheme(); + const listOfSuccessfulPublishesRef = useRef([]) + const [listOfSuccessfulPublishes, setListOfSuccessfulPublishes] = useState< + any[] + >([]); + const [listOfUnsuccessfulPublishes, setListOfUnSuccessfulPublishes] = useState< + any[] +>([]); + const [currentlyInPublish, setCurrentlyInPublish] = useState(null); + const hasStarted = useRef(false); + const publish = useCallback(async (pub: any) => { + const lengthOfResources = pub?.resources?.length + const lengthOfTimeout = lengthOfResources * 30000 + return await qortalRequestWithTimeout(pub, lengthOfTimeout); + }, []); + const [isPublishing, setIsPublishing] = useState(true) + + const handlePublish = useCallback( + async (pub: any) => { + try { + setCurrentlyInPublish(pub?.identifier); + setIsPublishing(true) + const res = await publish(pub); + + onSubmit() + setListOfUnSuccessfulPublishes([]) + + } catch (error: any) { + const unsuccessfulPublishes = error?.error?.unsuccessfulPublishes || [] + if(error?.error === 'User declined request'){ + onError() + return + } + + if(error?.error === 'The request timed out'){ + onError("The request timed out") + + return + } + + + if(unsuccessfulPublishes?.length > 0){ + setListOfUnSuccessfulPublishes(unsuccessfulPublishes) + + } + } finally { + + setIsPublishing(false) + } + }, + [publish] + ); + + const retry = ()=> { + let newlistOfMultiplePublishes: any[] = []; + listOfUnsuccessfulPublishes?.forEach((item)=> { + const findPub = publishes?.resources.find((res: any)=> res?.identifier === item.identifier) + if(findPub){ + newlistOfMultiplePublishes.push(findPub) + } + }) + const multiplePublish = { + ...publishes, + resources: newlistOfMultiplePublishes + }; + handlePublish(multiplePublish) + } + + const startPublish = useCallback( + async (pubs: any) => { + await handlePublish(pubs); + }, + [handlePublish, onSubmit, listOfSuccessfulPublishes, publishes] + ); + + useEffect(() => { + if (publishes && !hasStarted.current) { + hasStarted.current = true; + startPublish(publishes); + } + }, [startPublish, publishes, listOfSuccessfulPublishes]); + + + return ( + + + {publishes?.resources?.map((publish: any) => { + const unpublished = listOfUnsuccessfulPublishes.map(item => item?.identifier) + return ( + + {publish?.identifier} + {!isPublishing && hasStarted.current ? ( + <> + {!unpublished.includes(publish.identifier) ? ( + + ) : ( + + )} + + ): } + + + ); + })} + {!isPublishing && listOfUnsuccessfulPublishes.length > 0 && ( + <> + Some files were not published. Please try again. It's important that all the files get published. Maybe wait a couple minutes if the error keeps occurring + + + )} + + + + ); +}; + + +export const ModalBody = styled(Box)(({ theme }) => ({ + position: "absolute", + backgroundColor: theme.palette.background.default, + borderRadius: "4px", + top: "50%", + left: "50%", + transform: "translate(-50%, -50%)", + width: "75%", + maxWidth: "900px", + padding: "15px 35px", + display: "flex", + flexDirection: "column", + gap: "17px", + overflowY: "auto", + maxHeight: "95vh", + boxShadow: + theme.palette.mode === "dark" + ? "0px 4px 5px 0px hsla(0,0%,0%,0.14), 0px 1px 10px 0px hsla(0,0%,0%,0.12), 0px 2px 4px -1px hsla(0,0%,0%,0.2)" + : "rgba(99, 99, 99, 0.2) 0px 2px 8px 0px", + "&::-webkit-scrollbar-track": { + backgroundColor: theme.palette.background.paper, + }, + "&::-webkit-scrollbar-track:hover": { + backgroundColor: theme.palette.background.paper, + }, + "&::-webkit-scrollbar": { + width: "16px", + height: "10px", + backgroundColor: theme.palette.mode === "light" ? "#f6f8fa" : "#292d3e", + }, + "&::-webkit-scrollbar-thumb": { + backgroundColor: theme.palette.mode === "light" ? "#d3d9e1" : "#575757", + borderRadius: "8px", + backgroundClip: "content-box", + border: "4px solid transparent", + }, + "&::-webkit-scrollbar-thumb:hover": { + backgroundColor: theme.palette.mode === "light" ? "#b7bcc4" : "#474646", + }, +})); \ No newline at end of file diff --git a/src/components/common/SuperLike/SuperLike.tsx b/src/components/common/SuperLike/SuperLike.tsx index b8c8b08..5689fc2 100644 --- a/src/components/common/SuperLike/SuperLike.tsx +++ b/src/components/common/SuperLike/SuperLike.tsx @@ -14,7 +14,6 @@ import { Tooltip, } from "@mui/material"; import qortImg from "../../../assets/img/qort.png"; -import { MultiplePublish } from "../MultiplePublish/MultiplePublish"; import { useDispatch, useSelector } from "react-redux"; import { setNotification } from "../../../state/features/notificationsSlice"; import ShortUniqueId from "short-unique-id"; @@ -36,6 +35,7 @@ import { } from "../../UploadVideo/Upload-styles"; import { utf8ToBase64 } from "../SuperLikesList/CommentEditor"; import { RootState } from "../../../state/store"; +import { MultiplePublish } from "../MultiplePublish/MultiplePublishAll"; const uid = new ShortUniqueId({ length: 4 }); @@ -53,14 +53,14 @@ export const SuperLike = ({ const username = useSelector((state: RootState) => state.auth?.user?.name); const [isOpenMultiplePublish, setIsOpenMultiplePublish] = useState(false); - const [publishes, setPublishes] = useState([]); + const [publishes, setPublishes] = useState(null); const dispatch = useDispatch(); const resetValues = () => { setAmount(0); setComment(""); - setPublishes([]); + setPublishes(null); }; const onClose = () => { resetValues(); @@ -137,8 +137,11 @@ export const SuperLike = ({ }; listOfPublishes.push(requestBodyJson); - - setPublishes(listOfPublishes); + const multiplePublish = { + action: "PUBLISH_MULTIPLE_QDN_RESOURCES", + resources: [...listOfPublishes], + }; + setPublishes(multiplePublish); setIsOpenMultiplePublish(true); } catch (error: any) { let notificationObj: any = null; @@ -323,9 +326,21 @@ export const SuperLike = ({ - {isOpenMultiplePublish && ( + {isOpenMultiplePublish && ( { + setIsOpenMultiplePublish(false); + setPublishes(null) + if(messageNotification){ + dispatch( + setNotification({ + msg: messageNotification, + alertType: 'error' + }) + ) + } + }} onSubmit={() => { onSuccess({ name: username, diff --git a/src/pages/PlaylistContent/PlaylistContent.tsx b/src/pages/PlaylistContent/PlaylistContent.tsx index 03b3308..8c6ef2f 100644 --- a/src/pages/PlaylistContent/PlaylistContent.tsx +++ b/src/pages/PlaylistContent/PlaylistContent.tsx @@ -393,6 +393,8 @@ export const PlaylistContent = () => { getComments(videoData?.id, nameAddress); }, [getComments, videoData?.id, nameAddress]); + + return (