Change design of notification about lost connections in web UI (#29731)
This commit is contained in:
		
					parent
					
						
							
								dd061291b1
							
						
					
				
			
			
				commit
				
					
						29f9dc742e
					
				
			
		
					 4 changed files with 79 additions and 60 deletions
				
			
		|  | @ -12,7 +12,6 @@ import { HotKeys } from 'react-hotkeys'; | ||||||
| 
 | 
 | ||||||
| import EditIcon from '@/material-icons/400-24px/edit.svg?react'; | import EditIcon from '@/material-icons/400-24px/edit.svg?react'; | ||||||
| import FlagIcon from '@/material-icons/400-24px/flag-fill.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 HomeIcon from '@/material-icons/400-24px/home-fill.svg?react'; | ||||||
| import InsertChartIcon from '@/material-icons/400-24px/insert_chart.svg?react'; | import InsertChartIcon from '@/material-icons/400-24px/insert_chart.svg?react'; | ||||||
| import PersonIcon from '@/material-icons/400-24px/person-fill.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 FollowRequestContainer from '../containers/follow_request_container'; | ||||||
| 
 | 
 | ||||||
| import RelationshipsSeveranceEvent from './relationships_severance_event'; | import { RelationshipsSeveranceEvent } from './relationships_severance_event'; | ||||||
| import Report from './report'; | import Report from './report'; | ||||||
| 
 | 
 | ||||||
| const messages = defineMessages({ | const messages = defineMessages({ | ||||||
|  | @ -40,6 +39,7 @@ const messages = defineMessages({ | ||||||
|   update: { id: 'notification.update', defaultMessage: '{name} edited a post' }, |   update: { id: 'notification.update', defaultMessage: '{name} edited a post' }, | ||||||
|   adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' }, |   adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' }, | ||||||
|   adminReport: { id: 'notification.admin.report', defaultMessage: '{name} reported {target}' }, |   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) => { | const notificationForScreenReader = (intl, message, timestamp) => { | ||||||
|  | @ -361,24 +361,23 @@ class Notification extends ImmutablePureComponent { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   renderRelationshipsSevered (notification) { |   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 null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <HotKeys handlers={this.getHandlers()}> |       <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={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'))}> | ||||||
|           <div className='notification__message'> |           <RelationshipsSeveranceEvent | ||||||
|             <Icon id='heart_broken' icon={HeartBrokenIcon} /> |             type={event.get('type')} | ||||||
| 
 |             target={event.get('target_name')} | ||||||
|             <span title={notification.get('created_at')}> |             followersCount={event.get('followers_count')} | ||||||
|               <FormattedMessage id='notification.severed_relationships' defaultMessage='Relationships with {name} severed' values={{ name: notification.getIn(['event', 'target_name']) }} /> |             followingCount={event.get('following_count')} | ||||||
|             </span> |             hidden={hidden} | ||||||
|           </div> |           /> | ||||||
| 
 |  | ||||||
|           <RelationshipsSeveranceEvent event={notification.get('event')} /> |  | ||||||
|         </div> |         </div> | ||||||
|       </HotKeys> |       </HotKeys> | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|  | @ -2,60 +2,44 @@ import PropTypes from 'prop-types'; | ||||||
| 
 | 
 | ||||||
| import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; | 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/relationships_severance_event.rb | ||||||
| 
 |  | ||||||
| // This needs to be kept in sync with app/models/relationship_severance_event.rb |  | ||||||
| const messages = defineMessages({ | const messages = defineMessages({ | ||||||
|   account_suspension: { id: 'relationship_severance_notification.types.account_suspension', defaultMessage: 'Account has been suspended' }, |   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: 'relationship_severance_notification.types.domain_block', defaultMessage: 'Domain has been suspended' }, |   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: 'relationship_severance_notification.types.user_domain_block', defaultMessage: 'You blocked this domain' }, |   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(); |   const intl = useIntl(); | ||||||
| 
 | 
 | ||||||
|   if (hidden || !event) { |   if (hidden) { | ||||||
|     return null; |     return null; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <div className='notification__report'> |     <a href='/severed_relationships' target='_blank' rel='noopener noreferrer' className='notification__relationships-severance-event'> | ||||||
|       <div className='notification__report__details'> |       <Icon id='heart_broken' icon={HeartBrokenIcon} /> | ||||||
|         <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'> |       <div className='notification__relationships-severance-event__content'> | ||||||
|           <a href='/severed_relationships' className='button' target='_blank' rel='noopener noreferrer'> |         <p>{intl.formatMessage(messages[type], { from: <strong>{domain}</strong>, target: <strong>{target}</strong>, followingCount, followersCount })}</p> | ||||||
|             <FormattedMessage id='relationship_severance_notification.view' defaultMessage='View' /> |         <span className='link-button'><FormattedMessage id='notification.relationships_severance_event.learn_more' defaultMessage='Learn more' /></span> | ||||||
|           </a> |  | ||||||
|         </div> |  | ||||||
|       </div> |       </div> | ||||||
|     </div> |     </a> | ||||||
|   ); |   ); | ||||||
| 
 |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| RelationshipsSeveranceEvent.propTypes = { | 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, |   hidden: PropTypes.bool, | ||||||
| }; | }; | ||||||
| 
 |  | ||||||
| export default RelationshipsSeveranceEvent; |  | ||||||
|  |  | ||||||
|  | @ -471,7 +471,11 @@ | ||||||
|   "notification.own_poll": "Your poll has ended", |   "notification.own_poll": "Your poll has ended", | ||||||
|   "notification.poll": "A poll you have voted in has ended", |   "notification.poll": "A poll you have voted in has ended", | ||||||
|   "notification.reblog": "{name} boosted your post", |   "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.status": "{name} just posted", | ||||||
|   "notification.update": "{name} edited a post", |   "notification.update": "{name} edited a post", | ||||||
|   "notification_requests.accept": "Accept", |   "notification_requests.accept": "Accept", | ||||||
|  | @ -590,12 +594,6 @@ | ||||||
|   "refresh": "Refresh", |   "refresh": "Refresh", | ||||||
|   "regeneration_indicator.label": "Loading…", |   "regeneration_indicator.label": "Loading…", | ||||||
|   "regeneration_indicator.sublabel": "Your home feed is being prepared!", |   "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.days": "{number}d", | ||||||
|   "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", |   "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", | ||||||
|   "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", |   "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", | ||||||
|  |  | ||||||
|  | @ -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 { | .notification__message { | ||||||
|   padding: 16px; |   padding: 16px; | ||||||
|   padding-bottom: 0; |   padding-bottom: 0; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue