import React, { useState, useEffect, useRef } from 'react';
import { Link } 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 {import('history').History} history
* @property {import('history').Location} location
* @property {import('react-router').match} match
* @property {string=} search
* @property {import('../api').SecureUser} visitor
* @property {import('../api').Message[]=} msgs
*/
/**
* @param {PageProps} props
*/
export function Discover(props) {
let search = qs.parse(props.location.search.substring(1));
const query = {
baseUrl: '/api/messages',
search: search,
pageParam: search.search ? 'page' : 'before_mid'
};
return ();
}
/**
* @param {PageProps} props
*/
export function Discussions(props) {
const query = {
baseUrl: '/api/messages/discussions',
pageParam: 'to'
};
return ();
}
/**
* @param {PageProps} props
*/
export function Blog(props) {
const { user } = props.match.params;
let search = qs.parse(props.location.search.substring(1));
search.uname = user;
const query = {
baseUrl: '/api/messages',
search: search,
pageParam: search.search ? 'page' : 'before_mid'
};
return (
<>
>
);
}
/**
* @param {PageProps} props
*/
export function Tag(props) {
const { tag } = props.match.params;
const query = {
baseUrl: '/api/messages',
search: {
tag: tag
},
pageParam: 'before_mid'
};
return ();
}
/**
* @param {PageProps} props
*/
export function Home(props) {
const query = {
baseUrl: '/api/home',
pageParam: 'before_mid'
};
return ();
}
/**
* @typedef {Object} FeedState
* @property authRequired?: boolean
* @property visitor: import('../api').SecureUser
* @property history: import('history').History
* @property location: import('history').Location
* @property msgs: import('../api').Message[]
* @property query: Query
*/
/**
* @param {FeedState} props
*/
function Feed(props) {
const [state, setState] = useState({
history: props.history,
authRequired: props.authRequired,
query: props.query,
hash: props.visitor.hash,
filter: props.location.search.substring(1),
msgs: [],
loading: true,
nextpage: null,
error: false,
tag: ''
});
const stateRef = useRef(state);
useEffect(() => {
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(stateRef.current.filter);
let params = Object.assign({}, filterParams || {}, stateRef.current.query.search || {});
let url = stateRef.current.query.baseUrl;
if (stateRef.current.hash) {
params.hash = stateRef.current.hash;
}
if (!params.hash && stateRef.current.authRequired) {
stateRef.current.history.push('/');
}
getMessages(url, params)
.then(response => {
const { data } = response;
const { pageParam } = stateRef.current.query;
const lastMessage = data.slice(-1)[0] || {};
const nextpage = getPageParam(pageParam, lastMessage, filterParams);
setState({
...stateRef.current,
msgs: data,
loading: false,
nextpage: nextpage,
tag: qs.parse(location.search.substring(1))['tag'] || ''
});
}).catch(ex => {
setState({
...stateRef.current,
error: true
});
});
}, []);
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
: state.loading ?
: No more messages
);
}