Change hints for missing remote content in web UI (#31516)
This commit is contained in:
		
					parent
					
						
							
								9ba7c90151
							
						
					
				
			
			
				commit
				
					
						b06c7b6b5a
					
				
			
		
					 7 changed files with 82 additions and 44 deletions
				
			
		|  | @ -1,28 +1,23 @@ | |||
| import { FormattedMessage } from 'react-intl'; | ||||
| 
 | ||||
| import classNames from 'classnames'; | ||||
| 
 | ||||
| interface Props { | ||||
|   resource: JSX.Element; | ||||
|   message: React.ReactNode; | ||||
|   label: React.ReactNode; | ||||
|   url: string; | ||||
|   className?: string; | ||||
| } | ||||
| 
 | ||||
| export const TimelineHint: React.FC<Props> = ({ className, resource, url }) => ( | ||||
| export const TimelineHint: React.FC<Props> = ({ | ||||
|   className, | ||||
|   message, | ||||
|   label, | ||||
|   url, | ||||
| }) => ( | ||||
|   <div className={classNames('timeline-hint', className)}> | ||||
|     <strong> | ||||
|       <FormattedMessage | ||||
|         id='timeline_hint.remote_resource_not_displayed' | ||||
|         defaultMessage='{resource} from other servers are not displayed.' | ||||
|         values={{ resource }} | ||||
|       /> | ||||
|     </strong> | ||||
|     <br /> | ||||
|     <p>{message}</p> | ||||
| 
 | ||||
|     <a href={url} target='_blank' rel='noopener noreferrer'> | ||||
|       <FormattedMessage | ||||
|         id='account.browse_more_on_origin_server' | ||||
|         defaultMessage='Browse more on the original profile' | ||||
|       /> | ||||
|       {label} | ||||
|     </a> | ||||
|   </div> | ||||
| ); | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ import BundleColumnError from 'mastodon/features/ui/components/bundle_column_err | |||
| import { me } from 'mastodon/initial_state'; | ||||
| import { normalizeForLookup } from 'mastodon/reducers/accounts_map'; | ||||
| import { getAccountHidden } from 'mastodon/selectors'; | ||||
| import { useAppSelector } from 'mastodon/store'; | ||||
| 
 | ||||
| import { lookupAccount, fetchAccount } from '../../actions/accounts'; | ||||
| import { fetchFeaturedTags } from '../../actions/featured_tags'; | ||||
|  | @ -59,12 +60,22 @@ const mapStateToProps = (state, { params: { acct, id, tagged }, withReplies = fa | |||
|   }; | ||||
| }; | ||||
| 
 | ||||
| const RemoteHint = ({ url }) => ( | ||||
|   <TimelineHint url={url} resource={<FormattedMessage id='timeline_hint.resources.statuses' defaultMessage='Older posts' />} /> | ||||
| const RemoteHint = ({ accountId, url }) => { | ||||
|   const acct = useAppSelector(state => state.accounts.get(accountId)?.acct); | ||||
|   const domain = acct ? acct.split('@')[1] : undefined; | ||||
| 
 | ||||
|   return ( | ||||
|     <TimelineHint | ||||
|       url={url} | ||||
|       message={<FormattedMessage id='hints.profiles.posts_may_be_missing' defaultMessage='Some posts from this profile may be missing.' />} | ||||
|       label={<FormattedMessage id='hints.profiles.see_more_posts' defaultMessage='See more posts on {domain}' values={{ domain: <strong>{domain}</strong> }} />} | ||||
|     /> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| RemoteHint.propTypes = { | ||||
|   url: PropTypes.string.isRequired, | ||||
|   accountId: PropTypes.string.isRequired, | ||||
| }; | ||||
| 
 | ||||
| class AccountTimeline extends ImmutablePureComponent { | ||||
|  | @ -175,12 +186,12 @@ class AccountTimeline extends ImmutablePureComponent { | |||
|     } else if (blockedBy) { | ||||
|       emptyMessage = <FormattedMessage id='empty_column.account_unavailable' defaultMessage='Profile unavailable' />; | ||||
|     } else if (remote && statusIds.isEmpty()) { | ||||
|       emptyMessage = <RemoteHint url={remoteUrl} />; | ||||
|       emptyMessage = <RemoteHint accountId={accountId} url={remoteUrl} />; | ||||
|     } else { | ||||
|       emptyMessage = <FormattedMessage id='empty_column.account_timeline' defaultMessage='No posts found' />; | ||||
|     } | ||||
| 
 | ||||
|     const remoteMessage = remote ? <RemoteHint url={remoteUrl} /> : null; | ||||
|     const remoteMessage = remote ? <RemoteHint accountId={accountId} url={remoteUrl} /> : null; | ||||
| 
 | ||||
|     return ( | ||||
|       <Column> | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ import { TimelineHint } from 'mastodon/components/timeline_hint'; | |||
| import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error'; | ||||
| import { normalizeForLookup } from 'mastodon/reducers/accounts_map'; | ||||
| import { getAccountHidden } from 'mastodon/selectors'; | ||||
| import { useAppSelector } from 'mastodon/store'; | ||||
| 
 | ||||
| import { | ||||
|   lookupAccount, | ||||
|  | @ -51,12 +52,22 @@ const mapStateToProps = (state, { params: { acct, id } }) => { | |||
|   }; | ||||
| }; | ||||
| 
 | ||||
| const RemoteHint = ({ url }) => ( | ||||
|   <TimelineHint url={url} resource={<FormattedMessage id='timeline_hint.resources.followers' defaultMessage='Followers' />} /> | ||||
| const RemoteHint = ({ accountId, url }) => { | ||||
|   const acct = useAppSelector(state => state.accounts.get(accountId)?.acct); | ||||
|   const domain = acct ? acct.split('@')[1] : undefined; | ||||
| 
 | ||||
|   return ( | ||||
|     <TimelineHint | ||||
|       url={url} | ||||
|       message={<FormattedMessage id='hints.profiles.followers_may_be_missing' defaultMessage='Followers for this profile may be missing.' />} | ||||
|       label={<FormattedMessage id='hints.profiles.see_more_followers' defaultMessage='See more followers on {domain}' values={{ domain: <strong>{domain}</strong> }} />} | ||||
|     /> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| RemoteHint.propTypes = { | ||||
|   url: PropTypes.string.isRequired, | ||||
|   accountId: PropTypes.string.isRequired, | ||||
| }; | ||||
| 
 | ||||
| class Followers extends ImmutablePureComponent { | ||||
|  | @ -141,12 +152,12 @@ class Followers extends ImmutablePureComponent { | |||
|     } else if (hideCollections && accountIds.isEmpty()) { | ||||
|       emptyMessage = <FormattedMessage id='empty_column.account_hides_collections' defaultMessage='This user has chosen to not make this information available' />; | ||||
|     } else if (remote && accountIds.isEmpty()) { | ||||
|       emptyMessage = <RemoteHint url={remoteUrl} />; | ||||
|       emptyMessage = <RemoteHint accountId={accountId} url={remoteUrl} />; | ||||
|     } else { | ||||
|       emptyMessage = <FormattedMessage id='account.followers.empty' defaultMessage='No one follows this user yet.' />; | ||||
|     } | ||||
| 
 | ||||
|     const remoteMessage = remote ? <RemoteHint url={remoteUrl} /> : null; | ||||
|     const remoteMessage = remote ? <RemoteHint accountId={accountId} url={remoteUrl} /> : null; | ||||
| 
 | ||||
|     return ( | ||||
|       <Column> | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ import { TimelineHint } from 'mastodon/components/timeline_hint'; | |||
| import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error'; | ||||
| import { normalizeForLookup } from 'mastodon/reducers/accounts_map'; | ||||
| import { getAccountHidden } from 'mastodon/selectors'; | ||||
| import { useAppSelector } from 'mastodon/store'; | ||||
| 
 | ||||
| import { | ||||
|   lookupAccount, | ||||
|  | @ -51,12 +52,22 @@ const mapStateToProps = (state, { params: { acct, id } }) => { | |||
|   }; | ||||
| }; | ||||
| 
 | ||||
| const RemoteHint = ({ url }) => ( | ||||
|   <TimelineHint url={url} resource={<FormattedMessage id='timeline_hint.resources.follows' defaultMessage='Follows' />} /> | ||||
| const RemoteHint = ({ accountId, url }) => { | ||||
|   const acct = useAppSelector(state => state.accounts.get(accountId)?.acct); | ||||
|   const domain = acct ? acct.split('@')[1] : undefined; | ||||
| 
 | ||||
|   return ( | ||||
|     <TimelineHint | ||||
|       url={url} | ||||
|       message={<FormattedMessage id='hints.profiles.follows_may_be_missing' defaultMessage='Follows for this profile may be missing.' />} | ||||
|       label={<FormattedMessage id='hints.profiles.see_more_follows' defaultMessage='See more follows on {domain}' values={{ domain: <strong>{domain}</strong> }} />} | ||||
|     /> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| RemoteHint.propTypes = { | ||||
|   url: PropTypes.string.isRequired, | ||||
|   accountId: PropTypes.string.isRequired, | ||||
| }; | ||||
| 
 | ||||
| class Following extends ImmutablePureComponent { | ||||
|  | @ -141,12 +152,12 @@ class Following extends ImmutablePureComponent { | |||
|     } else if (hideCollections && accountIds.isEmpty()) { | ||||
|       emptyMessage = <FormattedMessage id='empty_column.account_hides_collections' defaultMessage='This user has chosen to not make this information available' />; | ||||
|     } else if (remote && accountIds.isEmpty()) { | ||||
|       emptyMessage = <RemoteHint url={remoteUrl} />; | ||||
|       emptyMessage = <RemoteHint accountId={accountId} url={remoteUrl} />; | ||||
|     } else { | ||||
|       emptyMessage = <FormattedMessage id='account.follows.empty' defaultMessage="This user doesn't follow anyone yet." />; | ||||
|     } | ||||
| 
 | ||||
|     const remoteMessage = remote ? <RemoteHint url={remoteUrl} /> : null; | ||||
|     const remoteMessage = remote ? <RemoteHint accountId={accountId} url={remoteUrl} /> : null; | ||||
| 
 | ||||
|     return ( | ||||
|       <Column> | ||||
|  |  | |||
|  | @ -629,7 +629,14 @@ class Status extends ImmutablePureComponent { | |||
|     const isIndexable = !status.getIn(['account', 'noindex']); | ||||
| 
 | ||||
|     if (!isLocal) { | ||||
|       remoteHint = <TimelineHint className={classNames(!!descendants && 'timeline-hint--with-descendants')} url={status.get('url')} resource={<FormattedMessage id='timeline_hint.resources.replies' defaultMessage='Some replies' />} />; | ||||
|       remoteHint = ( | ||||
|         <TimelineHint | ||||
|           className={classNames(!!descendants && 'timeline-hint--with-descendants')} | ||||
|           url={status.get('url')} | ||||
|           message={<FormattedMessage id='hints.threads.replies_may_be_missing' defaultMessage='Replies from other servers may be missing.' />} | ||||
|           label={<FormattedMessage id='hints.threads.see_more' defaultMessage='See more replies on {domain}' values={{ domain: <strong>{status.getIn(['account', 'acct']).split('@')[1]}</strong> }} />} | ||||
|         /> | ||||
|       ); | ||||
|     } | ||||
| 
 | ||||
|     const handlers = { | ||||
|  |  | |||
|  | @ -19,7 +19,6 @@ | |||
|   "account.block_domain": "Block domain {domain}", | ||||
|   "account.block_short": "Block", | ||||
|   "account.blocked": "Blocked", | ||||
|   "account.browse_more_on_origin_server": "Browse more on the original profile", | ||||
|   "account.cancel_follow_request": "Cancel follow", | ||||
|   "account.copy": "Copy link to profile", | ||||
|   "account.direct": "Privately mention @{name}", | ||||
|  | @ -349,6 +348,14 @@ | |||
|   "hashtag.follow": "Follow hashtag", | ||||
|   "hashtag.unfollow": "Unfollow hashtag", | ||||
|   "hashtags.and_other": "…and {count, plural, other {# more}}", | ||||
|   "hints.profiles.followers_may_be_missing": "Followers for this profile may be missing.", | ||||
|   "hints.profiles.follows_may_be_missing": "Follows for this profile may be missing.", | ||||
|   "hints.profiles.posts_may_be_missing": "Some posts from this profile may be missing.", | ||||
|   "hints.profiles.see_more_followers": "See more followers on {domain}", | ||||
|   "hints.profiles.see_more_follows": "See more follows on {domain}", | ||||
|   "hints.profiles.see_more_posts": "See more posts on {domain}", | ||||
|   "hints.threads.replies_may_be_missing": "Replies from other servers may be missing.", | ||||
|   "hints.threads.see_more": "See more replies on {domain}", | ||||
|   "home.column_settings.show_reblogs": "Show boosts", | ||||
|   "home.column_settings.show_replies": "Show replies", | ||||
|   "home.hide_announcements": "Hide announcements", | ||||
|  | @ -826,11 +833,6 @@ | |||
|   "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left", | ||||
|   "time_remaining.moments": "Moments remaining", | ||||
|   "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", | ||||
|   "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.", | ||||
|   "timeline_hint.resources.followers": "Followers", | ||||
|   "timeline_hint.resources.follows": "Follows", | ||||
|   "timeline_hint.resources.replies": "Some replies", | ||||
|   "timeline_hint.resources.statuses": "Older posts", | ||||
|   "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {{days} days}}", | ||||
|   "trends.trending_now": "Trending now", | ||||
|   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.", | ||||
|  |  | |||
|  | @ -4217,11 +4217,12 @@ a.status-card { | |||
| 
 | ||||
| .timeline-hint { | ||||
|   text-align: center; | ||||
|   color: $darker-text-color; | ||||
|   padding: 15px; | ||||
|   color: $dark-text-color; | ||||
|   padding: 16px; | ||||
|   box-sizing: border-box; | ||||
|   width: 100%; | ||||
|   cursor: default; | ||||
|   font-size: 14px; | ||||
|   line-height: 21px; | ||||
| 
 | ||||
|   strong { | ||||
|     font-weight: 500; | ||||
|  | @ -4238,11 +4239,11 @@ a.status-card { | |||
|       color: lighten($highlight-text-color, 4%); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .timeline-hint--with-descendants { | ||||
|   &--with-descendants { | ||||
|     border-top: 1px solid var(--background-border-color); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .regeneration-indicator { | ||||
|   text-align: center; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue