import React from 'react';
import PropTypes from 'prop-types';
import ReactRouterPropTypes from 'react-router-prop-types';
import { Link } from 'react-router-dom';
import * as qs from 'query-string';
import moment from 'moment';
import Message from './Message';
import Spinner from './Spinner';
import { getMessages } from '../api';
import { UserType } from './Types';
export function Discover(props) {
let search = qs.parse(props.location.search);
const query = {
baseUrl: '/messages',
search: search,
pageParam: search.search ? 'page' : 'before_mid'
};
return ();
}
export function Discussions(props) {
const query = {
baseUrl: '/messages/discussions',
pageParam: 'to'
};
return ();
}
export function Blog(props) {
const { user } = props.match.params;
let search = qs.parse(props.location.search);
search.uname = user;
const query = {
baseUrl: '/messages',
search: search,
pageParam: search.search ? 'page' : 'before_mid'
};
return ();
}
export function Tag(props) {
const { tag } = props.match.params;
const query = {
baseUrl: '/messages',
search: {
tag: tag
},
pageParam: 'before_mid'
};
return ();
}
export function Home(props) {
const query = {
baseUrl: '/home',
pageParam: 'before_mid'
};
return ();
}
class Feed extends React.Component {
constructor(props) {
super(props);
this.state = {
msgs: [],
loading: false
};
}
componentDidMount() {
this.loadMessages(this.props.visitor.hash, this.props.location.search);
}
shouldComponentUpdate(nextProps, nextState) {
return this.props.visitor.uid !== nextProps.visitor.uid
|| this.state !== nextState || this.props.location !== nextProps.location;
}
getSnapshotBeforeUpdate(prevProps) {
return (this.props.location.search != prevProps.location.search
|| this.props.visitor != prevProps.visitor || this.props.query.search != prevProps.query.search);
}
componentDidUpdate(prevProps, prevState, shouldReload) {
if (shouldReload) {
this.loadMessages(this.props.visitor.hash, this.props.location.search);
}
}
loadMessages = (hash = '', filter = '') => {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
this.setState({ msgs: [], loading: true });
const filterParams = qs.parse(filter);
let params = Object.assign({}, filterParams || {}, this.props.query.search || {});
let url = this.props.query.baseUrl;
if (hash) {
params.hash = hash;
}
if (!params.hash && this.props.authRequired) {
this.props.history.push('/');
}
getMessages(url, params)
.then(response => {
const { data } = response;
const { pageParam } = this.props.query;
const lastMessage = data.slice(-1)[0] || {};
const nextpage = this.getPageParam(pageParam, lastMessage, filterParams);
this.setState({ msgs: data, loading: false, nextpage: nextpage });
}).catch(ex => {
this.setState({ error: true });
});
}
getPageParam = (pageParam, lastMessage, filterParams) => {
const pageValue = pageParam === 'before_mid' ? lastMessage.mid : pageParam === 'page' ? (Number(filterParams.page) || 0) + 1 : moment.utc(lastMessage.updated).valueOf();
let newFilter = Object.assign({}, filterParams);
newFilter[pageParam] = pageValue;
return `?${qs.stringify(newFilter)}`;
}
render() {
const { tag } = qs.parse(this.props.location.search || {});
const nodes = (
<>
{
tag && (
← All posts with tag {tag}
)
}
{
this.state.msgs.map(msg =>
)
}
{
this.state.msgs.length >= 20 && (
Next →
)
}
>
);
return this.state.msgs.length > 0 ? (
{nodes}
) : this.state.error ? error
: this.state.loading ?
: No more messages
;
}
}
Discover.propTypes = {
location: ReactRouterPropTypes.location.isRequired,
search: PropTypes.string
};
Blog.propTypes = {
match: ReactRouterPropTypes.match.isRequired,
location: ReactRouterPropTypes.location.isRequired,
search: PropTypes.string
};
Tag.propTypes = {
match: ReactRouterPropTypes.match.isRequired
};
Feed.propTypes = {
authRequired: PropTypes.bool,
visitor: UserType,
history: ReactRouterPropTypes.history.isRequired,
location: ReactRouterPropTypes.location.isRequired,
msgs: PropTypes.array,
query: PropTypes.shape({
baseUrl: PropTypes.string.isRequired,
search: PropTypes.object,
pageParam: PropTypes.string.isRequired
})
};