diff --git a/src/components/Publish/PublishVideo/PublishVideo-styles.tsx b/src/components/Publish/PublishVideo/PublishVideo-styles.tsx index bf3d011..ed76029 100644 --- a/src/components/Publish/PublishVideo/PublishVideo-styles.tsx +++ b/src/components/Publish/PublishVideo/PublishVideo-styles.tsx @@ -175,8 +175,7 @@ export const CrowdfundTitle = styled(Typography)(({ theme }) => ({ export const CrowdfundSubTitleRow = styled(Box)({ display: "flex", alignItems: "center", - justifyContent: "center", - width: "100%", + justifyContent: "start", flexDirection: "row", }); diff --git a/src/components/common/Comments/CommentSection.tsx b/src/components/common/Comments/CommentSection.tsx index 99f3fb0..e49dd83 100644 --- a/src/components/common/Comments/CommentSection.tsx +++ b/src/components/common/Comments/CommentSection.tsx @@ -28,8 +28,8 @@ interface CommentSectionProps { const Panel = styled("div")` display: flex; flex-direction: column; - justify-content: center; - align-items: center; + justify-content: start; + align-items: start; width: 100%; padding-bottom: 10px; height: 100%; @@ -57,7 +57,7 @@ export const CommentSection = ({ postId, postName }: CommentSectionProps) => { const { user } = useSelector((state: RootState) => state.auth); const [newMessages, setNewMessages] = useState(0); const [loadingComments, setLoadingComments] = useState(false); - + // console.log("postId is: ", postId, " postName is: ", postName); const onSubmit = (obj?: any, isEdit?: boolean) => { if (isEdit) { setListComments((prev: any[]) => { @@ -113,6 +113,7 @@ export const CommentSection = ({ postId, postName }: CommentSectionProps) => { )}_reply_${removeBaseCommentId.slice( -6 )}&limit=0&includemetadata=false&offset=${offset}&reverse=false&excludeblocked=true`; + const response = await fetch(url, { method: "GET", headers: { @@ -120,6 +121,7 @@ export const CommentSection = ({ postId, postName }: CommentSectionProps) => { }, }); const responseData = await response.json(); + const comments: any[] = []; for (const comment of responseData) { if (comment.identifier && comment.name) { @@ -163,6 +165,9 @@ export const CommentSection = ({ postId, postName }: CommentSectionProps) => { }, }); const responseData = await response.json(); + // console.log("url is: ", url); + // console.log("response is: ", responseData); + let comments: any[] = []; for (const comment of responseData) { if (comment.identifier && comment.name) { @@ -222,18 +227,13 @@ export const CommentSection = ({ postId, postName }: CommentSectionProps) => { return ( <> - - Comments - {loadingComments ? ( ) : listComments.length === 0 ? ( - - There are no comments yet. Be the first to comment! - + <> ) : ( {structuredCommentList.map((comment: any) => { diff --git a/src/components/common/Comments/Comments-styles.tsx b/src/components/common/Comments/Comments-styles.tsx index e215c9d..9cda045 100644 --- a/src/components/common/Comments/Comments-styles.tsx +++ b/src/components/common/Comments/Comments-styles.tsx @@ -93,7 +93,7 @@ export const StyledCardComment = styled(Typography)(({ theme }) => ({ fontWeight: 400, color: theme.palette.text.primary, fontSize: "19px", - wordBreak: "break-word" + wordBreak: "break-word", })); export const TitleText = styled(Typography)({ @@ -159,7 +159,7 @@ export const BlockIconContainer = styled(Box)({ }); export const CommentsContainer = styled(Box)({ - width: "90%", + width: "70%", maxWidth: "1000px", display: "flex", flexDirection: "column", @@ -180,7 +180,7 @@ export const CommentContainer = styled(Box)({ export const NoCommentsRow = styled(Box)({ display: "flex", alignItems: "center", - justifyContent: "center", + justifyContent: "start", flex: "1", padding: "10px 0px", fontFamily: "Mulish", @@ -218,7 +218,7 @@ export const CommentActionButtonRow = styled(Box)({ export const CommentEditorContainer = styled(Box)({ width: "100%", display: "flex", - justifyContent: "center", + justifyContent: "start", }); export const CommentDateText = styled(Typography)(({ theme }) => ({ diff --git a/src/components/common/Notifications/Notifications.tsx b/src/components/common/Notifications/Notifications.tsx index 2fc29c0..f964a55 100644 --- a/src/components/common/Notifications/Notifications.tsx +++ b/src/components/common/Notifications/Notifications.tsx @@ -16,15 +16,15 @@ import React, { useState, } from "react"; import { useDispatch, useSelector } from "react-redux"; -import { RootState } from "../../../state/store"; -import NotificationsIcon from "@mui/icons-material/Notifications"; -import { formatDate } from "../../../utils/time"; -import ThumbUpIcon from "@mui/icons-material/ThumbUp"; import { extractSigValue, getPaymentInfo, isTimestampWithinRange, -} from "../../../pages/ContentPages/VideoContent/VideoContent"; +} from "../../../pages/ContentPages/VideoContent/VideoContent-functions.ts"; +import { RootState } from "../../../state/store"; +import NotificationsIcon from "@mui/icons-material/Notifications"; +import { formatDate } from "../../../utils/time"; +import ThumbUpIcon from "@mui/icons-material/ThumbUp"; import { useNavigate } from "react-router-dom"; import localForage from "localforage"; import moment from "moment"; @@ -148,7 +148,7 @@ export const Notifications = () => { ) { let urlReference = null; try { - let idForUrl = extractIdValue(comment?.metadata?.description); + const idForUrl = extractIdValue(comment?.metadata?.description); const url = `/arbitrary/resources/search?mode=ALL&service=DOCUMENT&identifier=${idForUrl}&limit=1&includemetadata=false&reverse=false&excludeblocked=true&offset=0&name=${username}`; const response2 = await fetch(url, { method: "GET", @@ -160,7 +160,9 @@ export const Notifications = () => { if (responseSearch.length > 0) { urlReference = responseSearch[0]; } - } catch (error) {} + } catch (error) { + console.log(error); + } // const url = `/arbitrary/BLOG_COMMENT/${comment.name}/${comment.identifier}`; // const response = await fetch(url, { // method: "GET", @@ -180,7 +182,9 @@ export const Notifications = () => { }, ]; } - } catch (error) {} + } catch (error) { + console.log(error); + } } } setNotifications(prev => { diff --git a/src/components/common/SuperLikesList/Comments-styles.tsx b/src/components/common/SuperLikesList/Comments-styles.tsx index 0f544df..333221a 100644 --- a/src/components/common/SuperLikesList/Comments-styles.tsx +++ b/src/components/common/SuperLikesList/Comments-styles.tsx @@ -93,7 +93,7 @@ export const StyledCardComment = styled(Typography)(({ theme }) => ({ fontWeight: 400, color: theme.palette.text.primary, fontSize: "19px", - wordBreak: "break-word" + wordBreak: "break-word", })); export const TitleText = styled(Typography)({ @@ -159,7 +159,7 @@ export const BlockIconContainer = styled(Box)({ }); export const CommentsContainer = styled(Box)({ - width: "90%", + width: "70%", maxWidth: "1000px", display: "flex", flexDirection: "column", @@ -180,7 +180,7 @@ export const CommentContainer = styled(Box)({ export const NoCommentsRow = styled(Box)({ display: "flex", alignItems: "center", - justifyContent: "center", + justifyContent: "start", flex: "1", padding: "10px 0px", fontFamily: "Mulish", diff --git a/src/components/common/SuperLikesList/SuperLikesSection.tsx b/src/components/common/SuperLikesList/SuperLikesSection.tsx index fb5d6de..4ae547e 100644 --- a/src/components/common/SuperLikesList/SuperLikesSection.tsx +++ b/src/components/common/SuperLikesList/SuperLikesSection.tsx @@ -24,15 +24,15 @@ interface CommentSectionProps { postId: string; postName: string; superlikes: any[]; - getMore: () => void; + getMore?: () => void; loadingSuperLikes: boolean; } const Panel = styled("div")` display: flex; flex-direction: column; - justify-content: center; - align-items: center; + justify-content: start; + align-items: start; width: 100%; padding-bottom: 10px; height: 100%; @@ -199,30 +199,18 @@ export const SuperLikesSection = ({ return ( <> - - - Super Likes - - {loadingComments || loadingSuperLikes ? ( ) : listComments.length === 0 ? ( - - There are no super likes yet. Be the first! - + <> ) : ( {structuredCommentList.map((comment: any) => { let hasHash = false; - let message = { ...comment }; + const message = { ...comment }; let hash = {}; if (hashMapSuperlikes[comment?.identifier]) { message.message = @@ -249,7 +237,7 @@ export const SuperLikesSection = ({ { - getMore(); + if (getMore) getMore(); }} variant="contained" size="small" diff --git a/src/components/common/VideoPlayer/VideoPlayer.tsx b/src/components/common/VideoPlayer/VideoPlayer.tsx index 82e9e19..99e923b 100644 --- a/src/components/common/VideoPlayer/VideoPlayer.tsx +++ b/src/components/common/VideoPlayer/VideoPlayer.tsx @@ -34,7 +34,11 @@ import { VideoElement, } from "./VideoPlayer-styles.ts"; import CSS from "csstype"; -import { setReduxPlaybackRate } from "../../../state/features/persistSlice.ts"; +import { + setReduxPlaybackRate, + setStretchVideoSetting, + StretchVideoType, +} from "../../../state/features/persistSlice.ts"; export interface VideoStyles { videoContainer?: CSS.Properties; @@ -101,6 +105,10 @@ export const VideoPlayer = React.forwardRef( const [anchorEl, setAnchorEl] = useState(null); const [showControlsFullScreen, setShowControlsFullScreen] = useState(true); + const [videoObjectFit, setVideoObjectFit] = useState( + persistSelector.stretchVideoSetting + ); + const videoPlaying = useSelector( (state: RootState) => state.global.videoPlaying ); @@ -597,10 +605,21 @@ export const VideoPlayer = React.forwardRef( } }; + const toggleStretchVideoSetting = () => { + const newStretchVideoSetting = + persistSelector.stretchVideoSetting === "contain" ? "fill" : "contain"; + + setVideoObjectFit(newStretchVideoSetting); + dispatch(setStretchVideoSetting(newStretchVideoSetting)); + }; const keyboardShortcutsDown = (e: React.KeyboardEvent) => { e.preventDefault(); switch (e.key) { + case "o": + toggleStretchVideoSetting(); + break; + case Key.Add: increaseSpeed(false); break; @@ -825,7 +844,7 @@ export const VideoPlayer = React.forwardRef( startPlay ? { ...videoStyles?.video, - objectFit: persistSelector.stretchVideoSetting, + objectFit: videoObjectFit, } : { height: "100%", ...videoStyles } } diff --git a/src/pages/ContentPages/PlaylistContent/PlaylistContent-styles.tsx b/src/pages/ContentPages/PlaylistContent/PlaylistContent-styles.tsx index 7c3bce6..01776ab 100644 --- a/src/pages/ContentPages/PlaylistContent/PlaylistContent-styles.tsx +++ b/src/pages/ContentPages/PlaylistContent/PlaylistContent-styles.tsx @@ -2,7 +2,6 @@ import { styled } from "@mui/system"; import { Box, Grid, Typography, Checkbox } from "@mui/material"; export const VideoPlayerContainer = styled(Box)(({ theme }) => ({ - maxWidth: "95%", display: "flex", flexDirection: "column", alignItems: "flex-start", diff --git a/src/pages/ContentPages/PlaylistContent/PlaylistContent.tsx b/src/pages/ContentPages/PlaylistContent/PlaylistContent.tsx index 401b650..0c1e501 100644 --- a/src/pages/ContentPages/PlaylistContent/PlaylistContent.tsx +++ b/src/pages/ContentPages/PlaylistContent/PlaylistContent.tsx @@ -20,6 +20,11 @@ import AttachFileIcon from "@mui/icons-material/AttachFile"; import DownloadIcon from "@mui/icons-material/Download"; import mockImg from "../../../test/mockimg.jpg"; +import { + extractSigValue, + getPaymentInfo, + isTimestampWithinRange, +} from "../VideoContent/VideoContent-functions.ts"; import { AuthorTextComment, FileAttachmentContainer, @@ -48,11 +53,6 @@ import { DisplayHtml } from "../../../components/common/TextEditor/DisplayHtml.t import FileElement from "../../../components/common/FileElement.tsx"; import { SuperLike } from "../../../components/common/ContentButtons/SuperLike.tsx"; import { useFetchSuperLikes } from "../../../hooks/useFetchSuperLikes.tsx"; -import { - extractSigValue, - getPaymentInfo, - isTimestampWithinRange, -} from "../VideoContent/VideoContent.tsx"; import { SuperLikesSection } from "../../../components/common/SuperLikesList/SuperLikesSection.tsx"; import { QTUBE_VIDEO_BASE, @@ -196,6 +196,7 @@ export const PlaylistContent = () => { setVideoData(combinedData); dispatch(addToHashMap(combinedData)); + checkforPlaylist(name, id); } } @@ -275,11 +276,8 @@ export const PlaylistContent = () => { const fullId = vid ? `${vid.identifier}-${vid.name}` : undefined; const existingVideo = hashMapVideos[fullId]; - if (existingVideo) { - setVideoData(existingVideo); - } else { - getVideoData(vid?.name, vid?.identifier); - } + if (existingVideo) setVideoData(existingVideo); + else getVideoData(vid?.name, vid?.identifier); } } } @@ -298,13 +296,12 @@ export const PlaylistContent = () => { } }, [id, channelName]); + const descriptionThreshold = 200; useEffect(() => { if (contentRef.current) { const height = contentRef.current.offsetHeight; - if (height > 100) { - // Assuming 100px is your threshold - setDescriptionHeight(100); - } + if (height > descriptionThreshold) + setDescriptionHeight(descriptionThreshold); } }, [videoData]); @@ -409,13 +406,27 @@ export const PlaylistContent = () => { }, [getComments, videoData?.id, nameAddress]); const focusVideo = (e: React.MouseEvent) => { - const focusRef = containerRef.current?.getContainerRef()?.current; - const isCorrectTarget = e.currentTarget == e.target; - if (focusRef && isCorrectTarget) { + console.log("in focusVideo"); + const target = e.target as Element; + + const textTagNames = ["TEXTAREA", "P", "H[1-6]", "STRONG", "svg", "A"]; + const noText = + textTagNames.findIndex(s => { + return target?.tagName.match(s); + }) < 0; + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + const clickOnEmptySpace = !target?.onclick && noText; + + console.log("tagName is: ", target?.tagName); + + if (target == e.currentTarget || clickOnEmptySpace) { + console.log("in correctTarget"); + const focusRef = containerRef.current?.getContainerRef()?.current; focusRef.focus({ preventScroll: true }); } }; - return ( { alignItems: "center", flexDirection: "column", padding: "0px 10px", + marginLeft: "5%", }} onClick={focusVideo} > @@ -492,7 +504,6 @@ export const PlaylistContent = () => { gridTemplateColumns: "1fr 1fr", }} > - {" "} { )} - - {descriptionHeight && !isExpandedDescription && ( - { - if (isExpandedDescription) return; - setIsExpandedDescription(true); - }} - /> - )} + {videoData?.fullDescription && ( - {videoData?.htmlDescription ? ( - - ) : ( - - {videoData?.fullDescription} - + onClick={() => { + if (isExpandedDescription) return; + setIsExpandedDescription(true); + }} + /> )} - - {descriptionHeight && ( - { - setIsExpandedDescription(prev => !prev); - }} + - {isExpandedDescription ? "Show less" : "...more"} - - )} - + {videoData?.htmlDescription ? ( + + ) : ( + + {videoData?.fullDescription} + + )} + + {descriptionHeight >= descriptionThreshold && ( + { + setIsExpandedDescription(prev => !prev); + }} + sx={{ + fontWeight: "bold", + fontSize: "16px", + cursor: "pointer", + paddingLeft: "15px", + paddingTop: "15px", + }} + > + {isExpandedDescription ? "Show less" : "...more"} + + )} + + )} )} + {videoData?.id && videoData?.user && ( + + )} + {videoData?.id && channelName && ( + + )} - {}} - loadingSuperLikes={loadingSuperLikes} - superlikes={superlikeList} - postId={videoData?.id || ""} - postName={videoData?.user || ""} - /> - - - ); }; diff --git a/src/pages/ContentPages/VideoContent/VideoContent-functions.ts b/src/pages/ContentPages/VideoContent/VideoContent-functions.ts new file mode 100644 index 0000000..d313932 --- /dev/null +++ b/src/pages/ContentPages/VideoContent/VideoContent-functions.ts @@ -0,0 +1,56 @@ +export function isTimestampWithinRange(resTimestamp, resCreated) { + // Calculate the absolute difference in milliseconds + const difference = Math.abs(resTimestamp - resCreated); + + // 2 minutes in milliseconds + const twoMinutesInMilliseconds = 3 * 60 * 1000; + + // Check if the difference is within 2 minutes + return difference <= twoMinutesInMilliseconds; +} + +export function extractSigValue(metadescription) { + // Function to extract the substring within double asterisks + function extractSubstring(str) { + const match = str.match(/\*\*(.*?)\*\*/); + return match ? match[1] : null; + } + + // Function to extract the 'sig' value + function extractSig(str) { + const regex = /sig:(.*?)(;|$)/; + const match = str.match(regex); + return match ? match[1] : null; + } + + // Extracting the relevant substring + const relevantSubstring = extractSubstring(metadescription); + + if (relevantSubstring) { + // Extracting the 'sig' value + return extractSig(relevantSubstring); + } else { + return null; + } +} + +export const getPaymentInfo = async (signature: string) => { + try { + const url = `/transactions/signature/${signature}`; + const response = await fetch(url, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + // Coin payment info must be added to responseData so we can display it to the user + const responseData = await response.json(); + if (responseData && !responseData.error) { + return responseData; + } else { + throw new Error("unable to get payment"); + } + } catch (error) { + throw new Error("unable to get payment"); + } +}; diff --git a/src/pages/ContentPages/VideoContent/VideoContent-styles.tsx b/src/pages/ContentPages/VideoContent/VideoContent-styles.tsx index 42d130f..5c1794d 100644 --- a/src/pages/ContentPages/VideoContent/VideoContent-styles.tsx +++ b/src/pages/ContentPages/VideoContent/VideoContent-styles.tsx @@ -1,12 +1,15 @@ import { styled } from "@mui/system"; import { Box, Grid, Typography, Checkbox } from "@mui/material"; -export const VideoPlayerContainer = styled(Box)(({ theme }) => ({ - maxWidth: "95%", - width: "1000px", +export const VideoContentContainer = styled(Box)(({ theme }) => ({ display: "flex", flexDirection: "column", - alignItems: "flex-start", + alignItems: "start", +})); + +export const VideoPlayerContainer = styled(Box)(({ theme }) => ({ + width: "55vw", + marginLeft: "5%", })); export const VideoTitle = styled(Typography)(({ theme }) => ({ diff --git a/src/pages/ContentPages/VideoContent/VideoContent.tsx b/src/pages/ContentPages/VideoContent/VideoContent.tsx index 60d1947..22573e9 100644 --- a/src/pages/ContentPages/VideoContent/VideoContent.tsx +++ b/src/pages/ContentPages/VideoContent/VideoContent.tsx @@ -1,26 +1,45 @@ +import DownloadIcon from "@mui/icons-material/Download"; +import { Avatar, Box, Typography, useTheme } from "@mui/material"; import React, { - useState, + useCallback, + useEffect, useMemo, useRef, - useEffect, - useCallback, + useState, } from "react"; import { useDispatch, useSelector } from "react-redux"; import { useNavigate, useParams } from "react-router-dom"; -import ResponsiveImage from "../../../components/ResponsiveImage.tsx"; -import { setIsLoadingGlobal } from "../../../state/features/globalSlice.ts"; -import { Avatar, Box, Typography, useTheme } from "@mui/material"; +import DeletedVideo from "../../../assets/img/DeletedVideo.jpg"; +import { CommentSection } from "../../../components/common/Comments/CommentSection.tsx"; +import { FollowButton } from "../../../components/common/ContentButtons/FollowButton.tsx"; +import { LikeAndDislike } from "../../../components/common/ContentButtons/LikeAndDislike.tsx"; +import { SubscribeButton } from "../../../components/common/ContentButtons/SubscribeButton.tsx"; +import { SuperLike } from "../../../components/common/ContentButtons/SuperLike.tsx"; +import FileElement from "../../../components/common/FileElement.tsx"; +import { SuperLikesSection } from "../../../components/common/SuperLikesList/SuperLikesSection.tsx"; +import { DisplayHtml } from "../../../components/common/TextEditor/DisplayHtml.tsx"; import { refType, VideoPlayer, } from "../../../components/common/VideoPlayer/VideoPlayer.tsx"; -import { RootState } from "../../../state/store.ts"; +import { + QTUBE_VIDEO_BASE, + SUPER_LIKE_BASE, +} from "../../../constants/Identifiers.ts"; +import { + minPriceSuperlike, + titleFormatterOnSave, +} from "../../../constants/Misc.ts"; +import { useFetchSuperLikes } from "../../../hooks/useFetchSuperLikes.tsx"; +import { setIsLoadingGlobal } from "../../../state/features/globalSlice.ts"; import { addToHashMap } from "../../../state/features/videoSlice.ts"; -import AttachFileIcon from "@mui/icons-material/AttachFile"; -import DownloadIcon from "@mui/icons-material/Download"; -import DeletedVideo from "../../../assets/img/DeletedVideo.jpg"; - -import mockImg from "../../../test/mockimg.jpg"; +import { RootState } from "../../../state/store.ts"; +import { formatDate } from "../../../utils/time.ts"; +import { + extractSigValue, + getPaymentInfo, + isTimestampWithinRange, +} from "./VideoContent-functions.ts"; import { AuthorTextComment, FileAttachmentContainer, @@ -29,98 +48,10 @@ import { StyledCardColComment, StyledCardHeaderComment, VideoDescription, - VideoPlayerContainer, + VideoContentContainer, VideoTitle, + VideoPlayerContainer, } from "./VideoContent-styles.tsx"; -import { setUserAvatarHash } from "../../../state/features/globalSlice.ts"; -import { - formatDate, - formatDateSeconds, - formatTimestampSeconds, -} from "../../../utils/time.ts"; -import { NavbarName } from "../../../components/layout/Navbar/Navbar-styles.tsx"; -import { CommentSection } from "../../../components/common/Comments/CommentSection.tsx"; -import { - CrowdfundSubTitle, - CrowdfundSubTitleRow, -} from "../../../components/Publish/PublishVideo/PublishVideo-styles.tsx"; -import { Playlists } from "../../../components/Playlists/Playlists.tsx"; -import { DisplayHtml } from "../../../components/common/TextEditor/DisplayHtml.tsx"; -import FileElement from "../../../components/common/FileElement.tsx"; -import { SuperLike } from "../../../components/common/ContentButtons/SuperLike.tsx"; -import { CommentContainer } from "../../../components/common/Comments/Comments-styles.tsx"; -import { Comment } from "../../../components/common/Comments/Comment.tsx"; -import { SuperLikesSection } from "../../../components/common/SuperLikesList/SuperLikesSection.tsx"; -import { useFetchSuperLikes } from "../../../hooks/useFetchSuperLikes.tsx"; -import { - FOR_SUPER_LIKE, - QTUBE_VIDEO_BASE, - SUPER_LIKE_BASE, -} from "../../../constants/Identifiers.ts"; -import { - minPriceSuperlike, - titleFormatterOnSave, -} from "../../../constants/Misc.ts"; -import { SubscribeButton } from "../../../components/common/ContentButtons/SubscribeButton.tsx"; -import { FollowButton } from "../../../components/common/ContentButtons/FollowButton.tsx"; -import { LikeAndDislike } from "../../../components/common/ContentButtons/LikeAndDislike.tsx"; - -export function isTimestampWithinRange(resTimestamp, resCreated) { - // Calculate the absolute difference in milliseconds - const difference = Math.abs(resTimestamp - resCreated); - - // 2 minutes in milliseconds - const twoMinutesInMilliseconds = 3 * 60 * 1000; - - // Check if the difference is within 2 minutes - return difference <= twoMinutesInMilliseconds; -} - -export function extractSigValue(metadescription) { - // Function to extract the substring within double asterisks - function extractSubstring(str) { - const match = str.match(/\*\*(.*?)\*\*/); - return match ? match[1] : null; - } - - // Function to extract the 'sig' value - function extractSig(str) { - const regex = /sig:(.*?)(;|$)/; - const match = str.match(regex); - return match ? match[1] : null; - } - - // Extracting the relevant substring - const relevantSubstring = extractSubstring(metadescription); - - if (relevantSubstring) { - // Extracting the 'sig' value - return extractSig(relevantSubstring); - } else { - return null; - } -} - -export const getPaymentInfo = async (signature: string) => { - try { - const url = `/transactions/signature/${signature}`; - const response = await fetch(url, { - method: "GET", - headers: { - "Content-Type": "application/json", - }, - }); - // Coin payment info must be added to responseData so we can display it to the user - const responseData = await response.json(); - if (responseData && !responseData.error) { - return responseData; - } else { - throw new Error("unable to get payment"); - } - } catch (error) { - throw new Error("unable to get payment"); - } -}; export const VideoContent = () => { const { name: channelName, id } = useParams(); @@ -130,6 +61,7 @@ export const VideoContent = () => { useState(false); const [superlikeList, setSuperlikelist] = useState([]); const [loadingSuperLikes, setLoadingSuperLikes] = useState(false); + const { addSuperlikeRawDataGetToList } = useFetchSuperLikes(); const containerRef = useRef(null); @@ -149,6 +81,8 @@ export const VideoContent = () => { const [descriptionHeight, setDescriptionHeight] = useState( null ); + const [videoData, setVideoData] = useState(null); + const [isVideoLoaded, setIsVideoLoaded] = useState(false); const userAvatarHash = useSelector( (state: RootState) => state.global.userAvatarHash @@ -183,8 +117,6 @@ export const VideoContent = () => { const navigate = useNavigate(); const theme = useTheme(); - const [videoData, setVideoData] = useState(null); - const saveAsFilename = useMemo(() => { // nb. we prefer to construct the local filename to use for // saving, from the video "title" when possible @@ -224,6 +156,7 @@ export const VideoContent = () => { videoReference?.name && videoReference?.service ) { + setIsVideoLoaded(true); return videoReference; } else { return null; @@ -302,13 +235,12 @@ export const VideoContent = () => { } }, [id, channelName]); + const descriptionThreshold = 200; useEffect(() => { if (contentRef.current) { const height = contentRef.current.offsetHeight; - if (height > 100) { - // Assuming 100px is your threshold - setDescriptionHeight(100); - } + if (height > descriptionThreshold) + setDescriptionHeight(descriptionThreshold); } }, [videoData]); @@ -382,35 +314,42 @@ export const VideoContent = () => { ); const focusVideo = (e: React.MouseEvent) => { - const focusRef = containerRef.current?.getContainerRef()?.current; - const isCorrectTarget = e.currentTarget == e.target; - if (focusRef && isCorrectTarget) { + console.log("in focusVideo"); + const target = e.target as Element; + + const textTagNames = ["TEXTAREA", "P", "H[1-6]", "STRONG", "svg", "A"]; + const noText = + textTagNames.findIndex(s => { + return target?.tagName.match(s); + }) < 0; + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + const clickOnEmptySpace = !target?.onclick && noText; + + console.log("tagName is: ", target?.tagName); + // clicking on link in superlikes bar shows deleted video when loading + + if (target == e.currentTarget || clickOnEmptySpace) { + console.log("in correctTarget"); + const focusRef = containerRef.current?.getContainerRef()?.current; focusRef.focus({ preventScroll: true }); } }; return ( - - + {videoReference ? ( - + { video: { aspectRatio: "16 / 9" }, }} /> - + + ) : isVideoLoaded ? ( + ) : ( - + )} - - - - + + + { - navigate(`/channel/${channelName}`); + "& .MuiCardHeader-content": { + overflow: "hidden", + }, }} > - - - - { navigate(`/channel/${channelName}`); }} > - {channelName} - {channelName !== userName && ( - <> - - - - )} - - - + + + + { + navigate(`/channel/${channelName}`); + }} + > + {channelName} + {channelName !== userName && ( + <> + + + + )} + + + + + + {videoData && ( + <> + + { + setSuperlikelist(prev => [val, ...prev]); + }} + /> + + )} + {videoData?.filename && ( + + Save to Disk + + + + + )} + - {videoData && ( - <> - - { - setSuperlikelist(prev => [val, ...prev]); - }} - /> - - )} - - Save to Disk - - - - - - - - - {videoData?.title} - - - - {videoData?.created && ( - - {formatDate(videoData.created)} - - )} - - - - {descriptionHeight && !isExpandedDescription && ( - { - if (isExpandedDescription) return; - setIsExpandedDescription(true); + textAlign: "start", }} - /> - )} - - {videoData?.htmlDescription ? ( - - ) : ( - - {videoData?.fullDescription} - - )} + > + {videoData?.title} + - {descriptionHeight && ( + + {videoData?.created && ( { - setIsExpandedDescription(prev => !prev); - }} + variant="h6" sx={{ - fontWeight: "bold", fontSize: "16px", - cursor: "pointer", - paddingLeft: "15px", - paddingTop: "15px", }} + color={theme.palette.text.primary} > - {isExpandedDescription ? "Show less" : "...more"} + {formatDate(videoData.created)} )} - - - {}} - loadingSuperLikes={loadingSuperLikes} - superlikes={superlikeList} - postId={id || ""} - postName={channelName || ""} - /> - - + + {videoData?.fullDescription && ( + + {descriptionHeight && !isExpandedDescription && ( + { + if (isExpandedDescription) return; + setIsExpandedDescription(true); + }} + /> + )} + + {videoData?.htmlDescription ? ( + + ) : ( + + {videoData?.fullDescription} + + )} + + {descriptionHeight >= descriptionThreshold && ( + { + setIsExpandedDescription(prev => !prev); + }} + sx={{ + fontWeight: "bold", + fontSize: "16px", + cursor: "pointer", + paddingLeft: "15px", + paddingTop: "15px", + }} + > + {isExpandedDescription ? "Show less" : "...more"} + + )} + + )} + + {id && channelName && ( + <> + {}} + loadingSuperLikes={loadingSuperLikes} + superlikes={superlikeList} + postId={id || ""} + postName={channelName || ""} + /> + + + )} + - + ); }; diff --git a/src/state/features/persistSlice.ts b/src/state/features/persistSlice.ts index 1b02954..70c21b3 100644 --- a/src/state/features/persistSlice.ts +++ b/src/state/features/persistSlice.ts @@ -77,6 +77,7 @@ export const persistSlice = createSlice({ export const { setHomePageSelectedTab, + setStretchVideoSetting, subscribe, unSubscribe, setReduxPlaybackRate, diff --git a/src/wrappers/GlobalWrapper.tsx b/src/wrappers/GlobalWrapper.tsx index c80f223..29ebe83 100644 --- a/src/wrappers/GlobalWrapper.tsx +++ b/src/wrappers/GlobalWrapper.tsx @@ -6,6 +6,11 @@ import React, { useMemo, } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { + extractSigValue, + getPaymentInfo, + isTimestampWithinRange, +} from "../pages/ContentPages/VideoContent/VideoContent-functions.ts"; import { addUser } from "../state/features/authSlice"; import NavBar from "../components/layout/Navbar/Navbar"; @@ -21,11 +26,6 @@ import { RequestQueue } from "../utils/queue"; import { EditVideo } from "../components/Publish/EditVideo/EditVideo"; import { EditPlaylist } from "../components/Publish/EditPlaylist/EditPlaylist"; import ConsentModal from "../components/common/ConsentModal"; -import { - extractSigValue, - getPaymentInfo, - isTimestampWithinRange, -} from "../pages/ContentPages/VideoContent/VideoContent"; import { useFetchSuperLikes } from "../hooks/useFetchSuperLikes"; import { SUPER_LIKE_BASE } from "../constants/Identifiers.ts"; import { minPriceSuperlike } from "../constants/Misc.ts"; @@ -185,7 +185,9 @@ const GlobalWrapper: React.FC = ({ children, setTheme }) => { ]; validCount++; } - } catch (error) {} + } catch (error) { + console.log(error); + } } } } @@ -194,7 +196,6 @@ const GlobalWrapper: React.FC = ({ children, setTheme }) => { dispatch(setSuperlikesAll(comments)); } catch (error) { console.error(error); - } finally { } }, []);