You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
5.6 KiB
TypeScript
168 lines
5.6 KiB
TypeScript
import { ChangeEvent, useRef, useState } from 'react';
|
|
import { useDispatch } from 'react-redux';
|
|
|
|
import { useFocusMount } from '../../hooks/useFocusMount';
|
|
import { useConversationPropsById } from '../../hooks/useParamSelector';
|
|
import { ConversationModel } from '../../models/conversation';
|
|
import {
|
|
sogsV3BanUser,
|
|
sogsV3UnbanUser,
|
|
} from '../../session/apis/open_group_api/sogsv3/sogsV3BanUnban';
|
|
import { getConversationController } from '../../session/conversations/ConversationController';
|
|
import { PubKey } from '../../session/types';
|
|
import { ToastUtils } from '../../session/utils';
|
|
import { BanType, updateBanOrUnbanUserModal } from '../../state/ducks/modalDialog';
|
|
import { useIsDarkTheme } from '../../state/selectors/theme';
|
|
import { SessionHeaderSearchInput } from '../SessionHeaderSearchInput';
|
|
import { SessionWrapperModal } from '../SessionWrapperModal';
|
|
import { Flex } from '../basic/Flex';
|
|
import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
|
|
import { SpacerSM } from '../basic/Text';
|
|
import { SessionSpinner } from '../loading';
|
|
|
|
async function banOrUnBanUserCall(
|
|
convo: ConversationModel,
|
|
textValue: string,
|
|
banType: BanType,
|
|
deleteAll: boolean
|
|
) {
|
|
// if we don't have valid data entered by the user
|
|
const pubkey = PubKey.from(textValue);
|
|
if (!pubkey) {
|
|
window.log.info(`invalid pubkey for ${banType} user:${textValue}`);
|
|
ToastUtils.pushInvalidPubKey();
|
|
return false;
|
|
}
|
|
try {
|
|
// this is a v2 opengroup
|
|
const roomInfos = convo.toOpenGroupV2();
|
|
const isChangeApplied =
|
|
banType === 'ban'
|
|
? await sogsV3BanUser(pubkey, roomInfos, deleteAll)
|
|
: await sogsV3UnbanUser(pubkey, roomInfos);
|
|
|
|
if (!isChangeApplied) {
|
|
window?.log?.warn(`failed to ${banType} user: ${isChangeApplied}`);
|
|
|
|
// eslint-disable-next-line no-unused-expressions
|
|
banType === 'ban' ? ToastUtils.pushUserBanFailure() : ToastUtils.pushUserUnbanSuccess();
|
|
return false;
|
|
}
|
|
window?.log?.info(`${pubkey.key} user ${banType}ned successfully...`);
|
|
// eslint-disable-next-line no-unused-expressions
|
|
banType === 'ban' ? ToastUtils.pushUserBanSuccess() : ToastUtils.pushUserUnbanSuccess();
|
|
return true;
|
|
} catch (e) {
|
|
window?.log?.error(`Got error while ${banType}ning user:`, e);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export const BanOrUnBanUserDialog = (props: {
|
|
conversationId: string;
|
|
banType: BanType;
|
|
pubkey?: string;
|
|
}) => {
|
|
const { conversationId, banType, pubkey } = props;
|
|
const { i18n } = window;
|
|
const isBan = banType === 'ban';
|
|
const dispatch = useDispatch();
|
|
const isDarkTheme = useIsDarkTheme();
|
|
const convo = getConversationController().get(conversationId);
|
|
const inputRef = useRef(null);
|
|
|
|
useFocusMount(inputRef, true);
|
|
const wasGivenAPubkey = Boolean(pubkey?.length);
|
|
const [inputBoxValue, setInputBoxValue] = useState('');
|
|
const [inProgress, setInProgress] = useState(false);
|
|
|
|
const sourceConvoProps = useConversationPropsById(pubkey);
|
|
|
|
const inputTextToDisplay =
|
|
wasGivenAPubkey && sourceConvoProps
|
|
? `${sourceConvoProps.displayNameInProfile} ${PubKey.shorten(sourceConvoProps.id)}`
|
|
: undefined;
|
|
|
|
/**
|
|
* Ban or Unban a user from an open group
|
|
* @param deleteAll Delete all messages for that user in the group (only works with ban)
|
|
*/
|
|
const banOrUnBanUser = async (deleteAll: boolean = false) => {
|
|
const castedPubkey = pubkey?.length ? pubkey : inputBoxValue;
|
|
|
|
window?.log?.info(`asked to ${banType} user: ${castedPubkey}, banAndDeleteAll:${deleteAll}`);
|
|
setInProgress(true);
|
|
const isBanned = await banOrUnBanUserCall(convo, castedPubkey, banType, deleteAll);
|
|
if (isBanned) {
|
|
// clear input box
|
|
setInputBoxValue('');
|
|
if (wasGivenAPubkey) {
|
|
dispatch(updateBanOrUnbanUserModal(null));
|
|
}
|
|
}
|
|
|
|
setInProgress(false);
|
|
};
|
|
|
|
const chatName = convo.getNicknameOrRealUsernameOrPlaceholder();
|
|
const title = `${isBan ? window.i18n('banUser') : window.i18n('unbanUser')}: ${chatName}`;
|
|
|
|
const onPubkeyBoxChanges = (e: ChangeEvent<HTMLInputElement>) => {
|
|
setInputBoxValue(e.target.value?.trim() || '');
|
|
};
|
|
|
|
/**
|
|
* Starts procedure for banning/unbanning user and all their messages using dialog
|
|
*/
|
|
const startBanAndDeleteAllSequence = async () => {
|
|
await banOrUnBanUser(true);
|
|
};
|
|
|
|
const buttonText = isBan ? i18n('banUser') : i18n('unbanUser');
|
|
|
|
return (
|
|
<SessionWrapperModal
|
|
showExitIcon={true}
|
|
title={title}
|
|
onClose={() => {
|
|
dispatch(updateBanOrUnbanUserModal(null));
|
|
}}
|
|
>
|
|
<Flex container={true} flexDirection="column" alignItems="center">
|
|
<SessionHeaderSearchInput
|
|
ref={inputRef}
|
|
type="text"
|
|
isDarkTheme={isDarkTheme}
|
|
placeholder={i18n('accountIdEnter')}
|
|
dir="auto"
|
|
onChange={onPubkeyBoxChanges}
|
|
disabled={inProgress || wasGivenAPubkey}
|
|
value={wasGivenAPubkey ? inputTextToDisplay : inputBoxValue}
|
|
/>
|
|
<Flex container={true}>
|
|
<SessionButton
|
|
buttonType={SessionButtonType.Simple}
|
|
onClick={banOrUnBanUser}
|
|
text={buttonText}
|
|
disabled={inProgress}
|
|
/>
|
|
{isBan && (
|
|
<>
|
|
<SpacerSM />
|
|
<SessionButton
|
|
buttonType={SessionButtonType.Simple}
|
|
buttonColor={SessionButtonColor.Danger}
|
|
onClick={startBanAndDeleteAllSequence}
|
|
text={i18n('banUserAndDeleteAll')}
|
|
disabled={inProgress}
|
|
/>
|
|
</>
|
|
)}
|
|
</Flex>
|
|
<SessionSpinner loading={inProgress} />
|
|
</Flex>
|
|
</SessionWrapperModal>
|
|
);
|
|
};
|