mirror of
https://github.com/oxen-io/session-desktop.git
synced 2023-12-14 02:12:57 +01:00
commit
334f371367
20 changed files with 157 additions and 72 deletions
|
@ -1752,6 +1752,18 @@
|
||||||
"message": "You cannot remove this user as they are the creator of the group.",
|
"message": "You cannot remove this user as they are the creator of the group.",
|
||||||
"description": "Toast description when the user tries to remove the creator from a closed group v2 member list."
|
"description": "Toast description when the user tries to remove the creator from a closed group v2 member list."
|
||||||
},
|
},
|
||||||
|
"userNeedsToHaveJoined": {
|
||||||
|
"message": "User needs to have joined",
|
||||||
|
"description": "Toast title when the user tries to remove the creator from a closed group v2 member list."
|
||||||
|
},
|
||||||
|
"userNeedsToHaveJoinedDesc": {
|
||||||
|
"message": "Remember that this user needs to have already joined the server for this ADD to work.",
|
||||||
|
"description": "Toast description when the user adds a moderator for an open group."
|
||||||
|
},
|
||||||
|
"addToTheListBelow": {
|
||||||
|
"message": "Add to the list below",
|
||||||
|
"description": "Button action to add a moderator by pubkey"
|
||||||
|
},
|
||||||
"noContactsForGroup": {
|
"noContactsForGroup": {
|
||||||
"message": "You don't have any contacts yet",
|
"message": "You don't have any contacts yet",
|
||||||
"androidKey": "activity_create_closed_group_empty_state_message"
|
"androidKey": "activity_create_closed_group_empty_state_message"
|
||||||
|
|
2
js/models/conversations.d.ts
vendored
2
js/models/conversations.d.ts
vendored
|
@ -65,7 +65,7 @@ export interface ConversationModel
|
||||||
isRss: () => boolean;
|
isRss: () => boolean;
|
||||||
isBlocked: () => boolean;
|
isBlocked: () => boolean;
|
||||||
isClosable: () => boolean;
|
isClosable: () => boolean;
|
||||||
isModerator: (id?: string) => boolean;
|
isModerator: (id: string) => boolean;
|
||||||
throttledBumpTyping: () => void;
|
throttledBumpTyping: () => void;
|
||||||
|
|
||||||
messageCollection: Backbone.Collection<MessageModel>;
|
messageCollection: Backbone.Collection<MessageModel>;
|
||||||
|
|
|
@ -1827,6 +1827,9 @@
|
||||||
if (!this.isPublic()) {
|
if (!this.isPublic()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!pubKey) {
|
||||||
|
throw new Error('isModerator() pubKey is falsy');
|
||||||
|
}
|
||||||
const moderators = this.get('moderators');
|
const moderators = this.get('moderators');
|
||||||
return Array.isArray(moderators) && moderators.includes(pubKey);
|
return Array.isArray(moderators) && moderators.includes(pubKey);
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
openInbox: 'openInbox',
|
openInbox: 'openInbox',
|
||||||
},
|
},
|
||||||
applyRtl() {
|
applyRtl() {
|
||||||
const rtlLocales = ['fa'];
|
const rtlLocales = ['fa', 'ar', 'he'];
|
||||||
|
|
||||||
const loc = window.i18n.getLocale();
|
const loc = window.i18n.getLocale();
|
||||||
if (rtlLocales.includes(loc)) {
|
if (rtlLocales.includes(loc)) {
|
||||||
|
|
|
@ -21,17 +21,20 @@
|
||||||
const modPubKeys = await this.channelAPI.getModerators();
|
const modPubKeys = await this.channelAPI.getModerators();
|
||||||
|
|
||||||
// private contacts (not you) that aren't already moderators
|
// private contacts (not you) that aren't already moderators
|
||||||
const contacts = convo.filter(
|
const contacts = window
|
||||||
d =>
|
.getConversationController()
|
||||||
!!d &&
|
.getConversations()
|
||||||
d.isPrivate() &&
|
.filter(
|
||||||
!d.isBlocked() &&
|
d =>
|
||||||
!d.isMe() &&
|
!!d &&
|
||||||
!modPubKeys.includes(d.id)
|
d.isPrivate() &&
|
||||||
);
|
!d.isBlocked() &&
|
||||||
|
!d.isMe() &&
|
||||||
|
!modPubKeys.includes(d.id)
|
||||||
|
);
|
||||||
|
|
||||||
this.contacts = contacts;
|
this.contacts = contacts;
|
||||||
this.this.theme = convo.theme;
|
this.theme = convo.theme;
|
||||||
|
|
||||||
this.$el.focus();
|
this.$el.focus();
|
||||||
this.render();
|
this.render();
|
||||||
|
@ -56,11 +59,16 @@
|
||||||
this.remove();
|
this.remove();
|
||||||
},
|
},
|
||||||
async onSubmit(pubKeys) {
|
async onSubmit(pubKeys) {
|
||||||
log.info(`asked to add ${pubKeys}`);
|
log.info(`asked to add moderators: ${pubKeys}`);
|
||||||
|
window.libsession.Utils.ToastUtils.pushUserNeedsToHaveJoined();
|
||||||
|
|
||||||
const res = await this.channelAPI.serverAPI.addModerators(pubKeys);
|
const res = await this.channelAPI.serverAPI.addModerators(pubKeys);
|
||||||
if (res !== true) {
|
if (res !== true) {
|
||||||
// we have errors, deal with them...
|
// we have errors, deal with them...
|
||||||
// how?
|
// how?
|
||||||
|
window.log.warn('failed to add moderators:', res);
|
||||||
|
} else {
|
||||||
|
window.log.info(`${pubKeys} added as moderators...`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -56,10 +56,15 @@
|
||||||
this.remove();
|
this.remove();
|
||||||
},
|
},
|
||||||
async onSubmit(pubKeys) {
|
async onSubmit(pubKeys) {
|
||||||
|
window.log.info(`asked to remove moderators ${pubKeys}`);
|
||||||
|
|
||||||
const res = await this.channelAPI.serverAPI.removeModerators(pubKeys);
|
const res = await this.channelAPI.serverAPI.removeModerators(pubKeys);
|
||||||
if (res !== true) {
|
if (res !== true) {
|
||||||
// we have errors, deal with them...
|
// we have errors, deal with them...
|
||||||
// how?
|
// how?
|
||||||
|
window.log.warn('failed to remove moderators:', res);
|
||||||
|
} else {
|
||||||
|
window.log.info(`${pubKeys} removed from moderators...`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
.content {
|
.content {
|
||||||
max-width: 100% !important;
|
max-width: 100% !important;
|
||||||
}
|
}
|
||||||
|
.contact-selection-list {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.buttons {
|
.buttons {
|
||||||
margin: 8px;
|
margin: 8px;
|
||||||
|
|
|
@ -4,8 +4,6 @@ import { QRCode } from 'react-qr-svg';
|
||||||
import { SessionModal } from './session/SessionModal';
|
import { SessionModal } from './session/SessionModal';
|
||||||
import { SessionButton, SessionButtonColor } from './session/SessionButton';
|
import { SessionButton, SessionButtonColor } from './session/SessionButton';
|
||||||
import { SessionSpinner } from './session/SessionSpinner';
|
import { SessionSpinner } from './session/SessionSpinner';
|
||||||
import { toast } from 'react-toastify';
|
|
||||||
import { SessionToast, SessionToastType } from './session/SessionToast';
|
|
||||||
import { ToastUtils } from '../session/utils';
|
import { ToastUtils } from '../session/utils';
|
||||||
import { DefaultTheme } from 'styled-components';
|
import { DefaultTheme } from 'styled-components';
|
||||||
import { ConversationController } from '../session/conversations';
|
import { ConversationController } from '../session/conversations';
|
||||||
|
|
|
@ -256,7 +256,7 @@ export class EditProfileDialog extends React.Component<Props, State> {
|
||||||
private renderAvatar() {
|
private renderAvatar() {
|
||||||
const { avatar, profileName } = this.state;
|
const { avatar, profileName } = this.state;
|
||||||
const { pubkey } = this.props;
|
const { pubkey } = this.props;
|
||||||
const userName = name || profileName || pubkey;
|
const userName = profileName || pubkey;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Avatar avatarPath={avatar} name={userName} size={80} pubkey={pubkey} />
|
<Avatar avatarPath={avatar} name={userName} size={80} pubkey={pubkey} />
|
||||||
|
@ -264,8 +264,6 @@ export class EditProfileDialog extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private onNameEdited(event: any) {
|
private onNameEdited(event: any) {
|
||||||
event.persist();
|
|
||||||
|
|
||||||
const newName = event.target.value.replace(window.displayNameRegex, '');
|
const newName = event.target.value.replace(window.displayNameRegex, '');
|
||||||
|
|
||||||
this.setState(state => {
|
this.setState(state => {
|
||||||
|
|
|
@ -44,7 +44,7 @@ interface Props {
|
||||||
isPrivate: boolean;
|
isPrivate: boolean;
|
||||||
isPublic: boolean;
|
isPublic: boolean;
|
||||||
isRss: boolean;
|
isRss: boolean;
|
||||||
amMod: boolean;
|
isAdmin: boolean;
|
||||||
|
|
||||||
// We might not always have the full list of members,
|
// We might not always have the full list of members,
|
||||||
// e.g. for open groups where we could have thousands
|
// e.g. for open groups where we could have thousands
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Contact, MemberList } from './MemberList';
|
import { Contact, MemberList } from './MemberList';
|
||||||
import { cleanSearchTerm } from '../../util/cleanSearchTerm';
|
import { cleanSearchTerm } from '../../util/cleanSearchTerm';
|
||||||
import { DefaultTheme } from 'styled-components';
|
import {
|
||||||
|
SessionButton,
|
||||||
|
SessionButtonColor,
|
||||||
|
SessionButtonType,
|
||||||
|
} from '../session/SessionButton';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
contactList: Array<any>;
|
contactList: Array<any>;
|
||||||
chatName: string;
|
chatName: string;
|
||||||
onSubmit: any;
|
onSubmit: any;
|
||||||
onClose: any;
|
onClose: any;
|
||||||
// theme: DefaultTheme;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
@ -117,7 +120,7 @@ export class AddModeratorsDialog extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const i18n = window.i18n;
|
const { i18n } = window;
|
||||||
|
|
||||||
const hasContacts = this.state.contactList.length !== 0;
|
const hasContacts = this.state.contactList.length !== 0;
|
||||||
|
|
||||||
|
@ -136,9 +139,12 @@ export class AddModeratorsDialog extends React.Component<Props, State> {
|
||||||
dir="auto"
|
dir="auto"
|
||||||
onChange={this.updateSearchBound}
|
onChange={this.updateSearchBound}
|
||||||
/>
|
/>
|
||||||
<button className="add" tabIndex={0} onClick={this.add}>
|
<SessionButton
|
||||||
{i18n('add')}
|
buttonType={SessionButtonType.Brand}
|
||||||
</button>
|
buttonColor={SessionButtonColor.Primary}
|
||||||
|
onClick={this.add}
|
||||||
|
text={i18n('addToTheListBelow')}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="moderatorList">
|
<div className="moderatorList">
|
||||||
<p>From friends:</p>
|
<p>From friends:</p>
|
||||||
|
@ -152,13 +158,19 @@ export class AddModeratorsDialog extends React.Component<Props, State> {
|
||||||
</div>
|
</div>
|
||||||
{hasContacts ? null : <p>{i18n('noContactsToAdd')}</p>}
|
{hasContacts ? null : <p>{i18n('noContactsToAdd')}</p>}
|
||||||
</div>
|
</div>
|
||||||
<div className="buttons">
|
<div className="session-modal__button-group">
|
||||||
<button className="cancel" tabIndex={0} onClick={this.closeDialog}>
|
<SessionButton
|
||||||
{i18n('cancel')}
|
buttonType={SessionButtonType.Brand}
|
||||||
</button>
|
buttonColor={SessionButtonColor.Secondary}
|
||||||
<button className="ok" tabIndex={0} onClick={this.onClickOK}>
|
onClick={this.closeDialog}
|
||||||
{i18n('ok')}
|
text={i18n('cancel')}
|
||||||
</button>
|
/>
|
||||||
|
<SessionButton
|
||||||
|
buttonType={SessionButtonType.BrandOutline}
|
||||||
|
buttonColor={SessionButtonColor.Green}
|
||||||
|
onClick={this.onClickOK}
|
||||||
|
text={i18n('ok')}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
SessionButton,
|
||||||
|
SessionButtonColor,
|
||||||
|
SessionButtonType,
|
||||||
|
} from '../session/SessionButton';
|
||||||
import { Contact, MemberList } from './MemberList';
|
import { Contact, MemberList } from './MemberList';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
@ -69,13 +74,19 @@ export class RemoveModeratorsDialog extends React.Component<Props, State> {
|
||||||
</div>
|
</div>
|
||||||
{hasMods ? null : <p>{i18n('noModeratorsToRemove')}</p>}
|
{hasMods ? null : <p>{i18n('noModeratorsToRemove')}</p>}
|
||||||
</div>
|
</div>
|
||||||
<div className="buttons">
|
<div className="session-modal__button-group">
|
||||||
<button className="cancel" tabIndex={0} onClick={this.closeDialog}>
|
<SessionButton
|
||||||
{i18n('cancel')}
|
buttonType={SessionButtonType.Brand}
|
||||||
</button>
|
buttonColor={SessionButtonColor.Primary}
|
||||||
<button className="ok" tabIndex={0} onClick={this.onClickOK}>
|
onClick={this.closeDialog}
|
||||||
{i18n('ok')}
|
text={i18n('cancel')}
|
||||||
</button>
|
/>
|
||||||
|
<SessionButton
|
||||||
|
buttonType={SessionButtonType.BrandOutline}
|
||||||
|
buttonColor={SessionButtonColor.Green}
|
||||||
|
onClick={this.onClickOK}
|
||||||
|
text={i18n('ok')}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -157,12 +157,11 @@ class UpdateGroupNameDialogInner extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private onGroupNameChanged(event: any) {
|
private onGroupNameChanged(event: any) {
|
||||||
event.persist();
|
const groupName = event.target.value;
|
||||||
|
|
||||||
this.setState(state => {
|
this.setState(state => {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
groupName: event.target.value,
|
groupName,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,6 @@ export class SessionInput extends React.PureComponent<Props, State> {
|
||||||
this.updateInputValue(e);
|
this.updateInputValue(e);
|
||||||
}}
|
}}
|
||||||
onKeyPress={event => {
|
onKeyPress={event => {
|
||||||
event.persist();
|
|
||||||
if (event.key === 'Enter' && this.props.onEnterPressed) {
|
if (event.key === 'Enter' && this.props.onEnterPressed) {
|
||||||
this.props.onEnterPressed();
|
this.props.onEnterPressed();
|
||||||
}
|
}
|
||||||
|
|
|
@ -285,14 +285,18 @@ class SessionPasswordModalInner extends React.Component<Props, State> {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
return this.setPassword(this.props.onOk);
|
return this.setPassword(this.props.onOk);
|
||||||
}
|
}
|
||||||
this.setState({ currentPasswordEntered: event.target.value });
|
const currentPasswordEntered = event.target.value;
|
||||||
|
|
||||||
|
this.setState({ currentPasswordEntered });
|
||||||
}
|
}
|
||||||
|
|
||||||
private async onPasswordConfirmInput(event: any) {
|
private async onPasswordConfirmInput(event: any) {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
return this.setPassword(this.props.onOk);
|
return this.setPassword(this.props.onOk);
|
||||||
}
|
}
|
||||||
this.setState({ currentPasswordConfirmEntered: event.target.value });
|
const currentPasswordConfirmEntered = event.target.value;
|
||||||
|
|
||||||
|
this.setState({ currentPasswordConfirmEntered });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -444,7 +444,7 @@ export class SessionConversation extends React.Component<Props, State> {
|
||||||
isPrivate: conversation.isPrivate(),
|
isPrivate: conversation.isPrivate(),
|
||||||
isPublic: conversation.isPublic(),
|
isPublic: conversation.isPublic(),
|
||||||
isRss: conversation.isRss(),
|
isRss: conversation.isRss(),
|
||||||
amMod: conversation.isModerator(
|
isAdmin: conversation.isModerator(
|
||||||
window.storage.get('primaryDevicePubKey')
|
window.storage.get('primaryDevicePubKey')
|
||||||
),
|
),
|
||||||
members,
|
members,
|
||||||
|
@ -484,7 +484,7 @@ export class SessionConversation extends React.Component<Props, State> {
|
||||||
},
|
},
|
||||||
|
|
||||||
onUpdateGroupName: () => {
|
onUpdateGroupName: () => {
|
||||||
conversation.onUpdateGroupName();
|
window.Whisper.events.trigger('updateGroupName', conversation);
|
||||||
},
|
},
|
||||||
|
|
||||||
onBlockUser: () => {
|
onBlockUser: () => {
|
||||||
|
@ -549,12 +549,14 @@ export class SessionConversation extends React.Component<Props, State> {
|
||||||
const conversation = ConversationController.getInstance().getOrThrow(
|
const conversation = ConversationController.getInstance().getOrThrow(
|
||||||
conversationKey
|
conversationKey
|
||||||
);
|
);
|
||||||
|
const ourPrimary = window.storage.get('primaryDevicePubKey');
|
||||||
|
|
||||||
const ourPK = window.textsecure.storage.user.getNumber();
|
|
||||||
const members = conversation.get('members') || [];
|
const members = conversation.get('members') || [];
|
||||||
const isAdmin = conversation.isMediumGroup()
|
const isAdmin = conversation.isMediumGroup()
|
||||||
? true
|
? true
|
||||||
: conversation.get('groupAdmins')?.includes(ourPK);
|
: conversation.isPublic()
|
||||||
|
? conversation.isModerator(ourPrimary)
|
||||||
|
: false;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: conversation.id,
|
id: conversation.id,
|
||||||
|
@ -563,7 +565,6 @@ export class SessionConversation extends React.Component<Props, State> {
|
||||||
phoneNumber: conversation.getNumber(),
|
phoneNumber: conversation.getNumber(),
|
||||||
profileName: conversation.getProfileName(),
|
profileName: conversation.getProfileName(),
|
||||||
avatarPath: conversation.getAvatarPath(),
|
avatarPath: conversation.getAvatarPath(),
|
||||||
amMod: conversation.isModerator(),
|
|
||||||
isKickedFromGroup: conversation.get('isKickedFromGroup'),
|
isKickedFromGroup: conversation.get('isKickedFromGroup'),
|
||||||
left: conversation.get('left'),
|
left: conversation.get('left'),
|
||||||
isGroup: !conversation.isPrivate(),
|
isGroup: !conversation.isPrivate(),
|
||||||
|
@ -601,7 +602,13 @@ export class SessionConversation extends React.Component<Props, State> {
|
||||||
onLeaveGroup: () => {
|
onLeaveGroup: () => {
|
||||||
window.Whisper.events.trigger('leaveGroup', conversation);
|
window.Whisper.events.trigger('leaveGroup', conversation);
|
||||||
},
|
},
|
||||||
|
onAddModerators: () => {
|
||||||
|
window.Whisper.events.trigger('addModerators', conversation);
|
||||||
|
},
|
||||||
|
|
||||||
|
onRemoveModerators: () => {
|
||||||
|
window.Whisper.events.trigger('removeModerators', conversation);
|
||||||
|
},
|
||||||
onShowLightBox: (lightBoxOptions = {}) => {
|
onShowLightBox: (lightBoxOptions = {}) => {
|
||||||
this.setState({ lightBoxOptions });
|
this.setState({ lightBoxOptions });
|
||||||
},
|
},
|
||||||
|
|
|
@ -29,7 +29,6 @@ interface Props {
|
||||||
timerOptions: Array<TimerOption>;
|
timerOptions: Array<TimerOption>;
|
||||||
isPublic: boolean;
|
isPublic: boolean;
|
||||||
isAdmin: boolean;
|
isAdmin: boolean;
|
||||||
amMod: boolean;
|
|
||||||
isKickedFromGroup: boolean;
|
isKickedFromGroup: boolean;
|
||||||
left: boolean;
|
left: boolean;
|
||||||
isBlocked: boolean;
|
isBlocked: boolean;
|
||||||
|
@ -40,6 +39,8 @@ interface Props {
|
||||||
onInviteContacts: () => void;
|
onInviteContacts: () => void;
|
||||||
onLeaveGroup: () => void;
|
onLeaveGroup: () => void;
|
||||||
onUpdateGroupName: () => void;
|
onUpdateGroupName: () => void;
|
||||||
|
onAddModerators: () => void;
|
||||||
|
onRemoveModerators: () => void;
|
||||||
onUpdateGroupMembers: () => void;
|
onUpdateGroupMembers: () => void;
|
||||||
onShowLightBox: (options: any) => void;
|
onShowLightBox: (options: any) => void;
|
||||||
onSetDisappearingMessages: (seconds: number) => void;
|
onSetDisappearingMessages: (seconds: number) => void;
|
||||||
|
@ -247,7 +248,6 @@ class SessionRightPanel extends React.Component<Props, State> {
|
||||||
left,
|
left,
|
||||||
isPublic,
|
isPublic,
|
||||||
isAdmin,
|
isAdmin,
|
||||||
amMod,
|
|
||||||
isBlocked,
|
isBlocked,
|
||||||
isGroup,
|
isGroup,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
@ -273,10 +273,9 @@ class SessionRightPanel extends React.Component<Props, State> {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const showUpdateGroupNameButton =
|
const showUpdateGroupNameButton = isAdmin && !commonNoShow;
|
||||||
isPublic && !commonNoShow
|
const showAddRemoveModeratorsButton = isAdmin && !commonNoShow && isPublic;
|
||||||
? amMod && !commonNoShow
|
|
||||||
: isAdmin && !commonNoShow;
|
|
||||||
const showUpdateGroupMembersButton = !isPublic && !commonNoShow && isAdmin;
|
const showUpdateGroupMembersButton = !isPublic && !commonNoShow && isAdmin;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -305,6 +304,25 @@ class SessionRightPanel extends React.Component<Props, State> {
|
||||||
{isPublic ? window.i18n('editGroup') : window.i18n('editGroupName')}
|
{isPublic ? window.i18n('editGroup') : window.i18n('editGroupName')}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{showAddRemoveModeratorsButton && (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
className="group-settings-item"
|
||||||
|
role="button"
|
||||||
|
onClick={this.props.onAddModerators}
|
||||||
|
>
|
||||||
|
{window.i18n('addModerators')}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="group-settings-item"
|
||||||
|
role="button"
|
||||||
|
onClick={this.props.onRemoveModerators}
|
||||||
|
>
|
||||||
|
{window.i18n('removeModerators')}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
{showUpdateGroupMembersButton && (
|
{showUpdateGroupMembersButton && (
|
||||||
<div
|
<div
|
||||||
className="group-settings-item"
|
className="group-settings-item"
|
||||||
|
|
|
@ -25,7 +25,7 @@ export type PropsConversationHeaderMenu = {
|
||||||
isKickedFromGroup?: boolean;
|
isKickedFromGroup?: boolean;
|
||||||
left?: boolean;
|
left?: boolean;
|
||||||
isGroup: boolean;
|
isGroup: boolean;
|
||||||
amMod: boolean;
|
isAdmin: boolean;
|
||||||
timerOptions: Array<TimerOption>;
|
timerOptions: Array<TimerOption>;
|
||||||
isPrivate: boolean;
|
isPrivate: boolean;
|
||||||
isBlocked: boolean;
|
isBlocked: boolean;
|
||||||
|
@ -54,7 +54,7 @@ export const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => {
|
||||||
isRss,
|
isRss,
|
||||||
isGroup,
|
isGroup,
|
||||||
isKickedFromGroup,
|
isKickedFromGroup,
|
||||||
amMod,
|
isAdmin,
|
||||||
timerOptions,
|
timerOptions,
|
||||||
isBlocked,
|
isBlocked,
|
||||||
isPrivate,
|
isPrivate,
|
||||||
|
@ -115,19 +115,19 @@ export const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => {
|
||||||
{getCopyMenuItem(isPublic, isRss, isGroup, onCopyPublicKey, window.i18n)}
|
{getCopyMenuItem(isPublic, isRss, isGroup, onCopyPublicKey, window.i18n)}
|
||||||
{getDeleteMessagesMenuItem(isPublic, onDeleteMessages, window.i18n)}
|
{getDeleteMessagesMenuItem(isPublic, onDeleteMessages, window.i18n)}
|
||||||
{getAddModeratorsMenuItem(
|
{getAddModeratorsMenuItem(
|
||||||
amMod,
|
isAdmin,
|
||||||
isKickedFromGroup,
|
isKickedFromGroup,
|
||||||
onAddModerators,
|
onAddModerators,
|
||||||
window.i18n
|
window.i18n
|
||||||
)}
|
)}
|
||||||
{getRemoveModeratorsMenuItem(
|
{getRemoveModeratorsMenuItem(
|
||||||
amMod,
|
isAdmin,
|
||||||
isKickedFromGroup,
|
isKickedFromGroup,
|
||||||
onRemoveModerators,
|
onRemoveModerators,
|
||||||
window.i18n
|
window.i18n
|
||||||
)}
|
)}
|
||||||
{getUpdateGroupNameMenuItem(
|
{getUpdateGroupNameMenuItem(
|
||||||
amMod,
|
isAdmin,
|
||||||
isKickedFromGroup,
|
isKickedFromGroup,
|
||||||
left,
|
left,
|
||||||
onUpdateGroupName,
|
onUpdateGroupName,
|
||||||
|
|
|
@ -75,25 +75,25 @@ function showDeleteContact(
|
||||||
}
|
}
|
||||||
|
|
||||||
function showAddModerators(
|
function showAddModerators(
|
||||||
amMod: boolean,
|
isAdmin: boolean,
|
||||||
isKickedFromGroup: boolean
|
isKickedFromGroup: boolean
|
||||||
): boolean {
|
): boolean {
|
||||||
return !isKickedFromGroup && amMod;
|
return !isKickedFromGroup && isAdmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
function showRemoveModerators(
|
function showRemoveModerators(
|
||||||
amMod: boolean,
|
isAdmin: boolean,
|
||||||
isKickedFromGroup: boolean
|
isKickedFromGroup: boolean
|
||||||
): boolean {
|
): boolean {
|
||||||
return !isKickedFromGroup && amMod;
|
return !isKickedFromGroup && isAdmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
function showUpdateGroupName(
|
function showUpdateGroupName(
|
||||||
amMod: boolean,
|
isAdmin: boolean,
|
||||||
isKickedFromGroup: boolean,
|
isKickedFromGroup: boolean,
|
||||||
left: boolean
|
left: boolean
|
||||||
): boolean {
|
): boolean {
|
||||||
return !isKickedFromGroup && !left && amMod;
|
return !isKickedFromGroup && !left && isAdmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
function showLeaveGroup(
|
function showLeaveGroup(
|
||||||
|
@ -174,7 +174,7 @@ export function getLeaveGroupMenuItem(
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUpdateGroupNameMenuItem(
|
export function getUpdateGroupNameMenuItem(
|
||||||
amMod: boolean | undefined,
|
isAdmin: boolean | undefined,
|
||||||
isKickedFromGroup: boolean | undefined,
|
isKickedFromGroup: boolean | undefined,
|
||||||
left: boolean | undefined,
|
left: boolean | undefined,
|
||||||
action: any,
|
action: any,
|
||||||
|
@ -182,7 +182,7 @@ export function getUpdateGroupNameMenuItem(
|
||||||
): JSX.Element | null {
|
): JSX.Element | null {
|
||||||
if (
|
if (
|
||||||
showUpdateGroupName(
|
showUpdateGroupName(
|
||||||
Boolean(amMod),
|
Boolean(isAdmin),
|
||||||
Boolean(isKickedFromGroup),
|
Boolean(isKickedFromGroup),
|
||||||
Boolean(left)
|
Boolean(left)
|
||||||
)
|
)
|
||||||
|
@ -193,24 +193,24 @@ export function getUpdateGroupNameMenuItem(
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRemoveModeratorsMenuItem(
|
export function getRemoveModeratorsMenuItem(
|
||||||
amMod: boolean | undefined,
|
isAdmin: boolean | undefined,
|
||||||
isKickedFromGroup: boolean | undefined,
|
isKickedFromGroup: boolean | undefined,
|
||||||
action: any,
|
action: any,
|
||||||
i18n: LocalizerType
|
i18n: LocalizerType
|
||||||
): JSX.Element | null {
|
): JSX.Element | null {
|
||||||
if (showRemoveModerators(Boolean(amMod), Boolean(isKickedFromGroup))) {
|
if (showRemoveModerators(Boolean(isAdmin), Boolean(isKickedFromGroup))) {
|
||||||
return <Item onClick={action}>{i18n('removeModerators')}</Item>;
|
return <Item onClick={action}>{i18n('removeModerators')}</Item>;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAddModeratorsMenuItem(
|
export function getAddModeratorsMenuItem(
|
||||||
amMod: boolean | undefined,
|
isAdmin: boolean | undefined,
|
||||||
isKickedFromGroup: boolean | undefined,
|
isKickedFromGroup: boolean | undefined,
|
||||||
action: any,
|
action: any,
|
||||||
i18n: LocalizerType
|
i18n: LocalizerType
|
||||||
): JSX.Element | null {
|
): JSX.Element | null {
|
||||||
if (showAddModerators(Boolean(amMod), Boolean(isKickedFromGroup))) {
|
if (showAddModerators(Boolean(isAdmin), Boolean(isKickedFromGroup))) {
|
||||||
return <Item onClick={action}>{i18n('addModerators')}</Item>;
|
return <Item onClick={action}>{i18n('addModerators')}</Item>;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -259,3 +259,11 @@ export function pushCannotRemoveCreatorFromGroup() {
|
||||||
window.i18n('cannotRemoveCreatorFromGroupDesc')
|
window.i18n('cannotRemoveCreatorFromGroupDesc')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function pushUserNeedsToHaveJoined() {
|
||||||
|
pushToastInfo(
|
||||||
|
'userNeedsToHaveJoined',
|
||||||
|
window.i18n('userNeedsToHaveJoined'),
|
||||||
|
window.i18n('userNeedsToHaveJoinedDesc')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue