Ban User from status action bar
This commit is contained in:
parent
e3fa58c0da
commit
9e27cb06cb
|
@ -1,12 +1,12 @@
|
||||||
import { Entities } from 'soapbox/entity-store/entities';
|
import { Entities } from 'soapbox/entity-store/entities';
|
||||||
import { useEntityActions } from 'soapbox/entity-store/hooks';
|
import { useEntityActions } from 'soapbox/entity-store/hooks';
|
||||||
|
|
||||||
import type { Group, GroupMember } from 'soapbox/schemas';
|
import type { Account, Group, GroupMember } from 'soapbox/schemas';
|
||||||
|
|
||||||
function useBlockGroupMember(group: Group, groupMember: GroupMember) {
|
function useBlockGroupMember(group: Group, account: Account) {
|
||||||
const { createEntity } = useEntityActions<GroupMember>(
|
const { createEntity } = useEntityActions<GroupMember>(
|
||||||
[Entities.GROUP_MEMBERSHIPS, groupMember.id],
|
[Entities.GROUP_MEMBERSHIPS, account.id],
|
||||||
{ post: `/api/v1/groups/${group.id}/blocks` },
|
{ post: `/api/v1/groups/${group?.id}/blocks` },
|
||||||
);
|
);
|
||||||
|
|
||||||
return createEntity;
|
return createEntity;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import type { Group, GroupMember } from 'soapbox/schemas';
|
||||||
|
|
||||||
function usePromoteGroupMember(group: Group, groupMember: GroupMember) {
|
function usePromoteGroupMember(group: Group, groupMember: GroupMember) {
|
||||||
const { createEntity } = useEntityActions<GroupMember>(
|
const { createEntity } = useEntityActions<GroupMember>(
|
||||||
[Entities.GROUP_MEMBERSHIPS, groupMember.id],
|
[Entities.GROUP_MEMBERSHIPS, groupMember.account.id],
|
||||||
{ post: `/api/v1/groups/${group.id}/promote` },
|
{ post: `/api/v1/groups/${group.id}/promote` },
|
||||||
{ schema: z.array(groupMemberSchema).transform((arr) => arr[0]) },
|
{ schema: z.array(groupMemberSchema).transform((arr) => arr[0]) },
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { List as ImmutableList } from 'immutable';
|
import { List as ImmutableList } from 'immutable';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory, useRouteMatch } from 'react-router-dom';
|
||||||
|
|
||||||
import { blockAccount } from 'soapbox/actions/accounts';
|
import { blockAccount } from 'soapbox/actions/accounts';
|
||||||
import { launchChat } from 'soapbox/actions/chats';
|
import { launchChat } from 'soapbox/actions/chats';
|
||||||
|
@ -14,7 +14,7 @@ import { initMuteModal } from 'soapbox/actions/mutes';
|
||||||
import { initReport, ReportableEntities } from 'soapbox/actions/reports';
|
import { initReport, ReportableEntities } from 'soapbox/actions/reports';
|
||||||
import { deleteStatus, editStatus, toggleMuteStatus } from 'soapbox/actions/statuses';
|
import { deleteStatus, editStatus, toggleMuteStatus } from 'soapbox/actions/statuses';
|
||||||
import { deleteFromTimelines } from 'soapbox/actions/timelines';
|
import { deleteFromTimelines } from 'soapbox/actions/timelines';
|
||||||
import { useGroup, useGroupRelationship, useMuteGroup, useUnmuteGroup } from 'soapbox/api/hooks';
|
import { useBlockGroupMember, useGroup, useGroupRelationship, useMuteGroup, useUnmuteGroup } from 'soapbox/api/hooks';
|
||||||
import { useDeleteGroupStatus } from 'soapbox/api/hooks/groups/useDeleteGroupStatus';
|
import { useDeleteGroupStatus } from 'soapbox/api/hooks/groups/useDeleteGroupStatus';
|
||||||
import DropdownMenu from 'soapbox/components/dropdown-menu';
|
import DropdownMenu from 'soapbox/components/dropdown-menu';
|
||||||
import StatusActionButton from 'soapbox/components/status-action-button';
|
import StatusActionButton from 'soapbox/components/status-action-button';
|
||||||
|
@ -36,6 +36,7 @@ const messages = defineMessages({
|
||||||
adminAccount: { id: 'status.admin_account', defaultMessage: 'Moderate @{name}' },
|
adminAccount: { id: 'status.admin_account', defaultMessage: 'Moderate @{name}' },
|
||||||
admin_status: { id: 'status.admin_status', defaultMessage: 'Open this post in the moderation interface' },
|
admin_status: { id: 'status.admin_status', defaultMessage: 'Open this post in the moderation interface' },
|
||||||
block: { id: 'account.block', defaultMessage: 'Block @{name}' },
|
block: { id: 'account.block', defaultMessage: 'Block @{name}' },
|
||||||
|
blocked: { id: 'group.group_mod_block.success', defaultMessage: '@{name} is banned' },
|
||||||
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
|
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
|
||||||
blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
|
blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
|
||||||
bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark' },
|
bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark' },
|
||||||
|
@ -57,6 +58,9 @@ const messages = defineMessages({
|
||||||
embed: { id: 'status.embed', defaultMessage: 'Embed' },
|
embed: { id: 'status.embed', defaultMessage: 'Embed' },
|
||||||
external: { id: 'status.external', defaultMessage: 'View post on {domain}' },
|
external: { id: 'status.external', defaultMessage: 'View post on {domain}' },
|
||||||
favourite: { id: 'status.favourite', defaultMessage: 'Like' },
|
favourite: { id: 'status.favourite', defaultMessage: 'Like' },
|
||||||
|
groupBlockConfirm: { id: 'confirmations.block_from_group.confirm', defaultMessage: 'Ban' },
|
||||||
|
groupBlockFromGroupHeading: { id: 'confirmations.block_from_group.heading', defaultMessage: 'Ban From Group' },
|
||||||
|
groupBlockFromGroupMessage: { id: 'confirmations.block_from_group.message', defaultMessage: 'Are you sure you want to ban @{name} from the group?' },
|
||||||
groupModDelete: { id: 'status.group_mod_delete', defaultMessage: 'Delete post from group' },
|
groupModDelete: { id: 'status.group_mod_delete', defaultMessage: 'Delete post from group' },
|
||||||
group_remove_account: { id: 'status.remove_account_from_group', defaultMessage: 'Remove account from group' },
|
group_remove_account: { id: 'status.remove_account_from_group', defaultMessage: 'Remove account from group' },
|
||||||
group_remove_post: { id: 'status.remove_post_from_group', defaultMessage: 'Remove post from group' },
|
group_remove_post: { id: 'status.remove_post_from_group', defaultMessage: 'Remove post from group' },
|
||||||
|
@ -121,19 +125,20 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
const match = useRouteMatch<{ groupSlug: string }>('/group/:groupSlug');
|
||||||
|
|
||||||
const { group } = useGroup((status.group as Group)?.id as string);
|
const { group } = useGroup((status.group as Group)?.id as string);
|
||||||
const muteGroup = useMuteGroup(group as Group);
|
const muteGroup = useMuteGroup(group as Group);
|
||||||
const unmuteGroup = useUnmuteGroup(group as Group);
|
const unmuteGroup = useUnmuteGroup(group as Group);
|
||||||
const isMutingGroup = !!group?.relationship?.muting;
|
const isMutingGroup = !!group?.relationship?.muting;
|
||||||
|
const deleteGroupStatus = useDeleteGroupStatus(group as Group, status.id);
|
||||||
|
const blockGroupMember = useBlockGroupMember(group as Group, status?.account as any);
|
||||||
|
|
||||||
const me = useAppSelector(state => state.me);
|
const me = useAppSelector(state => state.me);
|
||||||
const { groupRelationship } = useGroupRelationship(status.group?.id);
|
const { groupRelationship } = useGroupRelationship(status.group?.id);
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const settings = useSettings();
|
const settings = useSettings();
|
||||||
const soapboxConfig = useSoapboxConfig();
|
const soapboxConfig = useSoapboxConfig();
|
||||||
const deleteGroupStatus = useDeleteGroupStatus(status?.group as Group, status.id);
|
|
||||||
|
|
||||||
const { allowedEmoji } = soapboxConfig;
|
const { allowedEmoji } = soapboxConfig;
|
||||||
|
|
||||||
|
@ -371,6 +376,21 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleBlockFromGroup = () => {
|
||||||
|
dispatch(openModal('CONFIRM', {
|
||||||
|
heading: intl.formatMessage(messages.groupBlockFromGroupHeading),
|
||||||
|
message: intl.formatMessage(messages.groupBlockFromGroupMessage, { name: (status.account as any).username }),
|
||||||
|
confirm: intl.formatMessage(messages.groupBlockConfirm),
|
||||||
|
onConfirm: () => {
|
||||||
|
blockGroupMember({ account_ids: [(status.account as any).id] }, {
|
||||||
|
onSuccess() {
|
||||||
|
toast.success(intl.formatMessage(messages.blocked, { name: account?.acct }));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
const _makeMenu = (publicStatus: boolean) => {
|
const _makeMenu = (publicStatus: boolean) => {
|
||||||
const mutingConversation = status.muted;
|
const mutingConversation = status.muted;
|
||||||
const ownAccount = status.account.id === me;
|
const ownAccount = status.account.id === me;
|
||||||
|
@ -538,10 +558,24 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
const isGroupOwner = groupRelationship?.role === GroupRoles.OWNER;
|
const isGroupOwner = groupRelationship?.role === GroupRoles.OWNER;
|
||||||
const isGroupAdmin = groupRelationship?.role === GroupRoles.ADMIN;
|
const isGroupAdmin = groupRelationship?.role === GroupRoles.ADMIN;
|
||||||
const isStatusFromOwner = group.owner.id === account.id;
|
const isStatusFromOwner = group.owner.id === account.id;
|
||||||
|
|
||||||
|
const canBanUser = match?.isExact && (isGroupOwner || isGroupAdmin) && !isStatusFromOwner && !ownAccount;
|
||||||
const canDeleteStatus = !ownAccount && (isGroupOwner || (isGroupAdmin && !isStatusFromOwner));
|
const canDeleteStatus = !ownAccount && (isGroupOwner || (isGroupAdmin && !isStatusFromOwner));
|
||||||
|
|
||||||
if (canDeleteStatus) {
|
if (canBanUser || canDeleteStatus) {
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canBanUser) {
|
||||||
|
menu.push({
|
||||||
|
text: 'Ban from Group',
|
||||||
|
action: handleBlockFromGroup,
|
||||||
|
icon: require('@tabler/icons/ban.svg'),
|
||||||
|
destructive: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canDeleteStatus) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.groupModDelete),
|
text: intl.formatMessage(messages.groupModDelete),
|
||||||
action: handleDeleteFromGroup,
|
action: handleDeleteFromGroup,
|
||||||
|
|
|
@ -53,7 +53,7 @@ const GroupMemberListItem = (props: IGroupMemberListItem) => {
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const blockGroupMember = useBlockGroupMember(group, member);
|
const blockGroupMember = useBlockGroupMember(group, member.account);
|
||||||
const promoteGroupMember = usePromoteGroupMember(group, member);
|
const promoteGroupMember = usePromoteGroupMember(group, member);
|
||||||
const demoteGroupMember = useDemoteGroupMember(group, member);
|
const demoteGroupMember = useDemoteGroupMember(group, member);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue