Browse Source

Merge pull request #35 from QortalSeth/main

Updates to User Interface
pull/36/head^2
Qortal Dev 1 month ago committed by GitHub
parent
commit
15d8146c7c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 3
      src/components/Publish/PublishVideo/PublishVideo-styles.tsx
  2. 18
      src/components/common/Comments/CommentSection.tsx
  3. 8
      src/components/common/Comments/Comments-styles.tsx
  4. 20
      src/components/common/Notifications/Notifications.tsx
  5. 6
      src/components/common/SuperLikesList/Comments-styles.tsx
  6. 24
      src/components/common/SuperLikesList/SuperLikesSection.tsx
  7. 23
      src/components/common/VideoPlayer/VideoPlayer.tsx
  8. 1
      src/pages/ContentPages/PlaylistContent/PlaylistContent-styles.tsx
  9. 221
      src/pages/ContentPages/PlaylistContent/PlaylistContent.tsx
  10. 56
      src/pages/ContentPages/VideoContent/VideoContent-functions.ts
  11. 11
      src/pages/ContentPages/VideoContent/VideoContent-styles.tsx
  12. 627
      src/pages/ContentPages/VideoContent/VideoContent.tsx
  13. 1
      src/state/features/persistSlice.ts
  14. 15
      src/wrappers/GlobalWrapper.tsx

3
src/components/Publish/PublishVideo/PublishVideo-styles.tsx

