// view-user.tsx // Copyright (C) 2020 Dwayne Harris // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . import React, { FC, useEffect, useState } from 'react' import { useSelector, useDispatch } from 'react-redux' import { useParams, useHistory } from 'react-router-dom' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faUserPlus, faUserMinus, faUserClock, faBan } from '@fortawesome/free-solid-svg-icons' import moment from 'moment' import { handleApiError } from '../../api/errors' import { fetchUser, subscribe, unsubscribe } from '../../actions/users' import { fetchUserPosts } from '../../actions/posts' import { setTheme } from '../../actions/theme' import { getEntity } from '../../selectors/entities' import { getAuthenticatedUser, getChecked } from '../../selectors/authentication' import { getUserPosts } from '../../selectors/posts' import { getThemeName } from '../../selectors/theme' import { useDeepCompareEffect, useTheme, useSetting } from '../../hooks' import { setTitle } from '../../utils' import { AppState, EntityType, User, Post, AppThunkDispatch, LevelItem } from '../../types' import Title from '../../components/title' import Subtitle from '../../components/subtitle' import Level from '../../components/level' import PostList from '../../components/post-list' import Section from '../../components/section' import HorizontalRule from '../../components/horizontal-rule' import Loading from '../../components/pages/loading' interface Params { id: string } const ViewUser: FC = () => { const { id } = useParams() const theme = useTheme() const themeName = useSelector(getThemeName) const [selectedThemeName] = useState(themeName) const checked = useSelector(getChecked) const self = useSelector(getAuthenticatedUser) const user = useSelector(state => getEntity(state, EntityType.User, id)) const posts = useSelector(state => getUserPosts(state, id)) const dispatch = useDispatch() const history = useHistory() const allowThemeChange = useSetting('allowThemeChange', true) useEffect(() => { const init = async () => { try { await dispatch(fetchUser(id)) await dispatch(fetchUserPosts(id)) } catch (err) { handleApiError(err, dispatch, history) } } if (checked) init() }, [checked]) useDeepCompareEffect(() => { if (user) { setTitle(user.name) if (allowThemeChange && user.theme) dispatch(setTheme(user.theme)) } return () => { if (allowThemeChange && selectedThemeName) dispatch(setTheme(selectedThemeName)) } }, [user]) if (!user) return const isSelf = self && self.id === user.id const isGroup = self && self.group && user.group && self.group.id === user.group.id const subscription = self && user.subscriptions ? user.subscriptions.find(subscription => subscription.from === self.id && subscription.to === user.id) : undefined const subscribed = subscription && !subscription.pending const subscriptionPending = subscription && subscription.pending const items: LevelItem[] = [] items.push({ label: 'Posts', content: user.posts, }) items.push({ label: 'Awards', content: user.awards, }) items.push({ label: 'Points', content: user.points, }) items.push({ label: 'Joined', content: moment(user.created).format('MMMM Do, YYYY'), }) return (
{user.coverImageUrl &&
}
{user.imageUrl &&
}
{user.name}

{user.about}

{subscribed && } {subscriptionPending && } {self && !isSelf && !subscribed && !subscriptionPending && } {!isSelf && } {user.group && !isGroup && }
Posts
) } export default ViewUser