Can leave private group chats

pull/565/head
Maxim Shishmarev 6 years ago
parent f5e9a870f7
commit 9f81f67460

@ -928,6 +928,9 @@
"ok": {
"message": "OK"
},
"yes": {
"message": "Yes"
},
"cancel": {
"message": "Cancel"
},
@ -994,6 +997,9 @@
"description":
"Placeholder text in the message entry field when it is the first message sent to that contact"
},
"sendMessageLeftGroup": {
"message": "You left this group"
},
"groupMembers": {
"message": "Group members"
},
@ -1917,6 +1923,17 @@
"Button action that the user can click to rename the group or add a new member"
},
"leaveGroup": {
"message": "Leave Group",
"description": "Button action that the user can click to leave the group"
},
"leaveGroupDialogTitle": {
"message": "Are you sure you want to leave this group?",
"description":
"Title shown to the user to confirm they want to leave the group"
},
"copiedPublicKey": {
"message": "Copied public key",
"description": "A toast message telling the user that the key was copied"

@ -763,6 +763,12 @@
}
});
Whisper.events.on('leaveGroup', async groupConvo => {
if (appView) {
appView.showLeaveGroupDialog(groupConvo);
}
});
Whisper.events.on('deleteConversation', async conversation => {
await conversation.destroyMessages();
await window.Signal.Data.removeConversation(conversation.id, {

@ -671,6 +671,11 @@
this.trigger('disable:input', true);
return;
}
if (!this.isPrivate() && this.get('left')) {
this.trigger('disable:input', true);
this.trigger('change:placeholder', 'left-group');
return;
}
switch (this.get('friendRequestStatus')) {
case FriendRequestStatusEnum.none:
case FriendRequestStatusEnum.requestExpired:
@ -1962,6 +1967,8 @@
textsecure.messaging.leaveGroup(this.id, groupNumbers, options)
)
);
this.updateTextInputState();
}
},

@ -1816,6 +1816,8 @@
groupUpdate.joined = difference;
}
if (conversation.get('left')) {
// TODO: Maybe we shouldn't assume this message adds us:
// we could maybe still get this message by mistake
window.log.warn('re-added to a left group');
attributes.left = false;
}
@ -1885,6 +1887,9 @@
attributes.active_at = now;
conversation.set(attributes);
// Re-enable typing if re-joined the group
conversation.updateTextInputState();
if (message.isExpirationTimerUpdate()) {
message.set({
expirationTimerUpdate: {

@ -50,6 +50,7 @@ const {
const {
UpdateGroupDialog,
} = require('../../ts/components/conversation/UpdateGroupDialog');
const { ConfirmDialog } = require('../../ts/components/ConfirmDialog');
const {
MediaGallery,
} = require('../../ts/components/conversation/media-gallery/MediaGallery');
@ -226,6 +227,7 @@ exports.setup = (options = {}) => {
MainHeader,
MemberList,
CreateGroupDialog,
ConfirmDialog,
UpdateGroupDialog,
MediaGallery,
Message,

@ -215,5 +215,9 @@
const dialog = new Whisper.UpdateGroupDialogView(groupConvo);
this.el.append(dialog.el);
},
showLeaveGroupDialog(groupConvo) {
const dialog = new Whisper.LeaveGroupDialogView(groupConvo);
this.el.append(dialog.el);
},
});
})();

@ -272,6 +272,10 @@
onUpdateGroup: () => {
window.Whisper.events.trigger('updateGroup', this.model);
},
onLeaveGroup: () => {
window.Whisper.events.trigger('leaveGroup', this.model);
},
};
};
this.titleView = new Whisper.ReactWrapperView({
@ -440,6 +444,9 @@
case 'disabled':
placeholder = i18n('sendMessageDisabled');
break;
case 'left-group':
placeholder = i18n('sendMessageLeftGroup');
break;
default:
placeholder = i18n('sendMessage');
break;

@ -46,8 +46,48 @@
},
});
Whisper.LeaveGroupDialogView = Whisper.View.extend({
className: 'loki-dialog modal',
initialize(groupConvo) {
this.groupConvo = groupConvo;
this.titleText = groupConvo.get('name');
this.messageText = i18n('leaveGroupDialogTitle');
this.okText = i18n('yes');
this.cancelText = i18n('cancel');
this.close = this.close.bind(this);
this.confirm = this.confirm.bind(this);
this.$el.focus();
this.render();
},
render() {
this.dialogView = new Whisper.ReactWrapperView({
className: 'leave-group-dialog',
Component: window.Signal.Components.ConfirmDialog,
props: {
titleText: this.titleText,
messageText: this.messageText,
okText: this.okText,
cancelText: this.cancelText,
onConfirm: this.confirm,
onClose: this.close,
},
});
this.$el.append(this.dialogView.el);
return this;
},
async confirm() {
await this.groupConvo.leaveGroup();
this.close();
},
close() {
this.remove();
},
});
Whisper.UpdateGroupDialogView = Whisper.View.extend({
templateName: 'group-creation-template',
className: 'loki-dialog modal',
initialize(groupConvo) {
this.groupName = groupConvo.get('name');

@ -1,3 +1,30 @@
.leave-group-dialog {
.content {
max-width: 100% !important;
}
.titleText {
font-size: large;
text-align: center;
margin: 2px;
}
.ok {
background-color: orangered;
min-width: 70px;
border: none;
&:hover {
background-color: red;
}
}
.cancel {
border: none;
min-width: 70px;
}
}
.create-group-dialog {
.content {
max-width: 100% !important;

@ -0,0 +1,33 @@
import React from 'react';
interface Props {
titleText: string;
messageText: string;
okText: string;
cancelText: string;
onConfirm: any;
onClose: any;
}
export class ConfirmDialog extends React.Component<Props> {
constructor(props: any) {
super(props);
}
public render() {
return (
<div className="content">
<p className="titleText">{this.props.titleText}</p>
<p className="messageText">{this.props.messageText}</p>
<div className="buttons">
<button className="cancel" tabIndex={0} onClick={this.props.onClose}>
{this.props.cancelText}
</button>
<button className="ok" tabIndex={0} onClick={this.props.onConfirm}>
{this.props.okText}
</button>
</div>
</div>
);
}
}

@ -63,6 +63,7 @@ interface Props {
onCopyPublicKey: () => void;
onUpdateGroup: () => void;
onLeaveGroup: () => void;
i18n: LocalizerType;
}
@ -225,6 +226,7 @@ export class ConversationHeader extends React.Component<Props> {
onDeleteContact,
onCopyPublicKey,
onUpdateGroup,
onLeaveGroup,
} = this.props;
return (
@ -233,6 +235,7 @@ export class ConversationHeader extends React.Component<Props> {
<MenuItem onClick={onCopyPublicKey}>{i18n('copyPublicKey')}</MenuItem>
<MenuItem onClick={onDeleteMessages}>{i18n('deleteMessages')}</MenuItem>
<MenuItem onClick={onUpdateGroup}>{i18n('updateGroup')}</MenuItem>
<MenuItem onClick={onLeaveGroup}>{i18n('leaveGroup')}</MenuItem>
{!isMe && isClosable ? (
!isPublic ? (
<MenuItem onClick={onDeleteContact}>

Loading…
Cancel
Save