diff --git a/src/common/api/hive.ts b/src/common/api/hive.ts index 5da3780c022..5085b425843 100644 --- a/src/common/api/hive.ts +++ b/src/common/api/hive.ts @@ -656,3 +656,6 @@ export const getRcOperationStats = (): Promise => client.call("rc_api", "ge export const getContentReplies = (author: string, permlink: string): Promise => client.call("condenser_api", "get_content_replies", { author, permlink }); + + export const getRebloggedUsers = async (author: string, permlink: string) => + client.call("condenser_api", "get_reblogged_by", { author, permlink }); diff --git a/src/common/components/entry-reblog-btn/_index.scss b/src/common/components/entry-reblog-btn/_index.scss index 96be1f3b9bc..00ce367cebf 100644 --- a/src/common/components/entry-reblog-btn/_index.scss +++ b/src/common/components/entry-reblog-btn/_index.scss @@ -56,4 +56,13 @@ opacity: 1; } } + +} + +.reblog-stats{ + + .reblog-count{ + color: $dark-sky-blue; + cursor: pointer; + } } diff --git a/src/common/components/entry-reblog-btn/index.tsx b/src/common/components/entry-reblog-btn/index.tsx index 3650013eb6c..fac1a04512e 100644 --- a/src/common/components/entry-reblog-btn/index.tsx +++ b/src/common/components/entry-reblog-btn/index.tsx @@ -1,5 +1,4 @@ import React from "react"; - import { Entry } from "../../store/entries/types"; import { Account } from "../../store/accounts/types"; import { User } from "../../store/users/types"; @@ -17,6 +16,8 @@ import _c from "../../util/fix-class-names"; import { repeatSvg } from "../../img/svg"; import "./_index.scss"; import { useMappedStore } from "../../store/use-mapped-store"; +import { getRebloggedUsers } from "../../api/hive"; +import EntryRebloStats from "../entry-reblog-stats"; interface Props { entry: Entry; @@ -35,11 +36,15 @@ interface Props { interface State { inProgress: boolean; + rebloggedBy: string[]; + showReblogStats: boolean; } export class EntryReblogBtn extends BaseComponent { state: State = { - inProgress: false + inProgress: false, + rebloggedBy: [], + showReblogStats: false }; componentDidMount() { @@ -50,6 +55,7 @@ export class EntryReblogBtn extends BaseComponent { // Otherwise condenser_api.get_blog_entries will be called 2 times on page load. setTimeout(fetchReblogs, 500); } + this.getReblogs() } componentDidUpdate(prevProps: Readonly) { @@ -93,9 +99,24 @@ export class EntryReblogBtn extends BaseComponent { }); }; + getReblogs = async () => { + const { entry } = this.props + this.stateSet({inProgress: true}) + const rebloggedBy = await getRebloggedUsers(entry.author, entry.permlink) + this.stateSet({rebloggedBy, inProgress: false}) + } + + showReblogs = () => { + this.stateSet({showReblogStats: true}) + } + + hideReblogs = () => { + this.stateSet({showReblogStats: false}) + } + render() { const { activeUser, entry, reblogs } = this.props; - const { inProgress } = this.state; + const { inProgress, rebloggedBy, showReblogStats } = this.state; const reblogged = entry && @@ -103,16 +124,38 @@ export class EntryReblogBtn extends BaseComponent { reblogs.list.find((x) => x.author === entry.author && x.permlink === entry.permlink) !== undefined; + const reblogStats = ( + <> +
+ 1 ? `${rebloggedBy.length} ${_t("entry-reblog.reblogs")}` : + `${rebloggedBy.length} ${_t("entry-reblog.reblog")}`} + > + + {rebloggedBy.length} + + +
+ + + ); + const content = ( -
- - {repeatSvg} - -
+
+ + {repeatSvg} + +
); if (!activeUser) { @@ -125,14 +168,19 @@ export class EntryReblogBtn extends BaseComponent { // Delete reblog if (reblogged) { return ( - - {content} - +
+ + {content} + + <> + {reblogStats} + +
); } diff --git a/src/common/components/entry-reblog-stats/index.tsx b/src/common/components/entry-reblog-stats/index.tsx new file mode 100644 index 00000000000..68fb1bb0604 --- /dev/null +++ b/src/common/components/entry-reblog-stats/index.tsx @@ -0,0 +1,88 @@ +import React, { useState } from 'react' +import { Button, Form, Modal } from 'react-bootstrap'; +import { _t } from '../../i18n'; +import ProfileLink from '../profile-link'; +import UserAvatar from '../user-avatar'; +import LinearProgress from '../linear-progress'; + +const EntryRebloStats = (props: any) => { + const limit = 30 + const { hideReblogs, showReblogStats, rebloggedBy, inProgress} = props; + const [searchedText, setSearchedText] = useState(""); + const [loadLimit, setLoadLimit] = useState(10) + + const loadMore = () => { + setLoadLimit(prev => prev + limit) + } + + const reblogLists = ( + <> + {inProgress && } +
+
+ {rebloggedBy.length > 0 + ? rebloggedBy?.slice(0, loadLimit).filter( + (name: any) => + name.toLowerCase().startsWith(searchedText) || + name.toLowerCase().includes(searchedText) + ).map((username: string) => { + return ( +
+
+ {ProfileLink({ + ...props, + username, + children: + })} + +
+ {ProfileLink({ + ...props, + username, + children: {username} + })} +
+
+
+ ); + }) + : _t("communities.no-results")} +
+ {rebloggedBy.length > limit && } +
+ + ) + return ( +
+ + + {_t("entry-list-item.reblogs-list-title")} + + + { + setSearchedText(e.target.value); + }} + /> + + + {reblogLists} + + +
+ ) +} + +export default EntryRebloStats \ No newline at end of file diff --git a/src/common/i18n/locales/en-US.json b/src/common/i18n/locales/en-US.json index 7a644fccd30..49e326050a8 100644 --- a/src/common/i18n/locales/en-US.json +++ b/src/common/i18n/locales/en-US.json @@ -308,6 +308,7 @@ "cross-posted": "cross-posted", "cross-posted-to": "to", "reblogged": "{{n}} reblogged", + "reblogs-list-title": "Reblogs", "promoted": "Promoted", "pinned": "Pinned Post", "replies": "1 response. Click to respond.", @@ -339,7 +340,8 @@ "delete-reblog": "Undo Reblog", "delete-confirm-title": "Undo reblog?", "delete-confirm-ok": "Undo", - "delete-success": "Reblog removed" + "delete-success": "Reblog removed", + "reblogs":"Reblogs" }, "entry-tip": { "title": "Tip" diff --git a/src/common/img/svg.tsx b/src/common/img/svg.tsx index ffff97feba3..9ea6974d0eb 100644 --- a/src/common/img/svg.tsx +++ b/src/common/img/svg.tsx @@ -2013,3 +2013,4 @@ export const dragSvg = ( /> ); +