mirror of
https://github.com/mastodon/mastodon
synced 2024-11-30 15:58:14 +09:00
Add ability to search for all accounts when creating a list in web UI
This commit is contained in:
parent
86b42b0957
commit
1f6e616f17
@ -5,3 +5,16 @@ export const apiSubmitAccountNote = (id: string, value: string) =>
|
||||
apiRequestPost<ApiRelationshipJSON>(`v1/accounts/${id}/note`, {
|
||||
comment: value,
|
||||
});
|
||||
|
||||
export const apiFollowAccount = (
|
||||
id: string,
|
||||
params?: {
|
||||
reblogs: boolean;
|
||||
},
|
||||
) =>
|
||||
apiRequestPost<ApiRelationshipJSON>(`v1/accounts/${id}/follow`, {
|
||||
...params,
|
||||
});
|
||||
|
||||
export const apiUnfollowAccount = (id: string) =>
|
||||
apiRequestPost<ApiRelationshipJSON>(`v1/accounts/${id}/unfollow`);
|
||||
|
@ -9,10 +9,12 @@ import { useDebouncedCallback } from 'use-debounce';
|
||||
|
||||
import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react';
|
||||
import SquigglyArrow from '@/svg-icons/squiggly_arrow.svg?react';
|
||||
import { fetchFollowing } from 'mastodon/actions/accounts';
|
||||
import { fetchFollowing, fetchRelationships } from 'mastodon/actions/accounts';
|
||||
import { importFetchedAccounts } from 'mastodon/actions/importer';
|
||||
import { fetchList } from 'mastodon/actions/lists';
|
||||
import { openModal } from 'mastodon/actions/modal';
|
||||
import { apiRequest } from 'mastodon/api';
|
||||
import { apiFollowAccount } from 'mastodon/api/accounts';
|
||||
import {
|
||||
apiGetAccounts,
|
||||
apiAddAccountToList,
|
||||
@ -35,8 +37,8 @@ import { useAppDispatch, useAppSelector } from 'mastodon/store';
|
||||
const messages = defineMessages({
|
||||
heading: { id: 'column.list_members', defaultMessage: 'Manage list members' },
|
||||
placeholder: {
|
||||
id: 'lists.search_placeholder',
|
||||
defaultMessage: 'Search people you follow',
|
||||
id: 'lists.search',
|
||||
defaultMessage: 'Search',
|
||||
},
|
||||
enterSearch: { id: 'lists.add_to_list', defaultMessage: 'Add to list' },
|
||||
add: { id: 'lists.add_member', defaultMessage: 'Add' },
|
||||
@ -53,17 +55,50 @@ const AccountItem: React.FC<{
|
||||
onToggle: (accountId: string) => void;
|
||||
}> = ({ accountId, listId, partOfList, onToggle }) => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
const account = useAppSelector((state) => state.accounts.get(accountId));
|
||||
const relationship = useAppSelector((state) =>
|
||||
accountId ? state.relationships.get(accountId) : undefined,
|
||||
);
|
||||
const following = relationship?.following || relationship?.requested;
|
||||
|
||||
useEffect(() => {
|
||||
if (accountId) {
|
||||
dispatch(fetchRelationships([accountId]));
|
||||
}
|
||||
}, [dispatch, accountId]);
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
if (partOfList) {
|
||||
void apiRemoveAccountFromList(listId, accountId);
|
||||
} else {
|
||||
void apiAddAccountToList(listId, accountId);
|
||||
}
|
||||
|
||||
onToggle(accountId);
|
||||
}, [accountId, listId, partOfList, onToggle]);
|
||||
} else {
|
||||
if (following) {
|
||||
void apiAddAccountToList(listId, accountId);
|
||||
onToggle(accountId);
|
||||
} else {
|
||||
dispatch(
|
||||
openModal({
|
||||
modalType: 'CONFIRM_FOLLOW_TO_LIST',
|
||||
modalProps: {
|
||||
accountId,
|
||||
onConfirm: () => {
|
||||
apiFollowAccount(accountId)
|
||||
.then(() => apiAddAccountToList(listId, accountId))
|
||||
.then(() => {
|
||||
onToggle(accountId);
|
||||
return '';
|
||||
})
|
||||
.catch(() => {
|
||||
// Nothing
|
||||
});
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}, [dispatch, accountId, following, listId, partOfList, onToggle]);
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
@ -193,8 +228,7 @@ const ListMembers: React.FC<{
|
||||
signal: searchRequestRef.current.signal,
|
||||
params: {
|
||||
q: value,
|
||||
resolve: false,
|
||||
following: true,
|
||||
resolve: true,
|
||||
},
|
||||
})
|
||||
.then((data) => {
|
||||
|
@ -0,0 +1,43 @@
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import { useAppSelector } from 'mastodon/store';
|
||||
|
||||
import type { BaseConfirmationModalProps } from './confirmation_modal';
|
||||
import { ConfirmationModal } from './confirmation_modal';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: {
|
||||
id: 'confirmations.follow_to_list.title',
|
||||
defaultMessage: 'Follow user?',
|
||||
},
|
||||
confirm: {
|
||||
id: 'confirmations.follow_to_list.confirm',
|
||||
defaultMessage: 'Follow and add to list',
|
||||
},
|
||||
});
|
||||
|
||||
export const ConfirmFollowToListModal: React.FC<
|
||||
{
|
||||
accountId: string;
|
||||
onConfirm: () => void;
|
||||
} & BaseConfirmationModalProps
|
||||
> = ({ accountId, onConfirm, onClose }) => {
|
||||
const intl = useIntl();
|
||||
const account = useAppSelector((state) => state.accounts.get(accountId));
|
||||
|
||||
return (
|
||||
<ConfirmationModal
|
||||
title={intl.formatMessage(messages.title)}
|
||||
message={
|
||||
<FormattedMessage
|
||||
id='confirmations.follow_to_list.message'
|
||||
defaultMessage='You need to be following {name} to add them to a list.'
|
||||
values={{ name: <strong>@{account?.acct}</strong> }}
|
||||
/>
|
||||
}
|
||||
confirm={intl.formatMessage(messages.confirm)}
|
||||
onConfirm={onConfirm}
|
||||
onClose={onClose}
|
||||
/>
|
||||
);
|
||||
};
|
@ -6,3 +6,4 @@ export { ConfirmEditStatusModal } from './edit_status';
|
||||
export { ConfirmUnfollowModal } from './unfollow';
|
||||
export { ConfirmClearNotificationsModal } from './clear_notifications';
|
||||
export { ConfirmLogOutModal } from './log_out';
|
||||
export { ConfirmFollowToListModal } from './follow_to_list';
|
||||
|
@ -36,6 +36,7 @@ import {
|
||||
ConfirmUnfollowModal,
|
||||
ConfirmClearNotificationsModal,
|
||||
ConfirmLogOutModal,
|
||||
ConfirmFollowToListModal,
|
||||
} from './confirmation_modals';
|
||||
import FocalPointModal from './focal_point_modal';
|
||||
import ImageModal from './image_modal';
|
||||
@ -57,6 +58,7 @@ export const MODAL_COMPONENTS = {
|
||||
'CONFIRM_UNFOLLOW': () => Promise.resolve({ default: ConfirmUnfollowModal }),
|
||||
'CONFIRM_CLEAR_NOTIFICATIONS': () => Promise.resolve({ default: ConfirmClearNotificationsModal }),
|
||||
'CONFIRM_LOG_OUT': () => Promise.resolve({ default: ConfirmLogOutModal }),
|
||||
'CONFIRM_FOLLOW_TO_LIST': () => Promise.resolve({ default: ConfirmFollowToListModal }),
|
||||
'MUTE': MuteModal,
|
||||
'BLOCK': BlockModal,
|
||||
'DOMAIN_BLOCK': DomainBlockModal,
|
||||
|
@ -205,6 +205,9 @@
|
||||
"confirmations.edit.confirm": "Edit",
|
||||
"confirmations.edit.message": "Editing now will overwrite the message you are currently composing. Are you sure you want to proceed?",
|
||||
"confirmations.edit.title": "Overwrite post?",
|
||||
"confirmations.follow_to_list.confirm": "Follow and add to list",
|
||||
"confirmations.follow_to_list.message": "You need to be following {name} to add them to a list.",
|
||||
"confirmations.follow_to_list.title": "Follow user?",
|
||||
"confirmations.logout.confirm": "Log out",
|
||||
"confirmations.logout.message": "Are you sure you want to log out?",
|
||||
"confirmations.logout.title": "Log out?",
|
||||
@ -492,7 +495,7 @@
|
||||
"lists.replies_policy.list": "Members of the list",
|
||||
"lists.replies_policy.none": "No one",
|
||||
"lists.save": "Save",
|
||||
"lists.search_placeholder": "Search people you follow",
|
||||
"lists.search": "Search",
|
||||
"lists.show_replies_to": "Include replies from list members to",
|
||||
"load_pending": "{count, plural, one {# new item} other {# new items}}",
|
||||
"loading_indicator.label": "Loading…",
|
||||
|
Loading…
Reference in New Issue
Block a user