forked from Qortal/q-share
Added FollowButton.tsx
This commit is contained in:
@@ -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`,
|
||||
};
|
||||
|
||||
163
src/components/common/FollowButton.tsx
Normal file
163
src/components/common/FollowButton.tsx
Normal 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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user