Skip to content

Commit

Permalink
Merge pull request #617 from ResearchHub/selectorPageSlugs
Browse files Browse the repository at this point in the history
Selector Page Slugs
  • Loading branch information
joshslee committed Sep 12, 2020
2 parents 20af204 + a7c5e92 commit 40dba8f
Show file tree
Hide file tree
Showing 12 changed files with 687 additions and 80 deletions.
139 changes: 82 additions & 57 deletions components/Hubs/HubPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import PaperPlaceholder from "../Placeholders/PaperPlaceholder";
import PermissionNotificationWrapper from "~/components/PermissionNotificationWrapper";
import ResearchHubBanner from "../ResearchHubBanner";
import Head from "~/components/Head";
import LeaderboardContainer from "../Leaderboard/LeaderboardContainer";

// Redux
import { AuthActions } from "~/redux/auth";
Expand All @@ -29,51 +30,8 @@ import { HubActions } from "~/redux/hub";
import API from "~/config/api";
import { Helpers } from "@quantfive/js-web-config";
import colors from "~/config/themes/colors";
import LeaderboardContainer from "../Leaderboard/LeaderboardContainer";

const filterOptions = [
{
value: "hot",
label: "Trending",
disableScope: true,
},
{
value: "top_rated",
label: "Top Rated",
},
{
value: "newest",
label: "Newest",
disableScope: true,
},
{
value: "most_discussed",
label: "Most Discussed",
},
];

const scopeOptions = [
{
value: "day",
label: "Today",
},
{
value: "week",
label: "This Week",
},
{
value: "month",
label: "This Month",
},
{
value: "year",
label: "This Year",
},
{
value: "all-time",
label: "All Time",
},
];
import { getFragmentParameterByName } from "~/config/utils";
import { filterOptions, scopeOptions } from "~/config/utils/options";

