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, useSelector } 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 { isDarkTheme } 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 darkMode = useSelector(isDarkTheme);
 | 
						|
  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"
 | 
						|
          darkMode={darkMode}
 | 
						|
          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>
 | 
						|
  );
 | 
						|
};
 |