2024-03-11 11:02:21 -04:00
import PropTypes from 'prop-types' ;
import { useCallback } from 'react' ;
import { defineMessages , useIntl } from 'react-intl' ;
2024-08-09 10:56:39 -04:00
import classNames from 'classnames' ;
import { Link , useHistory } from 'react-router-dom' ;
2024-03-11 11:02:21 -04:00
import { useSelector , useDispatch } from 'react-redux' ;
2024-03-25 09:39:06 -04:00
import DeleteIcon from '@/material-icons/400-24px/delete.svg?react' ;
2024-08-09 10:56:39 -04:00
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react' ;
import { initBlockModal } from 'mastodon/actions/blocks' ;
import { initMuteModal } from 'mastodon/actions/mutes' ;
2024-03-11 11:02:21 -04:00
import { acceptNotificationRequest , dismissNotificationRequest } from 'mastodon/actions/notifications' ;
2024-08-09 10:56:39 -04:00
import { initReport } from 'mastodon/actions/reports' ;
2024-03-11 11:02:21 -04:00
import { Avatar } from 'mastodon/components/avatar' ;
2024-08-09 10:56:39 -04:00
import { CheckBox } from 'mastodon/components/check_box' ;
2024-03-11 11:02:21 -04:00
import { IconButton } from 'mastodon/components/icon_button' ;
2024-08-09 10:56:39 -04:00
import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container' ;
2024-03-11 11:02:21 -04:00
import { makeGetAccount } from 'mastodon/selectors' ;
import { toCappedNumber } from 'mastodon/utils/numbers' ;
const getAccount = makeGetAccount ( ) ;
const messages = defineMessages ( {
accept : { id : 'notification_requests.accept' , defaultMessage : 'Accept' } ,
dismiss : { id : 'notification_requests.dismiss' , defaultMessage : 'Dismiss' } ,
2024-08-09 10:56:39 -04:00
view : { id : 'notification_requests.view' , defaultMessage : 'View notifications' } ,
mute : { id : 'account.mute' , defaultMessage : 'Mute @{name}' } ,
block : { id : 'account.block' , defaultMessage : 'Block @{name}' } ,
report : { id : 'status.report' , defaultMessage : 'Report @{name}' } ,
more : { id : 'status.more' , defaultMessage : 'More' } ,
2024-03-11 11:02:21 -04:00
} ) ;
2024-08-09 10:56:39 -04:00
export const NotificationRequest = ( { id , accountId , notificationsCount , checked , showCheckbox , toggleCheck } ) => {
2024-03-11 11:02:21 -04:00
const dispatch = useDispatch ( ) ;
const account = useSelector ( state => getAccount ( state , accountId ) ) ;
const intl = useIntl ( ) ;
2024-08-09 10:56:39 -04:00
const { push : historyPush } = useHistory ( ) ;
2024-03-11 11:02:21 -04:00
const handleDismiss = useCallback ( ( ) => {
dispatch ( dismissNotificationRequest ( id ) ) ;
} , [ dispatch , id ] ) ;
const handleAccept = useCallback ( ( ) => {
dispatch ( acceptNotificationRequest ( id ) ) ;
} , [ dispatch , id ] ) ;
2024-08-09 10:56:39 -04:00
const handleMute = useCallback ( ( ) => {
dispatch ( initMuteModal ( account ) ) ;
} , [ dispatch , account ] ) ;
const handleBlock = useCallback ( ( ) => {
dispatch ( initBlockModal ( account ) ) ;
} , [ dispatch , account ] ) ;
const handleReport = useCallback ( ( ) => {
dispatch ( initReport ( account ) ) ;
} , [ dispatch , account ] ) ;
const handleView = useCallback ( ( ) => {
historyPush ( ` /notifications/requests/ ${ id } ` ) ;
} , [ historyPush , id ] ) ;
const menu = [
{ text : intl . formatMessage ( messages . view ) , action : handleView } ,
null ,
{ text : intl . formatMessage ( messages . accept ) , action : handleAccept } ,
null ,
{ text : intl . formatMessage ( messages . mute , { name : account . username } ) , action : handleMute , dangerous : true } ,
{ text : intl . formatMessage ( messages . block , { name : account . username } ) , action : handleBlock , dangerous : true } ,
{ text : intl . formatMessage ( messages . report , { name : account . username } ) , action : handleReport , dangerous : true } ,
] ;
const handleCheck = useCallback ( ( ) => {
toggleCheck ( id ) ;
} , [ toggleCheck , id ] ) ;
const handleClick = useCallback ( ( e ) => {
if ( showCheckbox ) {
toggleCheck ( id ) ;
e . preventDefault ( ) ;
e . stopPropagation ( ) ;
}
} , [ toggleCheck , id , showCheckbox ] ) ;
2024-03-11 11:02:21 -04:00
return (
2024-08-09 10:56:39 -04:00
/* eslint-disable-next-line jsx-a11y/no-static-element-interactions -- this is just a minor affordance, but we will need a comprehensive accessibility pass */
< div className = { classNames ( 'notification-request' , showCheckbox && 'notification-request--forced-checkbox' ) } onClick = { handleClick } >
< div className = 'notification-request__checkbox' aria - hidden = { ! showCheckbox } >
< CheckBox checked = { checked } onChange = { handleCheck } / >
< / div >
< Link to = { ` /notifications/requests/ ${ id } ` } className = 'notification-request__link' onClick = { handleClick } title = { account ? . acct } >
2024-08-02 09:18:19 -04:00
< Avatar account = { account } size = { 40 } counter = { toCappedNumber ( notificationsCount ) } / >
2024-03-11 11:02:21 -04:00
< div className = 'notification-request__name' >
< div className = 'notification-request__name__display-name' >
< bdi > < strong dangerouslySetInnerHTML = { { _ _html : account ? . get ( 'display_name_html' ) } } / > < / bdi >
< / div >
< span > @ { account ? . get ( 'acct' ) } < / span >
< / div >
< / Link >
< div className = 'notification-request__actions' >
2024-03-25 09:39:06 -04:00
< IconButton iconComponent = { DeleteIcon } onClick = { handleDismiss } title = { intl . formatMessage ( messages . dismiss ) } / >
2024-08-09 10:56:39 -04:00
< DropdownMenuContainer
items = { menu }
icons = 'ellipsis-h'
iconComponent = { MoreHorizIcon }
direction = 'right'
title = { intl . formatMessage ( messages . more ) }
/ >
2024-03-11 11:02:21 -04:00
< / div >
< / div >
) ;
} ;
NotificationRequest . propTypes = {
id : PropTypes . string . isRequired ,
accountId : PropTypes . string . isRequired ,
notificationsCount : PropTypes . string . isRequired ,
2024-08-09 10:56:39 -04:00
checked : PropTypes . bool ,
showCheckbox : PropTypes . bool ,
toggleCheck : PropTypes . func ,
2024-03-11 11:02:21 -04:00
} ;