mirror of
https://github.com/oxen-io/session-desktop.git
synced 2023-12-14 02:12:57 +01:00
227 lines
6.8 KiB
TypeScript
227 lines
6.8 KiB
TypeScript
import React from 'react';
|
|
import { DefaultTheme } from 'styled-components';
|
|
import { ConversationModel } from '../../models/conversation';
|
|
import { ApiV2 } from '../../opengroup/opengroupV2';
|
|
import { ConversationController } from '../../session/conversations';
|
|
import { PubKey } from '../../session/types';
|
|
import { ToastUtils } from '../../session/utils';
|
|
import { Flex } from '../session/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';
|
|
interface Props {
|
|
convo: ConversationModel;
|
|
onClose: any;
|
|
theme: DefaultTheme;
|
|
}
|
|
|
|
interface State {
|
|
modList: Array<ContactType>;
|
|
removingInProgress: boolean;
|
|
firstLoading: boolean;
|
|
}
|
|
|
|
export class RemoveModeratorsDialog extends React.Component<Props, State> {
|
|
private channelAPI: any;
|
|
|
|
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 async componentDidMount() {
|
|
if (this.props.convo.isOpenGroupV1()) {
|
|
this.channelAPI = await this.props.convo.getPublicSendData();
|
|
}
|
|
|
|
void this.refreshModList();
|
|
}
|
|
|
|
public render() {
|
|
const { i18n } = window;
|
|
const { removingInProgress, firstLoading } = this.state;
|
|
const hasMods = this.state.modList.length !== 0;
|
|
|
|
const chatName = this.props.convo.get('name');
|
|
|
|
const title = `${i18n('removeModerators')}: ${chatName}`;
|
|
|
|
const renderContent = !firstLoading;
|
|
|
|
return (
|
|
<SessionModal title={title} onClose={this.closeDialog} theme={this.props.theme}>
|
|
<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>
|
|
</SessionModal>
|
|
);
|
|
}
|
|
|
|
private closeDialog() {
|
|
this.props.onClose();
|
|
}
|
|
|
|
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);
|
|
}}
|
|
theme={this.props.theme}
|
|
/>
|
|
));
|
|
}
|
|
|
|
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 async refreshModList() {
|
|
let modPubKeys: Array<string> = [];
|
|
if (this.props.convo.isOpenGroupV1()) {
|
|
// get current list of moderators
|
|
modPubKeys = (await this.channelAPI.getModerators()) as Array<string>;
|
|
} else if (this.props.convo.isOpenGroupV2()) {
|
|
modPubKeys = this.props.convo.getGroupAdmins() || [];
|
|
}
|
|
const convos = ConversationController.getInstance().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;
|
|
if (this.props.convo.isOpenGroupV1()) {
|
|
res = await this.channelAPI.serverAPI.removeModerators(removedMods);
|
|
} else if (this.props.convo.isOpenGroupV2()) {
|
|
const roomInfos = this.props.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.pushUserNeedsToHaveJoined();
|
|
} else {
|
|
window.log.info(`${removedMods} removed from moderators...`);
|
|
ToastUtils.pushUserRemovedFromModerators();
|
|
}
|
|
} catch (e) {
|
|
window.log.error('Got error while adding moderator:', e);
|
|
} finally {
|
|
await this.refreshModList();
|
|
}
|
|
}
|
|
}
|