import React, { useState, useEffect } from 'react'; import { Link, useLocation, useHistory, useParams } from 'react-router-dom'; import qs from 'qs'; import moment from 'moment'; import Message from './Message'; import Spinner from './Spinner'; import UserInfo from './UserInfo'; import { getMessages } from '../api'; /** * @typedef {Object} Query * @property {string} baseUrl * @property {Object=} search * @property {string} pageParam */ /** * @typedef {Object} PageProps * @property {string=} search * @property {import('../api').SecureUser} visitor * @property {import('../api').Message[]=} msgs */ /** * @param {PageProps} props */ export function Discover({ visitor }) { const location = useLocation(); let search = qs.parse(location.search.substring(1)); const query = { baseUrl: '/api/messages', search: search, pageParam: search.search ? 'page' : 'before_mid' }; return (); } /** * @param {PageProps} props */ export function Discussions({ visitor }) { const query = { baseUrl: '/api/messages/discussions', pageParam: 'to' }; return (); } /** * @param {PageProps} props */ export function Blog({ visitor }) { const { user } = useParams(); const location = useLocation(); const search = { ...qs.parse(location.search.substring(1)), uname: user }; const query = { baseUrl: '/api/messages', search: search, pageParam: search.search ? 'page' : 'before_mid' }; return ( <>
); } /** * @param {PageProps} props */ export function Tag({ visitor }) { const params = useParams(); const { tag } = params; const query = { baseUrl: '/api/messages', search: { tag: tag }, pageParam: 'before_mid' }; return (); } /** * @param {PageProps} props */ export function Home({ visitor }) { const query = { baseUrl: '/api/home', pageParam: 'before_mid' }; return (); } /** * @typedef {Object} FeedState * @property authRequired?: boolean * @property visitor: import('../api').SecureUser * @property msgs: import('../api').Message[] * @property { Query} query */ /** * @param {FeedState} props */ function Feed({ visitor, query, authRequired }) { const location = useLocation(); const history = useHistory(); const [state, setState] = useState({ authRequired: authRequired, hash: visitor.hash, msgs: [], nextpage: null, error: false, tag: '' }); const [loading, setLoading] = useState(false); useEffect(() => { setLoading(true); const filter = location.search.substring(1); let 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 = { ...filterParams }; newFilter[pageParam] = pageValue; return `?${qs.stringify(newFilter)}`; }; document.body.scrollTop = 0; document.documentElement.scrollTop = 0; const filterParams = qs.parse(filter); let params = Object.assign({}, filterParams || {}, query.search || {}); let url = query.baseUrl; if (state.hash) { params.hash = state.hash; } if (!params.hash && state.authRequired) { history.push('/'); } getMessages(url, params) .then(response => { const { data } = response; const { pageParam } = query; const lastMessage = data.slice(-1)[0] || {}; const nextpage = getPageParam(pageParam, lastMessage, filterParams); setState((prevState) => { return { ...prevState, msgs: data, nextpage: nextpage, tag: qs.parse(location.search.substring(1))['tag'] || '' }; }); setLoading(false); }).catch(ex => { setState((prevState) => { return { ...prevState, error: true }; }); }); }, [location.search, state.hash, state.authRequired, history, query]); return (state.msgs.length > 0 ? (
{ state.tag && (

← All posts with tag {state.tag}

) } { state.msgs.map(msg => ) } { state.msgs.length >= 20 && (

Next →

) }
) : state.error ?
error
: loading ?
:
No more messages
); }