Mark pending accounts on the collection detail page (#38830)

This commit is contained in:
diondiondion 2026-04-28 18:31:18 +02:00 committed by GitHub
parent eb5bfa4541
commit b193913f46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 56 additions and 18 deletions

View File

@ -1,3 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M13.2502 8.00029C13.2502 5.10089 10.8996 2.75044 8.00024 2.75029C5.10075 2.75029 2.75024 5.10079 2.75024 8.00029C2.7504 10.8997 5.10084 13.2503 8.00024 13.2503C10.8995 13.2501 13.2501 10.8996 13.2502 8.00029ZM7.41663 4.50029C7.41663 4.17812 7.67808 3.91667 8.00024 3.91667C8.32228 3.91683 8.58301 4.17822 8.58301 4.50029V7.63884L10.5945 8.64458C10.8825 8.78865 10.999 9.13922 10.8551 9.42729C10.711 9.71541 10.3605 9.83276 10.0724 9.68877L7.73877 8.52153C7.54143 8.4227 7.41673 8.221 7.41663 8.00029V4.50029ZM14.4166 8.00029C14.4165 11.5439 11.5438 14.4165 8.00024 14.4167C4.45651 14.4167 1.58316 11.544 1.58301 8.00029C1.58301 4.45646 4.45642 1.58305 8.00024 1.58305C11.5439 1.58321 14.4166 4.45656 14.4166 8.00029Z" fill="black"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="black">
<path d="M13.2502 8.00029C13.2502 5.10089 10.8996 2.75044 8.00024 2.75029C5.10075 2.75029 2.75024 5.10079 2.75024 8.00029C2.7504 10.8997 5.10084 13.2503 8.00024 13.2503C10.8995 13.2501 13.2501 10.8996 13.2502 8.00029ZM7.41663 4.50029C7.41663 4.17812 7.67808 3.91667 8.00024 3.91667C8.32228 3.91683 8.58301 4.17822 8.58301 4.50029V7.63884L10.5945 8.64458C10.8825 8.78865 10.999 9.13922 10.8551 9.42729C10.711 9.71541 10.3605 9.83276 10.0724 9.68877L7.73877 8.52153C7.54143 8.4227 7.41673 8.221 7.41663 8.00029V4.50029ZM14.4166 8.00029C14.4165 11.5439 11.5438 14.4165 8.00024 14.4167C4.45651 14.4167 1.58316 11.544 1.58301 8.00029C1.58301 4.45646 4.45642 1.58305 8.00024 1.58305C11.5439 1.58321 14.4166 4.45656 14.4166 8.00029Z" />
</svg>

Before

Width:  |  Height:  |  Size: 810 B

After

Width:  |  Height:  |  Size: 799 B

View File

@ -87,7 +87,7 @@
}
.variantSubtle {
border: 1px solid var(--color-bg-brand-softest);
border: 1px solid var(--color-border-brand-soft);
background-color: var(--color-bg-primary);
.icon {

View File

@ -2,8 +2,12 @@ import { useCallback, useMemo, useRef, useState } from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { PendingBadge } from '@/mastodon/components/badge';
import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?react';
import type { ApiCollectionJSON } from 'mastodon/api_types/collections';
import type {
ApiCollectionJSON,
CollectionAccountItem,
} from 'mastodon/api_types/collections';
import type { RenderButtonOptions } from 'mastodon/components/account_list_item';
import {
AccountListItem,
@ -75,15 +79,22 @@ const SensitiveScreen: React.FC<{
);
};
const getCollectionAccounts = createAppSelector(
type CollectionItemWithAccount = CollectionAccountItem & {
account?: Account | null;
};
const getCollectionItems = createAppSelector(
[
(state) => state.accounts,
(state, collectionId?: string) =>
state.collections.collections[collectionId ?? '']?.items,
],
(accounts, collectionAccountItems) =>
(collectionAccountItems ?? []).map(({ account_id }) =>
account_id ? accounts.get(account_id) : null,
(collectionAccountItems ?? []).map(
(item): CollectionItemWithAccount => ({
...item,
account: item.account_id ? accounts.get(item.account_id) : null,
}),
),
);
@ -100,22 +111,22 @@ export const CollectionAccountsList: React.FC<{
const relationships = useAppSelector((state) => state.relationships);
const collectionAccounts = useAppSelector((state) =>
getCollectionAccounts(state, id),
getCollectionItems(state, id),
);
const { visibleAccounts, hiddenAccounts } = useMemo(() => {
const visibleAccounts: Account[] = [];
const hiddenAccounts: Account[] = [];
const visibleAccounts: CollectionItemWithAccount[] = [];
const hiddenAccounts: CollectionItemWithAccount[] = [];
collectionAccounts.forEach((item) => {
if (!item) {
// We currently simply hide unavailable accounts, this includes
// accounts that are pending inclusion; at least for the collection
// owner we should display an indication of pending users
const { account, account_id } = item;
if (!isOwnCollection && !account) {
// Hide unavailable accounts unless you own this collection
return;
}
const relationship = relationships.get(item.id);
const relationship = account_id ? relationships.get(account_id) : null;
if (relationship?.blocking || relationship?.muting) {
hiddenAccounts.push(item);
} else {
@ -124,7 +135,7 @@ export const CollectionAccountsList: React.FC<{
});
return { visibleAccounts, hiddenAccounts };
}, [collectionAccounts, relationships]);
}, [collectionAccounts, isOwnCollection, relationships]);
const renderAccountItemButton = useCallback(
({ relationship, accountId }: RenderButtonOptions) => {
@ -159,15 +170,16 @@ export const CollectionAccountsList: React.FC<{
index,
totalListLength,
isLastElement,
}: TruncatedListItemInfo<Account>) => (
}: TruncatedListItemInfo<CollectionItemWithAccount>) => (
<Article
key={item.id}
aria-posinset={index + 1}
aria-setsize={totalListLength}
>
<AccountListItem
accountId={item.id}
accountId={item.account_id}
withBorder={!isLastElement}
badge={item.state === 'pending' ? <PendingBadge /> : null}
renderButton={renderAccountItemButton}
/>
</Article>

View File

@ -8,6 +8,7 @@ import { Link } from 'react-router-dom';
import { openModal } from '@/mastodon/actions/modal';
import { useAccountHandle } from '@/mastodon/components/display_name/default';
import HelpIcon from '@/material-icons/400-24px/help.svg?react';
import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react';
import ShareIcon from '@/material-icons/400-24px/share.svg?react';
import type { ApiCollectionJSON } from 'mastodon/api_types/collections';
@ -101,6 +102,26 @@ const RevokeControls: React.FC<{
);
};
const PendingNote: React.FC = () => {
return (
<Callout
variant='subtle'
icon={HelpIcon}
title={
<FormattedMessage
id='collections.pending_accounts.title'
defaultMessage='Why am I seeing pending accounts?'
/>
}
>
<FormattedMessage
id='collections.pending_accounts.message'
defaultMessage='Accounts may appear as pending when were awaiting a response from the user or their server. Only you can see pending accounts.'
/>
</Callout>
);
};
const CollectionHeader: React.FC<{ collection: ApiCollectionJSON }> = ({
collection,
}) => {
@ -136,6 +157,8 @@ const CollectionHeader: React.FC<{ collection: ApiCollectionJSON }> = ({
}
}, [history, openShareModal, isNewCollection, location.pathname]);
const hasPendingAccounts = items.some((item) => item.state === 'pending');
return (
<header className={classes.header}>
<div className={classes.titleWithMenu}>
@ -160,6 +183,7 @@ const CollectionHeader: React.FC<{ collection: ApiCollectionJSON }> = ({
</div>
</div>
{description && <p className={classes.description}>{description}</p>}
{hasPendingAccounts && <PendingNote />}
{isCurrentUserInCollection && <RevokeControls collection={collection} />}
</header>
);

View File

@ -416,6 +416,8 @@
"collections.maximum_collection_count_reached": "You have created the maximum number of collections",
"collections.name_length_hint": "40 characters limit",
"collections.new_collection": "New collection",
"collections.pending_accounts.message": "Accounts may appear as pending when were awaiting a response from the user or their server. Only you can see pending accounts.",
"collections.pending_accounts.title": "Why am I seeing pending accounts?",
"collections.remove_account": "Remove",
"collections.report_collection": "Report this collection",
"collections.revoke_collection_inclusion": "Remove myself from this collection",