From f470636a70943a8ecad8bddc791a1c2dddd28e1e Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Sat, 4 May 2019 21:13:12 +0300 Subject: Components -> UI --- vnext/src/ui/Feeds.js | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 vnext/src/ui/Feeds.js (limited to 'vnext/src/ui/Feeds.js') diff --git a/vnext/src/ui/Feeds.js b/vnext/src/ui/Feeds.js new file mode 100644 index 00000000..c7b857b7 --- /dev/null +++ b/vnext/src/ui/Feeds.js @@ -0,0 +1,171 @@ +import React, { useState, useEffect } from 'react'; +import PropTypes from 'prop-types'; +import ReactRouterPropTypes from 'react-router-prop-types'; +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'; +import { UserType } from './Types'; + +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 (); +} + +export function Discussions(props) { + const query = { + baseUrl: '/api/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: '/api/messages', + search: search, + pageParam: search.search ? 'page' : 'before_mid' + }; + return ( + <> +
+ +
+ + + ); +} + +export function Tag(props) { + const { tag } = props.match.params; + const query = { + baseUrl: '/api/messages', + search: { + tag: tag + }, + pageParam: 'before_mid' + }; + return (); +} + +export function Home(props) { + const query = { + baseUrl: '/api/home', + pageParam: 'before_mid' + }; + return (); +} + +function Feed(props) { + const [msgs, setMsgs] = useState([]); + const [loading, setLoading] = useState(true); + const [nextpage, setNextpage] = useState(null); + const [error, setError] = useState(false); + + useEffect(() => { + let loadMessages = (hash = '', filter = '') => { + document.body.scrollTop = 0; + document.documentElement.scrollTop = 0; + setMsgs([]); + const filterParams = qs.parse(filter); + let params = Object.assign({}, filterParams || {}, props.query.search || {}); + let url = props.query.baseUrl; + if (hash) { + params.hash = hash; + } + if (!params.hash && props.authRequired) { + props.history.push('/'); + } + getMessages(url, params) + .then(response => { + const { data } = response; + const { pageParam } = props.query; + const lastMessage = data.slice(-1)[0] || {}; + const nextpage = getPageParam(pageParam, lastMessage, filterParams); + setMsgs(data); + setLoading(false); + setNextpage(nextpage); + }).catch(ex => { + setError(true); + }); + }; + loadMessages(props.visitor.hash, props.location.search.substring(1)); + }, [props]); + + 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)}`; + }; + const { tag } = qs.parse(location.search.substring(1) || {}); + const nodes = ( + <> + { + tag && ( +

+ + ← All posts with tag {tag} + +

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

+ Next → +

+ ) + } + + ); + return msgs.length > 0 ? ( +
{nodes}
+ ) : error ?
error
: 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 + }) +}; -- cgit v1.2.3