mirror of
https://github.com/Qortal/q-tube.git
synced 2025-02-11 17:55:51 +00:00
commit
15d8146c7c
@ -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",
|
||||
});
|
||||
|
||||
|
@ -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<boolean>(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 (
|
||||
<>
|
||||
<Panel>
|
||||
<CrowdfundSubTitleRow>
|
||||
<CrowdfundSubTitle>Comments</CrowdfundSubTitle>
|
||||
</CrowdfundSubTitleRow>
|
||||
<CommentsContainer>
|
||||
{loadingComments ? (
|
||||
<NoCommentsRow>
|
||||
<CircularProgress />
|
||||
</NoCommentsRow>
|
||||
) : listComments.length === 0 ? (
|
||||
<NoCommentsRow>
|
||||
There are no comments yet. Be the first to comment!
|
||||
</NoCommentsRow>
|
||||
<></>
|
||||
) : (
|
||||
<CommentContainer>
|
||||
{structuredCommentList.map((comment: any) => {
|
||||
|
@ -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 }) => ({
|
||||
|
@ -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 => {
|
||||
|
@ -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",
|
||||
|
@ -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 (
|
||||
<>
|
||||
<Panel>
|
||||
<CrowdfundSubTitleRow>
|
||||
<CrowdfundSubTitle
|
||||
sx={{
|
||||
fontSize: "18px",
|
||||
color: "gold",
|
||||
}}
|
||||
>
|
||||
Super Likes
|
||||
</CrowdfundSubTitle>
|
||||
</CrowdfundSubTitleRow>
|
||||
<CommentsContainer>
|
||||
{loadingComments || loadingSuperLikes ? (
|
||||
<NoCommentsRow>
|
||||
<CircularProgress />
|
||||
</NoCommentsRow>
|
||||
) : listComments.length === 0 ? (
|
||||
<NoCommentsRow>
|
||||
There are no super likes yet. Be the first!
|
||||
</NoCommentsRow>
|
||||
<></>
|
||||
) : (
|
||||
<CommentContainer>
|
||||
{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 = ({
|
||||
<LoadMoreCommentsButtonRow>
|
||||
<LoadMoreCommentsButton
|
||||
onClick={() => {
|
||||
getMore();
|
||||
if (getMore) getMore();
|
||||
}}
|
||||
variant="contained"
|
||||
size="small"
|
||||
|
@ -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<refType, VideoPlayerProps>(
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
const [showControlsFullScreen, setShowControlsFullScreen] =
|
||||
useState<boolean>(true);
|
||||
const [videoObjectFit, setVideoObjectFit] = useState<StretchVideoType>(
|
||||
persistSelector.stretchVideoSetting
|
||||
);
|
||||
|
||||
const videoPlaying = useSelector(
|
||||
(state: RootState) => state.global.videoPlaying
|
||||
);
|
||||
@ -597,10 +605,21 @@ export const VideoPlayer = React.forwardRef<refType, VideoPlayerProps>(
|
||||
}
|
||||
};
|
||||
|
||||
const toggleStretchVideoSetting = () => {
|
||||
const newStretchVideoSetting =
|
||||
persistSelector.stretchVideoSetting === "contain" ? "fill" : "contain";
|
||||
|
||||
setVideoObjectFit(newStretchVideoSetting);
|
||||
dispatch(setStretchVideoSetting(newStretchVideoSetting));
|
||||
};
|
||||
const keyboardShortcutsDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
|
||||
e.preventDefault();
|
||||
|
||||
switch (e.key) {
|
||||
case "o":
|
||||
toggleStretchVideoSetting();
|
||||
break;
|
||||
|
||||
case Key.Add:
|
||||
increaseSpeed(false);
|
||||
break;
|
||||
@ -825,7 +844,7 @@ export const VideoPlayer = React.forwardRef<refType, VideoPlayerProps>(
|
||||
startPlay
|
||||
? {
|
||||
...videoStyles?.video,
|
||||
objectFit: persistSelector.stretchVideoSetting,
|
||||
objectFit: videoObjectFit,
|
||||
}
|
||||
: { height: "100%", ...videoStyles }
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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<HTMLDivElement>) => {
|
||||
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 (
|
||||
<Box
|
||||
sx={{
|
||||
@ -423,6 +434,7 @@ export const PlaylistContent = () => {
|
||||
alignItems: "center",
|
||||
flexDirection: "column",
|
||||
padding: "0px 10px",
|
||||
marginLeft: "5%",
|
||||
}}
|
||||
onClick={focusVideo}
|
||||
>
|
||||
@ -492,7 +504,6 @@ export const PlaylistContent = () => {
|
||||
gridTemplateColumns: "1fr 1fr",
|
||||
}}
|
||||
>
|
||||
{" "}
|
||||
<Box>
|
||||
<StyledCardHeaderComment
|
||||
sx={{
|
||||
@ -627,108 +638,104 @@ export const PlaylistContent = () => {
|
||||
)}
|
||||
|
||||
<Spacer height="30px" />
|
||||
<Box
|
||||
sx={{
|
||||
background: "#333333",
|
||||
borderRadius: "5px",
|
||||
padding: "5px",
|
||||
width: "100%",
|
||||
cursor: !descriptionHeight
|
||||
? "default"
|
||||
: isExpandedDescription
|
||||
? "default"
|
||||
: "pointer",
|
||||
position: "relative",
|
||||
}}
|
||||
className={
|
||||
!descriptionHeight
|
||||
? ""
|
||||
: isExpandedDescription
|
||||
? ""
|
||||
: "hover-click"
|
||||
}
|
||||
>
|
||||
{descriptionHeight && !isExpandedDescription && (
|
||||
<Box
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: "0px",
|
||||
right: "0px",
|
||||
left: "0px",
|
||||
bottom: "0px",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onClick={() => {
|
||||
if (isExpandedDescription) return;
|
||||
setIsExpandedDescription(true);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{videoData?.fullDescription && (
|
||||
<Box
|
||||
ref={contentRef}
|
||||
sx={{
|
||||
height: !descriptionHeight
|
||||
? "auto"
|
||||
background: "#333333",
|
||||
borderRadius: "5px",
|
||||
padding: "5px",
|
||||
width: "100%",
|
||||
cursor: !descriptionHeight
|
||||
? "default"
|
||||
: isExpandedDescription
|
||||
? "auto"
|
||||
: "100px",
|
||||
overflow: "hidden",
|
||||
? "default"
|
||||
: "pointer",
|
||||
position: "relative",
|
||||
}}
|
||||
className={
|
||||
!descriptionHeight
|
||||
? ""
|
||||
: isExpandedDescription
|
||||
? ""
|
||||
: "hover-click"
|
||||
}
|
||||
>
|
||||
{videoData?.htmlDescription ? (
|
||||
<DisplayHtml html={videoData?.htmlDescription} />
|
||||
) : (
|
||||
<VideoDescription
|
||||
variant="body1"
|
||||
color="textPrimary"
|
||||
{descriptionHeight && !isExpandedDescription && (
|
||||
<Box
|
||||
sx={{
|
||||
cursor: "default",
|
||||
position: "absolute",
|
||||
top: "0px",
|
||||
right: "0px",
|
||||
left: "0px",
|
||||
bottom: "0px",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
>
|
||||
{videoData?.fullDescription}
|
||||
</VideoDescription>
|
||||
onClick={() => {
|
||||
if (isExpandedDescription) return;
|
||||
setIsExpandedDescription(true);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
{descriptionHeight && (
|
||||
<Typography
|
||||
onClick={() => {
|
||||
setIsExpandedDescription(prev => !prev);
|
||||
}}
|
||||
<Box
|
||||
ref={contentRef}
|
||||
sx={{
|
||||
fontWeight: "bold",
|
||||
fontSize: "16px",
|
||||
cursor: "pointer",
|
||||
paddingLeft: "15px",
|
||||
paddingTop: "15px",
|
||||
height: !descriptionHeight
|
||||
? "auto"
|
||||
: isExpandedDescription
|
||||
? "auto"
|
||||
: `${descriptionHeight}px`,
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{isExpandedDescription ? "Show less" : "...more"}
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
{videoData?.htmlDescription ? (
|
||||
<DisplayHtml html={videoData?.htmlDescription} />
|
||||
) : (
|
||||
<VideoDescription
|
||||
variant="body1"
|
||||
color="textPrimary"
|
||||
sx={{
|
||||
cursor: "default",
|
||||
}}
|
||||
>
|
||||
{videoData?.fullDescription}
|
||||
</VideoDescription>
|
||||
)}
|
||||
</Box>
|
||||
{descriptionHeight >= descriptionThreshold && (
|
||||
<Typography
|
||||
onClick={() => {
|
||||
setIsExpandedDescription(prev => !prev);
|
||||
}}
|
||||
sx={{
|
||||
fontWeight: "bold",
|
||||
fontSize: "16px",
|
||||
cursor: "pointer",
|
||||
paddingLeft: "15px",
|
||||
paddingTop: "15px",
|
||||
}}
|
||||
>
|
||||
{isExpandedDescription ? "Show less" : "...more"}
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{videoData?.id && videoData?.user && (
|
||||
<SuperLikesSection
|
||||
loadingSuperLikes={loadingSuperLikes}
|
||||
superlikes={superlikeList}
|
||||
postId={videoData?.id || ""}
|
||||
postName={videoData?.user || ""}
|
||||
/>
|
||||
)}
|
||||
{videoData?.id && channelName && (
|
||||
<CommentSection
|
||||
postId={videoData?.id || ""}
|
||||
postName={channelName || ""}
|
||||
/>
|
||||
)}
|
||||
</VideoPlayerContainer>
|
||||
<SuperLikesSection
|
||||
getMore={() => {}}
|
||||
loadingSuperLikes={loadingSuperLikes}
|
||||
superlikes={superlikeList}
|
||||
postId={videoData?.id || ""}
|
||||
postName={videoData?.user || ""}
|
||||
/>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "20px",
|
||||
width: "100%",
|
||||
maxWidth: "1200px",
|
||||
}}
|
||||
>
|
||||
<CommentSection
|
||||
postId={videoData?.id || ""}
|
||||
postName={channelName || ""}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
@ -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");
|
||||
}
|
||||
};
|
@ -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 }) => ({
|
||||
|
@ -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<boolean>(false);
|
||||
const [superlikeList, setSuperlikelist] = useState<any[]>([]);
|
||||
const [loadingSuperLikes, setLoadingSuperLikes] = useState<boolean>(false);
|
||||
|
||||
const { addSuperlikeRawDataGetToList } = useFetchSuperLikes();
|
||||
const containerRef = useRef<refType>(null);
|
||||
|
||||
@ -149,6 +81,8 @@ export const VideoContent = () => {
|
||||
const [descriptionHeight, setDescriptionHeight] = useState<null | number>(
|
||||
null
|
||||
);
|
||||
const [videoData, setVideoData] = useState<any>(null);
|
||||
const [isVideoLoaded, setIsVideoLoaded] = useState<boolean>(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<any>(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<HTMLDivElement>) => {
|
||||
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 (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
flexDirection: "column",
|
||||
padding: "0px 10px",
|
||||
}}
|
||||
onClick={focusVideo}
|
||||
>
|
||||
<VideoPlayerContainer
|
||||
<>
|
||||
<Box
|
||||
sx={{
|
||||
width: "55vw",
|
||||
aspectRatio: "16/9",
|
||||
display: "flex",
|
||||
marginLeft: "5%",
|
||||
flexDirection: "column",
|
||||
padding: "0px 10px",
|
||||
}}
|
||||
onClick={focusVideo}
|
||||
>
|
||||
{videoReference ? (
|
||||
<Box
|
||||
sx={{
|
||||
aspectRatio: "16/9",
|
||||
}}
|
||||
>
|
||||
<VideoPlayerContainer>
|
||||
<VideoPlayer
|
||||
name={videoReference?.name}
|
||||
service={videoReference?.service}
|
||||
@ -424,46 +363,35 @@ export const VideoContent = () => {
|
||||
video: { aspectRatio: "16 / 9" },
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</VideoPlayerContainer>
|
||||
) : isVideoLoaded ? (
|
||||
<img
|
||||
src={DeletedVideo}
|
||||
width={"70%"}
|
||||
height={"37%"}
|
||||
style={{ marginLeft: "5%" }}
|
||||
/>
|
||||
) : (
|
||||
<img src={DeletedVideo} width={"100%"} height={"100%"} />
|
||||
<Box sx={{ width: "55vw", aspectRatio: "16/9" }}></Box>
|
||||
)}
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr 1fr",
|
||||
marginTop: "15px",
|
||||
}}
|
||||
>
|
||||
<Box>
|
||||
<StyledCardHeaderComment
|
||||
sx={{
|
||||
"& .MuiCardHeader-content": {
|
||||
overflow: "hidden",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
<VideoContentContainer>
|
||||
<Box
|
||||
sx={{
|
||||
width: "80%",
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr 1fr",
|
||||
marginTop: "15px",
|
||||
}}
|
||||
>
|
||||
<Box>
|
||||
<StyledCardHeaderComment
|
||||
sx={{
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onClick={() => {
|
||||
navigate(`/channel/${channelName}`);
|
||||
"& .MuiCardHeader-content": {
|
||||
overflow: "hidden",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Avatar
|
||||
src={`/arbitrary/THUMBNAIL/${channelName}/qortal_avatar`}
|
||||
alt={`${channelName}'s avatar`}
|
||||
/>
|
||||
</Box>
|
||||
<StyledCardColComment>
|
||||
<AuthorTextComment
|
||||
color={
|
||||
theme.palette.mode === "light"
|
||||
? theme.palette.text.secondary
|
||||
: "#d6e8ff"
|
||||
}
|
||||
<Box
|
||||
sx={{
|
||||
cursor: "pointer",
|
||||
}}
|
||||
@ -471,196 +399,223 @@ export const VideoContent = () => {
|
||||
navigate(`/channel/${channelName}`);
|
||||
}}
|
||||
>
|
||||
{channelName}
|
||||
{channelName !== userName && (
|
||||
<>
|
||||
<SubscribeButton
|
||||
subscriberName={channelName}
|
||||
sx={{ marginLeft: "20px" }}
|
||||
/>
|
||||
<FollowButton
|
||||
followerName={channelName}
|
||||
sx={{ marginLeft: "20px" }}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</AuthorTextComment>
|
||||
</StyledCardColComment>
|
||||
</StyledCardHeaderComment>
|
||||
<Avatar
|
||||
src={`/arbitrary/THUMBNAIL/${channelName}/qortal_avatar`}
|
||||
alt={`${channelName}'s avatar`}
|
||||
/>
|
||||
</Box>
|
||||
<StyledCardColComment>
|
||||
<AuthorTextComment
|
||||
color={
|
||||
theme.palette.mode === "light"
|
||||
? theme.palette.text.secondary
|
||||
: "#d6e8ff"
|
||||
}
|
||||
sx={{
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onClick={() => {
|
||||
navigate(`/channel/${channelName}`);
|
||||
}}
|
||||
>
|
||||
{channelName}
|
||||
{channelName !== userName && (
|
||||
<>
|
||||
<SubscribeButton
|
||||
subscriberName={channelName}
|
||||
sx={{ marginLeft: "20px" }}
|
||||
/>
|
||||
<FollowButton
|
||||
followerName={channelName}
|
||||
sx={{ marginLeft: "20px" }}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</AuthorTextComment>
|
||||
</StyledCardColComment>
|
||||
</StyledCardHeaderComment>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
}}
|
||||
>
|
||||
{videoData && (
|
||||
<>
|
||||
<LikeAndDislike
|
||||
name={videoData?.user}
|
||||
identifier={videoData?.id}
|
||||
/>
|
||||
<SuperLike
|
||||
numberOfSuperlikes={numberOfSuperlikes}
|
||||
totalAmount={calculateAmountSuperlike}
|
||||
name={videoData?.user}
|
||||
service={videoData?.service}
|
||||
identifier={videoData?.id}
|
||||
onSuccess={val => {
|
||||
setSuperlikelist(prev => [val, ...prev]);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{videoData?.filename && (
|
||||
<FileAttachmentContainer>
|
||||
<FileAttachmentFont>Save to Disk</FileAttachmentFont>
|
||||
<FileElement
|
||||
fileInfo={{
|
||||
...videoReference,
|
||||
filename: saveAsFilename,
|
||||
mimeType: videoData?.videoType || '"video/mp4',
|
||||
}}
|
||||
title={
|
||||
videoData?.filename || videoData?.title?.slice(0, 20)
|
||||
}
|
||||
customStyles={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-end",
|
||||
}}
|
||||
>
|
||||
<DownloadIcon />
|
||||
</FileElement>
|
||||
</FileAttachmentContainer>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
marginTop: "20px",
|
||||
gap: "10px",
|
||||
}}
|
||||
>
|
||||
{videoData && (
|
||||
<>
|
||||
<LikeAndDislike
|
||||
name={videoData?.user}
|
||||
identifier={videoData?.id}
|
||||
/>
|
||||
<SuperLike
|
||||
numberOfSuperlikes={numberOfSuperlikes}
|
||||
totalAmount={calculateAmountSuperlike}
|
||||
name={videoData?.user}
|
||||
service={videoData?.service}
|
||||
identifier={videoData?.id}
|
||||
onSuccess={val => {
|
||||
setSuperlikelist(prev => [val, ...prev]);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<FileAttachmentContainer>
|
||||
<FileAttachmentFont>Save to Disk</FileAttachmentFont>
|
||||
<FileElement
|
||||
fileInfo={{
|
||||
...videoReference,
|
||||
filename: saveAsFilename,
|
||||
mimeType: videoData?.videoType || '"video/mp4',
|
||||
}}
|
||||
title={videoData?.filename || videoData?.title?.slice(0, 20)}
|
||||
customStyles={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-end",
|
||||
}}
|
||||
>
|
||||
<DownloadIcon />
|
||||
</FileElement>
|
||||
</FileAttachmentContainer>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
marginTop: "20px",
|
||||
gap: "10px",
|
||||
}}
|
||||
>
|
||||
<VideoTitle
|
||||
variant="h1"
|
||||
color="textPrimary"
|
||||
sx={{
|
||||
textAlign: "start",
|
||||
}}
|
||||
>
|
||||
{videoData?.title}
|
||||
</VideoTitle>
|
||||
</Box>
|
||||
|
||||
{videoData?.created && (
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{
|
||||
fontSize: "16px",
|
||||
}}
|
||||
color={theme.palette.text.primary}
|
||||
>
|
||||
{formatDate(videoData.created)}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
<Spacer height="30px" />
|
||||
<Box
|
||||
sx={{
|
||||
background: "#333333",
|
||||
borderRadius: "5px",
|
||||
padding: "5px",
|
||||
width: "100%",
|
||||
cursor: !descriptionHeight
|
||||
? "default"
|
||||
: isExpandedDescription
|
||||
? "default"
|
||||
: "pointer",
|
||||
position: "relative",
|
||||
}}
|
||||
className={
|
||||
!descriptionHeight ? "" : isExpandedDescription ? "" : "hover-click"
|
||||
}
|
||||
>
|
||||
{descriptionHeight && !isExpandedDescription && (
|
||||
<Box
|
||||
<VideoTitle
|
||||
variant="h1"
|
||||
color="textPrimary"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: "0px",
|
||||
right: "0px",
|
||||
left: "0px",
|
||||
bottom: "0px",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onClick={() => {
|
||||
if (isExpandedDescription) return;
|
||||
setIsExpandedDescription(true);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Box
|
||||
ref={contentRef}
|
||||
sx={{
|
||||
height: !descriptionHeight
|
||||
? "auto"
|
||||
: isExpandedDescription
|
||||
? "auto"
|
||||
: "100px",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{videoData?.htmlDescription ? (
|
||||
<DisplayHtml html={videoData?.htmlDescription} />
|
||||
) : (
|
||||
<VideoDescription
|
||||
variant="body1"
|
||||
color="textPrimary"
|
||||
sx={{
|
||||
cursor: "default",
|
||||
}}
|
||||
>
|
||||
{videoData?.fullDescription}
|
||||
</VideoDescription>
|
||||
)}
|
||||
</Box>
|
||||
{descriptionHeight && (
|
||||
<Typography
|
||||
onClick={() => {
|
||||
setIsExpandedDescription(prev => !prev);
|
||||
}}
|
||||
sx={{
|
||||
fontWeight: "bold",
|
||||
fontSize: "16px",
|
||||
cursor: "pointer",
|
||||
paddingLeft: "15px",
|
||||
paddingTop: "15px",
|
||||
textAlign: "start",
|
||||
}}
|
||||
>
|
||||
{isExpandedDescription ? "Show less" : "...more"}
|
||||
{videoData?.title}
|
||||
</VideoTitle>
|
||||
</Box>
|
||||
|
||||
{videoData?.created && (
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{
|
||||
fontSize: "16px",
|
||||
}}
|
||||
color={theme.palette.text.primary}
|
||||
>
|
||||
{formatDate(videoData.created)}
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
</VideoPlayerContainer>
|
||||
<SuperLikesSection
|
||||
/* eslint-disable-next-line @typescript-eslint/no-empty-function */
|
||||
getMore={() => {}}
|
||||
loadingSuperLikes={loadingSuperLikes}
|
||||
superlikes={superlikeList}
|
||||
postId={id || ""}
|
||||
postName={channelName || ""}
|
||||
/>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "20px",
|
||||
width: "100%",
|
||||
maxWidth: "1200px",
|
||||
}}
|
||||
>
|
||||
<CommentSection postId={id || ""} postName={channelName || ""} />
|
||||
<Spacer height="30px" />
|
||||
{videoData?.fullDescription && (
|
||||
<Box
|
||||
sx={{
|
||||
background: "#333333",
|
||||
borderRadius: "5px",
|
||||
padding: "5px",
|
||||
width: "70%",
|
||||
cursor: !descriptionHeight
|
||||
? "default"
|
||||
: isExpandedDescription
|
||||
? "default"
|
||||
: "pointer",
|
||||
position: "relative",
|
||||
|
||||
marginBottom: "30px",
|
||||
}}
|
||||
className={
|
||||
!descriptionHeight
|
||||
? ""
|
||||
: isExpandedDescription
|
||||
? ""
|
||||
: "hover-click"
|
||||
}
|
||||
>
|
||||
{descriptionHeight && !isExpandedDescription && (
|
||||
<Box
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: "0px",
|
||||
right: "0px",
|
||||
left: "0px",
|
||||
bottom: "0px",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onClick={() => {
|
||||
if (isExpandedDescription) return;
|
||||
setIsExpandedDescription(true);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Box
|
||||
ref={contentRef}
|
||||
sx={{
|
||||
height: !descriptionHeight
|
||||
? "auto"
|
||||
: isExpandedDescription
|
||||
? "auto"
|
||||
: "200px",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{videoData?.htmlDescription ? (
|
||||
<DisplayHtml html={videoData?.htmlDescription} />
|
||||
) : (
|
||||
<VideoDescription
|
||||
variant="body1"
|
||||
color="textPrimary"
|
||||
sx={{
|
||||
cursor: "default",
|
||||
}}
|
||||
>
|
||||
{videoData?.fullDescription}
|
||||
</VideoDescription>
|
||||
)}
|
||||
</Box>
|
||||
{descriptionHeight >= descriptionThreshold && (
|
||||
<Typography
|
||||
onClick={() => {
|
||||
setIsExpandedDescription(prev => !prev);
|
||||
}}
|
||||
sx={{
|
||||
fontWeight: "bold",
|
||||
fontSize: "16px",
|
||||
cursor: "pointer",
|
||||
paddingLeft: "15px",
|
||||
paddingTop: "15px",
|
||||
}}
|
||||
>
|
||||
{isExpandedDescription ? "Show less" : "...more"}
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{id && channelName && (
|
||||
<>
|
||||
<SuperLikesSection
|
||||
/* eslint-disable-next-line @typescript-eslint/no-empty-function */
|
||||
getMore={() => {}}
|
||||
loadingSuperLikes={loadingSuperLikes}
|
||||
superlikes={superlikeList}
|
||||
postId={id || ""}
|
||||
postName={channelName || ""}
|
||||
/>
|
||||
<CommentSection postId={id || ""} postName={channelName || ""} />
|
||||
</>
|
||||
)}
|
||||
</VideoContentContainer>
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -77,6 +77,7 @@ export const persistSlice = createSlice({
|
||||
|
||||
export const {
|
||||
setHomePageSelectedTab,
|
||||
setStretchVideoSetting,
|
||||
subscribe,
|
||||
unSubscribe,
|
||||
setReduxPlaybackRate,
|
||||
|
@ -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<Props> = ({ children, setTheme }) => {
|
||||
];
|
||||
validCount++;
|
||||
}
|
||||
} catch (error) {}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -194,7 +196,6 @@ const GlobalWrapper: React.FC<Props> = ({ children, setTheme }) => {
|
||||
dispatch(setSuperlikesAll(comments));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
}
|
||||
}, []);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user