From 2f5781b0468b844b48a5c20537a1a49b6fda7c02 Mon Sep 17 00:00:00 2001 From: "P. Reis" Date: Fri, 13 Dec 2024 22:03:14 -0300 Subject: [PATCH] refactor: make BoostModal pure, and openModal 'BOOST' pure --- src/components/status-action-bar.tsx | 9 ++++++--- src/components/status.tsx | 9 ++++++--- src/features/event/components/event-header.tsx | 13 ++++++++----- .../notifications/components/notification.tsx | 14 ++++++++------ src/features/status/components/thread.tsx | 9 ++++++--- src/features/ui/components/modals/boost-modal.tsx | 8 +++----- 6 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/components/status-action-bar.tsx b/src/components/status-action-bar.tsx index 28fd2f5ed..03a41cd47 100644 --- a/src/components/status-action-bar.tsx +++ b/src/components/status-action-bar.tsx @@ -36,7 +36,7 @@ import { blockAccount } from 'soapbox/actions/accounts.ts'; import { launchChat } from 'soapbox/actions/chats.ts'; import { directCompose, mentionCompose, quoteCompose, replyCompose } from 'soapbox/actions/compose.ts'; import { editEvent } from 'soapbox/actions/events.ts'; -import { pinToGroup, toggleBookmark, toggleDislike, toggleFavourite, togglePin, toggleReblog, unpinFromGroup } from 'soapbox/actions/interactions.ts'; +import { pinToGroup, toggleBookmark, toggleDislike, toggleFavourite, togglePin, unpinFromGroup } from 'soapbox/actions/interactions.ts'; import { openModal } from 'soapbox/actions/modals.ts'; import { deleteStatusModal, toggleStatusSensitivityModal } from 'soapbox/actions/moderation.tsx'; import { initMuteModal } from 'soapbox/actions/mutes.ts'; @@ -53,6 +53,7 @@ import { useAppDispatch } from 'soapbox/hooks/useAppDispatch.ts'; import { useAppSelector } from 'soapbox/hooks/useAppSelector.ts'; import { useFeatures } from 'soapbox/hooks/useFeatures.ts'; import { useOwnAccount } from 'soapbox/hooks/useOwnAccount.ts'; +import { useReblog } from 'soapbox/hooks/useReblog.ts'; import { useSettings } from 'soapbox/hooks/useSettings.ts'; import { GroupRoles } from 'soapbox/schemas/group-member.ts'; import { Status as StatusEntity } from 'soapbox/schemas/index.ts'; @@ -174,6 +175,8 @@ const StatusActionBar: React.FC = ({ const isStaff = account ? account.staff : false; const isAdmin = account ? account.admin : false; + const { toggleReblog } = useReblog(); + if (!status) { return null; } @@ -232,11 +235,11 @@ const StatusActionBar: React.FC = ({ const handleReblogClick: React.EventHandler = e => { if (me) { - const modalReblog = () => dispatch(toggleReblog(status)); + const modalReblog = () => toggleReblog(status.id); if ((e && e.shiftKey) || !boostModal) { modalReblog(); } else { - dispatch(openModal('BOOST', { status, onReblog: modalReblog })); + dispatch(openModal('BOOST', { status: status.toJS(), onReblog: modalReblog })); } } else { onOpenUnauthorizedModal('REBLOG'); diff --git a/src/components/status.tsx b/src/components/status.tsx index ccde634b8..317a7295e 100644 --- a/src/components/status.tsx +++ b/src/components/status.tsx @@ -7,7 +7,7 @@ import { useIntl, FormattedMessage, defineMessages } from 'react-intl'; import { Link, useHistory } from 'react-router-dom'; import { mentionCompose, replyCompose } from 'soapbox/actions/compose.ts'; -import { toggleFavourite, toggleReblog } from 'soapbox/actions/interactions.ts'; +import { toggleFavourite } from 'soapbox/actions/interactions.ts'; import { openModal } from 'soapbox/actions/modals.ts'; import { toggleStatusHidden, unfilterStatus } from 'soapbox/actions/statuses.ts'; import TranslateButton from 'soapbox/components/translate-button.tsx'; @@ -19,6 +19,7 @@ import AccountContainer from 'soapbox/containers/account-container.tsx'; import QuotedStatus from 'soapbox/features/status/containers/quoted-status-container.tsx'; import { HotKeys } from 'soapbox/features/ui/components/hotkeys.tsx'; import { useAppDispatch } from 'soapbox/hooks/useAppDispatch.ts'; +import { useReblog } from 'soapbox/hooks/useReblog.ts'; import { useSettings } from 'soapbox/hooks/useSettings.ts'; import { Status as StatusEntity } from 'soapbox/schemas/index.ts'; import { emojifyText } from 'soapbox/utils/emojify.tsx'; @@ -103,6 +104,8 @@ const Status: React.FC = (props) => { const filtered = (status.filtered.size || actualStatus.filtered.size) > 0; + const { toggleReblog } = useReblog(); + // Track height changes we know about to compensate scrolling. useEffect(() => { didShowCard.current = Boolean(!muted && !hidden && status?.card); @@ -166,11 +169,11 @@ const Status: React.FC = (props) => { }; const handleHotkeyBoost = (e?: KeyboardEvent): void => { - const modalReblog = () => dispatch(toggleReblog(actualStatus)); + const modalReblog = () => toggleReblog(actualStatus.id); if ((e && e.shiftKey) || !boostModal) { modalReblog(); } else { - dispatch(openModal('BOOST', { status: actualStatus, onReblog: modalReblog })); + dispatch(openModal('BOOST', { status: actualStatus.toJS(), onReblog: modalReblog })); } }; diff --git a/src/features/event/components/event-header.tsx b/src/features/event/components/event-header.tsx index 1a3d382d2..57aeff30e 100644 --- a/src/features/event/components/event-header.tsx +++ b/src/features/event/components/event-header.tsx @@ -29,7 +29,7 @@ import { blockAccount } from 'soapbox/actions/accounts.ts'; import { launchChat } from 'soapbox/actions/chats.ts'; import { directCompose, mentionCompose, quoteCompose } from 'soapbox/actions/compose.ts'; import { editEvent, fetchEventIcs } from 'soapbox/actions/events.ts'; -import { toggleBookmark, togglePin, toggleReblog } from 'soapbox/actions/interactions.ts'; +import { toggleBookmark, togglePin } from 'soapbox/actions/interactions.ts'; import { openModal } from 'soapbox/actions/modals.ts'; import { deleteStatusModal, toggleStatusSensitivityModal } from 'soapbox/actions/moderation.tsx'; import { initMuteModal } from 'soapbox/actions/mutes.ts'; @@ -47,6 +47,7 @@ import VerificationBadge from 'soapbox/components/verification-badge.tsx'; import { useAppDispatch } from 'soapbox/hooks/useAppDispatch.ts'; import { useFeatures } from 'soapbox/hooks/useFeatures.ts'; import { useOwnAccount } from 'soapbox/hooks/useOwnAccount.ts'; +import { useReblog } from 'soapbox/hooks/useReblog.ts'; import { useSettings } from 'soapbox/hooks/useSettings.ts'; import copy from 'soapbox/utils/copy.ts'; import { download } from 'soapbox/utils/download.ts'; @@ -58,7 +59,7 @@ import EventActionButton from '../components/event-action-button.tsx'; import EventDate from '../components/event-date.tsx'; import type { Menu as MenuType } from 'soapbox/components/dropdown-menu/index.ts'; -import type { Status as StatusEntity } from 'soapbox/types/entities.ts'; +import type { Status as LegacyStatus } from 'soapbox/types/entities.ts'; const messages = defineMessages({ bannerHeader: { id: 'event.banner', defaultMessage: 'Event banner' }, @@ -92,7 +93,7 @@ const messages = defineMessages({ }); interface IEventHeader { - status?: StatusEntity; + status?: LegacyStatus; } const EventHeader: React.FC = ({ status }) => { @@ -106,6 +107,8 @@ const EventHeader: React.FC = ({ status }) => { const isStaff = ownAccount ? ownAccount.staff : false; const isAdmin = ownAccount ? ownAccount.admin : false; + const { toggleReblog } = useReblog(); + if (!status || !status.event) { return ( <> @@ -148,11 +151,11 @@ const EventHeader: React.FC = ({ status }) => { }; const handleReblogClick = () => { - const modalReblog = () => dispatch(toggleReblog(status)); + const modalReblog = () => toggleReblog(status.id); if (!boostModal) { modalReblog(); } else { - dispatch(openModal('BOOST', { status, onReblog: modalReblog })); + dispatch(openModal('BOOST', { status: status.toJS(), onReblog: modalReblog })); } }; diff --git a/src/features/notifications/components/notification.tsx b/src/features/notifications/components/notification.tsx index c912c3ba4..e245710bd 100644 --- a/src/features/notifications/components/notification.tsx +++ b/src/features/notifications/components/notification.tsx @@ -17,7 +17,7 @@ import { defineMessages, useIntl, IntlShape, MessageDescriptor, defineMessage, F import { Link, useHistory } from 'react-router-dom'; import { mentionCompose } from 'soapbox/actions/compose.ts'; -import { reblog, favourite, unreblog, unfavourite } from 'soapbox/actions/interactions.ts'; +import { favourite, unreblog, unfavourite } from 'soapbox/actions/interactions.ts'; import { patchMe } from 'soapbox/actions/me.ts'; import { openModal } from 'soapbox/actions/modals.ts'; import { getSettings } from 'soapbox/actions/settings.ts'; @@ -35,13 +35,14 @@ import { HotKeys } from 'soapbox/features/ui/components/hotkeys.tsx'; import { useAppDispatch } from 'soapbox/hooks/useAppDispatch.ts'; import { useAppSelector } from 'soapbox/hooks/useAppSelector.ts'; import { useInstance } from 'soapbox/hooks/useInstance.ts'; +import { useReblog } from 'soapbox/hooks/useReblog.ts'; import { makeGetNotification } from 'soapbox/selectors/index.ts'; import toast from 'soapbox/toast.tsx'; import { emojifyText } from 'soapbox/utils/emojify.tsx'; import { NotificationType, validType } from 'soapbox/utils/notification.ts'; import type { ScrollPosition } from 'soapbox/components/status.tsx'; -import type { Account as AccountEntity, Status as StatusEntity, Notification as NotificationEntity } from 'soapbox/types/entities.ts'; +import type { Account as AccountEntity, Status as StatusLegacy, Notification as NotificationEntity } from 'soapbox/types/entities.ts'; const notificationForScreenReader = (intl: IntlShape, message: string, timestamp: Date) => { const output = [message]; @@ -204,7 +205,7 @@ interface INotification { notification: NotificationEntity; onMoveUp?: (notificationId: string) => void; onMoveDown?: (notificationId: string) => void; - onReblog?: (status: StatusEntity, e?: KeyboardEvent) => void; + onReblog?: (status: StatusLegacy, e?: KeyboardEvent) => void; getScrollPosition?: () => ScrollPosition | undefined; updateScrollBottom?: (bottom: number) => void; } @@ -221,6 +222,7 @@ const Notification: React.FC = (props) => { const history = useHistory(); const intl = useIntl(); const { instance } = useInstance(); + const { reblog } = useReblog(); const type = notification.type; const { account, status } = notification; @@ -277,10 +279,10 @@ const Notification: React.FC = (props) => { dispatch(unreblog(status)); } else { if (e?.shiftKey || !boostModal) { - dispatch(reblog(status)); + reblog(status.id); } else { - dispatch(openModal('BOOST', { status, onReblog: (status: StatusEntity) => { - dispatch(reblog(status)); + dispatch(openModal('BOOST', { status: status.toJS(), onReblog: (status: StatusLegacy) => { + reblog(status.id); } })); } } diff --git a/src/features/status/components/thread.tsx b/src/features/status/components/thread.tsx index bd0734098..16abb5430 100644 --- a/src/features/status/components/thread.tsx +++ b/src/features/status/components/thread.tsx @@ -7,7 +7,7 @@ import { useHistory } from 'react-router-dom'; import { type VirtuosoHandle } from 'react-virtuoso'; import { mentionCompose, replyCompose } from 'soapbox/actions/compose.ts'; -import { favourite, reblog, unfavourite, unreblog } from 'soapbox/actions/interactions.ts'; +import { favourite, unfavourite, unreblog } from 'soapbox/actions/interactions.ts'; import { openModal } from 'soapbox/actions/modals.ts'; import { getSettings } from 'soapbox/actions/settings.ts'; import { hideStatus, revealStatus } from 'soapbox/actions/statuses.ts'; @@ -20,6 +20,7 @@ import { HotKeys } from 'soapbox/features/ui/components/hotkeys.tsx'; import PendingStatus from 'soapbox/features/ui/components/pending-status.tsx'; import { useAppDispatch } from 'soapbox/hooks/useAppDispatch.ts'; import { useAppSelector } from 'soapbox/hooks/useAppSelector.ts'; +import { useReblog } from 'soapbox/hooks/useReblog.ts'; import { useSettings } from 'soapbox/hooks/useSettings.ts'; import { RootState } from 'soapbox/store.ts'; import { type Account, type Status } from 'soapbox/types/entities.ts'; @@ -100,6 +101,8 @@ const Thread = (props: IThread) => { const isUnderReview = status?.visibility === 'self'; + const { reblog } = useReblog(); + const { ancestorsIds, descendantsIds } = useAppSelector((state) => { let ancestorsIds = ImmutableOrderedSet(); let descendantsIds = ImmutableOrderedSet(); @@ -149,7 +152,7 @@ const Thread = (props: IThread) => { const handleReplyClick = (status: Status) => dispatch(replyCompose(status)); - const handleModalReblog = (status: Status) => dispatch(reblog(status)); + const handleModalReblog = (status: Status) => reblog(status.id); const handleReblogClick = (status: Status, e?: React.MouseEvent) => { dispatch((_, getState) => { @@ -160,7 +163,7 @@ const Thread = (props: IThread) => { if ((e && e.shiftKey) || !boostModal) { handleModalReblog(status); } else { - dispatch(openModal('BOOST', { status, onReblog: handleModalReblog })); + dispatch(openModal('BOOST', { status: status.toJS(), onReblog: handleModalReblog })); } } }); diff --git a/src/features/ui/components/modals/boost-modal.tsx b/src/features/ui/components/modals/boost-modal.tsx index 730586dcd..1258bc65b 100644 --- a/src/features/ui/components/modals/boost-modal.tsx +++ b/src/features/ui/components/modals/boost-modal.tsx @@ -8,16 +8,14 @@ import Text from 'soapbox/components/ui/text.tsx'; import ReplyIndicator from 'soapbox/features/compose/components/reply-indicator.tsx'; import { Status as StatusEntity } from 'soapbox/schemas/index.ts'; -import type { Status as LegacyStatus } from 'soapbox/types/entities.ts'; - const messages = defineMessages({ cancel_reblog: { id: 'status.cancel_reblog_private', defaultMessage: 'Un-repost' }, reblog: { id: 'status.reblog', defaultMessage: 'Repost' }, }); interface IBoostModal { - status: LegacyStatus; - onReblog: (status: LegacyStatus) => void; + status: StatusEntity; + onReblog: (status: StatusEntity) => void; onClose: () => void; } @@ -38,7 +36,7 @@ const BoostModal: React.FC = ({ status, onReblog, onClose }) => { confirmationText={intl.formatMessage(buttonText)} > - + {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}