From 580960695cf35a2f13d3c30dc1aa3034b4a89149 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 29 Apr 2022 17:59:30 -0500 Subject: [PATCH] ProfilePage: convert to TSX --- app/soapbox/components/ui/tabs/tabs.tsx | 2 +- app/soapbox/pages/profile_page.js | 173 ------------------------ app/soapbox/pages/profile_page.tsx | 160 ++++++++++++++++++++++ 3 files changed, 161 insertions(+), 174 deletions(-) delete mode 100644 app/soapbox/pages/profile_page.js create mode 100644 app/soapbox/pages/profile_page.tsx diff --git a/app/soapbox/components/ui/tabs/tabs.tsx b/app/soapbox/components/ui/tabs/tabs.tsx index a0dfe7abb..dbcbcbe33 100644 --- a/app/soapbox/components/ui/tabs/tabs.tsx +++ b/app/soapbox/components/ui/tabs/tabs.tsx @@ -92,7 +92,7 @@ const AnimatedTab: React.FC = ({ index, ...props }) => { }; type Item = { - text: string, + text: React.ReactNode, title?: string, href?: string, to?: string, diff --git a/app/soapbox/pages/profile_page.js b/app/soapbox/pages/profile_page.js deleted file mode 100644 index 68d2a1a66..000000000 --- a/app/soapbox/pages/profile_page.js +++ /dev/null @@ -1,173 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { FormattedMessage } from 'react-intl'; -import { connect } from 'react-redux'; -import { Redirect, withRouter } from 'react-router-dom'; - -import LinkFooter from 'soapbox/features/ui/components/link_footer'; -import BundleContainer from 'soapbox/features/ui/containers/bundle_container'; -import { - WhoToFollowPanel, - TrendsPanel, - ProfileInfoPanel, - ProfileMediaPanel, - SignUpPanel, -} from 'soapbox/features/ui/util/async-components'; -import { findAccountByUsername } from 'soapbox/selectors'; -import { getAcct } from 'soapbox/utils/accounts'; -import { getFeatures } from 'soapbox/utils/features'; -import { displayFqn } from 'soapbox/utils/state'; - -import { Column, Layout, Tabs } from '../components/ui'; -import HeaderContainer from '../features/account_timeline/containers/header_container'; -import { makeGetAccount } from '../selectors'; - -const mapStateToProps = (state, { params, withReplies = false }) => { - const username = params.username || ''; - const accounts = state.getIn(['accounts']); - const accountFetchError = ((state.getIn(['accounts', -1, 'username']) || '').toLowerCase() === username.toLowerCase()); - const getAccount = makeGetAccount(); - const me = state.get('me'); - - let accountId = -1; - let account = null; - let accountUsername = username; - if (accountFetchError) { - accountId = null; - } else { - account = findAccountByUsername(state, username); - accountId = account ? account.getIn(['id'], null) : -1; - accountUsername = account ? account.getIn(['acct'], '') : ''; - } - - //Children components fetch information - - let realAccount; - if (!account) { - const maybeAccount = accounts.get(username); - if (maybeAccount) { - realAccount = maybeAccount; - } - } - - return { - me, - account: accountId ? getAccount(state, accountId) : account, - accountId, - accountUsername, - features: getFeatures(state.get('instance')), - realAccount, - displayFqn: displayFqn(state), - }; -}; - -export default @connect(mapStateToProps) -@withRouter -class ProfilePage extends ImmutablePureComponent { - - static propTypes = { - account: ImmutablePropTypes.record, - accountUsername: PropTypes.string.isRequired, - displayFqn: PropTypes.bool, - features: PropTypes.object, - }; - - render() { - const { children, accountId, account, displayFqn, accountUsername, me, features, realAccount } = this.props; - - if (realAccount) { - return ; - } - - const tabItems = [ - { - text: , - to: `/@${accountUsername}`, - name: 'profile', - }, - { - text: , - to: `/@${accountUsername}/with_replies`, - name: 'replies', - }, - { - text: , - to: `/@${accountUsername}/media`, - name: 'media', - }, - ]; - - if (account) { - const ownAccount = account.get('id') === me; - if (ownAccount || !account.getIn(['pleroma', 'hide_favorites'], true)) { - tabItems.push({ - text: , - to: `/@${account.get('acct')}/favorites`, - name: 'likes', - }); - } - } - - const showTrendsPanel = features.trends; - const showWhoToFollowPanel = features.suggestions; - - let activeItem; - const pathname = this.props.history.location.pathname.replace(`@${accountUsername}/`); - if (pathname.includes('with_replies')) { - activeItem = 'replies'; - } else if (pathname.includes('media')) { - activeItem = 'media'; - } else if (pathname.includes('favorites')) { - activeItem = 'likes'; - } else if (pathname === `/@${accountUsername}`) { - activeItem = 'profile'; - } - - return ( - <> - - -
- - - - {Component => } - - - {account && ( - - )} - - {children} -
-
-
- - - {!me && ( - - {Component => } - - )} - - {Component => } - - {showTrendsPanel && ( - - {Component => } - - )} - {showWhoToFollowPanel && ( - - {Component => } - - )} - - - - ); - } - -} diff --git a/app/soapbox/pages/profile_page.tsx b/app/soapbox/pages/profile_page.tsx new file mode 100644 index 000000000..68d06388a --- /dev/null +++ b/app/soapbox/pages/profile_page.tsx @@ -0,0 +1,160 @@ +import React from 'react'; +import { FormattedMessage } from 'react-intl'; +import { Redirect, useHistory } from 'react-router-dom'; + +import LinkFooter from 'soapbox/features/ui/components/link_footer'; +import BundleContainer from 'soapbox/features/ui/containers/bundle_container'; +import { + WhoToFollowPanel, + TrendsPanel, + ProfileInfoPanel, + ProfileMediaPanel, + SignUpPanel, +} from 'soapbox/features/ui/util/async-components'; +import { useAppSelector, useFeatures, useSoapboxConfig } from 'soapbox/hooks'; +import { findAccountByUsername } from 'soapbox/selectors'; +import { getAcct } from 'soapbox/utils/accounts'; + +import { Column, Layout, Tabs } from '../components/ui'; +import HeaderContainer from '../features/account_timeline/containers/header_container'; +import { makeGetAccount } from '../selectors'; + +const getAccount = makeGetAccount(); + +interface IProfilePage { + params?: { + username?: string, + }, +} + +const ProfilePage: React.FC = ({ params, children }) => { + const history = useHistory(); + + const { accountId, account, accountUsername, realAccount } = useAppSelector(state => { + const username = params?.username || ''; + const { accounts } = state; + const accountFetchError = (((state.accounts.getIn([-1, 'username']) || '') as string).toLowerCase() === username.toLowerCase()); + + let accountId: string | -1 | null = -1; + let account = null; + let accountUsername = username; + if (accountFetchError) { + accountId = null; + } else { + account = findAccountByUsername(state, username); + accountId = account ? account.id : -1; + accountUsername = account ? account.acct : ''; + } + + let realAccount; + if (!account) { + const maybeAccount = accounts.get(username); + if (maybeAccount) { + realAccount = maybeAccount; + } + } + + return { + account: typeof accountId === 'string' ? getAccount(state, accountId) : account, + accountId, + accountUsername, + realAccount, + }; + }); + + const me = useAppSelector(state => state.me); + const features = useFeatures(); + const { displayFqn } = useSoapboxConfig(); + + if (realAccount) { + return ; + } + + const tabItems = [ + { + text: , + to: `/@${accountUsername}`, + name: 'profile', + }, + { + text: , + to: `/@${accountUsername}/with_replies`, + name: 'replies', + }, + { + text: , + to: `/@${accountUsername}/media`, + name: 'media', + }, + ]; + + if (account) { + const ownAccount = account.id === me; + if (ownAccount || !account.pleroma.get('hide_favorites', true)) { + tabItems.push({ + text: , + to: `/@${account.acct}/favorites`, + name: 'likes', + }); + } + } + + let activeItem; + const pathname = history.location.pathname.replace(`@${accountUsername}/`, ''); + if (pathname.includes('with_replies')) { + activeItem = 'replies'; + } else if (pathname.includes('media')) { + activeItem = 'media'; + } else if (pathname.includes('favorites')) { + activeItem = 'likes'; + } else if (pathname === `/@${accountUsername}`) { + activeItem = 'profile'; + } + + return ( + <> + + +
+ {/* @ts-ignore */} + + + + {Component => } + + + {account && activeItem && ( + + )} + + {children} +
+
+
+ + + {!me && ( + + {Component => } + + )} + + {Component => } + + {features.trends && ( + + {Component => } + + )} + {features.suggestions && ( + + {Component => } + + )} + + + + ); +}; + +export default ProfilePage;