diff --git a/app/javascript/mastodon/features/collections/editor/accounts.tsx b/app/javascript/mastodon/features/collections/editor/accounts.tsx index ec6dbdac27..a51f58c236 100644 --- a/app/javascript/mastodon/features/collections/editor/accounts.tsx +++ b/app/javascript/mastodon/features/collections/editor/accounts.tsx @@ -4,6 +4,8 @@ import { FormattedMessage, useIntl } from 'react-intl'; import { useHistory } from 'react-router-dom'; +import type { Map as ImmutableMap } from 'immutable'; + import type { ApiMutedAccountJSON } from 'mastodon/api_types/accounts'; import type { ApiCollectionJSON } from 'mastodon/api_types/collections'; import { AccountListItem } from 'mastodon/components/account_list_item'; @@ -25,6 +27,7 @@ import { import { useAccount } from 'mastodon/hooks/useAccount'; import { useSearchAccounts } from 'mastodon/hooks/useSearchAccounts'; import { domain } from 'mastodon/initial_state'; +import type { Relationship } from 'mastodon/models/relationship'; import { addCollectionItem, getCollectionItemIds, @@ -85,19 +88,37 @@ const renderAccountItem = (account: ApiMutedAccountJSON) => ( type GroupKey = 'available' | 'mustFollow' | 'disabled'; -function groupSuggestions(accounts: ApiMutedAccountJSON[]) { - const { available, disabled } = Object.groupBy(accounts, (account) => { - if (getIsItemDisabled(account)) { +const canAccountBeAdded = (account: ApiMutedAccountJSON) => + ['automatic', 'manual'].includes(account.feature_approval.current_user); + +function groupSuggestions( + accounts: ApiMutedAccountJSON[], + relationships: ImmutableMap, +) { + const { available, mustFollow, disabled } = Object.groupBy( + accounts, + (account): GroupKey => { + if (canAccountBeAdded(account)) { + return 'available'; + } + + const canAccountBeAddedByFollowers = + account.feature_approval.automatic.includes('followers') || + account.feature_approval.manual.includes('followers'); + + if ( + canAccountBeAddedByFollowers && + !relationships.get(account.id)?.following + ) { + return 'mustFollow'; + } + return 'disabled'; - } - // if (account.locked && !relationship?.following) { - // return 'mustFollow'; - // } - return 'available'; - }); + }, + ); // Returning a new object ensures a fixed property order - return { available, disabled }; + return { available, mustFollow, disabled }; } const renderGroupTitle = (groupKey: GroupKey, titleId: string) => { @@ -146,10 +167,8 @@ const renderGroupTitle = (groupKey: GroupKey, titleId: string) => { }; const getItemId = (account: ApiMutedAccountJSON) => account.id; - -// Disable accounts who can't be added to a collection const getIsItemDisabled = (account: ApiMutedAccountJSON) => - !['automatic', 'manual'].includes(account.feature_approval.current_user); + !canAccountBeAdded(account); export const CollectionAccounts: React.FC<{ collection?: ApiCollectionJSON | null; @@ -189,6 +208,10 @@ export const CollectionAccounts: React.FC<{ filterResults: (account) => !accountIds.includes(account.id), }); + const relationships = useAppSelector((state) => state.relationships); + + const groupedItems = groupSuggestions(suggestedAccounts, relationships); + const handleSearchValueChange = useCallback( (e: React.ChangeEvent) => { setSearchValue(e.target.value); @@ -330,7 +353,7 @@ export const CollectionAccounts: React.FC<{ onKeyDown={handleSearchKeyDown} disabled={hasMaxAccounts} isLoading={isLoadingSuggestions} - items={groupSuggestions(suggestedAccounts)} + items={groupedItems} getItemId={getItemId} getIsItemDisabled={getIsItemDisabled} renderItem={renderAccountItem}