diff --git a/background.html b/background.html index 85a217961..baf203d88 100644 --- a/background.html +++ b/background.html @@ -142,8 +142,6 @@ - - diff --git a/ts/components/conversation/UpdateGroupMembersDialog.tsx b/ts/components/conversation/UpdateGroupMembersDialog.tsx index 53c79e434..26efbe3d2 100644 --- a/ts/components/conversation/UpdateGroupMembersDialog.tsx +++ b/ts/components/conversation/UpdateGroupMembersDialog.tsx @@ -230,6 +230,57 @@ export class UpdateGroupMembersDialog extends React.Component { } } + private async onSubmit(newMembers) { + const _ = window.Lodash; + const ourPK = window.libsession.Utils.UserUtils.getOurPubKeyStrFromCache(); + + const allMembersAfterUpdate = window.Lodash.concat(newMembers, [ourPK]); + + if (!this.isAdmin) { + window.log.warn('Skipping update of members, we are not the admin'); + return; + } + // new members won't include the zombies. We are the admin and we want to remove them not matter what + + // We need to NOT trigger an group update if the list of member is the same. + // we need to merge all members, including zombies for this call. + + // we consider that the admin ALWAYS wants to remove zombies (actually they should be removed + // automatically by him when the LEFT message is received) + const allExistingMembersWithZombies = _.uniq( + this.existingMembers.concat(this.existingZombies) + ); + + const notPresentInOld = allMembersAfterUpdate.filter( + m => !allExistingMembersWithZombies.includes(m) + ); + + // be sure to include zombies in here + const membersToRemove = allExistingMembersWithZombies.filter( + m => !allMembersAfterUpdate.includes(m) + ); + + const xor = _.xor(membersToRemove, notPresentInOld); + if (xor.length === 0) { + window.log.info('skipping group update: no detected changes in group member list'); + + return; + } + + // If any extra devices of removed exist in newMembers, ensure that you filter them + // Note: I think this is useless + const filteredMembers = allMembersAfterUpdate.filter( + member => !_.includes(membersToRemove, member) + ); + + window.libsession.ClosedGroup.initiateGroupUpdate( + this.groupId, + this.groupName, + filteredMembers, + this.avatarPath + ); + } + // Return members that would comprise the group given the // current state in `users` private getWouldBeMembers(users: Array) { diff --git a/ts/components/conversation/UpdateGroupNameDialog.tsx b/ts/components/conversation/UpdateGroupNameDialog.tsx index bf568e278..85fd24b36 100644 --- a/ts/components/conversation/UpdateGroupNameDialog.tsx +++ b/ts/components/conversation/UpdateGroupNameDialog.tsx @@ -5,6 +5,7 @@ import { SessionModal } from '../session/SessionModal'; import { SessionButton, SessionButtonColor } from '../session/SessionButton'; import { Avatar, AvatarSize } from '../Avatar'; import { DefaultTheme, withTheme } from 'styled-components'; +import { SessionWrapperModal } from '../session/SessionWrapperModal'; interface Props { titleText: string; @@ -78,7 +79,7 @@ class UpdateGroupNameDialogInner extends React.Component { ); return ( - this.closeDialog()} @@ -112,7 +113,7 @@ class UpdateGroupNameDialogInner extends React.Component { buttonColor={SessionButtonColor.Green} /> - + ); } diff --git a/ts/components/session/conversation/SessionConversation.tsx b/ts/components/session/conversation/SessionConversation.tsx index 3ec085910..6ff7ee73a 100644 --- a/ts/components/session/conversation/SessionConversation.tsx +++ b/ts/components/session/conversation/SessionConversation.tsx @@ -1,14 +1,12 @@ // tslint:disable: no-backbone-get-set-outside-model import React from 'react'; -import { useDispatch } from "react-redux"; -import { updateConfirmModal } from '../../../state/ducks/modalDialog'; import classNames from 'classnames'; import { SessionCompositionBox, StagedAttachmentType } from './SessionCompositionBox'; -import { Constants } from '../../../session'; +import { ClosedGroup, Constants } from '../../../session'; import _ from 'lodash'; import { AttachmentUtil, GoogleChrome } from '../../../util'; import { ConversationHeaderWithDetails } from '../../conversation/ConversationHeader'; @@ -36,6 +34,7 @@ import { ConversationTypeEnum } from '../../../models/conversation'; import { SessionButtonColor } from '../SessionButton'; import { AddModeratorsDialog } from '../../conversation/ModeratorsAddDialog'; import { RemoveModeratorsDialog } from '../../conversation/ModeratorsRemoveDialog'; +import { UpdateGroupNameDialog } from '../../conversation/UpdateGroupNameDialog'; @@ -495,7 +494,59 @@ export class SessionConversation extends React.Component { }, onUpdateGroupName: () => { - window.Whisper.events.trigger('updateGroupName', conversation); + // warrick: remove trigger once everything is cleaned up + // window.Whisper.events.trigger('updateGroupName', conversation); + const avatarPath = conversation.getAvatarPath(); + const groupName = conversation.getName(); + const groupId = conversation.id; + const members = conversation.get('members') || []; + const isPublic = conversation.isPublic(); + + let isAdmin = true; + let titleText; + + if (isPublic) { + // fix the title + titleText = window.i18n('updateGroupDialogTitle', groupName); + // I'd much prefer to integrate mods with groupAdmins + // but lets discuss first... + isAdmin = conversation.isAdmin(window.storage.get('primaryDevicePubKey')); + } + + const onClose = () => { + this.setState({ ...this.state, modal: null }) + } + + const onUpdateGroupNameSubmit = (groupName: string, avatar: string) => { + ClosedGroup.initiateGroupUpdate( + groupId, + groupName, + members, + avatar + ) + } + + this.setState({ + ...this.state, + modal: ( + + ) + }) + }, onUpdateGroupMembers: async () => { if (conversation.isMediumGroup()) {