diff --git a/components/Author/Tabs/UserContributions.js b/components/Author/Tabs/UserContributions.js index c8d112b15c..b6274ebf32 100644 --- a/components/Author/Tabs/UserContributions.js +++ b/components/Author/Tabs/UserContributions.js @@ -1,11 +1,15 @@ import { StyleSheet, css } from "aphrodite"; import { connect } from "react-redux"; import ReactPlaceholder from "react-placeholder"; +import Ripples from "react-ripples"; // Components import ComponentWrapper from "~/components/ComponentWrapper"; import PaperEntryCard from "~/components/Hubs/PaperEntryCard"; -import { Reply, Comment } from "~/components/DiscussionComment"; +import Loader from "~/components/Loader/Loader"; + +// Redux +import { AuthorActions } from "~/redux/author"; // Config import colors from "~/config/themes/colors"; @@ -15,14 +19,19 @@ class UserContributionsTab extends React.Component { constructor(props) { super(props); this.state = { - contributions: [], + contributions: + this.props.author.userContributions && + this.props.author.userContributions.contributions + ? this.props.author.userContributions.contributions + : [], + fetching: false, }; } componentDidMount() { let { author } = this.props; this.setState({ - contributions: author.userContributions.contributions, + // contributions: author.userContributions.contributions, }); } @@ -40,42 +49,74 @@ class UserContributionsTab extends React.Component { let contributions = [...this.state.contributions]; contributions[index] = paper; - this.setState({ - contributions, + this.setState({ contributions }); + }; + + loadMore = () => { + this.setState({ fetching: true }, async () => { + const next = this.props.author.userContributions.next; + await this.props.getUserContributions({ next }); + setTimeout(() => this.setState({ fetching: false }), 400); }); }; + renderLoadMoreButton = () => { + let { author } = this.props; + + if (author && author.userContributions) { + let { next } = author.userContributions; + + if (next !== null) { + return ( +
+ {!this.state.fetching ? ( + + Load More + + ) : ( + + )} +
+ ); + } + } + }; + render() { let contributions = this.state.contributions.map((contribution, index) => { return (
- {contribution.type === "paper" ? ( - - ) : contribution.type === "comment" ? ( -
- -
- ) : ( -
- -
- )} +
); }); return ( } > {contributions.length > 0 ? ( -
{contributions}
+
+ {contributions} + {this.renderLoadMoreButton()} +
) : (
@@ -125,10 +166,47 @@ var styles = StyleSheet.create({ height: 50, marginBottom: 10, }, + buttonContainer: { + width: "100%", + display: "flex", + justifyContent: "center", + alignItems: "center", + marginTop: 25, + height: 45, + "@media only screen and (max-width: 768px)": { + marginTop: 15, + marginBottom: 15, + }, + }, + loadMoreButton: { + fontSize: 14, + border: `1px solid ${colors.BLUE()}`, + boxSizing: "border-box", + borderRadius: 4, + height: 45, + width: 155, + display: "flex", + justifyContent: "center", + alignItems: "center", + color: colors.BLUE(), + cursor: "pointer", + userSelect: "none", + ":hover": { + color: "#FFF", + backgroundColor: colors.BLUE(), + }, + }, }); const mapStateToProps = (state) => ({ author: state.author, }); -export default connect(mapStateToProps)(UserContributionsTab); +const mapDispatchToProps = { + getUserContributions: AuthorActions.getUserContributions, +}; + +export default connect( + mapStateToProps, + mapDispatchToProps +)(UserContributionsTab); diff --git a/components/Author/Tabs/UserDiscussions.js b/components/Author/Tabs/UserDiscussions.js index 0a51177f49..7465c9e36d 100644 --- a/components/Author/Tabs/UserDiscussions.js +++ b/components/Author/Tabs/UserDiscussions.js @@ -100,7 +100,9 @@ class UserDiscussionsTab extends React.Component { return ( } > diff --git a/components/Author/Tabs/UserTransactions.js b/components/Author/Tabs/UserTransactions.js index 8226046396..71ddf74bea 100644 --- a/components/Author/Tabs/UserTransactions.js +++ b/components/Author/Tabs/UserTransactions.js @@ -76,7 +76,7 @@ class UserTransaction extends React.Component { return ( } > diff --git a/components/DiscussionComment.js b/components/DiscussionComment.js index f769f1d26d..538d163eeb 100644 --- a/components/DiscussionComment.js +++ b/components/DiscussionComment.js @@ -58,7 +58,11 @@ class DiscussionComment extends React.Component { } createdByCurrentUser = () => { - return this.state.createdBy.id === this.props.currentUser.id; + if (this.state.createdBy) { + if (this.props.currentUser) { + return this.state.createdBy.id === this.props.currentUser.id; + } + } }; setReadOnly = (readOnly) => { diff --git a/components/Hubs/HubPage.js b/components/Hubs/HubPage.js index 24e79db9f5..a897f247e0 100644 --- a/components/Hubs/HubPage.js +++ b/components/Hubs/HubPage.js @@ -644,14 +644,14 @@ class HubPage extends React.Component { )} id={"topbar"} > -
+

{this.getTitle()} {this.props.home ? "ResearchHub" : this.props.hub.name} -

+
{ ref={discussionRef} >
-
+

Comments {fetching ? ( @@ -452,7 +452,7 @@ const DiscussionTab = (props) => { Tweets

-
+ {!showEditor && !showTwitterComments && renderAddDiscussion()}
diff --git a/components/Paper/Tabs/LimitationTab.js b/components/Paper/Tabs/LimitationTab.js index cd2e377e96..c10a9b3c53 100644 --- a/components/Paper/Tabs/LimitationTab.js +++ b/components/Paper/Tabs/LimitationTab.js @@ -255,7 +255,7 @@ class LimitationTab extends React.Component { return (
-
Limitations
+

Limitations

{this.renderDropdown()}
diff --git a/components/Paper/Tabs/PaperTab.js b/components/Paper/Tabs/PaperTab.js index a283c1dd03..ab902e5610 100644 --- a/components/Paper/Tabs/PaperTab.js +++ b/components/Paper/Tabs/PaperTab.js @@ -267,7 +267,7 @@ function PaperTab(props) {
-
Paper PDF
+

Paper PDF

{file && renderDownloadPdf()}
{file && isModerator && ( diff --git a/components/Paper/Tabs/SummaryTab.js b/components/Paper/Tabs/SummaryTab.js index b6299f6a20..8953607967 100644 --- a/components/Paper/Tabs/SummaryTab.js +++ b/components/Paper/Tabs/SummaryTab.js @@ -465,10 +465,10 @@ class SummaryTab extends React.Component { {this.state.readOnly ? (
-
+

Description {this.renderTabs()} -

+
{/*
-
+

{paper && paper.title} -

+ {paper.paper_title && paper.paper_title !== paper.title ? ( -
+

{`From Paper: ${paper.paper_title}`} -

+ ) : null}
@@ -933,6 +933,9 @@ const styles = StyleSheet.create({ fontSize: 30, position: "relative", wordBreak: "break-word", + fontWeight: "unset", + padding: 0, + margin: 0, "@media only screen and (max-width: 760px)": { fontSize: 28, }, @@ -951,6 +954,7 @@ const styles = StyleSheet.create({ opacity: 0.5, fontSize: 16, marginTop: 10, + fontWeight: "unset", "@media only screen and (max-width: 415px)": { fontSize: 14, }, diff --git a/components/TabBar.js b/components/TabBar.js index 9907f4f703..d5c0b40054 100644 --- a/components/TabBar.js +++ b/components/TabBar.js @@ -2,13 +2,14 @@ import Link from "next/link"; import { StyleSheet, css } from "aphrodite"; import colors, { paperTabColors } from "~/config/themes/colors"; import { paperTabFont } from "~/config/themes/fonts"; +import Loader from "~/components/Loader/Loader"; // Components import ComponentWrapper from "./ComponentWrapper"; const TabBar = (props) => { const selectedTab = props.selectedTab; - const { dynamic_href } = props; + const { dynamic_href, fetching } = props; const tabs = props.tabs.map(formatTabs); return ( @@ -22,7 +23,7 @@ const TabBar = (props) => { return null; } } - return renderTab(tab, selectedTab, dynamic_href); + return renderTab(tab, selectedTab, dynamic_href, props.fetching); })}
@@ -38,7 +39,8 @@ function formatTabs(tab) { function renderTab( { key, href, label, showCount, count }, selected, - dynamic_href + dynamic_href, + fetching ) { let isSelected = false; let classNames = [styles.tab]; @@ -52,7 +54,9 @@ function renderTab(
{label}{" "} - {showCount && } + {showCount && ( + + )}
@@ -60,14 +64,29 @@ function renderTab( } const Count = (props) => { - const { amount, isSelected } = props; + const { amount, isSelected, fetching } = props; // if (amount < 1) { // return ; // } + return ( - - {amount > 0 ? amount : 0} + + {fetching ? ( + + ) : amount > 0 ? ( + amount + ) : ( + 0 + )} ); @@ -134,6 +153,13 @@ const styles = StyleSheet.create({ borderBottom: "solid 3px", borderColor: colors.PURPLE(1), }, + loaderContainer: { + padding: 0, + width: "unset", + }, + loaderStyle: { + display: "unset", + }, }); export default TabBar; diff --git a/config/api.js b/config/api.js index 0c764a2ae0..1d64c87449 100644 --- a/config/api.js +++ b/config/api.js @@ -183,15 +183,8 @@ const routes = (BASE_URL) => { return url; }, - USER_CONTRIBUTION: ({ - authorId, - commentOffset, - replyOffset, - paperUploadOffset, - }) => { - let url = - BASE_URL + - `author/${authorId}/get_user_contributions/?commentOffset=${commentOffset}&replyOffset=${replyOffset}&paperUploadOffset=${paperUploadOffset}`; + USER_CONTRIBUTION: ({ authorId }) => { + let url = BASE_URL + `author/${authorId}/get_user_contributions/`; return url; }, diff --git a/pages/user/[authorId]/[tabName]/index.js b/pages/user/[authorId]/[tabName]/index.js index c58fb36064..6e590299f1 100644 --- a/pages/user/[authorId]/[tabName]/index.js +++ b/pages/user/[authorId]/[tabName]/index.js @@ -35,6 +35,7 @@ const AuthorPage = (props) => { let { tabName } = router.query; const dispatch = useDispatch(); const store = useStore(); + const [fetching, setFetching] = useState(true); const [openShareModal, setOpenShareModal] = useState(false); const [hoverName, setHoverName] = useState(false); const [hoverDescription, setHoverDescription] = useState(false); @@ -106,19 +107,12 @@ const AuthorPage = (props) => { if (!author.user) { return; } - let { - commentOffset, - replyOffset, - paperUploadOffset, - } = props.author.userContributions; await dispatch( AuthorActions.getUserContributions({ authorId: router.query.authorId, - commentOffset, - replyOffset, - paperUploadOffset, }) ); + setFetching(false); } function fetchUserTransactions() { @@ -150,6 +144,7 @@ const AuthorPage = (props) => { } useEffect(() => { + setFetching(true); async function refetchAuthor() { await dispatch( AuthorActions.getAuthor({ authorId: router.query.authorId }) @@ -246,20 +241,44 @@ const AuthorPage = (props) => { ]; let renderTabContent = () => { - switch (tabName) { - case "contributions": - return ; - case "authored-papers": - return ; - case "discussions": - return ; - case "citations": - return null; - case "transactions": - return ; - case "boosts": - return ; - } + return ( + // render all tab content on the dom, but only show if selected +
+ + + + + + + + + + + + + + + +
+ ); }; let renderEditButton = (action) => { @@ -703,6 +722,7 @@ const AuthorPage = (props) => { dynamic_href={"/user/[authorId]/[tabName]"} author={author} user={user} + fetching={fetching} />
{renderTabContent()}
({ diff --git a/redux/author/index.js b/redux/author/index.js index d08e3650bf..e6417334ee 100644 --- a/redux/author/index.js +++ b/redux/author/index.js @@ -79,44 +79,47 @@ export const AuthorActions = { }; }, - getUserContributions: ({ - authorId, - commentOffset = 0, - replyOffset = 0, - paperUploadOffset = 0, - }) => { - return async (dispatch) => { + getUserContributions: ({ authorId, next = null }) => { + return async (dispatch, getState) => { dispatch({ contributionsDoneFetching: false, type: types.GET_USER_CONTRIBUTIONS_PENDING, }); - const response = await fetch( - API.USER_CONTRIBUTION({ - authorId, - commentOffset, - replyOffset, - paperUploadOffset, - }), - API.GET_CONFIG() - ).catch(utils.handleCatch); + + let ENDPOINT = next + ? next + : API.USER_CONTRIBUTION({ + authorId, + }); + + const response = await fetch(ENDPOINT, API.GET_CONFIG()).catch( + utils.handleCatch + ); let action = actions.getUserContributionsFailure(); if (response.ok) { const body = await response.json(); - let contributions = []; + + let contributions = next + ? [...getState().author.userContributions.contributions] + : []; for (let i = 0; i < body.results.length; i++) { let contribution = body.results[i]; if (contribution.type === "reply") { let formatted = discussionShim.transformReply(body.results[i]); - formatted.type = contribution.type; + // formatted.type = contribution.type; contributions.push(formatted); } else if (contribution.type === "comment") { let formatted = discussionShim.transformComment(body.results[i]); - formatted.type = contribution.type; + // formatted.type = contribution.type; contributions.push(formatted); } else if (contribution.type === "paper") { let formatted = paperShim.paper(body.results[i]); - formatted.type = contribution.type; + // formatted.type = contribution.type; + contributions.push(formatted); + } else { + let formatted = paperShim.paper(body.results[i]); + // formatted.type = contribution.type; contributions.push(formatted); } } @@ -135,6 +138,15 @@ export const AuthorActions = { }; }, + getNextUserContributions: ({ authorId }) => { + return async (dispatch) => { + dispatch({ + contributionsDoneFetching: false, + type: types.GET_USER_CONTRIBUTIONS_PENDING, + }); + }; + }, + saveAuthorChanges: ({ changes, authorId, file }) => { return (dispatch) => { let config = API.PATCH_CONFIG(changes);