From fb351f8dfd8071b980df452ab01095f5e9187251 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 18 Apr 2022 19:00:04 -0500 Subject: [PATCH 1/8] eslint: stop screaming about proptypes --- .eslintrc.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index d885cbeea..ae8c9e981 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -150,7 +150,6 @@ module.exports = { 'react/jsx-wrap-multilines': 'error', 'react/no-multi-comp': 'off', 'react/no-string-refs': 'error', - 'react/prop-types': 'error', 'react/self-closing-comp': 'error', 'jsx-a11y/accessible-emoji': 'warn', @@ -264,7 +263,6 @@ module.exports = { files: ['**/*.ts', '**/*.tsx'], rules: { 'no-undef': 'off', // https://stackoverflow.com/a/69155899 - 'react/prop-types': 'off', }, parser: '@typescript-eslint/parser', }, From 000121d74f77a7e18aa3b8dc9a6a113c65019bfd Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 18 Apr 2022 19:00:19 -0500 Subject: [PATCH 2/8] Notifications: use Virtuoso --- .../features/chats/components/chat_list.tsx | 4 +- app/soapbox/features/notifications/index.js | 114 +++++++++--------- 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/app/soapbox/features/chats/components/chat_list.tsx b/app/soapbox/features/chats/components/chat_list.tsx index 2608a8f03..8347c0e89 100644 --- a/app/soapbox/features/chats/components/chat_list.tsx +++ b/app/soapbox/features/chats/components/chat_list.tsx @@ -78,9 +78,7 @@ const ChatList: React.FC = ({ onClickChat, useWindowScroll = false }) Footer: () => hasMore ? : null, EmptyPlaceholder: () => { if (isLoading) { - return ( - <>{Array(20).fill()} - ); + return ; } else { return {intl.formatMessage(messages.emptyMessage)}; } diff --git a/app/soapbox/features/notifications/index.js b/app/soapbox/features/notifications/index.js index fce474a96..5f739e913 100644 --- a/app/soapbox/features/notifications/index.js +++ b/app/soapbox/features/notifications/index.js @@ -1,4 +1,3 @@ -import classNames from 'classnames'; import { List as ImmutableList } from 'immutable'; import { debounce } from 'lodash'; import PropTypes from 'prop-types'; @@ -6,10 +5,12 @@ import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { connect } from 'react-redux'; +import { Virtuoso } from 'react-virtuoso'; import { createSelector } from 'reselect'; import { getSettings } from 'soapbox/actions/settings'; import BirthdayReminders from 'soapbox/components/birthday_reminders'; +import PullToRefresh from 'soapbox/components/pull-to-refresh'; import PlaceholderNotification from 'soapbox/features/placeholder/components/placeholder_notification'; import { getFeatures } from 'soapbox/utils/features'; @@ -18,10 +19,8 @@ import { scrollTopNotifications, dequeueNotifications, } from '../../actions/notifications'; -import LoadGap from '../../components/load_gap'; -import ScrollableList from '../../components/scrollable_list'; import TimelineQueueButtonHeader from '../../components/timeline_queue_button_header'; -import { Column } from '../../components/ui'; +import { Column, Text } from '../../components/ui'; import FilterBarContainer from './containers/filter_bar_container'; import NotificationContainer from './containers/notification_container'; @@ -31,6 +30,30 @@ const messages = defineMessages({ queue: { id: 'notifications.queue_label', defaultMessage: 'Click to see {count} new {count, plural, one {notification} other {notifications}}' }, }); +const Header = ({ context }) => ( + context.showBirthdayReminders ? ( + + ) : null +); + +const Footer = ({ context }) => ( + context.hasMore ? ( + + ) : null +); + +const EmptyPlaceholder = ({ context }) => { + if (context.isLoading) { + return ; + } else { + return {context.emptyMessage}; + } +}; + +const Item = ({ context, ...rest }) => ( +
+); + const getNotifications = createSelector([ state => getSettings(state).getIn(['notifications', 'quickFilter', 'show']), state => getSettings(state).getIn(['notifications', 'quickFilter', 'active']), @@ -163,63 +186,42 @@ class Notifications extends React.PureComponent { const { intl, notifications, isLoading, hasMore, showFilterBar, totalQueuedNotificationsCount, showBirthdayReminders } = this.props; const emptyMessage = ; - let scrollableContent = null; - const filterBarContainer = showFilterBar ? () : null; - if (isLoading && this.scrollableContent) { - scrollableContent = this.scrollableContent; - } else if (notifications.size > 0 || hasMore) { - scrollableContent = notifications.map((item, index) => item === null ? ( - 0 ? notifications.getIn([index - 1, 'id']) : null} - onClick={this.handleLoadGap} + const scrollContainer = ( + + isScrolling && this.handleScroll} + itemContent={(_index, notification) => ( + + )} + context={{ + hasMore, + showBirthdayReminders, + handleMoveBelowBirthdays: this.handleMoveBelowBirthdays, + isLoading, + emptyMessage, + }} + components={{ + Header, + ScrollSeekPlaceholder: PlaceholderNotification, + Footer, + EmptyPlaceholder, + Item, + }} /> - ) : ( - - )); - - if (showBirthdayReminders) scrollableContent = scrollableContent.unshift( - , - ); - } else { - scrollableContent = null; - } - - this.scrollableContent = scrollableContent; - - const scrollContainer = ( - 0, - 'space-y-2': notifications.size === 0, - })} - > - {scrollableContent} - + ); return ( From 97b5c5af43776adb007fddc7768abde5f81eafb2 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 18 Apr 2022 22:49:17 -0500 Subject: [PATCH 3/8] Widget: add actions --- app/soapbox/components/ui/widget/widget.tsx | 27 ++++++++++++--- .../components/crypto_donate_panel.tsx | 34 +++++++++---------- .../ui/components/who-to-follow-panel.tsx | 10 +++++- 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/app/soapbox/components/ui/widget/widget.tsx b/app/soapbox/components/ui/widget/widget.tsx index e5cc6dfd1..d0f34b90b 100644 --- a/app/soapbox/components/ui/widget/widget.tsx +++ b/app/soapbox/components/ui/widget/widget.tsx @@ -1,9 +1,9 @@ import React from 'react'; -import { Stack, Text } from 'soapbox/components/ui'; +import { Stack, HStack, Text, IconButton } from 'soapbox/components/ui'; interface IWidgetTitle { - title: string | React.ReactNode + title: string | React.ReactNode, } const WidgetTitle = ({ title }: IWidgetTitle): JSX.Element => ( @@ -16,12 +16,31 @@ const WidgetBody: React.FC = ({ children }): JSX.Element => ( interface IWidget { title: string | React.ReactNode, + onActionClick?: () => void, + actionIcon?: string, + actionTitle?: string, } -const Widget: React.FC = ({ title, children }): JSX.Element => { +const Widget: React.FC = ({ + title, + children, + onActionClick, + actionIcon = require('@tabler/icons/icons/arrow-right.svg'), + actionTitle, +}): JSX.Element => { return ( - + + + {onActionClick && ( + + )} + {children} ); diff --git a/app/soapbox/features/crypto_donate/components/crypto_donate_panel.tsx b/app/soapbox/features/crypto_donate/components/crypto_donate_panel.tsx index 073852a8b..581f53f03 100644 --- a/app/soapbox/features/crypto_donate/components/crypto_donate_panel.tsx +++ b/app/soapbox/features/crypto_donate/components/crypto_donate_panel.tsx @@ -1,17 +1,24 @@ import React from 'react'; -import { FormattedMessage } from 'react-intl'; -import { Link } from 'react-router-dom'; +import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; +import { useHistory } from 'react-router-dom'; import { Text, Widget } from 'soapbox/components/ui'; import { useAppSelector, useSoapboxConfig } from 'soapbox/hooks'; import SiteWallet from './site_wallet'; +const messages = defineMessages({ + actionTitle: { id: 'crypto_donate_panel.actions.view', defaultMessage: 'Click to see {count} {count, plural, one {wallet} other {wallets}}' }, +}); + interface ICryptoDonatePanel { limit: number, } const CryptoDonatePanel: React.FC = ({ limit = 3 }): JSX.Element | null => { + const intl = useIntl(); + const history = useHistory(); + const addresses = useSoapboxConfig().get('cryptoAddresses'); const siteTitle = useAppSelector((state) => state.instance.title); @@ -19,11 +26,16 @@ const CryptoDonatePanel: React.FC = ({ limit = 3 }): JSX.Ele return null; } - const more = addresses.size - limit; - const hasMore = more > 0; + const handleAction = () => { + history.push('/donate/crypto'); + }; return ( - }> + } + onActionClick={handleAction} + actionTitle={intl.formatMessage(messages.actionTitle, { count: addresses.size })} + > = ({ limit = 3 }): JSX.Ele - - {hasMore && ( - - - - - - )} ); }; diff --git a/app/soapbox/features/ui/components/who-to-follow-panel.tsx b/app/soapbox/features/ui/components/who-to-follow-panel.tsx index cea616407..25a730603 100644 --- a/app/soapbox/features/ui/components/who-to-follow-panel.tsx +++ b/app/soapbox/features/ui/components/who-to-follow-panel.tsx @@ -36,8 +36,16 @@ const WhoToFollowPanel = ({ limit }: IWhoToFollowPanel) => { return null; } + // FIXME: This page actually doesn't look good right now + // const handleAction = () => { + // history.push('/suggestions'); + // }; + return ( - }> + } + // onAction={handleAction} + > {suggestionsToRender.map((suggestion: ImmutableMap) => ( Date: Mon, 18 Apr 2022 23:30:40 -0500 Subject: [PATCH 4/8] Add BirthdayPanel --- app/soapbox/actions/accounts.js | 2 +- app/soapbox/components/account.tsx | 2 +- app/soapbox/components/birthday-panel.tsx | 47 +++++++++++++++++++ app/soapbox/components/birthday_reminders.js | 2 +- app/soapbox/features/edit_profile/index.js | 13 +++++ .../features/ui/util/async-components.js | 4 ++ app/soapbox/pages/home_page.js | 6 +++ 7 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 app/soapbox/components/birthday-panel.tsx diff --git a/app/soapbox/actions/accounts.js b/app/soapbox/actions/accounts.js index 23aad5601..1005af838 100644 --- a/app/soapbox/actions/accounts.js +++ b/app/soapbox/actions/accounts.js @@ -1035,7 +1035,7 @@ export function accountLookup(acct, cancelToken) { }; } -export function fetchBirthdayReminders(day, month) { +export function fetchBirthdayReminders(month, day) { return (dispatch, getState) => { if (!isLoggedIn(getState)) return; diff --git a/app/soapbox/components/account.tsx b/app/soapbox/components/account.tsx index ab9c7af68..ccdc10578 100644 --- a/app/soapbox/components/account.tsx +++ b/app/soapbox/components/account.tsx @@ -175,7 +175,7 @@ const Account = ({ @{username} {favicon && ( - + )} diff --git a/app/soapbox/components/birthday-panel.tsx b/app/soapbox/components/birthday-panel.tsx new file mode 100644 index 000000000..6008cb423 --- /dev/null +++ b/app/soapbox/components/birthday-panel.tsx @@ -0,0 +1,47 @@ +import { OrderedSet as ImmutableOrderedSet } from 'immutable'; +import * as React from 'react'; +import { FormattedMessage } from 'react-intl'; +import { useDispatch } from 'react-redux'; + +import { fetchBirthdayReminders } from 'soapbox/actions/accounts'; +import { Widget } from 'soapbox/components/ui'; +import AccountContainer from 'soapbox/containers/account_container'; +import { useAppSelector } from 'soapbox/hooks'; + +interface IBirthdayPanel { + limit: number +} + +const BirthdayPanel = ({ limit }: IBirthdayPanel) => { + const dispatch = useDispatch(); + + const birthdays: ImmutableOrderedSet = useAppSelector(state => state.user_lists.getIn(['birthday_reminders', state.me], ImmutableOrderedSet())); + const birthdaysToRender = birthdays.slice(0, limit); + + React.useEffect(() => { + const date = new Date(); + + const day = date.getDate(); + const month = date.getMonth() + 1; + + dispatch(fetchBirthdayReminders(month, day)); + }, []); + + if (birthdaysToRender.isEmpty()) { + return null; + } + + return ( + }> + {birthdaysToRender.map(accountId => ( + , but it isn't + id={accountId} + /> + ))} + + ); +}; + +export default BirthdayPanel; diff --git a/app/soapbox/components/birthday_reminders.js b/app/soapbox/components/birthday_reminders.js index d57452150..aa50a2fec 100644 --- a/app/soapbox/components/birthday_reminders.js +++ b/app/soapbox/components/birthday_reminders.js @@ -51,7 +51,7 @@ class BirthdayReminders extends ImmutablePureComponent { const day = date.getDate(); const month = date.getMonth() + 1; - dispatch(fetchBirthdayReminders(day, month)); + dispatch(fetchBirthdayReminders(month, day)); } getHandlers() { diff --git a/app/soapbox/features/edit_profile/index.js b/app/soapbox/features/edit_profile/index.js index b683e8f19..fe0c66882 100644 --- a/app/soapbox/features/edit_profile/index.js +++ b/app/soapbox/features/edit_profile/index.js @@ -150,6 +150,7 @@ class EditProfile extends ImmutablePureComponent { display_name: state.display_name, website: state.website, location: state.location, + birthday: state.birthday, note: state.note, avatar: state.avatar_file, header: state.header_file, @@ -263,6 +264,18 @@ class EditProfile extends ImmutablePureComponent { /> + {features.birthdays && ( + } + > + + + )} + {features.accountLocation && ( } diff --git a/app/soapbox/features/ui/util/async-components.js b/app/soapbox/features/ui/util/async-components.js index 9f031adbc..17f54d3f4 100644 --- a/app/soapbox/features/ui/util/async-components.js +++ b/app/soapbox/features/ui/util/async-components.js @@ -222,6 +222,10 @@ export function BirthdaysModal() { return import(/* webpackChunkName: "features/ui" */'../components/birthdays_modal'); } +export function BirthdayPanel() { + return import(/* webpackChunkName: "features/ui" */'../../../components/birthday-panel'); +} + export function AccountNoteModal() { return import(/* webpackChunkName: "features/ui" */'../components/account_note_modal'); } diff --git a/app/soapbox/pages/home_page.js b/app/soapbox/pages/home_page.js index e8a12a5d8..e9b6630aa 100644 --- a/app/soapbox/pages/home_page.js +++ b/app/soapbox/pages/home_page.js @@ -11,6 +11,7 @@ import { TrendsPanel, SignUpPanel, CryptoDonatePanel, + BirthdayPanel, } from 'soapbox/features/ui/util/async-components'; // import GroupSidebarPanel from '../features/groups/sidebar_panel'; import { getFeatures } from 'soapbox/utils/features'; @@ -93,6 +94,11 @@ class HomePage extends ImmutablePureComponent { {Component => } )} + {features.birthdays && ( + + {Component => } + + )} {features.suggestions && ( {Component => } From 6968c6bf40e4c1d94799a9fe99a091cc0fc91888 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 18 Apr 2022 23:35:40 -0500 Subject: [PATCH 5/8] Remove BirthdayReminders component --- app/soapbox/components/birthday_reminders.js | 161 ------------------- app/soapbox/features/notifications/index.js | 35 +--- 2 files changed, 3 insertions(+), 193 deletions(-) delete mode 100644 app/soapbox/components/birthday_reminders.js diff --git a/app/soapbox/components/birthday_reminders.js b/app/soapbox/components/birthday_reminders.js deleted file mode 100644 index aa50a2fec..000000000 --- a/app/soapbox/components/birthday_reminders.js +++ /dev/null @@ -1,161 +0,0 @@ - -import PropTypes from 'prop-types'; -import React from 'react'; -import { HotKeys } from 'react-hotkeys'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { injectIntl, FormattedMessage } from 'react-intl'; -import { connect } from 'react-redux'; -import { Link } from 'react-router-dom'; - -import { fetchBirthdayReminders } from 'soapbox/actions/accounts'; -import { openModal } from 'soapbox/actions/modals'; -import Icon from 'soapbox/components/icon'; -import { HStack, Text } from 'soapbox/components/ui'; -import { makeGetAccount } from 'soapbox/selectors'; - -const mapStateToProps = (state, props) => { - const me = state.get('me'); - const getAccount = makeGetAccount(); - - const birthdays = state.getIn(['user_lists', 'birthday_reminders', me]); - - if (birthdays?.size > 0) { - return { - birthdays, - account: getAccount(state, birthdays.first()), - }; - } - - return { - birthdays, - }; -}; - -export default @connect(mapStateToProps) -@injectIntl -class BirthdayReminders extends ImmutablePureComponent { - - static propTypes = { - birthdays: ImmutablePropTypes.orderedSet, - intl: PropTypes.object.isRequired, - dispatch: PropTypes.func.isRequired, - onMoveDown: PropTypes.func, - }; - - componentDidMount() { - const { dispatch } = this.props; - - const date = new Date(); - - const day = date.getDate(); - const month = date.getMonth() + 1; - - dispatch(fetchBirthdayReminders(month, day)); - } - - getHandlers() { - return { - open: this.handleOpenBirthdaysModal, - moveDown: this.props.onMoveDown, - }; - } - - handleOpenBirthdaysModal = () => { - const { dispatch } = this.props; - - dispatch(openModal('BIRTHDAYS')); - } - - renderMessage() { - const { birthdays, account } = this.props; - - const link = ( - - - - ); - - if (birthdays.size === 1) { - return ; - } - - return ( - - - - ), - }} - /> - ); - } - - renderMessageForScreenReader = () => { - const { intl, birthdays, account } = this.props; - - if (birthdays.size === 1) { - return intl.formatMessage({ id: 'notification.birthday', defaultMessage: '{name} has a birthday today' }, { name: account.get('display_name') }); - } - - return intl.formatMessage( - { - id: 'notification.birthday_plural', - defaultMessage: '{name} and {more} have birthday today', - }, - { - name: account.get('display_name'), - more: intl.formatMessage( - { - id: 'notification.birthday.more', - defaultMessage: '{count} more {count, plural, one {friend} other {friends}}', - }, - { count: birthdays.size - 1 }, - ), - }, - ); - } - - render() { - const { birthdays } = this.props; - - if (!birthdays || birthdays.size === 0) return null; - - return ( - -
-
- - - - - {this.renderMessage()} - - -
-
-
- ); - } - -} diff --git a/app/soapbox/features/notifications/index.js b/app/soapbox/features/notifications/index.js index 5f739e913..2ed33a9c5 100644 --- a/app/soapbox/features/notifications/index.js +++ b/app/soapbox/features/notifications/index.js @@ -9,10 +9,8 @@ import { Virtuoso } from 'react-virtuoso'; import { createSelector } from 'reselect'; import { getSettings } from 'soapbox/actions/settings'; -import BirthdayReminders from 'soapbox/components/birthday_reminders'; import PullToRefresh from 'soapbox/components/pull-to-refresh'; import PlaceholderNotification from 'soapbox/features/placeholder/components/placeholder_notification'; -import { getFeatures } from 'soapbox/utils/features'; import { expandNotifications, @@ -30,12 +28,6 @@ const messages = defineMessages({ queue: { id: 'notifications.queue_label', defaultMessage: 'Click to see {count} new {count, plural, one {notification} other {notifications}}' }, }); -const Header = ({ context }) => ( - context.showBirthdayReminders ? ( - - ) : null -); - const Footer = ({ context }) => ( context.hasMore ? ( @@ -71,10 +63,6 @@ const getNotifications = createSelector([ const mapStateToProps = state => { const settings = getSettings(state); - const instance = state.get('instance'); - const features = getFeatures(instance); - const showBirthdayReminders = settings.getIn(['notifications', 'birthdays', 'show']) && settings.getIn(['notifications', 'quickFilter', 'active']) === 'all' && features.birthdays; - const birthdays = showBirthdayReminders && state.getIn(['user_lists', 'birthday_reminders', state.get('me')]); return { showFilterBar: settings.getIn(['notifications', 'quickFilter', 'show']), @@ -83,8 +71,6 @@ const mapStateToProps = state => { isUnread: state.getIn(['notifications', 'unread']) > 0, hasMore: state.getIn(['notifications', 'hasMore']), totalQueuedNotificationsCount: state.getIn(['notifications', 'totalQueuedNotificationsCount'], 0), - showBirthdayReminders, - hasBirthdays: !!birthdays, }; }; @@ -102,8 +88,6 @@ class Notifications extends React.PureComponent { hasMore: PropTypes.bool, dequeueNotifications: PropTypes.func, totalQueuedNotificationsCount: PropTypes.number, - showBirthdayReminders: PropTypes.bool, - hasBirthdays: PropTypes.bool, }; componentWillUnmount() { @@ -140,25 +124,15 @@ class Notifications extends React.PureComponent { } handleMoveUp = id => { - const { hasBirthdays } = this.props; - - let elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) - 1; - if (hasBirthdays) elementIndex++; + const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) - 1; this._selectChild(elementIndex, true); } handleMoveDown = id => { - const { hasBirthdays } = this.props; - - let elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) + 1; - if (hasBirthdays) elementIndex++; + const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) + 1; this._selectChild(elementIndex, false); } - handleMoveBelowBirthdays = () => { - this._selectChild(1, false); - } - _selectChild(index, align_top) { const container = this.column; const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`); @@ -183,7 +157,7 @@ class Notifications extends React.PureComponent { } render() { - const { intl, notifications, isLoading, hasMore, showFilterBar, totalQueuedNotificationsCount, showBirthdayReminders } = this.props; + const { intl, notifications, isLoading, hasMore, showFilterBar, totalQueuedNotificationsCount } = this.props; const emptyMessage = ; const filterBarContainer = showFilterBar @@ -208,13 +182,10 @@ class Notifications extends React.PureComponent { )} context={{ hasMore, - showBirthdayReminders, - handleMoveBelowBirthdays: this.handleMoveBelowBirthdays, isLoading, emptyMessage, }} components={{ - Header, ScrollSeekPlaceholder: PlaceholderNotification, Footer, EmptyPlaceholder, From 5a4ad706cf896cbf18a1c296bd99d80ebf57ba9a Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 19 Apr 2022 11:36:55 -0500 Subject: [PATCH 6/8] Widget: prevent circular imports --- app/soapbox/components/ui/widget/widget.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/soapbox/components/ui/widget/widget.tsx b/app/soapbox/components/ui/widget/widget.tsx index d0f34b90b..98d29e728 100644 --- a/app/soapbox/components/ui/widget/widget.tsx +++ b/app/soapbox/components/ui/widget/widget.tsx @@ -1,6 +1,8 @@ import React from 'react'; -import { Stack, HStack, Text, IconButton } from 'soapbox/components/ui'; +import { Text, IconButton } from 'soapbox/components/ui'; +import HStack from 'soapbox/components/ui/hstack/hstack'; +import Stack from 'soapbox/components/ui/stack/stack'; interface IWidgetTitle { title: string | React.ReactNode, From e5ca5464b76dcbef209f1ed8c354a4b9a8836c6b Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 19 Apr 2022 12:28:37 -0500 Subject: [PATCH 7/8] Widget: fix action button in dark mode --- app/soapbox/components/ui/widget/widget.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/soapbox/components/ui/widget/widget.tsx b/app/soapbox/components/ui/widget/widget.tsx index 98d29e728..1257d9779 100644 --- a/app/soapbox/components/ui/widget/widget.tsx +++ b/app/soapbox/components/ui/widget/widget.tsx @@ -36,7 +36,7 @@ const Widget: React.FC = ({ {onActionClick && ( Date: Tue, 19 Apr 2022 12:28:47 -0500 Subject: [PATCH 8/8] Account: normalize favicon and domain, clean up account.tsx --- app/soapbox/components/account.tsx | 35 +++++++++---------- .../normalizers/__tests__/account-test.js | 14 ++++++++ app/soapbox/normalizers/account.ts | 14 ++++++++ 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/app/soapbox/components/account.tsx b/app/soapbox/components/account.tsx index ccdc10578..c60893e5a 100644 --- a/app/soapbox/components/account.tsx +++ b/app/soapbox/components/account.tsx @@ -5,7 +5,7 @@ import HoverRefWrapper from 'soapbox/components/hover_ref_wrapper'; import VerificationBadge from 'soapbox/components/verification_badge'; import ActionButton from 'soapbox/features/ui/components/action_button'; import { useAppSelector, useOnScreen } from 'soapbox/hooks'; -import { getAcct, getDomain } from 'soapbox/utils/accounts'; +import { getAcct } from 'soapbox/utils/accounts'; import { displayFqn } from 'soapbox/utils/state'; import RelativeTimestamp from './relative_timestamp'; @@ -91,7 +91,7 @@ const Account = ({ ); } - if (account.get('id') !== me && account.get('relationship', null) !== null) { + if (account.id !== me) { return ; } @@ -118,8 +118,8 @@ const Account = ({ if (hidden) { return ( <> - {account.get('display_name')} - {account.get('username')} + {account.display_name} + {account.username} ); } @@ -128,34 +128,31 @@ const Account = ({ const LinkEl: any = showProfileHoverCard ? Link : 'div'; - const favicon = account.pleroma.get('favicon'); - const domain = getDomain(account); - return (
{children}} + wrapper={(children) => {children}} > event.stopPropagation()} > - +
{children}} + wrapper={(children) => {children}} > event.stopPropagation()} >
@@ -163,10 +160,10 @@ const Account = ({ size='sm' weight='semibold' truncate - dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }} + dangerouslySetInnerHTML={{ __html: account.display_name_html }} /> - {account.get('verified') && } + {account.verified && }
@@ -174,9 +171,9 @@ const Account = ({ @{username} - {favicon && ( - - + {account.favicon && ( + e.stopPropagation()}> + )} diff --git a/app/soapbox/normalizers/__tests__/account-test.js b/app/soapbox/normalizers/__tests__/account-test.js index 1735d0628..b78017e06 100644 --- a/app/soapbox/normalizers/__tests__/account-test.js +++ b/app/soapbox/normalizers/__tests__/account-test.js @@ -177,4 +177,18 @@ describe('normalizeAccount()', () => { expect(result.staff).toBe(true); expect(result.moderator).toBe(false); }); + + it('normalizes Pleroma favicon', () => { + const account = require('soapbox/__fixtures__/pleroma-account.json'); + const result = normalizeAccount(account); + + expect(result.favicon).toEqual('https://gleasonator.com/favicon.png'); + }); + + it('adds account domain', () => { + const account = require('soapbox/__fixtures__/pleroma-account.json'); + const result = normalizeAccount(account); + + expect(result.domain).toEqual('gleasonator.com'); + }); }); diff --git a/app/soapbox/normalizers/account.ts b/app/soapbox/normalizers/account.ts index 679dd770d..2ca866c18 100644 --- a/app/soapbox/normalizers/account.ts +++ b/app/soapbox/normalizers/account.ts @@ -28,6 +28,7 @@ export const AccountRecord = ImmutableRecord({ created_at: new Date(), display_name: '', emojis: ImmutableList(), + favicon: '', fields: ImmutableList(), followers_count: 0, following_count: 0, @@ -52,6 +53,7 @@ export const AccountRecord = ImmutableRecord({ // Internal fields admin: false, display_name_html: '', + domain: '', moderator: false, note_emojified: '', note_plain: '', @@ -224,6 +226,16 @@ const normalizeFqn = (account: ImmutableMap) => { return account.set('fqn', fqn); }; +const normalizeFavicon = (account: ImmutableMap) => { + const favicon = account.getIn(['pleroma', 'favicon']) || ''; + return account.set('favicon', favicon); +}; + +const addDomain = (account: ImmutableMap) => { + const domain = account.get('fqn', '').split('@')[1] || ''; + return account.set('domain', domain); +}; + const addStaffFields = (account: ImmutableMap) => { const admin = account.getIn(['pleroma', 'is_admin']) === true; const moderator = account.getIn(['pleroma', 'is_moderator']) === true; @@ -248,6 +260,8 @@ export const normalizeAccount = (account: Record) => { normalizeBirthday(account); normalizeLocation(account); normalizeFqn(account); + normalizeFavicon(account); + addDomain(account); addStaffFields(account); fixUsername(account); fixDisplayName(account);