const defaultFilter = filterOptions[0];
const defaultScope = scopeOptions[0];
Expand All @@ -100,9 +58,12 @@ class HubPage extends React.Component {
? this.props.initialFeed.next
: null,
doneFetching: this.props.initialFeed ? true : false,
filterBy: defaultFilter,
scope: defaultScope,
disableScope: true,
filterBy: this.props.filter ? this.props.filter : defaultFilter,
scope: this.props.scope ? this.props.scope : defaultScope,
disableScope: this.props.filter
? this.props.filter.value === "hot" ||
this.props.filter.value === "newest"
: true,
mobileView: false,
mobileBanner: false,
papersLoading: false,
Expand Down Expand Up @@ -357,12 +318,25 @@ class HubPage extends React.Component {
.then(Helpers.parseJSON)
.then((res) => {
this.detectPromoted([...res.results.data]);
this.setState({
papers: [...this.state.papers, ...res.results.data],
next: res.next,
page: this.state.page + 1,
loadingMore: false,
});
this.setState(
{
papers: [...this.state.papers, ...res.results.data],
next: res.next,
prev: !res.next ? res.previous : null,
page: this.state.page + 1,
loadingMore: false,
},
() => {
let page = getFragmentParameterByName(
"page",
this.state.next ? this.state.next : this.state.prev
); // grab page from backend response
let offset = this.state.next ? -1 : 1;
page = Number(page) + offset;

this.updateSlugs(page);
}
);
})
.then(
setTimeout(() => {
Expand All @@ -371,6 +345,52 @@ class HubPage extends React.Component {
);
};

updateSlugs = (page) => {
let { filterBy, scope, disableScope } = this.state;

let filter = filterBy.label
.split(" ")
.join("-")
.toLowerCase();

let href, as;

if (disableScope) {
// if filter, but no scope
if (this.props.home) {
href = "/[filter]";
as = `/${filter}`;
} else {
// Hub Page
href = "/hubs/[slug]/[filter]";
as = `/hubs/${this.props.slug}/${filter}`;
}
} else {
// filter & scope
if (this.props.home) {
href = "/[filter]/[scope]";
as = `/${filter}/${scope.value}`;
} else {
href = "/hubs/[slug]/[filter]/[scope]";
as = `/hubs/${this.props.slug}/${filter}/${scope.value}`;
}
}

if (this.props.home && filter === "trending") {
href = "/";
as = "/";
} else if (!this.props.home && filter === "trending") {
href = "/hubs/[slug]";
as = `/hubs/${this.props.slug}`;
}

if (page) {
as += `?page=${page}`;
}

Router.push(href, as, { shallow: true });
};

calculateScope = () => {
let scope = {
start: 0,
Expand Down Expand Up @@ -442,9 +462,14 @@ class HubPage extends React.Component {
let param = {};
param[type] = option;
showMessage({ show: true, load: true });
this.setState({
...param,
});
this.setState(
{
...param,
},
() => {
this.updateSlugs();
}
);
};

voteCallback = (index, paper) => {
Expand Down
2 changes: 1 addition & 1 deletion components/Paper/Tabs/DiscussionTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ const DiscussionTab = (props) => {
cancel();
props.checkUserFirstTime(!props.auth.user.has_seen_first_coin_modal);
props.getUser();
}, 800);
}, 200);
})
.catch((err) => {
if (err.response.status === 429) {
Expand Down
54 changes: 53 additions & 1 deletion config/utils/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,56 @@ const cslFields = [
{ label: "ISSN", key: "ISSN" },
];

export { months, range, convertNumToMonth, convertMonthToNum, cslFields };
const filterOptions = [
{
value: "hot",
label: "Trending",
disableScope: true,
},
{
value: "top_rated",
label: "Top Rated",
},
{
value: "newest",
label: "Newest",
disableScope: true,
},
{
value: "most_discussed",
label: "Most Discussed",
},
];

const scopeOptions = [
{
value: "day",
label: "Today",
},
{
value: "week",
label: "This Week",
},
{
value: "month",
label: "This Month",
},
{
value: "year",
label: "This Year",
},
{
value: "all-time",
label: "All Time",
},
];

export {
months,
range,
convertNumToMonth,
convertMonthToNum,
cslFields,
filterOptions,
scopeOptions,
};
54 changes: 54 additions & 0 deletions config/utils/routing.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import moment from "moment";

export function redirect(ctx, baseKey, path) {
path = buildRedirectPath(ctx, baseKey, path);
const { res } = ctx;
Expand Down Expand Up @@ -51,3 +53,55 @@ export function openExternalLink(url) {
const tab = window.open(url);
tab.focus();
}

export function slugToFilterQuery(slug) {
switch (slug) {
case "trending":
return "hot";
case "top-rated":
return "top_rated";
case "most-discussed":
return "most_discussed";
default:
return slug;
}
}

export function calculateScopeFromSlug(scopeId) {
let scope = {
start: 0,
end: 0,
};

let now = moment();
let today = moment().startOf("day");
let week = moment()
.startOf("day")
.subtract(7, "days");
let month = moment()
.startOf("day")
.subtract(30, "days");
let year = moment()
.startOf("day")
.subtract(365, "days");

scope.end = now.unix();

if (scopeId === "day") {
scope.start = today.unix();
} else if (scopeId === "week") {
scope.start = week.unix();
} else if (scopeId === "month") {
scope.start = month.unix();
} else if (scopeId === "year") {
scope.start = year.unix();
} else if (scopeId === "all-time") {
let start = "2019-01-01";
let diff = now.diff(start, "days") + 1;

let alltime = now.startOf("day").subtract(diff, "days");
scope.start = alltime.unix();
}

return scope;
}
69 changes: 69 additions & 0 deletions pages/[filter]/[scope]/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { connect } from "react-redux";
import { StyleSheet } from "aphrodite";
import { useRouter } from "next/router";

import HubPage from "~/components/Hubs/HubPage";

import API from "~/config/api";
import { getInitialScope } from "~/config/utils/dates";
import {
slugToFilterQuery,
calculateScopeFromSlug,
} from "~/config/utils/routing";
import { filterOptions, scopeOptions } from "~/config/utils/options";

const Index = (props) => {
return <HubPage home={true} {...props} />;
};

Index.getInitialProps = async (ctx) => {
let { query } = ctx;

let page = query.page ? query.page : 1;
let filter = query.filter ? slugToFilterQuery(query.filter) : "hot";
let scope = query.scope
? calculateScopeFromSlug(query.scope)
: getInitialScope();

try {
const [initialFeed, leaderboardFeed, initialHubList] = await Promise.all([
fetch(
API.GET_HUB_PAPERS({
// Initial Feed
hubId: 0,
ordering: filter,
timePeriod: scope,
page,
}),
API.GET_CONFIG()
).then((res) => res.json()),
fetch(
API.LEADERBOARD({ limit: 10, page: 1, hubId: 0 }), // Leaderboard
API.GET_CONFIG()
).then((res) => res.json()),
fetch(API.SORTED_HUB({}), API.GET_CONFIG()).then((res) => res.json()),
]);

let filterObj = filterOptions.filter((el) => el.value === filter)[0];
let scopeObj = scopeOptions.filter((el) => el.value === query.scope)[0];

return {
initialFeed,
leaderboardFeed,
initialHubList,
query,
filter: filterObj,
scope: scopeObj,
};
} catch {
let defaultProps = {
initialFeed: null,
leaderboardFeed: null,
initialHubList: null,
error: true,
query: query,
};
return defaultProps;
}
};
export default Index;
Loading

0 comments on commit 40dba8f

Please sign in to comment.