StatusActionBar: move action code directly into component, clean up

environments/review-status-fc-k135sw/deployments/733
Alex Gleason 2 years ago
parent 4970c6c307
commit 33fbb0f147
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7

@ -102,7 +102,6 @@ const Status: React.FC<IStatus> = (props) => {
const node = useRef<HTMLDivElement>(null); const node = useRef<HTMLDivElement>(null);
const [showMedia, setShowMedia] = useState<boolean>(defaultMediaVisibility(status, displayMedia)); const [showMedia, setShowMedia] = useState<boolean>(defaultMediaVisibility(status, displayMedia));
const [emojiSelectorFocused, setEmojiSelectorFocused] = useState(false);
const actualStatus = getActualStatus(status); const actualStatus = getActualStatus(status);
@ -192,12 +191,7 @@ const Status: React.FC<IStatus> = (props) => {
_expandEmojiSelector(); _expandEmojiSelector();
}; };
const handleEmojiSelectorUnfocus = (): void => {
setEmojiSelectorFocused(false);
};
const _expandEmojiSelector = (): void => { const _expandEmojiSelector = (): void => {
setEmojiSelectorFocused(true);
const firstEmoji: HTMLDivElement | null | undefined = node.current?.querySelector('.emoji-react-selector .emoji-react-selector__emoji'); const firstEmoji: HTMLDivElement | null | undefined = node.current?.querySelector('.emoji-react-selector .emoji-react-selector__emoji');
firstEmoji?.focus(); firstEmoji?.focus();
}; };
@ -397,13 +391,7 @@ const Status: React.FC<IStatus> = (props) => {
{quote} {quote}
{!hideActionBar && ( {!hideActionBar && (
// @ts-ignore <StatusActionBar status={actualStatus} />
<StatusActionBar
emojiSelectorFocused={emojiSelectorFocused}
handleEmojiSelectorUnfocus={handleEmojiSelectorUnfocus}
{...props}
status={actualStatus}
/>
)} )}
</div> </div>
</div> </div>

@ -1,19 +1,26 @@
import { List as ImmutableList } from 'immutable'; import { List as ImmutableList } from 'immutable';
import React from 'react'; import React from 'react';
import { defineMessages, useIntl } from 'react-intl'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { useDispatch } from 'react-redux';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { blockAccount } from 'soapbox/actions/accounts';
import { showAlertForError } from 'soapbox/actions/alerts';
import { launchChat } from 'soapbox/actions/chats';
import { directCompose, mentionCompose, quoteCompose, replyCompose } from 'soapbox/actions/compose';
import { bookmark, favourite, pin, reblog, unbookmark, unfavourite, unpin, unreblog } from 'soapbox/actions/interactions';
import { openModal } from 'soapbox/actions/modals'; import { openModal } from 'soapbox/actions/modals';
import { deactivateUserModal, deleteStatusModal, deleteUserModal, toggleStatusSensitivityModal } from 'soapbox/actions/moderation';
import { initMuteModal } from 'soapbox/actions/mutes';
import { initReport } from 'soapbox/actions/reports';
import { deleteStatus, editStatus, muteStatus, unmuteStatus } from 'soapbox/actions/statuses';
import EmojiButtonWrapper from 'soapbox/components/emoji-button-wrapper'; import EmojiButtonWrapper from 'soapbox/components/emoji-button-wrapper';
import StatusActionButton from 'soapbox/components/status-action-button'; import StatusActionButton from 'soapbox/components/status-action-button';
import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container'; import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container';
import { useAppSelector, useFeatures, useOwnAccount } from 'soapbox/hooks'; import { useAppDispatch, useAppSelector, useFeatures, useOwnAccount, useSettings, useSoapboxConfig } from 'soapbox/hooks';
import { getReactForStatus, reduceEmoji } from 'soapbox/utils/emoji_reacts'; import { getReactForStatus, reduceEmoji } from 'soapbox/utils/emoji_reacts';
import type { History } from 'history';
import type { Menu } from 'soapbox/components/dropdown_menu'; import type { Menu } from 'soapbox/components/dropdown_menu';
import type { Status } from 'soapbox/types/entities'; import type { Account, Status } from 'soapbox/types/entities';
const messages = defineMessages({ const messages = defineMessages({
delete: { id: 'status.delete', defaultMessage: 'Delete' }, delete: { id: 'status.delete', defaultMessage: 'Delete' },
@ -59,75 +66,43 @@ const messages = defineMessages({
reactionCry: { id: 'status.reactions.cry', defaultMessage: 'Sad' }, reactionCry: { id: 'status.reactions.cry', defaultMessage: 'Sad' },
reactionWeary: { id: 'status.reactions.weary', defaultMessage: 'Weary' }, reactionWeary: { id: 'status.reactions.weary', defaultMessage: 'Weary' },
quotePost: { id: 'status.quote', defaultMessage: 'Quote post' }, quotePost: { id: 'status.quote', defaultMessage: 'Quote post' },
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
deleteHeading: { id: 'confirmations.delete.heading', defaultMessage: 'Delete post' },
deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this post?' },
redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this post and re-draft it? Favorites and reposts will be lost, and replies to the original post will be orphaned.' },
blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
redraftHeading: { id: 'confirmations.redraft.heading', defaultMessage: 'Delete & redraft' },
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
}); });
interface IStatusActionBar { interface IStatusActionBar {
status: Status, status: Status,
onReply: (status: Status) => void,
onFavourite: (status: Status) => void,
onEmojiReact: (status: Status, emoji: string) => void,
onBookmark: (status: Status) => void,
onReblog: (status: Status, e: React.MouseEvent) => void,
onQuote: (status: Status) => void,
onDelete: (status: Status, redraft?: boolean) => void,
onEdit: (status: Status) => void,
onDirect: (account: any) => void,
onChat: (account: any, history: History) => void,
onMention: (account: any) => void,
onMute: (account: any) => void,
onBlock: (status: Status) => void,
onReport: (status: Status) => void,
onEmbed: (status: Status) => void,
onDeactivateUser: (status: Status) => void,
onDeleteUser: (status: Status) => void,
onToggleStatusSensitivity: (status: Status) => void,
onDeleteStatus: (status: Status) => void,
onMuteConversation: (status: Status) => void,
onPin: (status: Status) => void,
withDismiss?: boolean, withDismiss?: boolean,
withGroupAdmin?: boolean,
allowedEmoji: ImmutableList<string>,
emojiSelectorFocused: boolean,
handleEmojiSelectorUnfocus: () => void,
handleEmojiSelectorExpand?: React.EventHandler<React.KeyboardEvent>,
} }
const StatusActionBar: React.FC<IStatusActionBar> = ({ const StatusActionBar: React.FC<IStatusActionBar> = ({ status, withDismiss = false }) => {
status,
onReply,
onFavourite,
allowedEmoji,
onBookmark,
onReblog,
onQuote,
onDelete,
onEdit,
onPin,
onMention,
onDirect,
onChat,
onMute,
onBlock,
onEmbed,
onReport,
onMuteConversation,
onDeactivateUser,
onDeleteUser,
onDeleteStatus,
onToggleStatusSensitivity,
withDismiss,
}) => {
const intl = useIntl(); const intl = useIntl();
const history = useHistory(); const history = useHistory();
const dispatch = useDispatch(); const dispatch = useAppDispatch();
const me = useAppSelector(state => state.me); const me = useAppSelector(state => state.me);
const features = useFeatures(); const features = useFeatures();
const settings = useSettings();
const soapboxConfig = useSoapboxConfig();
const { allowedEmoji } = soapboxConfig;
const account = useOwnAccount(); const account = useOwnAccount();
const isStaff = account ? account.staff : false; const isStaff = account ? account.staff : false;
const isAdmin = account ? account.admin : false; const isAdmin = account ? account.admin : false;
if (!status) {
return null;
}
const onOpenUnauthorizedModal = (action?: string) => { const onOpenUnauthorizedModal = (action?: string) => {
dispatch(openModal('UNAUTHORIZED', { dispatch(openModal('UNAUTHORIZED', {
action, action,
@ -137,7 +112,18 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
const handleReplyClick: React.MouseEventHandler = (e) => { const handleReplyClick: React.MouseEventHandler = (e) => {
if (me) { if (me) {
onReply(status); dispatch((_, getState) => {
const state = getState();
if (state.compose.text.trim().length !== 0) {
dispatch(openModal('CONFIRM', {
message: intl.formatMessage(messages.replyMessage),
confirm: intl.formatMessage(messages.replyConfirm),
onConfirm: () => dispatch(replyCompose(status)),
}));
} else {
dispatch(replyCompose(status));
}
});
} else { } else {
onOpenUnauthorizedModal('REPLY'); onOpenUnauthorizedModal('REPLY');
} }
@ -156,7 +142,11 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
const handleFavouriteClick: React.EventHandler<React.MouseEvent> = (e) => { const handleFavouriteClick: React.EventHandler<React.MouseEvent> = (e) => {
if (me) { if (me) {
onFavourite(status); if (status.get('favourited')) {
dispatch(unfavourite(status));
} else {
dispatch(favourite(status));
}
} else { } else {
onOpenUnauthorizedModal('FAVOURITE'); onOpenUnauthorizedModal('FAVOURITE');
} }
@ -166,14 +156,32 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
const handleBookmarkClick: React.EventHandler<React.MouseEvent> = (e) => { const handleBookmarkClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation(); e.stopPropagation();
onBookmark(status);
if (status.get('bookmarked')) {
dispatch(unbookmark(status));
} else {
dispatch(bookmark(status));
}
};
const modalReblog = () => {
if (status.get('reblogged')) {
dispatch(unreblog(status));
} else {
dispatch(reblog(status));
}
}; };
const handleReblogClick: React.EventHandler<React.MouseEvent> = e => { const handleReblogClick: React.EventHandler<React.MouseEvent> = e => {
e.stopPropagation(); e.stopPropagation();
if (me) { if (me) {
onReblog(status, e); const boostModal = settings.get('boostModal');
if ((e && e.shiftKey) || !boostModal) {
modalReblog();
} else {
dispatch(openModal('BOOST', { status, onReblog: modalReblog }));
}
} else { } else {
onOpenUnauthorizedModal('REBLOG'); onOpenUnauthorizedModal('REBLOG');
} }
@ -183,54 +191,101 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
e.stopPropagation(); e.stopPropagation();
if (me) { if (me) {
onQuote(status); dispatch((_, getState) => {
const state = getState();
if (state.compose.text.trim().length !== 0) {
dispatch(openModal('CONFIRM', {
message: intl.formatMessage(messages.replyMessage),
confirm: intl.formatMessage(messages.replyConfirm),
onConfirm: () => dispatch(quoteCompose(status)),
}));
} else {
dispatch(quoteCompose(status));
}
});
} else { } else {
onOpenUnauthorizedModal('REBLOG'); onOpenUnauthorizedModal('REBLOG');
} }
}; };
const doDeleteStatus = (withRedraft = false) => {
dispatch((_, getState) => {
const deleteModal = settings.get('deleteModal');
if (!deleteModal) {
dispatch(deleteStatus(status.id, withRedraft));
} else {
dispatch(openModal('CONFIRM', {
icon: withRedraft ? require('@tabler/icons/edit.svg') : require('@tabler/icons/trash.svg'),
heading: intl.formatMessage(withRedraft ? messages.redraftHeading : messages.deleteHeading),
message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
onConfirm: () => dispatch(deleteStatus(status.id, withRedraft)),
}));
}
});
};
const handleDeleteClick: React.EventHandler<React.MouseEvent> = (e) => { const handleDeleteClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation(); e.stopPropagation();
onDelete(status); doDeleteStatus();
}; };
const handleRedraftClick: React.EventHandler<React.MouseEvent> = (e) => { const handleRedraftClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation(); e.stopPropagation();
onDelete(status, true); doDeleteStatus(true);
}; };
const handleEditClick: React.EventHandler<React.MouseEvent> = () => { const handleEditClick: React.EventHandler<React.MouseEvent> = () => {
onEdit(status); dispatch(editStatus(status.id));
}; };
const handlePinClick: React.EventHandler<React.MouseEvent> = (e) => { const handlePinClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation(); e.stopPropagation();
onPin(status);
if (status.get('pinned')) {
dispatch(unpin(status));
} else {
dispatch(pin(status));
}
}; };
const handleMentionClick: React.EventHandler<React.MouseEvent> = (e) => { const handleMentionClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation(); e.stopPropagation();
onMention(status.account); dispatch(mentionCompose(status.account as Account));
}; };
const handleDirectClick: React.EventHandler<React.MouseEvent> = (e) => { const handleDirectClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation(); e.stopPropagation();
onDirect(status.account); dispatch(directCompose(status.account as Account));
}; };
const handleChatClick: React.EventHandler<React.MouseEvent> = (e) => { const handleChatClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation(); e.stopPropagation();
onChat(status.account, history); const account = status.account as Account;
dispatch(launchChat(account.id, history));
}; };
const handleMuteClick: React.EventHandler<React.MouseEvent> = (e) => { const handleMuteClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation(); e.stopPropagation();
onMute(status.account); dispatch(initMuteModal(status.account as Account));
}; };
const handleBlockClick: React.EventHandler<React.MouseEvent> = (e) => { const handleBlockClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation(); e.stopPropagation();
onBlock(status);
const account = status.get('account') as Account;
dispatch(openModal('CONFIRM', {
icon: require('@tabler/icons/ban.svg'),
heading: <FormattedMessage id='confirmations.block.heading' defaultMessage='Block @{name}' values={{ name: account.get('acct') }} />,
message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.blockConfirm),
onConfirm: () => dispatch(blockAccount(account.id)),
secondary: intl.formatMessage(messages.blockAndReport),
onSecondary: () => {
dispatch(blockAccount(account.id));
dispatch(initReport(account, status));
},
}));
}; };
const handleOpen: React.EventHandler<React.MouseEvent> = (e) => { const handleOpen: React.EventHandler<React.MouseEvent> = (e) => {
@ -239,17 +294,25 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
}; };
const handleEmbed = () => { const handleEmbed = () => {
onEmbed(status); dispatch(openModal('EMBED', {
url: status.get('url'),
onError: (error: any) => dispatch(showAlertForError(error)),
}));
}; };
const handleReport: React.EventHandler<React.MouseEvent> = (e) => { const handleReport: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation(); e.stopPropagation();
onReport(status); dispatch(initReport(status.account as Account, status));
}; };
const handleConversationMuteClick: React.EventHandler<React.MouseEvent> = (e) => { const handleConversationMuteClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation(); e.stopPropagation();
onMuteConversation(status);
if (status.get('muted')) {
dispatch(unmuteStatus(status.id));
} else {
dispatch(muteStatus(status.id));
}
}; };
const handleCopy: React.EventHandler<React.MouseEvent> = (e) => { const handleCopy: React.EventHandler<React.MouseEvent> = (e) => {
@ -275,22 +338,22 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
const handleDeactivateUser: React.EventHandler<React.MouseEvent> = (e) => { const handleDeactivateUser: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation(); e.stopPropagation();
onDeactivateUser(status); dispatch(deactivateUserModal(intl, status.getIn(['account', 'id']) as string));
}; };
const handleDeleteUser: React.EventHandler<React.MouseEvent> = (e) => { const handleDeleteUser: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation(); e.stopPropagation();
onDeleteUser(status); dispatch(deleteUserModal(intl, status.getIn(['account', 'id']) as string));
}; };
const handleDeleteStatus: React.EventHandler<React.MouseEvent> = (e) => { const handleDeleteStatus: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation(); e.stopPropagation();
onDeleteStatus(status); dispatch(deleteStatusModal(intl, status.id));
}; };
const handleToggleStatusSensitivity: React.EventHandler<React.MouseEvent> = (e) => { const handleToggleStatusSensitivity: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation(); e.stopPropagation();
onToggleStatusSensitivity(status); dispatch(toggleStatusSensitivityModal(intl, status.id, status.sensitive));
}; };
const _makeMenu = (publicStatus: boolean) => { const _makeMenu = (publicStatus: boolean) => {

@ -3,46 +3,25 @@ import { List as ImmutableList, OrderedSet as ImmutableOrderedSet } from 'immuta
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import React, { useCallback, useEffect, useRef, useState } from 'react'; import React, { useCallback, useEffect, useRef, useState } from 'react';
import { HotKeys } from 'react-hotkeys'; import { HotKeys } from 'react-hotkeys';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { defineMessages, useIntl } from 'react-intl';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { blockAccount } from 'soapbox/actions/accounts';
import { launchChat } from 'soapbox/actions/chats';
import { import {
replyCompose, replyCompose,
mentionCompose, mentionCompose,
directCompose,
quoteCompose,
} from 'soapbox/actions/compose'; } from 'soapbox/actions/compose';
import { simpleEmojiReact } from 'soapbox/actions/emoji_reacts';
import { import {
favourite, favourite,
unfavourite, unfavourite,
reblog, reblog,
unreblog, unreblog,
bookmark,
unbookmark,
pin,
unpin,
} from 'soapbox/actions/interactions'; } from 'soapbox/actions/interactions';
import { openModal } from 'soapbox/actions/modals'; import { openModal } from 'soapbox/actions/modals';
import {
deactivateUserModal,
deleteUserModal,
deleteStatusModal,
toggleStatusSensitivityModal,
} from 'soapbox/actions/moderation';
import { initMuteModal } from 'soapbox/actions/mutes';
import { initReport } from 'soapbox/actions/reports';
import { getSettings } from 'soapbox/actions/settings'; import { getSettings } from 'soapbox/actions/settings';
import { import {
muteStatus,
unmuteStatus,
deleteStatus,
hideStatus, hideStatus,
revealStatus, revealStatus,
editStatus,
fetchStatusWithContext, fetchStatusWithContext,
fetchNext, fetchNext,
} from 'soapbox/actions/statuses'; } from 'soapbox/actions/statuses';
@ -55,7 +34,7 @@ import Tombstone from 'soapbox/components/tombstone';
import { Column, Stack } from 'soapbox/components/ui'; import { Column, Stack } from 'soapbox/components/ui';
import PlaceholderStatus from 'soapbox/features/placeholder/components/placeholder_status'; import PlaceholderStatus from 'soapbox/features/placeholder/components/placeholder_status';
import PendingStatus from 'soapbox/features/ui/components/pending_status'; import PendingStatus from 'soapbox/features/ui/components/pending_status';
import { useAppDispatch, useAppSelector, useSettings, useSoapboxConfig } from 'soapbox/hooks'; import { useAppDispatch, useAppSelector, useSettings } from 'soapbox/hooks';
import { makeGetStatus } from 'soapbox/selectors'; import { makeGetStatus } from 'soapbox/selectors';
import { defaultMediaVisibility, textForScreenReader } from 'soapbox/utils/status'; import { defaultMediaVisibility, textForScreenReader } from 'soapbox/utils/status';
@ -63,7 +42,6 @@ import DetailedStatus from './components/detailed-status';
import ThreadLoginCta from './components/thread-login-cta'; import ThreadLoginCta from './components/thread-login-cta';
import ThreadStatus from './components/thread-status'; import ThreadStatus from './components/thread-status';
import type { History } from 'history';
import type { VirtuosoHandle } from 'react-virtuoso'; import type { VirtuosoHandle } from 'react-virtuoso';
import type { RootState } from 'soapbox/store'; import type { RootState } from 'soapbox/store';
import type { import type {
@ -153,12 +131,10 @@ const Thread: React.FC<IThread> = (props) => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const settings = useSettings(); const settings = useSettings();
const soapboxConfig = useSoapboxConfig();
const me = useAppSelector(state => state.me); const me = useAppSelector(state => state.me);
const status = useAppSelector(state => getStatus(state, { id: props.params.statusId })); const status = useAppSelector(state => getStatus(state, { id: props.params.statusId }));
const displayMedia = settings.get('displayMedia') as DisplayMedia; const displayMedia = settings.get('displayMedia') as DisplayMedia;
const allowedEmoji = soapboxConfig.allowedEmoji;
const askReplyConfirmation = useAppSelector(state => state.compose.text.trim().length !== 0); const askReplyConfirmation = useAppSelector(state => state.compose.text.trim().length !== 0);
const { ancestorsIds, descendantsIds } = useAppSelector(state => { const { ancestorsIds, descendantsIds } = useAppSelector(state => {
@ -181,7 +157,6 @@ const Thread: React.FC<IThread> = (props) => {
}); });
const [showMedia, setShowMedia] = useState<boolean>(defaultMediaVisibility(status, displayMedia)); const [showMedia, setShowMedia] = useState<boolean>(defaultMediaVisibility(status, displayMedia));
const [emojiSelectorFocused, setEmojiSelectorFocused] = useState(false);
const [isLoaded, setIsLoaded] = useState<boolean>(!!status); const [isLoaded, setIsLoaded] = useState<boolean>(!!status);
const [next, setNext] = useState<string>(); const [next, setNext] = useState<string>();
@ -210,8 +185,11 @@ const Thread: React.FC<IThread> = (props) => {
setShowMedia(!showMedia); setShowMedia(!showMedia);
}; };
const handleEmojiReactClick = (status: StatusEntity, emoji: string) => { const handleHotkeyReact = () => {
dispatch(simpleEmojiReact(status, emoji)); if (statusRef.current) {
const firstEmoji: HTMLButtonElement | null = statusRef.current.querySelector('.emoji-react-selector .emoji-react-selector__emoji');
firstEmoji?.focus();
}
}; };
const handleFavouriteClick = (status: StatusEntity) => { const handleFavouriteClick = (status: StatusEntity) => {
@ -222,22 +200,6 @@ const Thread: React.FC<IThread> = (props) => {
} }
}; };
const handlePin = (status: StatusEntity) => {
if (status.pinned) {
dispatch(unpin(status));
} else {
dispatch(pin(status));
}
};
const handleBookmark = (status: StatusEntity) => {
if (status.bookmarked) {
dispatch(unbookmark(status));
} else {
dispatch(bookmark(status));
}
};
const handleReplyClick = (status: StatusEntity) => { const handleReplyClick = (status: StatusEntity) => {
if (askReplyConfirmation) { if (askReplyConfirmation) {
dispatch(openModal('CONFIRM', { dispatch(openModal('CONFIRM', {
@ -269,47 +231,6 @@ const Thread: React.FC<IThread> = (props) => {
}); });
}; };
const handleQuoteClick = (status: StatusEntity) => {
if (askReplyConfirmation) {
dispatch(openModal('CONFIRM', {
message: intl.formatMessage(messages.replyMessage),
confirm: intl.formatMessage(messages.replyConfirm),
onConfirm: () => dispatch(quoteCompose(status)),
}));
} else {
dispatch(quoteCompose(status));
}
};
const handleDeleteClick = (status: StatusEntity, withRedraft = false) => {
dispatch((_, getState) => {
const deleteModal = getSettings(getState()).get('deleteModal');
if (!deleteModal) {
dispatch(deleteStatus(status.id, withRedraft));
} else {
dispatch(openModal('CONFIRM', {
icon: withRedraft ? require('@tabler/icons/edit.svg') : require('@tabler/icons/trash.svg'),
heading: intl.formatMessage(withRedraft ? messages.redraftHeading : messages.deleteHeading),
message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
onConfirm: () => dispatch(deleteStatus(status.id, withRedraft)),
}));
}
});
};
const handleEditClick = (status: StatusEntity) => {
dispatch(editStatus(status.id));
};
const handleDirectClick = (account: AccountEntity) => {
dispatch(directCompose(account));
};
const handleChatClick = (account: AccountEntity, router: History) => {
dispatch(launchChat(account.id, router));
};
const handleMentionClick = (account: AccountEntity) => { const handleMentionClick = (account: AccountEntity) => {
dispatch(mentionCompose(account)); dispatch(mentionCompose(account));
}; };
@ -337,18 +258,6 @@ const Thread: React.FC<IThread> = (props) => {
} }
}; };
const handleMuteClick = (account: AccountEntity) => {
dispatch(initMuteModal(account));
};
const handleConversationMuteClick = (status: StatusEntity) => {
if (status.muted) {
dispatch(unmuteStatus(status.id));
} else {
dispatch(muteStatus(status.id));
}
};
const handleToggleHidden = (status: StatusEntity) => { const handleToggleHidden = (status: StatusEntity) => {
if (status.hidden) { if (status.hidden) {
dispatch(revealStatus(status.id)); dispatch(revealStatus(status.id));
@ -357,48 +266,6 @@ const Thread: React.FC<IThread> = (props) => {
} }
}; };
const handleBlockClick = (status: StatusEntity) => {
const { account } = status;
if (!account || typeof account !== 'object') return;
dispatch(openModal('CONFIRM', {
icon: require('@tabler/icons/ban.svg'),
heading: <FormattedMessage id='confirmations.block.heading' defaultMessage='Block @{name}' values={{ name: account.acct }} />,
message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong>@{account.acct}</strong> }} />,
confirm: intl.formatMessage(messages.blockConfirm),
onConfirm: () => dispatch(blockAccount(account.id)),
secondary: intl.formatMessage(messages.blockAndReport),
onSecondary: () => {
dispatch(blockAccount(account.id));
dispatch(initReport(account, status));
},
}));
};
const handleReport = (status: StatusEntity) => {
dispatch(initReport(status.account as AccountEntity, status));
};
const handleEmbed = (status: StatusEntity) => {
dispatch(openModal('EMBED', { url: status.url }));
};
const handleDeactivateUser = (status: StatusEntity) => {
dispatch(deactivateUserModal(intl, status.getIn(['account', 'id']) as string));
};
const handleDeleteUser = (status: StatusEntity) => {
dispatch(deleteUserModal(intl, status.getIn(['account', 'id']) as string));
};
const handleToggleStatusSensitivity = (status: StatusEntity) => {
dispatch(toggleStatusSensitivityModal(intl, status.id, status.sensitive));
};
const handleDeleteStatus = (status: StatusEntity) => {
dispatch(deleteStatusModal(intl, status.id));
};
const handleHotkeyMoveUp = () => { const handleHotkeyMoveUp = () => {
handleMoveUp(status!.id); handleMoveUp(status!.id);
}; };
@ -439,10 +306,6 @@ const Thread: React.FC<IThread> = (props) => {
handleToggleMediaVisibility(); handleToggleMediaVisibility();
}; };
const handleHotkeyReact = () => {
_expandEmojiSelector();
};
const handleMoveUp = (id: string) => { const handleMoveUp = (id: string) => {
if (id === status?.id) { if (id === status?.id) {
_selectChild(ancestorsIds.size - 1); _selectChild(ancestorsIds.size - 1);
@ -473,25 +336,6 @@ const Thread: React.FC<IThread> = (props) => {
} }
}; };
const handleEmojiSelectorExpand: React.EventHandler<React.KeyboardEvent> = e => {
if (e.key === 'Enter') {
_expandEmojiSelector();
}
e.preventDefault();
};
const handleEmojiSelectorUnfocus = () => {
setEmojiSelectorFocused(false);
};
const _expandEmojiSelector = () => {
if (statusRef.current) {
setEmojiSelectorFocused(true);
const firstEmoji: HTMLButtonElement | null = statusRef.current.querySelector('.emoji-react-selector .emoji-react-selector__emoji');
firstEmoji?.focus();
}
};
const _selectChild = (index: number) => { const _selectChild = (index: number) => {
scroller.current?.scrollIntoView({ scroller.current?.scrollIntoView({
index, index,
@ -640,34 +484,7 @@ const Thread: React.FC<IThread> = (props) => {
<hr className='mb-2 border-t-2 dark:border-primary-800' /> <hr className='mb-2 border-t-2 dark:border-primary-800' />
<StatusActionBar <StatusActionBar status={status} />
status={status}
onReply={handleReplyClick}
onFavourite={handleFavouriteClick}
onEmojiReact={handleEmojiReactClick}
onReblog={handleReblogClick}
onQuote={handleQuoteClick}
onDelete={handleDeleteClick}
onEdit={handleEditClick}
onDirect={handleDirectClick}
onChat={handleChatClick}
onMention={handleMentionClick}
onMute={handleMuteClick}
onMuteConversation={handleConversationMuteClick}
onBlock={handleBlockClick}
onReport={handleReport}
onPin={handlePin}
onBookmark={handleBookmark}
onEmbed={handleEmbed}
onDeactivateUser={handleDeactivateUser}
onDeleteUser={handleDeleteUser}
onToggleStatusSensitivity={handleToggleStatusSensitivity}
onDeleteStatus={handleDeleteStatus}
allowedEmoji={allowedEmoji}
emojiSelectorFocused={emojiSelectorFocused}
handleEmojiSelectorExpand={handleEmojiSelectorExpand}
handleEmojiSelectorUnfocus={handleEmojiSelectorUnfocus}
/>
</div> </div>
</HotKeys> </HotKeys>

Loading…
Cancel
Save