mirror of
https://github.com/lux-tel/session-desktop.git
synced 2026-10-30 20:33:24 +00:00
190 lines
6.7 KiB
TypeScript
190 lines
6.7 KiB
TypeScript
import { useRef, useState } from 'react';
|
|
import { getAppDispatch } from '../../state/dispatch';
|
|
|
|
import { useFocusMount } from '../../hooks/useFocusMount';
|
|
import { useConversationUsernameWithFallback } from '../../hooks/useParamSelector';
|
|
import { ConversationModel } from '../../models/conversation';
|
|
import {
|
|
sogsV3BanUser,
|
|
sogsV3UnbanUser,
|
|
} from '../../session/apis/open_group_api/sogsv3/sogsV3BanUnban';
|
|
import { ConvoHub } from '../../session/conversations/ConversationController';
|
|
import { PubKey } from '../../session/types';
|
|
import { ToastUtils } from '../../session/utils';
|
|
import { BanType, updateBanOrUnbanUserModal } from '../../state/ducks/modalDialog';
|
|
import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
|
|
import { SessionSpinner } from '../loading';
|
|
import {
|
|
ModalBasicHeader,
|
|
ModalActionsContainer,
|
|
SessionWrapperModal,
|
|
} from '../SessionWrapperModal';
|
|
import { tr } from '../../localization/localeTools';
|
|
import { SimpleSessionInput } from '../inputs/SessionInput';
|
|
import { ModalDescription } from './shared/ModalDescriptionContainer';
|
|
import { ModalFlexContainer } from './shared/ModalFlexContainer';
|
|
|
|
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 isBan = banType === 'ban';
|
|
const dispatch = getAppDispatch();
|
|
const convo = ConvoHub.use().get(conversationId);
|
|
const inputRef = useRef(null);
|
|
|
|
useFocusMount(inputRef, true);
|
|
const [inputBoxValue, setInputBoxValue] = useState('');
|
|
const [inProgress, setInProgress] = useState(false);
|
|
|
|
const displayName = useConversationUsernameWithFallback(true, pubkey);
|
|
|
|
const hasPubkeyOnLoad = pubkey?.length;
|
|
|
|
const inputTextToDisplay =
|
|
!!pubkey && displayName ? `${displayName} ${PubKey.shorten(pubkey)}` : 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) => {
|
|
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 (pubkey) {
|
|
dispatch(updateBanOrUnbanUserModal(null));
|
|
}
|
|
}
|
|
|
|
setInProgress(false);
|
|
};
|
|
|
|
const title = isBan ? tr('banUser') : tr('banUnbanUser');
|
|
|
|
/**
|
|
* Starts procedure for banning/unbanning user and all their messages using dialog
|
|
*/
|
|
const startBanAndDeleteAllSequence = async () => {
|
|
await banOrUnBanUser(true);
|
|
};
|
|
|
|
const onClose = () => {
|
|
dispatch(updateBanOrUnbanUserModal(null));
|
|
};
|
|
|
|
const buttonText = isBan ? tr('banUser') : tr('banUnbanUser');
|
|
|
|
return (
|
|
<SessionWrapperModal
|
|
modalId="banOrUnbanUserModal"
|
|
headerChildren={<ModalBasicHeader title={title} />}
|
|
onClose={onClose}
|
|
buttonChildren={
|
|
<ModalActionsContainer buttonType={SessionButtonType.Simple}>
|
|
<SessionButton
|
|
buttonType={SessionButtonType.Simple}
|
|
onClick={banOrUnBanUser}
|
|
text={buttonText}
|
|
disabled={inProgress}
|
|
buttonColor={isBan && !hasPubkeyOnLoad ? SessionButtonColor.Danger : undefined}
|
|
dataTestId={isBan ? 'ban-user-confirm-button' : 'unban-user-confirm-button'}
|
|
/>
|
|
{/*
|
|
* Note: we can only ban-and-delete-all when we have a pubkey on load currently.
|
|
* The reason is that there is an issue (sogs side), and the server won't lookup a blindedId from a
|
|
* sessionID, for the delete_all endpoint specifically.
|
|
* When hasPubkeyOnLoad is true, the dialog was shown from a right click on the messages list,
|
|
* so we do have the blindedId already in this case.
|
|
*/}
|
|
{isBan && hasPubkeyOnLoad ? (
|
|
<SessionButton
|
|
buttonType={SessionButtonType.Simple}
|
|
buttonColor={SessionButtonColor.Danger}
|
|
onClick={startBanAndDeleteAllSequence}
|
|
text={tr('banDeleteAll')}
|
|
disabled={inProgress}
|
|
dataTestId="ban-user-delete-all-confirm-button"
|
|
/>
|
|
) : (
|
|
<SessionButton
|
|
buttonType={SessionButtonType.Simple}
|
|
onClick={onClose}
|
|
text={tr('cancel')}
|
|
dataTestId="unban-user-cancel-button"
|
|
/>
|
|
)}
|
|
</ModalActionsContainer>
|
|
}
|
|
>
|
|
<ModalFlexContainer>
|
|
<ModalDescription
|
|
dataTestId="modal-description"
|
|
localizerProps={{ token: isBan ? 'banUserDescription' : 'banUnbanUserDescription' }}
|
|
/>
|
|
|
|
<SimpleSessionInput
|
|
inputRef={inputRef}
|
|
placeholder={tr('accountId')}
|
|
onValueChanged={setInputBoxValue}
|
|
disabled={inProgress || !!pubkey}
|
|
value={pubkey ? inputTextToDisplay : inputBoxValue}
|
|
errorDataTestId="error-message"
|
|
padding="var(--margins-sm) var(--margins-md)"
|
|
providedError={''}
|
|
// don't do anything on enter as we don't know if the user wants to ban or ban-delete-all
|
|
onEnterPressed={() => {}}
|
|
inputDataTestId={isBan ? 'ban-user-input' : 'unban-user-input'}
|
|
/>
|
|
<SessionSpinner $loading={inProgress} />
|
|
</ModalFlexContainer>
|
|
</SessionWrapperModal>
|
|
);
|
|
};
|