Added FollowButton.tsx

This commit is contained in:
2025-06-26 15:34:11 -06:00
parent be77d225d4
commit b593efe7f2
4 changed files with 180 additions and 8 deletions

View File

@@ -221,10 +221,10 @@ export const PublishFile = ({ editId, editContent }: NewCrowdfundProps) => {
action: "PUBLISH_QDN_RESOURCE",
name: name,
service: "DOCUMENT",
identifier: identifier + "_metadata",
data64: crowdfundObjectToBase64,
title: title.slice(0, 50),
description: metadescription,
identifier: identifier + "_metadata",
tag1: QSHARE_FILE_BASE,
filename: `video_metadata.json`,
};

View File

@@ -0,0 +1,163 @@
import { Box, Button, ButtonProps } from "@mui/material";
import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
import { MouseEvent, useEffect, useState } from "react";
import { styled } from "@mui/material/styles";
interface FollowButtonProps extends ButtonProps {
followerName: string;
}
const TooltipLine = styled("div")(({ theme }) => ({
fontSize: "18px",
}));
const CustomWidthTooltipStyles = styled(
({ className, ...props }: TooltipProps) => (
<Tooltip {...props} classes={{ popper: className }} />
)
)({
[`& .${tooltipClasses.tooltip}`]: {
maxWidth: 600,
},
});
const CustomTooltip = ({ title, ...props }: TooltipProps) => {
if (typeof title === "string") title = <TooltipLine>{title}</TooltipLine>;
return <CustomWidthTooltipStyles title={title} {...props} />;
};
export const FollowButton = ({ followerName, ...props }: FollowButtonProps) => {
const [followingList, setFollowingList] = useState<string[]>([]);
const [followingSize, setFollowingSize] = useState<string>("");
const [followingItemCount, setFollowingItemCount] = useState<string>("");
const isFollowingName = () => {
return followingList.includes(followerName);
};
useEffect(() => {
qortalRequest({
action: "GET_LIST_ITEMS",
list_name: "followedNames",
}).then(followList => {
setFollowingList(followList);
});
getFollowSize();
}, []);
const followName = () => {
if (followingList.includes(followerName) === false) {
qortalRequest({
action: "ADD_LIST_ITEMS",
list_name: "followedNames",
items: [followerName],
}).then(response => {
if (response === false) console.log("followName failed");
else {
setFollowingList([...followingList, followerName]);
console.log("following Name: ", followerName);
}
});
}
};
const unfollowName = () => {
if (followingList.includes(followerName)) {
qortalRequest({
action: "DELETE_LIST_ITEM",
list_name: "followedNames",
items: [followerName],
}).then(response => {
if (response === false) console.log("unfollowName failed");
else {
const listWithoutName = followingList.filter(
item => followerName !== item
);
setFollowingList(listWithoutName);
console.log("unfollowing Name: ", followerName);
}
});
}
};
const manageFollow = (e: MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
e.stopPropagation();
isFollowingName() ? unfollowName() : followName();
};
const verticalPadding = "3px";
const horizontalPadding = "8px";
const buttonStyle = {
fontSize: "15px",
fontWeight: "700",
paddingTop: verticalPadding,
paddingBottom: verticalPadding,
paddingLeft: horizontalPadding,
paddingRight: horizontalPadding,
borderRadius: 28,
color: "white",
width: "96px",
height: "45px",
...props.sx,
};
const getFollowSize = () => {
qortalRequest({
action: "LIST_QDN_RESOURCES",
name: followerName,
limit: 0,
includeMetadata: false,
}).then(publishesList => {
let totalSize = 0;
let itemsCount = 0;
publishesList.map(publish => {
totalSize += +publish.size;
itemsCount++;
});
setFollowingSize(formatBytes(totalSize));
setFollowingItemCount(itemsCount.toString());
});
};
function formatBytes(bytes: number, decimals = 2) {
if (!+bytes) return "0 Bytes";
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
}
const tooltipTitle = followingSize && (
<>
<TooltipLine>
Following a name automatically downloads all of its content to your
node. The more followers a name has, the faster its content will
download for everyone.
</TooltipLine>
<br />
<TooltipLine>{`${followerName}'s Current Download Size: ${followingSize}`}</TooltipLine>
<TooltipLine>{`Number of Files: ${followingItemCount}`}</TooltipLine>
</>
);
return (
<>
<CustomTooltip title={tooltipTitle} placement={"top"} arrow>
<Button
{...props}
variant={"contained"}
color="success"
sx={buttonStyle}
onClick={e => manageFollow(e)}
>
{isFollowingName() ? "Unfollow" : "Follow"}
</Button>
</CustomTooltip>
</>
);
};

View File

@@ -2,6 +2,7 @@ import React, { useEffect, useMemo, useRef, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate, useParams } from "react-router-dom";
import { CopyLinkButton } from "../../components/common/CopyLinkButton.tsx";
import { FollowButton } from "../../components/common/FollowButton.tsx";
import { fontSizeMedium } from "../../constants/Misc.ts";
import { setIsLoadingGlobal } from "../../state/features/globalSlice";
import { Avatar, Box, Typography, useTheme } from "@mui/material";
@@ -40,7 +41,8 @@ import {
getIconsFromObject,
} from "../../constants/Categories/CategoryFunctions.ts";
export function formatBytes(bytes, decimals = 2) {
export const formatBytes = (bytes: number | string, decimals = 2) => {
bytes = Number(bytes);
if (bytes === 0) return "0 Bytes";
const k = 1024;
@@ -50,7 +52,7 @@ export function formatBytes(bytes, decimals = 2) {
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
}
};
export const FileContent = () => {
const { name, id } = useParams();
@@ -381,6 +383,8 @@ export const FileContent = () => {
>
<StyledCardHeaderComment
sx={{
display: "flex",
gap: "20px",
"& .MuiCardHeader-content": {
overflow: "hidden",
},
@@ -403,6 +407,14 @@ export const FileContent = () => {
{name}
</AuthorTextComment>
</StyledCardColComment>
<FollowButton
sx={{ minWidth: "96px" }}
followerName={fileData?.user}
/>
<CopyLinkButton
link={`qortal://APP/Q-Share/share/${encodeURIComponent(fileData?.user)}/${encodeURIComponent(fileData?.id)}`}
tooltipTitle={`Copy page link`}
/>
</StyledCardHeaderComment>
</Box>
<Spacer height="15px" />
@@ -417,10 +429,6 @@ export const FileContent = () => {
}}
>
{categoriesDisplay}
<CopyLinkButton
link={`qortal://APP/Q-Share/share/${encodeURIComponent(fileData?.user)}/${encodeURIComponent(fileData?.id)}`}
tooltipTitle={`Copy page link`}
/>
</Box>
<Spacer height="15px" />
<Box

View File

@@ -11,12 +11,13 @@ import {
VideoUploadDate,
} from "./FileList-styles.tsx";
import EditIcon from "@mui/icons-material/Edit";
import BlockIcon from "@mui/icons-material/Block";
import {
blockUser,
setEditFile,
Video,
} from "../../state/features/fileSlice.ts";
import BlockIcon from "@mui/icons-material/Block";
import AttachFileIcon from "@mui/icons-material/AttachFile";
import { formatBytes } from "../FileContent/FileContent.tsx";
import { formatDate } from "../../utils/time.ts";