refactor: make BoostModal pure, and openModal 'BOOST' pure

This commit is contained in:
P. Reis 2024-12-13 22:03:14 -03:00
parent 3aa6582b09
commit 2f5781b046
6 changed files with 37 additions and 25 deletions

View File

@ -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<IStatusActionBar> = ({
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<IStatusActionBar> = ({
const handleReblogClick: React.EventHandler<React.MouseEvent> = 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');

View File

@ -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<IStatus> = (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<IStatus> = (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 }));
}
};

View File

@ -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<IEventHeader> = ({ status }) => {
@ -106,6 +107,8 @@ const EventHeader: React.FC<IEventHeader> = ({ 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<IEventHeader> = ({ 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 }));
}
};

View File

@ -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<INotification> = (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<INotification> = (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);
} }));
}
}

View File

@ -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<string>();
let descendantsIds = ImmutableOrderedSet<string>();
@ -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 }));
}
}
});

View File

@ -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<IBoostModal> = ({ status, onReblog, onClose }) => {
confirmationText={intl.formatMessage(buttonText)}
>
<Stack space={4}>
<ReplyIndicator status={status.toJS() as StatusEntity} hideActions />
<ReplyIndicator status={status} hideActions />
<Text>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}