[Glitch] Change hints for missing remote content in web UI

Port b06c7b6b5a to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
pull/2819/head
Eugen Rochko 2024-08-21 09:08:58 +02:00 committed by Claire
parent 0cec9077a4
commit bae0b81779
6 changed files with 74 additions and 38 deletions

View File

@ -1,28 +1,23 @@
import { FormattedMessage } from 'react-intl';
import classNames from 'classnames'; import classNames from 'classnames';
interface Props { interface Props {
resource: JSX.Element; message: React.ReactNode;
label: React.ReactNode;
url: string; url: string;
className?: 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)}> <div className={classNames('timeline-hint', className)}>
<strong> <p>{message}</p>
<FormattedMessage
id='timeline_hint.remote_resource_not_displayed'
defaultMessage='{resource} from other servers are not displayed.'
values={{ resource }}
/>
</strong>
<br />
<a href={url} target='_blank' rel='noopener noreferrer'> <a href={url} target='_blank' rel='noopener noreferrer'>
<FormattedMessage {label}
id='account.browse_more_on_origin_server'
defaultMessage='Browse more on the original profile'
/>
</a> </a>
</div> </div>
); );

View File

@ -12,6 +12,7 @@ import ProfileColumnHeader from 'flavours/glitch/features/account/components/pro
import BundleColumnError from 'flavours/glitch/features/ui/components/bundle_column_error'; import BundleColumnError from 'flavours/glitch/features/ui/components/bundle_column_error';
import { normalizeForLookup } from 'flavours/glitch/reducers/accounts_map'; import { normalizeForLookup } from 'flavours/glitch/reducers/accounts_map';
import { getAccountHidden } from 'flavours/glitch/selectors'; import { getAccountHidden } from 'flavours/glitch/selectors';
import { useAppSelector } from 'flavours/glitch/store';
import { lookupAccount, fetchAccount } from '../../actions/accounts'; import { lookupAccount, fetchAccount } from '../../actions/accounts';
import { fetchFeaturedTags } from '../../actions/featured_tags'; import { fetchFeaturedTags } from '../../actions/featured_tags';
@ -57,12 +58,22 @@ const mapStateToProps = (state, { params: { acct, id, tagged }, withReplies = fa
}; };
}; };
const RemoteHint = ({ url }) => ( const RemoteHint = ({ accountId, url }) => {
<TimelineHint url={url} resource={<FormattedMessage id='timeline_hint.resources.statuses' defaultMessage='Older posts' />} /> 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 = { RemoteHint.propTypes = {
url: PropTypes.string.isRequired, url: PropTypes.string.isRequired,
accountId: PropTypes.string.isRequired,
}; };
class AccountTimeline extends ImmutablePureComponent { class AccountTimeline extends ImmutablePureComponent {
@ -176,12 +187,12 @@ class AccountTimeline extends ImmutablePureComponent {
} else if (hidden) { } else if (hidden) {
emptyMessage = <LimitedAccountHint accountId={accountId} />; emptyMessage = <LimitedAccountHint accountId={accountId} />;
} else if (remote && statusIds.isEmpty()) { } else if (remote && statusIds.isEmpty()) {
emptyMessage = <RemoteHint url={remoteUrl} />; emptyMessage = <RemoteHint accountId={accountId} url={remoteUrl} />;
} else { } else {
emptyMessage = <FormattedMessage id='empty_column.account_timeline' defaultMessage='No posts found' />; 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 ( return (
<Column ref={this.setRef}> <Column ref={this.setRef}>

View File

@ -12,6 +12,7 @@ import { TimelineHint } from 'flavours/glitch/components/timeline_hint';
import BundleColumnError from 'flavours/glitch/features/ui/components/bundle_column_error'; import BundleColumnError from 'flavours/glitch/features/ui/components/bundle_column_error';
import { normalizeForLookup } from 'flavours/glitch/reducers/accounts_map'; import { normalizeForLookup } from 'flavours/glitch/reducers/accounts_map';
import { getAccountHidden } from 'flavours/glitch/selectors'; import { getAccountHidden } from 'flavours/glitch/selectors';
import { useAppSelector } from 'flavours/glitch/store';
import { import {
lookupAccount, lookupAccount,
@ -50,12 +51,22 @@ const mapStateToProps = (state, { params: { acct, id } }) => {
}; };
}; };
const RemoteHint = ({ url }) => ( const RemoteHint = ({ accountId, url }) => {
<TimelineHint url={url} resource={<FormattedMessage id='timeline_hint.resources.followers' defaultMessage='Followers' />} /> 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 = { RemoteHint.propTypes = {
url: PropTypes.string.isRequired, url: PropTypes.string.isRequired,
accountId: PropTypes.string.isRequired,
}; };
class Followers extends ImmutablePureComponent { class Followers extends ImmutablePureComponent {
@ -145,12 +156,12 @@ class Followers extends ImmutablePureComponent {
} else if (hideCollections && accountIds.isEmpty()) { } else if (hideCollections && accountIds.isEmpty()) {
emptyMessage = <FormattedMessage id='empty_column.account_hides_collections' defaultMessage='This user has chosen to not make this information available' />; emptyMessage = <FormattedMessage id='empty_column.account_hides_collections' defaultMessage='This user has chosen to not make this information available' />;
} else if (remote && accountIds.isEmpty()) { } else if (remote && accountIds.isEmpty()) {
emptyMessage = <RemoteHint url={remoteUrl} />; emptyMessage = <RemoteHint accountId={accountId} url={remoteUrl} />;
} else { } else {
emptyMessage = <FormattedMessage id='account.followers.empty' defaultMessage='No one follows this user yet.' />; 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 ( return (
<Column ref={this.setRef}> <Column ref={this.setRef}>

View File

@ -12,6 +12,7 @@ import { TimelineHint } from 'flavours/glitch/components/timeline_hint';
import BundleColumnError from 'flavours/glitch/features/ui/components/bundle_column_error'; import BundleColumnError from 'flavours/glitch/features/ui/components/bundle_column_error';
import { normalizeForLookup } from 'flavours/glitch/reducers/accounts_map'; import { normalizeForLookup } from 'flavours/glitch/reducers/accounts_map';
import { getAccountHidden } from 'flavours/glitch/selectors'; import { getAccountHidden } from 'flavours/glitch/selectors';
import { useAppSelector } from 'flavours/glitch/store';
import { import {
lookupAccount, lookupAccount,
@ -50,12 +51,22 @@ const mapStateToProps = (state, { params: { acct, id } }) => {
}; };
}; };
const RemoteHint = ({ url }) => ( const RemoteHint = ({ accountId, url }) => {
<TimelineHint url={url} resource={<FormattedMessage id='timeline_hint.resources.follows' defaultMessage='Follows' />} /> 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 = { RemoteHint.propTypes = {
url: PropTypes.string.isRequired, url: PropTypes.string.isRequired,
accountId: PropTypes.string.isRequired,
}; };
class Following extends ImmutablePureComponent { class Following extends ImmutablePureComponent {
@ -145,12 +156,12 @@ class Following extends ImmutablePureComponent {
} else if (hideCollections && accountIds.isEmpty()) { } else if (hideCollections && accountIds.isEmpty()) {
emptyMessage = <FormattedMessage id='empty_column.account_hides_collections' defaultMessage='This user has chosen to not make this information available' />; emptyMessage = <FormattedMessage id='empty_column.account_hides_collections' defaultMessage='This user has chosen to not make this information available' />;
} else if (remote && accountIds.isEmpty()) { } else if (remote && accountIds.isEmpty()) {
emptyMessage = <RemoteHint url={remoteUrl} />; emptyMessage = <RemoteHint accountId={accountId} url={remoteUrl} />;
} else { } else {
emptyMessage = <FormattedMessage id='account.follows.empty' defaultMessage="This user doesn't follow anyone yet." />; 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 ( return (
<Column ref={this.setRef}> <Column ref={this.setRef}>

View File

@ -655,7 +655,14 @@ class Status extends ImmutablePureComponent {
const isIndexable = !status.getIn(['account', 'noindex']); const isIndexable = !status.getIn(['account', 'noindex']);
if (!isLocal) { 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 = { const handlers = {

View File

@ -4422,11 +4422,12 @@ a.status-card {
.timeline-hint { .timeline-hint {
text-align: center; text-align: center;
color: $darker-text-color; color: $dark-text-color;
padding: 15px; padding: 16px;
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;
cursor: default; font-size: 14px;
line-height: 21px;
strong { strong {
font-weight: 500; font-weight: 500;
@ -4443,11 +4444,11 @@ a.status-card {
color: lighten($highlight-text-color, 4%); color: lighten($highlight-text-color, 4%);
} }
} }
}
.timeline-hint--with-descendants { &--with-descendants {
border-top: 1px solid var(--background-border-color); border-top: 1px solid var(--background-border-color);
} }
}
.regeneration-indicator { .regeneration-indicator {
text-align: center; text-align: center;