import PropTypes from 'prop-types'; import { useRef, useCallback, useEffect, useState } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; import { Helmet } from 'react-helmet'; import { useSelector, useDispatch } from 'react-redux'; import InventoryIcon from '@/material-icons/400-24px/inventory_2.svg?react'; import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; import { openModal } from 'mastodon/actions/modal'; import { fetchNotificationRequests, expandNotificationRequests, acceptNotificationRequests, dismissNotificationRequests } from 'mastodon/actions/notifications'; import { changeSetting } from 'mastodon/actions/settings'; import { CheckBox } from 'mastodon/components/check_box'; import Column from 'mastodon/components/column'; import ColumnHeader from 'mastodon/components/column_header'; import ScrollableList from 'mastodon/components/scrollable_list'; import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container'; import { NotificationRequest } from './components/notification_request'; import { PolicyControls } from './components/policy_controls'; import SettingToggle from './components/setting_toggle'; const messages = defineMessages({ title: { id: 'notification_requests.title', defaultMessage: 'Filtered notifications' }, maximize: { id: 'notification_requests.maximize', defaultMessage: 'Maximize' }, more: { id: 'status.more', defaultMessage: 'More' }, acceptAll: { id: 'notification_requests.accept_all', defaultMessage: 'Accept all' }, dismissAll: { id: 'notification_requests.dismiss_all', defaultMessage: 'Dismiss all' }, acceptMultiple: { id: 'notification_requests.accept_multiple', defaultMessage: '{count, plural, one {Accept # request} other {Accept # requests}}' }, dismissMultiple: { id: 'notification_requests.dismiss_multiple', defaultMessage: '{count, plural, one {Dismiss # request} other {Dismiss # requests}}' }, confirmAcceptAllTitle: { id: 'notification_requests.confirm_accept_all.title', defaultMessage: 'Accept notification requests?' }, confirmAcceptAllMessage: { id: 'notification_requests.confirm_accept_all.message', defaultMessage: 'You are about to accept {count, plural, one {one notification request} other {# notification requests}}. Are you sure you want to proceed?' }, confirmAcceptAllButton: { id: 'notification_requests.confirm_accept_all.button', defaultMessage: 'Accept all' }, confirmDismissAllTitle: { id: 'notification_requests.confirm_dismiss_all.title', defaultMessage: 'Dismiss notification requests?' }, confirmDismissAllMessage: { id: 'notification_requests.confirm_dismiss_all.message', defaultMessage: "You are about to dismiss {count, plural, one {one notification request} other {# notification requests}}. You won't be able to easily access {count, plural, one {it} other {them}} again. Are you sure you want to proceed?" }, confirmDismissAllButton: { id: 'notification_requests.confirm_dismiss_all.button', defaultMessage: 'Dismiss all' }, }); const ColumnSettings = () => { const dispatch = useDispatch(); const settings = useSelector((state) => state.settings.get('notifications')); const onChange = useCallback( (key, checked) => { dispatch(changeSetting(['notifications', ...key], checked)); }, [dispatch], ); return (
} />
); }; const SelectRow = ({selectAllChecked, toggleSelectAll, selectedItems, selectionMode, setSelectionMode}) => { const intl = useIntl(); const dispatch = useDispatch(); const notificationRequests = useSelector(state => state.getIn(['notificationRequests', 'items'])); const selectedCount = selectedItems.length; const handleAcceptAll = useCallback(() => { const items = notificationRequests.map(request => request.get('id')).toArray(); dispatch(openModal({ modalType: 'CONFIRM', modalProps: { title: intl.formatMessage(messages.confirmAcceptAllTitle), message: intl.formatMessage(messages.confirmAcceptAllMessage, { count: items.length }), confirm: intl.formatMessage(messages.confirmAcceptAllButton), onConfirm: () => dispatch(acceptNotificationRequests(items)), }, })); }, [dispatch, intl, notificationRequests]); const handleDismissAll = useCallback(() => { const items = notificationRequests.map(request => request.get('id')).toArray(); dispatch(openModal({ modalType: 'CONFIRM', modalProps: { title: intl.formatMessage(messages.confirmDismissAllTitle), message: intl.formatMessage(messages.confirmDismissAllMessage, { count: items.length }), confirm: intl.formatMessage(messages.confirmDismissAllButton), onConfirm: () => dispatch(dismissNotificationRequests(items)), }, })); }, [dispatch, intl, notificationRequests]); const handleAcceptMultiple = useCallback(() => { dispatch(openModal({ modalType: 'CONFIRM', modalProps: { title: intl.formatMessage(messages.confirmAcceptAllTitle), message: intl.formatMessage(messages.confirmAcceptAllMessage, { count: selectedItems.length }), confirm: intl.formatMessage(messages.confirmAcceptAllButton), onConfirm: () => dispatch(acceptNotificationRequests(selectedItems)), }, })); }, [dispatch, intl, selectedItems]); const handleDismissMultiple = useCallback(() => { dispatch(openModal({ modalType: 'CONFIRM', modalProps: { title: intl.formatMessage(messages.confirmDismissAllTitle), message: intl.formatMessage(messages.confirmDismissAllMessage, { count: selectedItems.length }), confirm: intl.formatMessage(messages.confirmDismissAllButton), onConfirm: () => dispatch(dismissNotificationRequests(selectedItems)), }, })); }, [dispatch, intl, selectedItems]); const handleToggleSelectionMode = useCallback(() => { setSelectionMode((mode) => !mode); }, [setSelectionMode]); const menu = selectedCount === 0 ? [ { text: intl.formatMessage(messages.acceptAll), action: handleAcceptAll }, { text: intl.formatMessage(messages.dismissAll), action: handleDismissAll }, ] : [ { text: intl.formatMessage(messages.acceptMultiple, { count: selectedCount }), action: handleAcceptMultiple }, { text: intl.formatMessage(messages.dismissMultiple, { count: selectedCount }), action: handleDismissMultiple }, ]; return (
{selectionMode && (
0 && !selectAllChecked} onChange={toggleSelectAll} />
)}
{selectedCount > 0 &&
{selectedCount} selected
}
); }; SelectRow.propTypes = { selectAllChecked: PropTypes.func.isRequired, toggleSelectAll: PropTypes.func.isRequired, selectedItems: PropTypes.arrayOf(PropTypes.string).isRequired, selectionMode: PropTypes.bool, setSelectionMode: PropTypes.func.isRequired, }; export const NotificationRequests = ({ multiColumn }) => { const columnRef = useRef(); const intl = useIntl(); const dispatch = useDispatch(); const isLoading = useSelector(state => state.getIn(['notificationRequests', 'isLoading'])); const notificationRequests = useSelector(state => state.getIn(['notificationRequests', 'items'])); const hasMore = useSelector(state => !!state.getIn(['notificationRequests', 'next'])); const [selectionMode, setSelectionMode] = useState(false); const [checkedRequestIds, setCheckedRequestIds] = useState([]); const [selectAllChecked, setSelectAllChecked] = useState(false); const handleHeaderClick = useCallback(() => { columnRef.current?.scrollTop(); }, [columnRef]); const handleCheck = useCallback(id => { setCheckedRequestIds(ids => { const position = ids.indexOf(id); if(position > -1) ids.splice(position, 1); else ids.push(id); setSelectAllChecked(ids.length === notificationRequests.size); return [...ids]; }); }, [setCheckedRequestIds, notificationRequests]); const toggleSelectAll = useCallback(() => { setSelectAllChecked(checked => { if(checked) setCheckedRequestIds([]); else setCheckedRequestIds(notificationRequests.map(request => request.get('id')).toArray()); return !checked; }); }, [notificationRequests]); const handleLoadMore = useCallback(() => { dispatch(expandNotificationRequests()); }, [dispatch]); useEffect(() => { dispatch(fetchNotificationRequests()); }, [dispatch]); return ( } > } > {notificationRequests.map(request => ( ))} {intl.formatMessage(messages.title)} ); }; NotificationRequests.propTypes = { multiColumn: PropTypes.bool, }; export default NotificationRequests;