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.
221 lines
6.6 KiB
TypeScript
221 lines
6.6 KiB
TypeScript
import React from 'react';
|
|
import { DefaultTheme } from 'styled-components';
|
|
import { ConversationModel } from '../../models/conversation';
|
|
import { ApiV2 } from '../../opengroup/opengroupV2';
|
|
import { getConversationController } from '../../session/conversations';
|
|
import { PubKey } from '../../session/types';
|
|
import { ToastUtils } from '../../session/utils';
|
|
import { Flex } from '../basic/Flex';
|
|
import { SessionButton, SessionButtonColor, SessionButtonType } from '../session/SessionButton';
|
|
import { ContactType, SessionMemberListItem } from '../session/SessionMemberListItem';
|
|
import { SessionModal } from '../session/SessionModal';
|
|
import { SessionSpinner } from '../session/SessionSpinner';
|
|
import _ from 'lodash';
|
|
import { SessionWrapperModal } from '../session/SessionWrapperModal';
|
|
import { updateRemoveModeratorsModal } from '../../state/ducks/modalDialog';
|
|
interface Props {
|
|
conversationId: string;
|
|
}
|
|
|
|
interface State {
|
|
modList: Array<ContactType>;
|
|
removingInProgress: boolean;
|
|
firstLoading: boolean;
|
|
}
|
|
|
|
export class RemoveModeratorsDialog extends React.Component<Props, State> {
|
|
constructor(props: any) {
|
|
super(props);
|
|
|
|
this.onModClicked = this.onModClicked.bind(this);
|
|
this.closeDialog = this.closeDialog.bind(this);
|
|
this.removeThem = this.removeThem.bind(this);
|
|
|
|
this.state = {
|
|
modList: [],
|
|
removingInProgress: false,
|
|
firstLoading: true,
|
|
};
|
|
}
|
|
|
|
public componentDidMount() {
|
|
this.refreshModList();
|
|
}
|
|
|
|
public render() {
|
|
const { i18n } = window;
|
|
const { removingInProgress, firstLoading } = this.state;
|
|
const hasMods = this.state.modList.length !== 0;
|
|
|
|
const convo = getConversationController().get(this.props.conversationId);
|
|
|
|
const chatName = convo.get('name');
|
|
|
|
const title = `${i18n('removeModerators')}: ${chatName}`;
|
|
|
|
const renderContent = !firstLoading;
|
|
|
|
return (
|
|
<SessionWrapperModal title={title} onClose={this.closeDialog}>
|
|
<Flex container={true} flexDirection="column" alignItems="center">
|
|
{renderContent && (
|
|
<>
|
|
<p>Existing moderators:</p>
|
|
<div className="contact-selection-list">{this.renderMemberList()}</div>
|
|
|
|
{hasMods ? null : <p>{i18n('noModeratorsToRemove')}</p>}
|
|
<SessionSpinner loading={removingInProgress} />
|
|
|
|
<div className="session-modal__button-group">
|
|
<SessionButton
|
|
buttonType={SessionButtonType.Brand}
|
|
buttonColor={SessionButtonColor.Green}
|
|
onClick={this.removeThem}
|
|
disabled={removingInProgress}
|
|
text={i18n('ok')}
|
|
/>
|
|
<SessionButton
|
|
buttonType={SessionButtonType.Brand}
|
|
buttonColor={SessionButtonColor.Primary}
|
|
onClick={this.closeDialog}
|
|
disabled={removingInProgress}
|
|
text={i18n('cancel')}
|
|
/>
|
|
</div>
|
|
</>
|
|
)}
|
|
|
|
<SessionSpinner loading={firstLoading} />
|
|
</Flex>
|
|
</SessionWrapperModal>
|
|
);
|
|
}
|
|
|
|
private closeDialog() {
|
|
window.inboxStore?.dispatch(updateRemoveModeratorsModal(null));
|
|
}
|
|
|
|
private renderMemberList() {
|
|
const members = this.state.modList;
|
|
const selectedContacts = members.filter(d => d.checkmarked).map(d => d.id);
|
|
|
|
return members.map((member: ContactType, index: number) => (
|
|
<SessionMemberListItem
|
|
member={member}
|
|
key={index}
|
|
index={index}
|
|
isSelected={selectedContacts.some(m => m === member.id)}
|
|
onSelect={(selectedMember: ContactType) => {
|
|
this.onModClicked(selectedMember);
|
|
}}
|
|
onUnselect={(selectedMember: ContactType) => {
|
|
this.onModClicked(selectedMember);
|
|
}}
|
|
/>
|
|
));
|
|
}
|
|
|
|
private onModClicked(selected: ContactType) {
|
|
const updatedContacts = this.state.modList.map(member => {
|
|
if (member.id === selected.id) {
|
|
return { ...member, checkmarked: !member.checkmarked };
|
|
} else {
|
|
return member;
|
|
}
|
|
});
|
|
|
|
this.setState(state => {
|
|
return {
|
|
...state,
|
|
modList: updatedContacts,
|
|
};
|
|
});
|
|
}
|
|
|
|
private refreshModList() {
|
|
let modPubKeys: Array<string> = [];
|
|
const convo = getConversationController().get(this.props.conversationId);
|
|
|
|
modPubKeys = convo.getGroupAdmins() || [];
|
|
|
|
const convos = getConversationController().getConversations();
|
|
const moderatorsConvos = modPubKeys
|
|
.map(
|
|
pubKey =>
|
|
convos.find(c => c.id === pubKey) || {
|
|
id: pubKey, // memberList need a key
|
|
authorPhoneNumber: pubKey,
|
|
}
|
|
)
|
|
.filter(c => !!c);
|
|
|
|
const mods = moderatorsConvos.map((d: any) => {
|
|
let name = '';
|
|
if (d.getLokiProfile) {
|
|
const lokiProfile = d.getLokiProfile();
|
|
name = lokiProfile ? lokiProfile.displayName : 'Anonymous';
|
|
}
|
|
// TODO: should take existing members into account
|
|
const existingMember = false;
|
|
|
|
return {
|
|
id: d.id,
|
|
authorPhoneNumber: d.id,
|
|
authorProfileName: name,
|
|
selected: false,
|
|
authorAvatarPath: '',
|
|
authorName: name,
|
|
checkmarked: true,
|
|
existingMember,
|
|
};
|
|
});
|
|
this.setState({
|
|
modList: mods,
|
|
firstLoading: false,
|
|
removingInProgress: false,
|
|
});
|
|
}
|
|
|
|
private async removeThem() {
|
|
const removedMods = this.state.modList.filter(d => !d.checkmarked).map(d => d.id);
|
|
|
|
if (removedMods.length === 0) {
|
|
window?.log?.info('No moderators removed. Nothing todo');
|
|
return;
|
|
}
|
|
window?.log?.info(`asked to remove moderator: ${removedMods}`);
|
|
|
|
try {
|
|
this.setState({
|
|
removingInProgress: true,
|
|
});
|
|
let res;
|
|
const convo = getConversationController().get(this.props.conversationId);
|
|
|
|
const roomInfos = convo.toOpenGroupV2();
|
|
const modsToRemove = _.compact(removedMods.map(m => PubKey.from(m)));
|
|
res = await Promise.all(
|
|
modsToRemove.map(async m => {
|
|
return ApiV2.removeModerator(m, roomInfos);
|
|
})
|
|
);
|
|
// all moderators are removed means all promise resolved with bool= true
|
|
res = res.every(r => !!r);
|
|
|
|
if (!res) {
|
|
window?.log?.warn('failed to remove moderators:', res);
|
|
|
|
ToastUtils.pushFailedToRemoveFromModerator();
|
|
} else {
|
|
window?.log?.info(`${removedMods} removed from moderators...`);
|
|
ToastUtils.pushUserRemovedFromModerators();
|
|
this.closeDialog();
|
|
}
|
|
} catch (e) {
|
|
window?.log?.error('Got error while removing moderator:', e);
|
|
} finally {
|
|
this.refreshModList();
|
|
}
|
|
}
|
|
}
|