diff --git a/app/javascript/flavours/glitch/features/notifications/components/admin_report.jsx b/app/javascript/flavours/glitch/features/notifications/components/admin_report.jsx deleted file mode 100644 index 5ca8b59a5e..0000000000 --- a/app/javascript/flavours/glitch/features/notifications/components/admin_report.jsx +++ /dev/null @@ -1,114 +0,0 @@ -import PropTypes from 'prop-types'; - -import { FormattedMessage } from 'react-intl'; - -import classNames from 'classnames'; -import { withRouter } from 'react-router-dom'; - -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - -import { HotKeys } from 'react-hotkeys'; - -import FlagIcon from '@/material-icons/400-24px/flag-fill.svg?react'; -import { Icon } from 'flavours/glitch/components/icon'; -import { Permalink } from 'flavours/glitch/components/permalink'; -import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router'; - -import NotificationOverlayContainer from '../containers/overlay_container'; - -import Report from './report'; - -class AdminReport extends ImmutablePureComponent { - - static propTypes = { - hidden: PropTypes.bool, - id: PropTypes.string.isRequired, - account: ImmutablePropTypes.map.isRequired, - notification: ImmutablePropTypes.map.isRequired, - unread: PropTypes.bool, - report: ImmutablePropTypes.map.isRequired, - ...WithRouterPropTypes, - }; - - handleMoveUp = () => { - const { notification, onMoveUp } = this.props; - onMoveUp(notification.get('id')); - }; - - handleMoveDown = () => { - const { notification, onMoveDown } = this.props; - onMoveDown(notification.get('id')); - }; - - handleOpen = () => { - this.handleOpenProfile(); - }; - - handleOpenProfile = () => { - const { history, notification } = this.props; - history.push(`/@${notification.getIn(['account', 'acct'])}`); - }; - - handleMention = e => { - e.preventDefault(); - - const { history, notification, onMention } = this.props; - onMention(notification.get('account'), history); - }; - - getHandlers () { - return { - moveUp: this.handleMoveUp, - moveDown: this.handleMoveDown, - open: this.handleOpen, - openProfile: this.handleOpenProfile, - mention: this.handleMention, - reply: this.handleMention, - }; - } - - render () { - const { account, notification, unread, report } = this.props; - - if (!report) { - return null; - } - - // Links to the display name. - const displayName = account.get('display_name_html') || account.get('username'); - const link = ( - - ); - - const targetAccount = report.get('target_account'); - const targetDisplayNameHtml = { __html: targetAccount.get('display_name_html') }; - const targetLink = ; - - return ( - -
-
- - - - - -
- -
-
- ); - } - -} - -export default withRouter(AdminReport); diff --git a/app/javascript/flavours/glitch/features/notifications/components/admin_signup.jsx b/app/javascript/flavours/glitch/features/notifications/components/admin_signup.jsx deleted file mode 100644 index 4c815099b1..0000000000 --- a/app/javascript/flavours/glitch/features/notifications/components/admin_signup.jsx +++ /dev/null @@ -1,107 +0,0 @@ -import PropTypes from 'prop-types'; - -import { FormattedMessage } from 'react-intl'; - -import classNames from 'classnames'; -import { withRouter } from 'react-router-dom'; - -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - -import { HotKeys } from 'react-hotkeys'; - -import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react'; -import { Icon } from 'flavours/glitch/components/icon'; -import { Permalink } from 'flavours/glitch/components/permalink'; -import AccountContainer from 'flavours/glitch/containers/account_container'; -import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router'; - -import NotificationOverlayContainer from '../containers/overlay_container'; - -class NotificationAdminSignup extends ImmutablePureComponent { - - static propTypes = { - hidden: PropTypes.bool, - id: PropTypes.string.isRequired, - account: ImmutablePropTypes.map.isRequired, - notification: ImmutablePropTypes.map.isRequired, - unread: PropTypes.bool, - ...WithRouterPropTypes, - }; - - handleMoveUp = () => { - const { notification, onMoveUp } = this.props; - onMoveUp(notification.get('id')); - }; - - handleMoveDown = () => { - const { notification, onMoveDown } = this.props; - onMoveDown(notification.get('id')); - }; - - handleOpen = () => { - this.handleOpenProfile(); - }; - - handleOpenProfile = () => { - const { history, notification } = this.props; - history.push(`/@${notification.getIn(['account', 'acct'])}`); - }; - - handleMention = e => { - e.preventDefault(); - - const { history, notification, onMention } = this.props; - onMention(notification.get('account'), history); - }; - - getHandlers () { - return { - moveUp: this.handleMoveUp, - moveDown: this.handleMoveDown, - open: this.handleOpen, - openProfile: this.handleOpenProfile, - mention: this.handleMention, - reply: this.handleMention, - }; - } - - render () { - const { account, notification, hidden, unread } = this.props; - - // Links to the display name. - const displayName = account.get('display_name_html') || account.get('username'); - const link = ( - - ); - - // Renders. - return ( - -
-
- - - -
- -
-
- ); - } - -} - -export default withRouter(NotificationAdminSignup); diff --git a/app/javascript/flavours/glitch/features/notifications/components/follow.jsx b/app/javascript/flavours/glitch/features/notifications/components/follow.jsx deleted file mode 100644 index d26039fd5f..0000000000 --- a/app/javascript/flavours/glitch/features/notifications/components/follow.jsx +++ /dev/null @@ -1,107 +0,0 @@ -import PropTypes from 'prop-types'; - -import { FormattedMessage } from 'react-intl'; - -import classNames from 'classnames'; -import { withRouter } from 'react-router-dom'; - -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - -import { HotKeys } from 'react-hotkeys'; - -import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react'; -import { Icon } from 'flavours/glitch/components/icon'; -import { Permalink } from 'flavours/glitch/components/permalink'; -import AccountContainer from 'flavours/glitch/containers/account_container'; -import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router'; - -import NotificationOverlayContainer from '../containers/overlay_container'; - -class NotificationFollow extends ImmutablePureComponent { - - static propTypes = { - hidden: PropTypes.bool, - id: PropTypes.string.isRequired, - account: ImmutablePropTypes.map.isRequired, - notification: ImmutablePropTypes.map.isRequired, - unread: PropTypes.bool, - ...WithRouterPropTypes, - }; - - handleMoveUp = () => { - const { notification, onMoveUp } = this.props; - onMoveUp(notification.get('id')); - }; - - handleMoveDown = () => { - const { notification, onMoveDown } = this.props; - onMoveDown(notification.get('id')); - }; - - handleOpen = () => { - this.handleOpenProfile(); - }; - - handleOpenProfile = () => { - const { history, notification } = this.props; - history.push(`/@${notification.getIn(['account', 'acct'])}`); - }; - - handleMention = e => { - e.preventDefault(); - - const { history, notification, onMention } = this.props; - onMention(notification.get('account'), history); - }; - - getHandlers () { - return { - moveUp: this.handleMoveUp, - moveDown: this.handleMoveDown, - open: this.handleOpen, - openProfile: this.handleOpenProfile, - mention: this.handleMention, - reply: this.handleMention, - }; - } - - render () { - const { account, notification, hidden, unread } = this.props; - - // Links to the display name. - const displayName = account.get('display_name_html') || account.get('username'); - const link = ( - - ); - - // Renders. - return ( - -
-
- - - -
- -
-
- ); - } - -} - -export default withRouter(NotificationFollow); diff --git a/app/javascript/flavours/glitch/features/notifications/components/follow_request.jsx b/app/javascript/flavours/glitch/features/notifications/components/follow_request.jsx index 11aa343609..bd45e1f826 100644 --- a/app/javascript/flavours/glitch/features/notifications/components/follow_request.jsx +++ b/app/javascript/flavours/glitch/features/notifications/components/follow_request.jsx @@ -1,26 +1,16 @@ import PropTypes from 'prop-types'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; - -import classNames from 'classnames'; -import { withRouter } from 'react-router-dom'; +import { defineMessages, injectIntl } from 'react-intl'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; -import { HotKeys } from 'react-hotkeys'; - import CheckIcon from '@/material-icons/400-24px/check.svg?react'; import CloseIcon from '@/material-icons/400-24px/close.svg?react'; -import PersonIcon from '@/material-icons/400-24px/person-fill.svg?react'; import { Avatar } from 'flavours/glitch/components/avatar'; import { DisplayName } from 'flavours/glitch/components/display_name'; -import { Icon } from 'flavours/glitch/components/icon'; import { IconButton } from 'flavours/glitch/components/icon_button'; import { Permalink } from 'flavours/glitch/components/permalink'; -import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router'; - -import NotificationOverlayContainer from '../containers/overlay_container'; const messages = defineMessages({ authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' }, @@ -34,50 +24,10 @@ class FollowRequest extends ImmutablePureComponent { onAuthorize: PropTypes.func.isRequired, onReject: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, - notification: ImmutablePropTypes.map.isRequired, - unread: PropTypes.bool, - ...WithRouterPropTypes, }; - handleMoveUp = () => { - const { notification, onMoveUp } = this.props; - onMoveUp(notification.get('id')); - }; - - handleMoveDown = () => { - const { notification, onMoveDown } = this.props; - onMoveDown(notification.get('id')); - }; - - handleOpen = () => { - this.handleOpenProfile(); - }; - - handleOpenProfile = () => { - const { history, notification } = this.props; - history.push(`/@${notification.getIn(['account', 'acct'])}`); - }; - - handleMention = e => { - e.preventDefault(); - - const { history, notification, onMention } = this.props; - onMention(notification.get('account'), history); - }; - - getHandlers () { - return { - moveUp: this.handleMoveUp, - moveDown: this.handleMoveDown, - open: this.handleOpen, - openProfile: this.handleOpenProfile, - mention: this.handleMention, - reply: this.handleMention, - }; - } - render () { - const { intl, hidden, account, onAuthorize, onReject, notification, unread } = this.props; + const { intl, hidden, account, onAuthorize, onReject } = this.props; if (!account) { return
; @@ -92,51 +42,23 @@ class FollowRequest extends ImmutablePureComponent { ); } - // Links to the display name. - const displayName = account.get('display_name_html') || account.get('username'); - const link = ( - - ); - return ( - -
-
- +
+
+ +
+ +
- +
+ +
- -
-
- -
- -
- -
- - -
-
-
- -
- +
); } } -export default withRouter(injectIntl(FollowRequest)); +export default injectIntl(FollowRequest); diff --git a/app/javascript/flavours/glitch/features/notifications/components/notification.jsx b/app/javascript/flavours/glitch/features/notifications/components/notification.jsx index 1d476969cb..4aac5e8d6d 100644 --- a/app/javascript/flavours/glitch/features/notifications/components/notification.jsx +++ b/app/javascript/flavours/glitch/features/notifications/components/notification.jsx @@ -1,236 +1,410 @@ -// Package imports. import PropTypes from 'prop-types'; +import { injectIntl, FormattedMessage, defineMessages } from 'react-intl'; + +import classNames from 'classnames'; +import { withRouter } from 'react-router-dom'; + import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; -// Our imports, +import { HotKeys } from 'react-hotkeys'; + +import FlagIcon from '@/material-icons/400-24px/flag-fill.svg?react'; +import PersonIcon from '@/material-icons/400-24px/person-fill.svg?react'; +import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react'; +import { Icon } from 'flavours/glitch/components/icon'; +import { Permalink } from 'flavours/glitch/components/permalink'; +import AccountContainer from 'flavours/glitch/containers/account_container'; import StatusContainer from 'flavours/glitch/containers/status_container'; +import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router'; -import NotificationAdminReportContainer from '../containers/admin_report_container'; -import NotificationFollowRequestContainer from '../containers/follow_request_container'; +import FollowRequestContainer from '../containers/follow_request_container'; +import NotificationOverlayContainer from '../containers/overlay_container'; -import NotificationAdminSignup from './admin_signup'; -import NotificationFollow from './follow'; +import Report from './report'; -export default class Notification extends ImmutablePureComponent { +const messages = defineMessages({ + follow: { id: 'notification.follow', defaultMessage: '{name} followed you' }, + adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' }, + adminReport: { id: 'notification.admin.report', defaultMessage: '{name} reported {target}' }, +}); +const notificationForScreenReader = (intl, message, timestamp) => { + const output = [message]; + + output.push(intl.formatDate(timestamp, { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' })); + + return output.join(', '); +}; + +class Notification extends ImmutablePureComponent { static propTypes = { notification: ImmutablePropTypes.map.isRequired, hidden: PropTypes.bool, onMoveUp: PropTypes.func.isRequired, onMoveDown: PropTypes.func.isRequired, onMention: PropTypes.func.isRequired, + onFavourite: PropTypes.func.isRequired, + onReblog: PropTypes.func.isRequired, + onToggleHidden: PropTypes.func.isRequired, + status: ImmutablePropTypes.map, + intl: PropTypes.object.isRequired, getScrollPosition: PropTypes.func, updateScrollBottom: PropTypes.func, cacheMediaWidth: PropTypes.func, cachedMediaWidth: PropTypes.number, onUnmount: PropTypes.func, unread: PropTypes.bool, + ...WithRouterPropTypes, }; + handleMoveUp = () => { + const { notification, onMoveUp } = this.props; + onMoveUp(notification.get('id')); + }; + + handleMoveDown = () => { + const { notification, onMoveDown } = this.props; + onMoveDown(notification.get('id')); + }; + + handleOpen = () => { + const { notification } = this.props; + + if (notification.get('status')) { + this.props.history.push(`/@${notification.getIn(['status', 'account', 'acct'])}/${notification.get('status')}`); + } else { + this.handleOpenProfile(); + } + }; + + handleOpenProfile = () => { + const { notification } = this.props; + this.props.history.push(`/@${notification.getIn(['account', 'acct'])}`); + }; + + handleMention = e => { + e.preventDefault(); + + const { notification, onMention } = this.props; + onMention(notification.get('account'), this.props.history); + }; + + handleHotkeyFavourite = () => { + const { status } = this.props; + if (status) this.props.onFavourite(status); + }; + + handleHotkeyBoost = e => { + const { status } = this.props; + if (status) this.props.onReblog(status, e); + }; + + getHandlers () { + return { + reply: this.handleMention, + favourite: this.handleHotkeyFavourite, + boost: this.handleHotkeyBoost, + mention: this.handleMention, + open: this.handleOpen, + openProfile: this.handleOpenProfile, + moveUp: this.handleMoveUp, + moveDown: this.handleMoveDown, + }; + } + + renderFollow (notification, account, link) { + const { intl, unread } = this.props; + + return ( + +
+
+ + + + + +
+ +
+
+ ); + } + + renderFollowRequest (notification, account, link) { + const { intl, unread } = this.props; + + return ( + +
+
+ + + + + +
+ +
+
+ ); + } + + renderMention (notification) { + return ( +