@ -175,8 +175,7 @@ export const CrowdfundTitle = styled(Typography)(({ theme }) => ({
export const CrowdfundSubTitleRow = styled(Box)({ export const CrowdfundSubTitleRow = styled(Box)({
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "center", justifyContent: "start",
width: "100%",
flexDirection: "row", flexDirection: "row",
}); });

18
src/components/common/Comments/CommentSection.tsx

@ -28,8 +28,8 @@ interface CommentSectionProps {
const Panel = styled("div")` const Panel = styled("div")`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: start;
align-items: center; align-items: start;
width: 100%; width: 100%;
padding-bottom: 10px; padding-bottom: 10px;
height: 100%; height: 100%;
@ -57,7 +57,7 @@ export const CommentSection = ({ postId, postName }: CommentSectionProps) => {
const { user } = useSelector((state: RootState) => state.auth); const { user } = useSelector((state: RootState) => state.auth);
const [newMessages, setNewMessages] = useState(0); const [newMessages, setNewMessages] = useState(0);
const [loadingComments, setLoadingComments] = useState<boolean>(false); const [loadingComments, setLoadingComments] = useState<boolean>(false);
// console.log("postId is: ", postId, " postName is: ", postName);
const onSubmit = (obj?: any, isEdit?: boolean) => { const onSubmit = (obj?: any, isEdit?: boolean) => {
if (isEdit) { if (isEdit) {
setListComments((prev: any[]) => { setListComments((prev: any[]) => {
@ -113,6 +113,7 @@ export const CommentSection = ({ postId, postName }: CommentSectionProps) => {
)}_reply_${removeBaseCommentId.slice( )}_reply_${removeBaseCommentId.slice(
-6 -6
)}&limit=0&includemetadata=false&offset=${offset}&reverse=false&excludeblocked=true`; )}&limit=0&includemetadata=false&offset=${offset}&reverse=false&excludeblocked=true`;
const response = await fetch(url, { const response = await fetch(url, {
method: "GET", method: "GET",
headers: { headers: {
@ -120,6 +121,7 @@ export const CommentSection = ({ postId, postName }: CommentSectionProps) => {
}, },
}); });
const responseData = await response.json(); const responseData = await response.json();
const comments: any[] = []; const comments: any[] = [];
for (const comment of responseData) { for (const comment of responseData) {
if (comment.identifier && comment.name) { if (comment.identifier && comment.name) {
@ -163,6 +165,9 @@ export const CommentSection = ({ postId, postName }: CommentSectionProps) => {
}, },
}); });
const responseData = await response.json(); const responseData = await response.json();
// console.log("url is: ", url);
// console.log("response is: ", responseData);
let comments: any[] = []; let comments: any[] = [];
for (const comment of responseData) { for (const comment of responseData) {
if (comment.identifier && comment.name) { if (comment.identifier && comment.name) {
@ -222,18 +227,13 @@ export const CommentSection = ({ postId, postName }: CommentSectionProps) => {
return ( return (
<> <>
<Panel> <Panel>
<CrowdfundSubTitleRow>
<CrowdfundSubTitle>Comments</CrowdfundSubTitle>
</CrowdfundSubTitleRow>
<CommentsContainer> <CommentsContainer>
{loadingComments ? ( {loadingComments ? (
<NoCommentsRow> <NoCommentsRow>
<CircularProgress /> <CircularProgress />
</NoCommentsRow> </NoCommentsRow>
) : listComments.length === 0 ? ( ) : listComments.length === 0 ? (
<NoCommentsRow> <></>
There are no comments yet. Be the first to comment!
</NoCommentsRow>
) : ( ) : (
<CommentContainer> <CommentContainer>
{structuredCommentList.map((comment: any) => { {structuredCommentList.map((comment: any) => {

8
src/components/common/Comments/Comments-styles.tsx

@ -93,7 +93,7 @@ export const StyledCardComment = styled(Typography)(({ theme }) => ({
fontWeight: 400, fontWeight: 400,
color: theme.palette.text.primary, color: theme.palette.text.primary,
fontSize: "19px", fontSize: "19px",
wordBreak: "break-word" wordBreak: "break-word",
})); }));
export const TitleText = styled(Typography)({ export const TitleText = styled(Typography)({
@ -159,7 +159,7 @@ export const BlockIconContainer = styled(Box)({
}); });
export const CommentsContainer = styled(Box)({ export const CommentsContainer = styled(Box)({
width: "90%", width: "70%",
maxWidth: "1000px", maxWidth: "1000px",
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
@ -180,7 +180,7 @@ export const CommentContainer = styled(Box)({
export const NoCommentsRow = styled(Box)({ export const NoCommentsRow = styled(Box)({
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "center", justifyContent: "start",
flex: "1", flex: "1",
padding: "10px 0px", padding: "10px 0px",
fontFamily: "Mulish", fontFamily: "Mulish",
@ -218,7 +218,7 @@ export const CommentActionButtonRow = styled(Box)({
export const CommentEditorContainer = styled(Box)({ export const CommentEditorContainer = styled(Box)({
width: "100%", width: "100%",
display: "flex", display: "flex",
justifyContent: "center", justifyContent: "start",
}); });
export const CommentDateText = styled(Typography)(({ theme }) => ({ export const CommentDateText = styled(Typography)(({ theme }) => ({

20
src/components/common/Notifications/Notifications.tsx

@ -16,15 +16,15 @@ import React, {
useState, useState,
} from "react"; } from "react";
import { useDispatch, useSelector } from "react-redux"; 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 { import {
extractSigValue, extractSigValue,
getPaymentInfo, getPaymentInfo,
isTimestampWithinRange, 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 { useNavigate } from "react-router-dom";
import localForage from "localforage"; import localForage from "localforage";
import moment from "moment"; import moment from "moment";
@ -148,7 +148,7 @@ export const Notifications = () => {
) { ) {
let urlReference = null; let urlReference = null;
try { 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 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, { const response2 = await fetch(url, {
method: "GET", method: "GET",
@ -160,7 +160,9 @@ export const Notifications = () => {
if (responseSearch.length > 0) { if (responseSearch.length > 0) {
urlReference = responseSearch[0]; urlReference = responseSearch[0];
} }
} catch (error) {} } catch (error) {
console.log(error);
}
// const url = `/arbitrary/BLOG_COMMENT/${comment.name}/${comment.identifier}`; // const url = `/arbitrary/BLOG_COMMENT/${comment.name}/${comment.identifier}`;
// const response = await fetch(url, { // const response = await fetch(url, {
// method: "GET", // method: "GET",
@ -180,7 +182,9 @@ export const Notifications = () => {
}, },
]; ];
} }
} catch (error) {} } catch (error) {
console.log(error);
}
} }
} }
setNotifications(prev => { setNotifications(prev => {

6
src/components/common/SuperLikesList/Comments-styles.tsx

@ -93,7 +93,7 @@ export const StyledCardComment = styled(Typography)(({ theme }) => ({
fontWeight: 400, fontWeight: 400,
color: theme.palette.text.primary, color: theme.palette.text.primary,
fontSize: "19px", fontSize: "19px",
wordBreak: "break-word" wordBreak: "break-word",
})); }));
export const TitleText = styled(Typography)({ export const TitleText = styled(Typography)({
@ -159,7 +159,7 @@ export const BlockIconContainer = styled(Box)({
}); });
export const CommentsContainer = styled(Box)({ export const CommentsContainer = styled(Box)({
width: "90%", width: "70%",
maxWidth: "1000px", maxWidth: "1000px",
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
@ -180,7 +180,7 @@ export const CommentContainer = styled(Box)({
export const NoCommentsRow = styled(Box)({ export const NoCommentsRow = styled(Box)({
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "center", justifyContent: "start",
flex: "1", flex: "1",
padding: "10px 0px", padding: "10px 0px",
fontFamily: "Mulish", fontFamily: "Mulish",

24
src/components/common/SuperLikesList/SuperLikesSection.tsx

@ -24,15 +24,15 @@ interface CommentSectionProps {
postId: string; postId: string;
postName: string; postName: string;
superlikes: any[]; superlikes: any[];
getMore: () => void; getMore?: () => void;
loadingSuperLikes: boolean; loadingSuperLikes: boolean;
} }
const Panel = styled("div")` const Panel = styled("div")`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: start;
align-items: center; align-items: start;
width: 100%; width: 100%;
padding-bottom: 10px; padding-bottom: 10px;
height: 100%; height: 100%;
@ -199,30 +199,18 @@ export const SuperLikesSection = ({
return ( return (
<> <>
<Panel> <Panel>
<CrowdfundSubTitleRow>
<CrowdfundSubTitle
sx={{
fontSize: "18px",
color: "gold",
}}
>
Super Likes
</CrowdfundSubTitle>
</CrowdfundSubTitleRow>
<CommentsContainer> <CommentsContainer>
{loadingComments || loadingSuperLikes ? ( {loadingComments || loadingSuperLikes ? (
<NoCommentsRow> <NoCommentsRow>
<CircularProgress /> <CircularProgress />
</NoCommentsRow> </NoCommentsRow>
) : listComments.length === 0 ? ( ) : listComments.length === 0 ? (
<NoCommentsRow> <></>
There are no super likes yet. Be the first!
</NoCommentsRow>
) : ( ) : (
<CommentContainer> <CommentContainer>
{structuredCommentList.map((comment: any) => { {structuredCommentList.map((comment: any) => {
let hasHash = false; let hasHash = false;
let message = { ...comment }; const message = { ...comment };
let hash = {}; let hash = {};
if (hashMapSuperlikes[comment?.identifier]) { if (hashMapSuperlikes[comment?.identifier]) {
message.message = message.message =
@ -249,7 +237,7 @@ export const SuperLikesSection = ({
<LoadMoreCommentsButtonRow> <LoadMoreCommentsButtonRow>
<LoadMoreCommentsButton <LoadMoreCommentsButton
onClick={() => { onClick={() => {
getMore(); if (getMore) getMore();
}} }}
variant="contained" variant="contained"
size="small" size="small"

23
src/components/common/VideoPlayer/VideoPlayer.tsx

@ -34,7 +34,11 @@ import {
VideoElement, VideoElement,
} from "./VideoPlayer-styles.ts"; } from "./VideoPlayer-styles.ts";
import CSS from "csstype"; import CSS from "csstype";
import { setReduxPlaybackRate } from "../../../state/features/persistSlice.ts"; import {
setReduxPlaybackRate,
setStretchVideoSetting,
StretchVideoType,
} from "../../../state/features/persistSlice.ts";
export interface VideoStyles { export interface VideoStyles {
videoContainer?: CSS.Properties; videoContainer?: CSS.Properties;
@ -101,6 +105,10 @@ export const VideoPlayer = React.forwardRef<refType, VideoPlayerProps>(
const [anchorEl, setAnchorEl] = useState(null); const [anchorEl, setAnchorEl] = useState(null);
const [showControlsFullScreen, setShowControlsFullScreen] = const [showControlsFullScreen, setShowControlsFullScreen] =
useState<boolean>(true); useState<boolean>(true);
const [videoObjectFit, setVideoObjectFit] = useState<StretchVideoType>(
persistSelector.stretchVideoSetting
);
const videoPlaying = useSelector( const videoPlaying = useSelector(
(state: RootState) => state.global.videoPlaying (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>) => { const keyboardShortcutsDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
e.preventDefault(); e.preventDefault();
switch (e.key) { switch (e.key) {
case "o":
toggleStretchVideoSetting();
break;
case Key.Add: case Key.Add:
increaseSpeed(false); increaseSpeed(false);
break; break;
@ -825,7 +844,7 @@ export const VideoPlayer = React.forwardRef<refType, VideoPlayerProps>(
startPlay startPlay
? { ? {
...videoStyles?.video, ...videoStyles?.video,
objectFit: persistSelector.stretchVideoSetting, objectFit: videoObjectFit,
} }
: { height: "100%", ...videoStyles } : { height: "100%", ...videoStyles }
} }

1
src/pages/ContentPages/PlaylistContent/PlaylistContent-styles.tsx

@ -2,7 +2,6 @@ import { styled } from "@mui/system";
import { Box, Grid, Typography, Checkbox } from "@mui/material"; import { Box, Grid, Typography, Checkbox } from "@mui/material";
export const VideoPlayerContainer = styled(Box)(({ theme }) => ({ export const VideoPlayerContainer = styled(Box)(({ theme }) => ({
maxWidth: "95%",
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
alignItems: "flex-start", alignItems: "flex-start",

221
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 DownloadIcon from "@mui/icons-material/Download";
import mockImg from "../../../test/mockimg.jpg"; import mockImg from "../../../test/mockimg.jpg";
import {
extractSigValue,
getPaymentInfo,
isTimestampWithinRange,
} from "../VideoContent/VideoContent-functions.ts";
import { import {
AuthorTextComment, AuthorTextComment,
FileAttachmentContainer, FileAttachmentContainer,
@ -48,11 +53,6 @@ import { DisplayHtml } from "../../../components/common/TextEditor/DisplayHtml.t
import FileElement from "../../../components/common/FileElement.tsx"; import FileElement from "../../../components/common/FileElement.tsx";
import { SuperLike } from "../../../components/common/ContentButtons/SuperLike.tsx"; import { SuperLike } from "../../../components/common/ContentButtons/SuperLike.tsx";
import { useFetchSuperLikes } from "../../../hooks/useFetchSuperLikes.tsx"; import { useFetchSuperLikes } from "../../../hooks/useFetchSuperLikes.tsx";
import {
extractSigValue,
getPaymentInfo,
isTimestampWithinRange,
} from "../VideoContent/VideoContent.tsx";
import { SuperLikesSection } from "../../../components/common/SuperLikesList/SuperLikesSection.tsx"; import { SuperLikesSection } from "../../../components/common/SuperLikesList/SuperLikesSection.tsx";
import { import {
QTUBE_VIDEO_BASE, QTUBE_VIDEO_BASE,
@ -196,6 +196,7 @@ export const PlaylistContent = () => {
setVideoData(combinedData); setVideoData(combinedData);
dispatch(addToHashMap(combinedData)); dispatch(addToHashMap(combinedData));
checkforPlaylist(name, id); checkforPlaylist(name, id);
} }
} }
@ -275,11 +276,8 @@ export const PlaylistContent = () => {
const fullId = vid ? `${vid.identifier}-${vid.name}` : undefined; const fullId = vid ? `${vid.identifier}-${vid.name}` : undefined;
const existingVideo = hashMapVideos[fullId]; const existingVideo = hashMapVideos[fullId];
if (existingVideo) { if (existingVideo) setVideoData(existingVideo);
setVideoData(existingVideo); else getVideoData(vid?.name, vid?.identifier);
} else {
getVideoData(vid?.name, vid?.identifier);
}
} }
} }
} }
@ -298,13 +296,12 @@ export const PlaylistContent = () => {
} }
}, [id, channelName]); }, [id, channelName]);
const descriptionThreshold = 200;
useEffect(() => { useEffect(() => {
if (contentRef.current) { if (contentRef.current) {
const height = contentRef.current.offsetHeight; const height = contentRef.current.offsetHeight;
if (height > 100) { if (height > descriptionThreshold)
// Assuming 100px is your threshold setDescriptionHeight(descriptionThreshold);
setDescriptionHeight(100);
}
} }
}, [videoData]); }, [videoData]);
@ -409,13 +406,27 @@ export const PlaylistContent = () => {
}, [getComments, videoData?.id, nameAddress]); }, [getComments, videoData?.id, nameAddress]);
const focusVideo = (e: React.MouseEvent<HTMLDivElement>) => { const focusVideo = (e: React.MouseEvent<HTMLDivElement>) => {
const focusRef = containerRef.current?.getContainerRef()?.current; console.log("in focusVideo");
const isCorrectTarget = e.currentTarget == e.target; const target = e.target as Element;
if (focusRef && isCorrectTarget) {
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 }); focusRef.focus({ preventScroll: true });
} }
}; };
return ( return (
<Box <Box
sx={{ sx={{
@ -423,6 +434,7 @@ export const PlaylistContent = () => {
alignItems: "center", alignItems: "center",
flexDirection: "column", flexDirection: "column",
padding: "0px 10px", padding: "0px 10px",
marginLeft: "5%",
}} }}
onClick={focusVideo} onClick={focusVideo}
> >
@ -492,7 +504,6 @@ export const PlaylistContent = () => {
gridTemplateColumns: "1fr 1fr", gridTemplateColumns: "1fr 1fr",
}} }}
> >
{" "}
<Box> <Box>
<StyledCardHeaderComment <StyledCardHeaderComment
sx={{ sx={{
@ -627,108 +638,104 @@ export const PlaylistContent = () => {
)} )}
<Spacer height="30px" /> <Spacer height="30px" />
<Box {videoData?.fullDescription && (
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);
}}
/>
)}
<Box <Box
ref={contentRef}
sx={{ sx={{
height: !descriptionHeight background: "#333333",
? "auto" borderRadius: "5px",
padding: "5px",
width: "100%",
cursor: !descriptionHeight
? "default"
: isExpandedDescription : isExpandedDescription
? "auto" ? "default"
: "100px", : "pointer",
overflow: "hidden", position: "relative",
}} }}
className={
!descriptionHeight
? ""
: isExpandedDescription
? ""
: "hover-click"
}
> >
{videoData?.htmlDescription ? ( {descriptionHeight && !isExpandedDescription && (
<DisplayHtml html={videoData?.htmlDescription} /> <Box
) : (
<VideoDescription
variant="body1"
color="textPrimary"
sx={{ sx={{
cursor: "default", position: "absolute",
top: "0px",
right: "0px",
left: "0px",
bottom: "0px",
cursor: "pointer",
}} }}
> onClick={() => {
{videoData?.fullDescription} if (isExpandedDescription) return;
</VideoDescription> setIsExpandedDescription(true);
}}
/>
)} )}
</Box> <Box
{descriptionHeight && ( ref={contentRef}
<Typography
onClick={() => {
setIsExpandedDescription(prev => !prev);
}}
sx={{ sx={{
fontWeight: "bold", height: !descriptionHeight
fontSize: "16px", ? "auto"
cursor: "pointer", : isExpandedDescription
paddingLeft: "15px", ? "auto"
paddingTop: "15px", : `${descriptionHeight}px`,
overflow: "hidden",
}} }}
> >
{isExpandedDescription ? "Show less" : "...more"} {videoData?.htmlDescription ? (
</Typography> <DisplayHtml html={videoData?.htmlDescription} />
)} ) : (
</Box> <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> </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> </Box>
); );
}; };

56
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");
}
};

11
src/pages/ContentPages/VideoContent/VideoContent-styles.tsx

@ -1,12 +1,15 @@
import { styled } from "@mui/system"; import { styled } from "@mui/system";
import { Box, Grid, Typography, Checkbox } from "@mui/material"; import { Box, Grid, Typography, Checkbox } from "@mui/material";
export const VideoPlayerContainer = styled(Box)(({ theme }) => ({ export const VideoContentContainer = styled(Box)(({ theme }) => ({
maxWidth: "95%",
width: "1000px",
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
alignItems: "flex-start", alignItems: "start",
}));
export const VideoPlayerContainer = styled(Box)(({ theme }) => ({
width: "55vw",
marginLeft: "5%",
})); }));
export const VideoTitle = styled(Typography)(({ theme }) => ({ export const VideoTitle = styled(Typography)(({ theme }) => ({

627
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, { import React, {
useState, useCallback,
useEffect,
useMemo, useMemo,
useRef, useRef,
useEffect, useState,
useCallback,
} from "react"; } from "react";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
import ResponsiveImage from "../../../components/ResponsiveImage.tsx"; import DeletedVideo from "../../../assets/img/DeletedVideo.jpg";
import { setIsLoadingGlobal } from "../../../state/features/globalSlice.ts"; import { CommentSection } from "../../../components/common/Comments/CommentSection.tsx";
import { Avatar, Box, Typography, useTheme } from "@mui/material"; 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 { import {
refType, refType,
VideoPlayer, VideoPlayer,
} from "../../../components/common/VideoPlayer/VideoPlayer.tsx"; } 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 { addToHashMap } from "../../../state/features/videoSlice.ts";
import AttachFileIcon from "@mui/icons-material/AttachFile"; import { RootState } from "../../../state/store.ts";
import DownloadIcon from "@mui/icons-material/Download"; import { formatDate } from "../../../utils/time.ts";
import DeletedVideo from "../../../assets/img/DeletedVideo.jpg"; import {
extractSigValue,
import mockImg from "../../../test/mockimg.jpg"; getPaymentInfo,
isTimestampWithinRange,
} from "./VideoContent-functions.ts";
import { import {
AuthorTextComment, AuthorTextComment,
FileAttachmentContainer, FileAttachmentContainer,
@ -29,98 +48,10 @@ import {
StyledCardColComment, StyledCardColComment,
StyledCardHeaderComment, StyledCardHeaderComment,
VideoDescription, VideoDescription,
VideoPlayerContainer, VideoContentContainer,
VideoTitle, VideoTitle,
VideoPlayerContainer,
} from "./VideoContent-styles.tsx"; } 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 = () => { export const VideoContent = () => {
const { name: channelName, id } = useParams(); const { name: channelName, id } = useParams();
@ -130,6 +61,7 @@ export const VideoContent = () => {
useState<boolean>(false); useState<boolean>(false);
const [superlikeList, setSuperlikelist] = useState<any[]>([]); const [superlikeList, setSuperlikelist] = useState<any[]>([]);
const [loadingSuperLikes, setLoadingSuperLikes] = useState<boolean>(false); const [loadingSuperLikes, setLoadingSuperLikes] = useState<boolean>(false);
const { addSuperlikeRawDataGetToList } = useFetchSuperLikes(); const { addSuperlikeRawDataGetToList } = useFetchSuperLikes();
const containerRef = useRef<refType>(null); const containerRef = useRef<refType>(null);
@ -149,6 +81,8 @@ export const VideoContent = () => {
const [descriptionHeight, setDescriptionHeight] = useState<null | number>( const [descriptionHeight, setDescriptionHeight] = useState<null | number>(
null null
); );
const [videoData, setVideoData] = useState<any>(null);
const [isVideoLoaded, setIsVideoLoaded] = useState<boolean>(false);
const userAvatarHash = useSelector( const userAvatarHash = useSelector(
(state: RootState) => state.global.userAvatarHash (state: RootState) => state.global.userAvatarHash
@ -183,8 +117,6 @@ export const VideoContent = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const theme = useTheme(); const theme = useTheme();
const [videoData, setVideoData] = useState<any>(null);
const saveAsFilename = useMemo(() => { const saveAsFilename = useMemo(() => {
// nb. we prefer to construct the local filename to use for // nb. we prefer to construct the local filename to use for
// saving, from the video "title" when possible // saving, from the video "title" when possible
@ -224,6 +156,7 @@ export const VideoContent = () => {
videoReference?.name && videoReference?.name &&
videoReference?.service videoReference?.service
) { ) {
setIsVideoLoaded(true);
return videoReference; return videoReference;
} else { } else {
return null; return null;
@ -302,13 +235,12 @@ export const VideoContent = () => {
} }
}, [id, channelName]); }, [id, channelName]);
const descriptionThreshold = 200;
useEffect(() => { useEffect(() => {
if (contentRef.current) { if (contentRef.current) {
const height = contentRef.current.offsetHeight; const height = contentRef.current.offsetHeight;
if (height > 100) { if (height > descriptionThreshold)
// Assuming 100px is your threshold setDescriptionHeight(descriptionThreshold);
setDescriptionHeight(100);
}
} }
}, [videoData]); }, [videoData]);
@ -382,35 +314,42 @@ export const VideoContent = () => {
); );
const focusVideo = (e: React.MouseEvent<HTMLDivElement>) => { const focusVideo = (e: React.MouseEvent<HTMLDivElement>) => {
const focusRef = containerRef.current?.getContainerRef()?.current; console.log("in focusVideo");
const isCorrectTarget = e.currentTarget == e.target; const target = e.target as Element;
if (focusRef && isCorrectTarget) {
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 }); focusRef.focus({ preventScroll: true });
} }
}; };
return ( return (
<Box <>
sx={{ <Box
display: "flex",
alignItems: "center",
flexDirection: "column",
padding: "0px 10px",
}}
onClick={focusVideo}
>
<VideoPlayerContainer
sx={{ sx={{
width: "55vw", display: "flex",
aspectRatio: "16/9", marginLeft: "5%",
flexDirection: "column",
padding: "0px 10px",
}} }}
onClick={focusVideo}
> >
{videoReference ? ( {videoReference ? (
<Box <VideoPlayerContainer>
sx={{
aspectRatio: "16/9",
}}
>
<VideoPlayer <VideoPlayer
name={videoReference?.name} name={videoReference?.name}
service={videoReference?.service} service={videoReference?.service}
@ -424,46 +363,35 @@ export const VideoContent = () => {
video: { aspectRatio: "16 / 9" }, 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 <VideoContentContainer>
sx={{ <Box
width: "100%", sx={{
display: "grid", width: "80%",
gridTemplateColumns: "1fr 1fr", display: "grid",
marginTop: "15px", gridTemplateColumns: "1fr 1fr",
}} marginTop: "15px",
> }}
<Box> >
<StyledCardHeaderComment <Box>
sx={{ <StyledCardHeaderComment
"& .MuiCardHeader-content": {
overflow: "hidden",
},
}}
>
<Box
sx={{ sx={{
cursor: "pointer", "& .MuiCardHeader-content": {
}} overflow: "hidden",
onClick={() => { },
navigate(`/channel/${channelName}`);
}} }}
> >
<Avatar <Box
src={`/arbitrary/THUMBNAIL/${channelName}/qortal_avatar`}
alt={`${channelName}'s avatar`}
/>
</Box>
<StyledCardColComment>
<AuthorTextComment
color={
theme.palette.mode === "light"
? theme.palette.text.secondary
: "#d6e8ff"
}
sx={{ sx={{
cursor: "pointer", cursor: "pointer",
}} }}
@ -471,196 +399,223 @@ export const VideoContent = () => {
navigate(`/channel/${channelName}`); navigate(`/channel/${channelName}`);
}} }}
> >
{channelName} <Avatar
{channelName !== userName && ( src={`/arbitrary/THUMBNAIL/${channelName}/qortal_avatar`}
<> alt={`${channelName}'s avatar`}
<SubscribeButton />
subscriberName={channelName} </Box>
sx={{ marginLeft: "20px" }} <StyledCardColComment>
/> <AuthorTextComment
<FollowButton color={
followerName={channelName} theme.palette.mode === "light"
sx={{ marginLeft: "20px" }} ? theme.palette.text.secondary
/> : "#d6e8ff"
</> }
)} sx={{
</AuthorTextComment> cursor: "pointer",
</StyledCardColComment> }}
</StyledCardHeaderComment> 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>
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
flexDirection: "row", justifyContent: "space-between",
alignItems: "center",
width: "100%",
marginTop: "20px",
gap: "10px",
}} }}
> >
{videoData && ( <VideoTitle
<> variant="h1"
<LikeAndDislike color="textPrimary"
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
sx={{ sx={{
position: "absolute", textAlign: "start",
top: "0px",
right: "0px",
left: "0px",
bottom: "0px",
cursor: "pointer",
}}
onClick={() => {
if (isExpandedDescription) return;
setIsExpandedDescription(true);
}} }}
/> >
)} {videoData?.title}
<Box </VideoTitle>
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> </Box>
{descriptionHeight && (
{videoData?.created && (
<Typography <Typography
onClick={() => { variant="h6"
setIsExpandedDescription(prev => !prev);
}}
sx={{ sx={{
fontWeight: "bold",
fontSize: "16px", fontSize: "16px",
cursor: "pointer",
paddingLeft: "15px",
paddingTop: "15px",
}} }}
color={theme.palette.text.primary}
> >
{isExpandedDescription ? "Show less" : "...more"} {formatDate(videoData.created)}
</Typography> </Typography>
)} )}
</Box>
</VideoPlayerContainer>
<SuperLikesSection
/* eslint-disable-next-line @typescript-eslint/no-empty-function */
getMore={() => {}}
loadingSuperLikes={loadingSuperLikes}
superlikes={superlikeList}
postId={id || ""}
postName={channelName || ""}
/>
<Box <Spacer height="30px" />
sx={{ {videoData?.fullDescription && (
display: "flex", <Box
gap: "20px", sx={{
width: "100%", background: "#333333",
maxWidth: "1200px", borderRadius: "5px",
}} padding: "5px",
> width: "70%",
<CommentSection postId={id || ""} postName={channelName || ""} /> 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>
</Box> </>
); );
}; };

1
src/state/features/persistSlice.ts

@ -77,6 +77,7 @@ export const persistSlice = createSlice({
export const { export const {
setHomePageSelectedTab, setHomePageSelectedTab,
setStretchVideoSetting,
subscribe, subscribe,
unSubscribe, unSubscribe,
setReduxPlaybackRate, setReduxPlaybackRate,

15
src/wrappers/GlobalWrapper.tsx

@ -6,6 +6,11 @@ import React, {
useMemo, useMemo,
} from "react"; } from "react";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import {
extractSigValue,
getPaymentInfo,
isTimestampWithinRange,
} from "../pages/ContentPages/VideoContent/VideoContent-functions.ts";
import { addUser } from "../state/features/authSlice"; import { addUser } from "../state/features/authSlice";
import NavBar from "../components/layout/Navbar/Navbar"; import NavBar from "../components/layout/Navbar/Navbar";
@ -21,11 +26,6 @@ import { RequestQueue } from "../utils/queue";
import { EditVideo } from "../components/Publish/EditVideo/EditVideo"; import { EditVideo } from "../components/Publish/EditVideo/EditVideo";
import { EditPlaylist } from "../components/Publish/EditPlaylist/EditPlaylist"; import { EditPlaylist } from "../components/Publish/EditPlaylist/EditPlaylist";
import ConsentModal from "../components/common/ConsentModal"; import ConsentModal from "../components/common/ConsentModal";
import {
extractSigValue,
getPaymentInfo,
isTimestampWithinRange,
} from "../pages/ContentPages/VideoContent/VideoContent";
import { useFetchSuperLikes } from "../hooks/useFetchSuperLikes"; import { useFetchSuperLikes } from "../hooks/useFetchSuperLikes";
import { SUPER_LIKE_BASE } from "../constants/Identifiers.ts"; import { SUPER_LIKE_BASE } from "../constants/Identifiers.ts";
import { minPriceSuperlike } from "../constants/Misc.ts"; import { minPriceSuperlike } from "../constants/Misc.ts";
@ -185,7 +185,9 @@ const GlobalWrapper: React.FC<Props> = ({ children, setTheme }) => {
]; ];
validCount++; validCount++;
} }
} catch (error) {} } catch (error) {
console.log(error);
}
} }
} }
} }
@ -194,7 +196,6 @@ const GlobalWrapper: React.FC<Props> = ({ children, setTheme }) => {
dispatch(setSuperlikesAll(comments)); dispatch(setSuperlikesAll(comments));
} catch (error) { } catch (error) {
console.error(error); console.error(error);
} finally {
} }
}, []); }, []);

Loading…
Cancel
Save