mirror of
https://github.com/mastodon/mastodon.git
synced 2026-09-08 06:45:21 -05:00
Add even more features to feature usage counter (#40340)
This commit is contained in:
@@ -309,8 +309,9 @@ export const Account: React.FC<AccountProps> = ({
|
||||
<Link
|
||||
className='account__display-name focusable'
|
||||
title={account?.acct}
|
||||
to={`/@${account?.acct}`}
|
||||
to={{ pathname: `/@${account?.acct}`, state: { reference } }}
|
||||
data-hover-card-account={id}
|
||||
data-hover-card-reference={reference}
|
||||
>
|
||||
<div className='account__avatar-wrapper'>
|
||||
{account ? (
|
||||
|
||||
@@ -3,6 +3,8 @@ import type { FC } from 'react';
|
||||
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { followAccount } from '@/mastodon/actions/accounts';
|
||||
import { useAccount } from '@/mastodon/hooks/useAccount';
|
||||
import { getAccountHidden } from '@/mastodon/selectors/accounts';
|
||||
@@ -81,6 +83,10 @@ const AccountButtonsOther: FC<
|
||||
});
|
||||
}
|
||||
}, [accountUrl]);
|
||||
const { state } = useLocation<{
|
||||
reference?: string;
|
||||
} | null>();
|
||||
const reference = state?.reference ?? 'profile';
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
@@ -96,7 +102,7 @@ const AccountButtonsOther: FC<
|
||||
accountId={accountId}
|
||||
className={classes.followButton}
|
||||
labelLength='long'
|
||||
reference='profile'
|
||||
reference={reference}
|
||||
/>
|
||||
)}
|
||||
{isFollowing && (
|
||||
|
||||
@@ -27,6 +27,7 @@ import classes from './styles.module.scss';
|
||||
export interface RenderButtonOptions {
|
||||
accountId: string | undefined;
|
||||
relationship: Relationship | null | undefined;
|
||||
reference?: string;
|
||||
}
|
||||
|
||||
type Stat = 'followers' | 'following' | 'posts' | 'joined' | 'last-active';
|
||||
@@ -38,6 +39,7 @@ interface Props {
|
||||
withBorder?: boolean;
|
||||
badge?: ReactNode;
|
||||
renderButton?: (options: RenderButtonOptions) => React.ReactNode;
|
||||
reference?: string;
|
||||
}
|
||||
|
||||
const DEFAULT_STATS: Stat[] = ['followers', 'posts', 'last-active'];
|
||||
@@ -56,6 +58,7 @@ export const AccountListItem: React.FC<Props> = ({
|
||||
withBorder = true,
|
||||
badge: badgeProp,
|
||||
renderButton = defaultRenderButton,
|
||||
reference,
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const account = useAccount(accountId);
|
||||
@@ -83,13 +86,14 @@ export const AccountListItem: React.FC<Props> = ({
|
||||
icon={<Avatar account={account} size={40} />}
|
||||
sideContent={
|
||||
<span className={classes.button}>
|
||||
{renderButton({ accountId, relationship })}
|
||||
{renderButton({ accountId, relationship, reference })}
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<ListItemLink
|
||||
to={`/@${account.acct}`}
|
||||
to={{ pathname: `/@${account.acct}`, state: { reference } }}
|
||||
data-hover-card-account={accountId}
|
||||
data-hover-card-reference={reference}
|
||||
subtitle={<span className={classes.handle}>{handle}</span>}
|
||||
>
|
||||
<DisplayNameSimple
|
||||
@@ -193,8 +197,8 @@ export const AccountListItem: React.FC<Props> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const defaultRenderButton = ({ accountId }: RenderButtonOptions) => (
|
||||
<AccountListItemFollowButton accountId={accountId} />
|
||||
const defaultRenderButton = ({ accountId, reference }: RenderButtonOptions) => (
|
||||
<AccountListItemFollowButton accountId={accountId} reference={reference} />
|
||||
);
|
||||
|
||||
export const AccountListItemFollowButton: React.FC<{
|
||||
|
||||
@@ -29,8 +29,9 @@ export const DisplayName: FC<
|
||||
export const LinkedDisplayName: FC<
|
||||
Omit<LinkProps, 'to'> & {
|
||||
displayProps: DisplayNameProps & ComponentPropsWithoutRef<'span'>;
|
||||
reference?: string;
|
||||
}
|
||||
> = ({ displayProps, children, ...linkProps }) => {
|
||||
> = ({ displayProps, reference, children, ...linkProps }) => {
|
||||
const { account } = displayProps;
|
||||
if (!account) {
|
||||
return <DisplayName {...displayProps} />;
|
||||
@@ -38,10 +39,11 @@ export const LinkedDisplayName: FC<
|
||||
|
||||
return (
|
||||
<Link
|
||||
to={`/@${account.acct}`}
|
||||
to={{ pathname: `/@${account.acct}`, state: { reference } }}
|
||||
title={`@${account.acct}`}
|
||||
data-id={account.id}
|
||||
data-hover-card-account={account.id}
|
||||
data-hover-card-reference={reference}
|
||||
{...linkProps}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -25,8 +25,8 @@ import { useAppSelector, useAppDispatch } from 'mastodon/store';
|
||||
|
||||
export const HoverCardAccount = forwardRef<
|
||||
HTMLDivElement,
|
||||
{ accountId?: string }
|
||||
>(({ accountId }, ref) => {
|
||||
{ accountId?: string; reference?: string }
|
||||
>(({ accountId, reference }, ref) => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const account = useAppSelector((state) =>
|
||||
@@ -171,7 +171,10 @@ export const HoverCardAccount = forwardRef<
|
||||
)}
|
||||
</div>
|
||||
|
||||
<FollowButton accountId={accountId} />
|
||||
<FollowButton
|
||||
accountId={accountId}
|
||||
reference={reference ?? 'hover_card'}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -21,6 +21,7 @@ const isHoverCardAnchor = (element: HTMLElement) =>
|
||||
export const HoverCardController: React.FC = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [accountId, setAccountId] = useState<string | undefined>();
|
||||
const [reference, setReference] = useState<string | undefined>();
|
||||
const [anchor, setAnchor] = useState<HTMLElement | null>(null);
|
||||
const cardRef = useRef<HTMLDivElement>(null);
|
||||
const [setLeaveTimeout, cancelLeaveTimeout] = useTimeout();
|
||||
@@ -53,6 +54,9 @@ export const HoverCardController: React.FC = () => {
|
||||
setOpen(true);
|
||||
setAnchor(target);
|
||||
setAccountId(target.getAttribute('data-hover-card-account') ?? undefined);
|
||||
setReference(
|
||||
target.getAttribute('data-hover-card-reference') ?? undefined,
|
||||
);
|
||||
};
|
||||
|
||||
const close = () => {
|
||||
@@ -61,6 +65,7 @@ export const HoverCardController: React.FC = () => {
|
||||
setOpen(false);
|
||||
setAnchor(null);
|
||||
setAccountId(undefined);
|
||||
setReference(undefined);
|
||||
};
|
||||
|
||||
const handleTouchStart = () => {
|
||||
@@ -216,7 +221,11 @@ export const HoverCardController: React.FC = () => {
|
||||
>
|
||||
{({ props }) => (
|
||||
<div {...props} className='hover-card-controller'>
|
||||
<HoverCardAccount accountId={accountId} ref={cardRef} />
|
||||
<HoverCardAccount
|
||||
accountId={accountId}
|
||||
reference={reference}
|
||||
ref={cardRef}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</Popover>
|
||||
|
||||
@@ -432,6 +432,7 @@ class Status extends ImmutablePureComponent {
|
||||
variant: 'simple'
|
||||
}}
|
||||
className='status__display-name muted'
|
||||
reference='status'
|
||||
/>
|
||||
)
|
||||
|
||||
|
||||
@@ -53,9 +53,10 @@ export const HandledLink: FC<HandledLinkProps & ComponentProps<'a'>> = ({
|
||||
return (
|
||||
<Link
|
||||
className={classNames('mention', className)}
|
||||
to={`/@${mention.acct}`}
|
||||
to={{ pathname: `/@${mention.acct}`, state: { reference: 'status' } }}
|
||||
title={`@${mention.acct}`}
|
||||
data-hover-card-account={mention.id}
|
||||
data-hover-card-reference='status'
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
|
||||
@@ -118,6 +118,7 @@ const StatusDisplayName: FC<{
|
||||
<LinkedDisplayName
|
||||
displayProps={{ account: statusAccount }}
|
||||
className='status__display-name'
|
||||
reference='status'
|
||||
>
|
||||
<div className='status__avatar'>
|
||||
<AccountComponent
|
||||
|
||||
@@ -151,7 +151,10 @@ const AccountFeatured: React.FC<{ multiColumn: boolean }> = ({
|
||||
aria-posinset={index + 1}
|
||||
aria-setsize={featuredAccountIds.size}
|
||||
>
|
||||
<AccountListItem accountId={featuredAccountId} />
|
||||
<AccountListItem
|
||||
accountId={featuredAccountId}
|
||||
reference='featured_account'
|
||||
/>
|
||||
</Article>
|
||||
))}
|
||||
</ItemList>
|
||||
|
||||
@@ -197,6 +197,7 @@ export const CollectionAccountsList: React.FC<{
|
||||
withBorder={!isLastElement}
|
||||
badge={item.state === 'pending' ? <PendingBadge /> : null}
|
||||
renderButton={renderAccountItemButton}
|
||||
reference='collection'
|
||||
/>
|
||||
</Article>
|
||||
),
|
||||
|
||||
@@ -15,6 +15,7 @@ export const AuthorLink: FC<{ accountId: string }> = ({ accountId }) => {
|
||||
<LinkedDisplayName
|
||||
displayProps={{ account, variant: 'simple' }}
|
||||
className='story__details__shared__author-link'
|
||||
reference='author_attribution'
|
||||
>
|
||||
<Avatar account={account} size={16} />
|
||||
</LinkedDisplayName>
|
||||
|
||||
@@ -97,8 +97,12 @@ export const Card: React.FC<{ id: string; source: SuggestionSource }> = ({
|
||||
|
||||
<div className='explore-suggestions-card__body'>
|
||||
<Link
|
||||
to={`/@${account.get('acct')}`}
|
||||
to={{
|
||||
pathname: `/@${account.get('acct')}`,
|
||||
state: { reference: 'suggestions' },
|
||||
}}
|
||||
data-hover-card-account={account.id}
|
||||
data-hover-card-reference='suggestions'
|
||||
className='explore-suggestions-card__link'
|
||||
>
|
||||
<Avatar
|
||||
|
||||
@@ -88,7 +88,7 @@ class Favourites extends ImmutablePureComponent {
|
||||
bindToDocument={!multiColumn}
|
||||
>
|
||||
{accountIds.map(id =>
|
||||
<Account key={id} id={id} />,
|
||||
<Account key={id} id={id} reference='status' />,
|
||||
)}
|
||||
</ScrollableList>
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ export const AccountList: FC<AccountListProps> = ({
|
||||
accountId={followerId}
|
||||
withBio={false}
|
||||
badge={withoutFollowsYouBadge ? false : null}
|
||||
reference='profile'
|
||||
/>
|
||||
)) ?? [];
|
||||
|
||||
@@ -70,6 +71,7 @@ export const AccountList: FC<AccountListProps> = ({
|
||||
accountId={prependAccountId}
|
||||
withBio={false}
|
||||
badge={withoutFollowsYouBadge ? false : null}
|
||||
reference='profile'
|
||||
/>,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -142,13 +142,27 @@ const Card: React.FC<{
|
||||
/>
|
||||
|
||||
<div className='inline-follow-suggestions__body__scrollable__card__avatar'>
|
||||
<Link to={`/@${account?.acct}`} data-hover-card-account={account?.id}>
|
||||
<Link
|
||||
to={{
|
||||
pathname: `/@${account?.acct}`,
|
||||
state: { reference: 'inline_suggestions' },
|
||||
}}
|
||||
data-hover-card-account={account?.id}
|
||||
data-hover-card-reference='inline_suggestions'
|
||||
>
|
||||
<Avatar account={account} size={72} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className='inline-follow-suggestions__body__scrollable__card__text-stack'>
|
||||
<Link to={`/@${account?.acct}`} data-hover-card-account={account?.id}>
|
||||
<Link
|
||||
to={{
|
||||
pathname: `/@${account?.acct}`,
|
||||
state: { reference: 'inline_suggestions' },
|
||||
}}
|
||||
data-hover-card-account={account?.id}
|
||||
data-hover-card-reference='inline_suggestions'
|
||||
>
|
||||
<DisplayName account={account} />
|
||||
</Link>
|
||||
{firstVerifiedField ? (
|
||||
|
||||
@@ -88,7 +88,7 @@ class Reblogs extends ImmutablePureComponent {
|
||||
bindToDocument={!multiColumn}
|
||||
>
|
||||
{accountIds.map(id =>
|
||||
<Account key={id} id={id} />,
|
||||
<Account key={id} id={id} reference='status' />,
|
||||
)}
|
||||
</ScrollableList>
|
||||
|
||||
|
||||
@@ -441,8 +441,12 @@ export const DetailedStatus: React.FC<{
|
||||
</div>
|
||||
)}
|
||||
<Link
|
||||
to={`/@${status.getIn(['account', 'acct'])}`}
|
||||
to={{
|
||||
pathname: `/@${status.getIn(['account', 'acct'])}`,
|
||||
state: { reference: 'status' },
|
||||
}}
|
||||
data-hover-card-account={status.getIn(['account', 'id'])}
|
||||
data-hover-card-reference='status'
|
||||
className='detailed-status__display-name'
|
||||
>
|
||||
<div className='detailed-status__display-avatar'>
|
||||
|
||||
@@ -8,11 +8,15 @@ class FeatureUsageTracker
|
||||
).freeze
|
||||
|
||||
REF_VALUES = %w(
|
||||
author_attribution
|
||||
collection
|
||||
featured_account
|
||||
hover_card
|
||||
inline_suggestions
|
||||
onboarding
|
||||
profile
|
||||
search
|
||||
status
|
||||
suggestions
|
||||
).freeze
|
||||
|
||||
|
||||
Reference in New Issue
Block a user