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 'qs'; import moment from 'moment'; import Message from './Message'; import Spinner from './Spinner'; import UserInfo from './UserInfo'; import { getMessages } from '../api'; import { UserType } from './Types'; export function Discover(props) { let search = qs.parse(props.location.search.substring(1)); 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.substring(1)); 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.substring(1)); } 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.substring(1)); } } 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.substring(1) || {}); 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 }) };