summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2024-03-25 14:27:38 +0100
committerGitHub <noreply@github.com>2024-03-25 13:27:38 +0000
commit29f9dc742eaca1898455e37e01fff087e4bf42a6 (patch)
tree48c45ba9c0846644683d1300b2303b79e05a663c
parentdd061291b1e89b6c67e6dff06ad087abdf7821dc (diff)
Change design of notification about lost connections in web UI (#29731)
-rw-r--r--app/javascript/mastodon/features/notifications/components/notification.jsx27
-rw-r--r--app/javascript/mastodon/features/notifications/components/relationships_severance_event.jsx64
-rw-r--r--app/javascript/mastodon/locales/en.json12
-rw-r--r--app/javascript/styles/mastodon/components.scss38
4 files changed, 80 insertions, 61 deletions
diff --git a/app/javascript/mastodon/features/notifications/components/notification.jsx b/app/javascript/mastodon/features/notifications/components/notification.jsx
index 5527f3d4826..c0915546280 100644
--- a/app/javascript/mastodon/features/notifications/components/notification.jsx
+++ b/app/javascript/mastodon/features/notifications/components/notification.jsx
@@ -12,7 +12,6 @@ import { HotKeys } from 'react-hotkeys';
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
import FlagIcon from '@/material-icons/400-24px/flag-fill.svg?react';
-import HeartBrokenIcon from '@/material-icons/400-24px/heart_broken-fill.svg?react';
import HomeIcon from '@/material-icons/400-24px/home-fill.svg?react';
import InsertChartIcon from '@/material-icons/400-24px/insert_chart.svg?react';
import PersonIcon from '@/material-icons/400-24px/person-fill.svg?react';
@@ -27,7 +26,7 @@ import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import FollowRequestContainer from '../containers/follow_request_container';
-import RelationshipsSeveranceEvent from './relationships_severance_event';
+import { RelationshipsSeveranceEvent } from './relationships_severance_event';
import Report from './report';
const messages = defineMessages({
@@ -40,6 +39,7 @@ const messages = defineMessages({
update: { id: 'notification.update', defaultMessage: '{name} edited a post' },
adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' },
adminReport: { id: 'notification.admin.report', defaultMessage: '{name} reported {target}' },
+ relationshipsSevered: { id: 'notification.relationships_severance_event', defaultMessage: 'Lost connections with {name}' },
});
const notificationForScreenReader = (intl, message, timestamp) => {
@@ -361,24 +361,23 @@ class Notification extends ImmutablePureComponent {
}
renderRelationshipsSevered (notification) {
- const { intl, unread } = this.props;
+ const { intl, unread, hidden } = this.props;
+ const event = notification.get('event');
- if (!notification.get('event')) {
+ if (!event) {
return null;
}
return (
<HotKeys handlers={this.getHandlers()}>
- <div className={classNames('notification notification-severed-relationships focusable', { unread })} tabIndex={0} aria-label={notificationForScreenReader(intl, intl.formatMessage(messages.adminReport, { name: notification.getIn(['event', 'target_name']) }), notification.get('created_at'))}>
- <div className='notification__message'>
- <Icon id='heart_broken' icon={HeartBrokenIcon} />
-
- <span title={notification.get('created_at')}>
- <FormattedMessage id='notification.severed_relationships' defaultMessage='Relationships with {name} severed' values={{ name: notification.getIn(['event', 'target_name']) }} />
- </span>
- </div>
-
- <RelationshipsSeveranceEvent event={notification.get('event')} />
+ <div className={classNames('notification notification-severed-relationships focusable', { unread })} tabIndex={0} aria-label={notificationForScreenReader(intl, intl.formatMessage(messages.relationshipsSevered, { name: notification.getIn(['event', 'target_name']) }), notification.get('created_at'))}>
+ <RelationshipsSeveranceEvent
+ type={event.get('type')}
+ target={event.get('target_name')}
+ followersCount={event.get('followers_count')}
+ followingCount={event.get('following_count')}
+ hidden={hidden}
+ />
</div>
</HotKeys>
);
diff --git a/app/javascript/mastodon/features/notifications/components/relationships_severance_event.jsx b/app/javascript/mastodon/features/notifications/components/relationships_severance_event.jsx
index 23d0d2eecf3..738159fc5a2 100644
--- a/app/javascript/mastodon/features/notifications/components/relationships_severance_event.jsx
+++ b/app/javascript/mastodon/features/notifications/components/relationships_severance_event.jsx
@@ -2,60 +2,44 @@ import PropTypes from 'prop-types';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
-import ImmutablePropTypes from 'react-immutable-proptypes';
+import HeartBrokenIcon from '@/material-icons/400-24px/heart_broken-fill.svg?react';
+import { Icon } from 'mastodon/components/icon';
+import { domain } from 'mastodon/initial_state';
-import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
-
-// This needs to be kept in sync with app/models/relationship_severance_event.rb
+// This needs to be kept in sync with app/models/relationships_severance_event.rb
const messages = defineMessages({
- account_suspension: { id: 'relationship_severance_notification.types.account_suspension', defaultMessage: 'Account has been suspended' },
- domain_block: { id: 'relationship_severance_notification.types.domain_block', defaultMessage: 'Domain has been suspended' },
- user_domain_block: { id: 'relationship_severance_notification.types.user_domain_block', defaultMessage: 'You blocked this domain' },
+ account_suspension: { id: 'notification.relationships_severance_event.account_suspension', defaultMessage: 'An admin from {from} has suspended {target}, which means you can no longer receive updates from them or interact with them.' },
+ domain_block: { id: 'notification.relationships_severance_event.domain_block', defaultMessage: 'An admin from {from} has blocked {target}, including {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.' },
+ user_domain_block: { id: 'notification.relationships_severance_event.user_domain_block', defaultMessage: 'You have blocked {target}, removing {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.' },
});
-const RelationshipsSeveranceEvent = ({ event, hidden }) => {
+export const RelationshipsSeveranceEvent = ({ type, target, followingCount, followersCount, hidden }) => {
const intl = useIntl();
- if (hidden || !event) {
+ if (hidden) {
return null;
}
return (
- <div className='notification__report'>
- <div className='notification__report__details'>
- <div>
- <RelativeTimestamp timestamp={event.get('created_at')} short={false} />
- {' · '}
- { event.get('purged') ? (
- <FormattedMessage
- id='relationship_severance_notification.purged_data'
- defaultMessage='purged by administrators'
- />
- ) : (
- <FormattedMessage
- id='relationship_severance_notification.relationships'
- defaultMessage='{count, plural, one {# relationship} other {# relationships}}'
- values={{ count: event.get('followers_count', 0) + event.get('following_count', 0) }}
- />
- )}
- <br />
- <strong>{intl.formatMessage(messages[event.get('type')])}</strong>
- </div>
-
- <div className='notification__report__actions'>
- <a href='/severed_relationships' className='button' target='_blank' rel='noopener noreferrer'>
- <FormattedMessage id='relationship_severance_notification.view' defaultMessage='View' />
- </a>
- </div>
+ <a href='/severed_relationships' target='_blank' rel='noopener noreferrer' className='notification__relationships-severance-event'>
+ <Icon id='heart_broken' icon={HeartBrokenIcon} />
+
+ <div className='notification__relationships-severance-event__content'>
+ <p>{intl.formatMessage(messages[type], { from: <strong>{domain}</strong>, target: <strong>{target}</strong>, followingCount, followersCount })}</p>
+ <span className='link-button'><FormattedMessage id='notification.relationships_severance_event.learn_more' defaultMessage='Learn more' /></span>
</div>
- </div>
+ </a>
);
-
};
RelationshipsSeveranceEvent.propTypes = {
- event: ImmutablePropTypes.map.isRequired,
+ type: PropTypes.oneOf([
+ 'account_suspension',
+ 'domain_block',
+ 'user_domain_block',
+ ]).isRequired,
+ target: PropTypes.string.isRequired,
+ followersCount: PropTypes.number.isRequired,
+ followingCount: PropTypes.number.isRequired,
hidden: PropTypes.bool,
};
-
-export default RelationshipsSeveranceEvent;
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index 1134b393a76..5aa3b5c90b4 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -471,7 +471,11 @@
"notification.own_poll": "Your poll has ended",
"notification.poll": "A poll you have voted in has ended",
"notification.reblog": "{name} boosted your post",
- "notification.severed_relationships": "Relationships with {name} severed",
+ "notification.relationships_severance_event": "Lost connections with {name}",
+ "notification.relationships_severance_event.account_suspension": "An admin from {from} has suspended {target}, which means you can no longer receive updates from them or interact with them.",
+ "notification.relationships_severance_event.domain_block": "An admin from {from} has blocked {target}, including {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.",
+ "notification.relationships_severance_event.learn_more": "Learn more",
+ "notification.relationships_severance_event.user_domain_block": "You have blocked {target}, removing {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.",
"notification.status": "{name} just posted",
"notification.update": "{name} edited a post",
"notification_requests.accept": "Accept",
@@ -590,12 +594,6 @@
"refresh": "Refresh",
"regeneration_indicator.label": "Loading…",
"regeneration_indicator.sublabel": "Your home feed is being prepared!",
- "relationship_severance_notification.purged_data": "purged by administrators",
- "relationship_severance_notification.relationships": "{count, plural, one {# relationship} other {# relationships}}",
- "relationship_severance_notification.types.account_suspension": "Account has been suspended",
- "relationship_severance_notification.types.domain_block": "Domain has been suspended",
- "relationship_severance_notification.types.user_domain_block": "You blocked this domain",
- "relationship_severance_notification.view": "View",
"relative_time.days": "{number}d",
"relative_time.full.days": "{number, plural, one {# day} other {# days}} ago",
"relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago",
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 55792f22d2a..e5cfe235da6 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -2165,6 +2165,44 @@ a.account__display-name {
}
}
+.notification__relationships-severance-event {
+ display: flex;
+ gap: 16px;
+ color: $secondary-text-color;
+ text-decoration: none;
+ align-items: flex-start;
+ padding: 16px 32px;
+ border-bottom: 1px solid var(--background-border-color);
+
+ &:hover {
+ color: $primary-text-color;
+ }
+
+ .icon {
+ padding: 2px;
+ color: $highlight-text-color;
+ }
+
+ &__content {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 8px;
+ flex-grow: 1;
+ font-size: 16px;
+ line-height: 24px;
+
+ strong {
+ font-weight: 700;
+ }
+
+ .link-button {
+ font-size: inherit;
+ line-height: inherit;
+ }
+ }
+}
+
.notification__message {
padding: 16px;
padding-bottom: 0;