From 6856c0e7489f3eabe07a1da44bcf8b26e6409f6e Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Wed, 13 Jan 2021 15:28:20 +1100 Subject: [PATCH] remove updateTextInputState not needed and add left to menu tests --- _locales/de/messages.json | 3 - _locales/en/messages.json | 4 - _locales/es/messages.json | 3 - _locales/fr/messages.json | 6 +- _locales/id/messages.json | 3 - _locales/it/messages.json | 3 - _locales/ja/messages.json | 3 - _locales/pl/messages.json | 3 - _locales/pt_BR/messages.json | 3 - _locales/ru/messages.json | 3 - _locales/vi/messages.json | 3 - js/models/conversations.d.ts | 1 - js/models/conversations.js | 104 ++++-------------- js/modules/attachment_downloads.js | 4 +- js/views/app_view.js | 3 +- js/views/conversation_view.js | 7 -- ts/components/ConversationListItem.tsx | 1 + .../conversation/ConversationHeader.tsx | 1 + .../conversation/SessionCompositionBox.tsx | 14 +-- .../conversation/SessionConversation.tsx | 7 +- .../conversation/SessionRightPanel.tsx | 24 ++-- .../session/menu/ConversationHeaderMenu.tsx | 5 + .../menu/ConversationListItemContextMenu.tsx | 3 + ts/components/session/menu/Menu.tsx | 24 +++- ts/receiver/closedGroupsV2.ts | 8 +- ts/receiver/multidevice.ts | 3 +- ts/receiver/queuedJob.ts | 3 - .../conversations/ConversationController.ts | 2 +- ts/session/groupv2/index.ts | 3 +- ts/state/ducks/conversations.ts | 2 +- ts/test/state/selectors/conversations_test.ts | 10 +- 31 files changed, 92 insertions(+), 174 deletions(-) diff --git a/_locales/de/messages.json b/_locales/de/messages.json index 1a43346b3..dc28e1e26 100644 --- a/_locales/de/messages.json +++ b/_locales/de/messages.json @@ -1333,9 +1333,6 @@ "deviceUnpaired": { "message": "Ihr Gerät wurde erfolgreich getrennt." }, - "sendMessageLeftGroup": { - "message": "Du hast die Gruppe verlassen" - }, "moreInformation": { "message": "Mehr Informationen" }, diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 02d669bc0..47de3b572 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -959,10 +959,6 @@ "message": "Message", "description": "Placeholder text in the message entry field" }, - "sendMessageLeftGroup": { - "message": "You have left the group.", - "androidKey": "MessageRecord_left_group" - }, "sendMessageBlockedUser": { "message": "You have blocked this contact" }, diff --git a/_locales/es/messages.json b/_locales/es/messages.json index 65a7f9e15..342dbd904 100644 --- a/_locales/es/messages.json +++ b/_locales/es/messages.json @@ -1207,9 +1207,6 @@ "deviceUnpaired": { "message": "Tu dispositivo se ha desvinculado correctamente" }, - "sendMessageLeftGroup": { - "message": "Has abandonado el grupo." - }, "moreInformation": { "message": "Más detalles" }, diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json index 6afa73eb3..88a5f74d6 100644 --- a/_locales/fr/messages.json +++ b/_locales/fr/messages.json @@ -1207,9 +1207,6 @@ "deviceUnpaired": { "message": "Votre appareil a été déconnecté avec succès" }, - "sendMessageLeftGroup": { - "message": "Vous avez quitté le groupe" - }, "moreInformation": { "message": "Plus d’informations" }, @@ -1768,7 +1765,6 @@ "enterOptionalPassword": { "message": "Entrer un mot de passe (optionel)" }, - "devicePairingHeaderReassure": { "message": "Linking may take up to one minute to register on your primary device. Please be patient." }, @@ -1820,4 +1816,4 @@ "description": { "message": "Description" } -} +} \ No newline at end of file diff --git a/_locales/id/messages.json b/_locales/id/messages.json index cc6f448be..e51394097 100644 --- a/_locales/id/messages.json +++ b/_locales/id/messages.json @@ -1204,9 +1204,6 @@ "deviceUnpaired": { "message": "Sukses memutus perangkat" }, - "sendMessageLeftGroup": { - "message": "Anda telah keluar dari grup." - }, "moreInformation": { "message": "Informasi lebih lanjut" }, diff --git a/_locales/it/messages.json b/_locales/it/messages.json index 1f19d5d2c..38ee2b883 100644 --- a/_locales/it/messages.json +++ b/_locales/it/messages.json @@ -1207,9 +1207,6 @@ "deviceUnpaired": { "message": "Il dispositivo è stato scollegato correttamente" }, - "sendMessageLeftGroup": { - "message": "Hai lasciato il gruppo." - }, "moreInformation": { "message": "Maggiori informazioni" }, diff --git a/_locales/ja/messages.json b/_locales/ja/messages.json index e5b9a9225..74c19d1e5 100644 --- a/_locales/ja/messages.json +++ b/_locales/ja/messages.json @@ -1207,9 +1207,6 @@ "deviceUnpaired": { "message": "デバイスは正常にリンク解除されました" }, - "sendMessageLeftGroup": { - "message": "グループを抜けました" - }, "moreInformation": { "message": "詳細" }, diff --git a/_locales/pl/messages.json b/_locales/pl/messages.json index f48ccaa4b..e2ca51fa5 100644 --- a/_locales/pl/messages.json +++ b/_locales/pl/messages.json @@ -1207,9 +1207,6 @@ "deviceUnpaired": { "message": "Twoje urządzenie zostało rozłączone pomyślnie" }, - "sendMessageLeftGroup": { - "message": "Opuściłeś(aś) grupę." - }, "moreInformation": { "message": "Więcej informacji" }, diff --git a/_locales/pt_BR/messages.json b/_locales/pt_BR/messages.json index 3b2d32270..e00f0e6fb 100644 --- a/_locales/pt_BR/messages.json +++ b/_locales/pt_BR/messages.json @@ -1207,9 +1207,6 @@ "deviceUnpaired": { "message": "O seu dispositivo foi dessincronizado com sucesso" }, - "sendMessageLeftGroup": { - "message": "Você saiu do grupo." - }, "moreInformation": { "message": "Mais informações" }, diff --git a/_locales/ru/messages.json b/_locales/ru/messages.json index a319d95e0..e22014637 100644 --- a/_locales/ru/messages.json +++ b/_locales/ru/messages.json @@ -1207,9 +1207,6 @@ "deviceUnpaired": { "message": "Ваше устройство успешно отвязано" }, - "sendMessageLeftGroup": { - "message": "Вы покинули группу." - }, "moreInformation": { "message": "Больше информации" }, diff --git a/_locales/vi/messages.json b/_locales/vi/messages.json index dcd2c9cc2..ed5f078e7 100644 --- a/_locales/vi/messages.json +++ b/_locales/vi/messages.json @@ -1192,9 +1192,6 @@ "deviceUnpaired": { "message": "Thiết bị của bạn đã được hủy liên kết thành công" }, - "sendMessageLeftGroup": { - "message": "Bạn đã rời nhóm." - }, "resend": { "message": "Gửi lại" }, diff --git a/js/models/conversations.d.ts b/js/models/conversations.d.ts index 17580c52c..fa1ecaf8a 100644 --- a/js/models/conversations.d.ts +++ b/js/models/conversations.d.ts @@ -51,7 +51,6 @@ export interface ConversationModel getRecipients: () => Array; getTitle: () => string; onReadMessage: (message: MessageModel) => void; - updateTextInputState: () => void; getName: () => string; addMessage: (attributes: Partial) => Promise; isMediumGroup: () => boolean; diff --git a/js/models/conversations.js b/js/models/conversations.js index c5e142853..d60dc75c2 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -57,6 +57,7 @@ groupAdmins: [], isKickedFromGroup: false, profileSharing: false, + left: false, }; }, @@ -214,9 +215,7 @@ ? BlockedNumberController.block(this.id) : BlockedNumberController.blockGroup(this.id); await promise; - this.trigger('change', this); - this.messageCollection.forEach(m => m.trigger('change')); - this.updateTextInputState(); + this.commit(); await textsecure.messaging.sendBlockedListSyncMessage(); }, async unblock() { @@ -227,14 +226,11 @@ ? BlockedNumberController.unblock(this.id) : BlockedNumberController.unblockGroup(this.id); await promise; - this.trigger('change', this); - this.messageCollection.forEach(m => m.trigger('change')); - this.updateTextInputState(); + this.commit(); await textsecure.messaging.sendBlockedListSyncMessage(); }, async bumpTyping() { - if (this.isPublic()) { - window.log.debug('public conversation... No need to bumpTyping'); + if (this.isPublic() || this.isMediumGroup()) { return; } // We don't send typing messages if the setting is disabled or we do not have a session @@ -308,49 +304,37 @@ }, sendTypingMessage(isTyping) { - // Loki - Temporarily disable typing messages for groups if (!this.isPrivate()) { return; } - const groupId = !this.isPrivate() ? this.id : null; - const recipientId = this.isPrivate() ? this.id : null; + const recipientId = this.id; + + if (!recipientId) { + throw new Error('Need to provide either recipientId'); + } - // We don't want to send typing messages to our other devices, but we will - // in the group case. const primaryDevicePubkey = window.storage.get('primaryDevicePubKey'); if (recipientId && primaryDevicePubkey === recipientId) { + // note to self return; } - if (!recipientId && !groupId) { - throw new Error('Need to provide either recipientId or groupId!'); - } - const typingParams = { timestamp: Date.now(), isTyping, typingTimestamp: Date.now(), - groupId, // might be null }; const typingMessage = new libsession.Messages.Outgoing.TypingMessage( typingParams ); // send the message to a single recipient if this is a session chat - if (this.isPrivate()) { - const device = new libsession.Types.PubKey(recipientId); - libsession - .getMessageQueue() - .sendUsingMultiDevice(device, typingMessage) - .catch(log.error); - } else { - // the recipients on the case of a group are found by the messageQueue using message.groupId - libsession - .getMessageQueue() - .sendToGroup(typingMessage) - .catch(log.error); - } + const device = new libsession.Types.PubKey(recipientId); + libsession + .getMessageQueue() + .sendUsingMultiDevice(device, typingMessage) + .catch(log.error); }, async cleanup() { @@ -460,7 +444,7 @@ messageModel: model, }); - this.trigger('change', this); + this.commit(); }, addSingleMessage(message, setToExpire = true) { const model = this.messageCollection.add(message, { merge: true }); @@ -508,7 +492,7 @@ }, hasNickname: !!this.getNickname(), isKickedFromGroup: !!this.get('isKickedFromGroup'), - leftGroup: !!this.get('left'), + left: !!this.get('left'), onClick: () => this.trigger('select', this), onBlockContact: () => this.block(), @@ -560,8 +544,6 @@ } }) ); - - this.onMemberVerifiedChange(); }, setVerifiedDefault(options) { const { DEFAULT } = this.verifiedEnum; @@ -672,36 +654,6 @@ // Something funky has happened return this; }, - async updateTextInputState() { - if (this.isRss()) { - // or if we're an rss conversation, disable it - this.trigger('disable:input', true); - return; - } - if (this.isSecondaryDevice()) { - // Or if we're a secondary device, update the primary device text input - const primaryConversation = await this.getPrimaryConversation(); - primaryConversation.updateTextInputState(); - return; - } - if (this.get('isKickedFromGroup')) { - this.trigger('disable:input', true); - return; - } - if (!this.isPrivate() && this.get('left')) { - this.trigger('disable:input', true); - this.trigger('change:placeholder', 'left-group'); - return; - } - if (this.isBlocked()) { - this.trigger('disable:input', true); - this.trigger('change:placeholder', 'blocked-user'); - return; - } - // otherwise, enable the input and set default placeholder - this.trigger('disable:input', false); - this.trigger('change:placeholder', 'chat'); - }, isSecondaryDevice() { return !!this.get('secondaryStatus'); }, @@ -819,12 +771,6 @@ ); }); }, - onMemberVerifiedChange() { - // If the verified state of a member changes, our aggregate state changes. - // We trigger both events to replicate the behavior of Backbone.Model.set() - this.trigger('change:verified', this); - this.trigger('change', this); - }, toggleVerified() { if (this.isVerified()) { return this.setVerifiedDefault(); @@ -1650,8 +1596,6 @@ 'Legacy group are not supported anymore. You need to create this group again.' ); } - - this.updateTextInputState(); }, async markRead(newestUnreadDate, providedOptions) { @@ -2039,14 +1983,6 @@ ); return Promise.all(promises).then(contacts => { - _.forEach(contacts, contact => { - this.listenTo( - contact, - 'change:verified', - this.onMemberVerifiedChange - ); - }); - this.contactCollection.reset(contacts); }); }, @@ -2401,14 +2337,14 @@ if (!record) { // User was not previously typing before. State change! this.trigger('typing-update'); - this.trigger('change', this); + this.commit(); } } else { delete this.contactTypingTimers[identifier]; if (record) { // User was previously typing, and is no longer. State change! this.trigger('typing-update'); - this.trigger('change', this); + this.commit(); } } }, @@ -2423,7 +2359,7 @@ // User was previously typing, but timed out or we received message. State change! this.trigger('typing-update'); - this.trigger('change', this); + this.commit(); } }, }); diff --git a/js/modules/attachment_downloads.js b/js/modules/attachment_downloads.js index dd49daa4f..b208b5b70 100644 --- a/js/modules/attachment_downloads.js +++ b/js/modules/attachment_downloads.js @@ -235,9 +235,9 @@ async function _finishJob(message, id) { if (fromConversation && message !== fromConversation) { fromConversation.set(message.attributes); - fromConversation.trigger('change', fromConversation); + fromConversation.commit(); } else { - message.trigger('change', message); + message.commit(); } } } diff --git a/js/views/app_view.js b/js/views/app_view.js index 11c143b02..82fb65d1c 100644 --- a/js/views/app_view.js +++ b/js/views/app_view.js @@ -207,8 +207,7 @@ window.confirmationDialog({ title, message, - resolve: () => - window.getConversationController().deleteContact(groupConvo.id), + resolve: () => groupConvo.leaveGroup(), theme: this.getThemeObject(), }); } else { diff --git a/js/views/conversation_view.js b/js/views/conversation_view.js index 141ceabc0..73edb344f 100644 --- a/js/views/conversation_view.js +++ b/js/views/conversation_view.js @@ -37,12 +37,9 @@ }, initialize(options) { this.listenTo(this.model, 'destroy', this.stopListening); - this.listenTo(this.model, 'change:verified', this.onVerifiedChange); this.listenTo(this.model, 'newmessage', this.addMessage); this.listenTo(this.model, 'opened', this.onOpened); this.listenTo(this.model, 'prune', this.onPrune); - this.listenTo(this.model, 'disable:input', this.onDisableInput); - this.listenTo(this.model, 'change:placeholder', this.onChangePlaceholder); this.listenTo(this.model, 'unload', () => this.unload('model trigger')); this.listenTo(this.model, 'typing-update', this.renderTypingBubble); this.listenTo( @@ -98,8 +95,6 @@ this.render(); - this.model.updateTextInputState(); - this.window = options.window; Whisper.events.on('mediaPermissionsChanged', () => @@ -127,8 +122,6 @@ this.$('.send-message').focus(this.focusBottomBar.bind(this)); this.$('.send-message').blur(this.unfocusBottomBar.bind(this)); - this.model.updateTextInputState(); - this.selectMember = this.selectMember.bind(this); const updateMemberList = async () => { diff --git a/ts/components/ConversationListItem.tsx b/ts/components/ConversationListItem.tsx index 90db8de51..90f75835c 100644 --- a/ts/components/ConversationListItem.tsx +++ b/ts/components/ConversationListItem.tsx @@ -54,6 +54,7 @@ export type ConversationListItemProps = { isSecondary?: boolean; isGroupInvitation?: boolean; isKickedFromGroup?: boolean; + left?: boolean; memberAvatars?: Array; // this is added by usingClosedConversationDetails }; diff --git a/ts/components/conversation/ConversationHeader.tsx b/ts/components/conversation/ConversationHeader.tsx index fba634316..b8f5c7c1e 100644 --- a/ts/components/conversation/ConversationHeader.tsx +++ b/ts/components/conversation/ConversationHeader.tsx @@ -62,6 +62,7 @@ interface Props { isBlocked: boolean; isKickedFromGroup: boolean; + left: boolean; selectionMode: boolean; // is the UI on the message selection mode or not onInviteContacts: () => void; diff --git a/ts/components/session/conversation/SessionCompositionBox.tsx b/ts/components/session/conversation/SessionCompositionBox.tsx index 67b67cb01..6fb9a096c 100644 --- a/ts/components/session/conversation/SessionCompositionBox.tsx +++ b/ts/components/session/conversation/SessionCompositionBox.tsx @@ -63,7 +63,7 @@ interface Props { isBlocked: boolean; isPrivate: boolean; isKickedFromGroup: boolean; - leftGroup: boolean; + left: boolean; conversationKey: string; isPublic: boolean; @@ -259,9 +259,9 @@ export class SessionCompositionBox extends React.Component { } private isTypingEnabled(): boolean { - const { isBlocked, isKickedFromGroup, leftGroup, isPrivate } = this.props; + const { isBlocked, isKickedFromGroup, left, isPrivate } = this.props; - return !(isBlocked || isKickedFromGroup || leftGroup); + return !(isBlocked || isKickedFromGroup || left); } private renderCompositionView() { @@ -347,10 +347,10 @@ export class SessionCompositionBox extends React.Component { private renderTextArea() { const { i18n } = window; const { message } = this.state; - const { isKickedFromGroup, leftGroup, isPrivate, isBlocked } = this.props; + const { isKickedFromGroup, left, isPrivate, isBlocked } = this.props; const messagePlaceHolder = isKickedFromGroup ? i18n('youGotKickedFromGroup') - : leftGroup + : left ? i18n('youLeftTheGroup') : isBlocked && isPrivate ? i18n('unblockToSend') @@ -784,7 +784,7 @@ export class SessionCompositionBox extends React.Component { this.parseEmojis(this.state.message) ); - const { isBlocked, isPrivate, leftGroup, isKickedFromGroup } = this.props; + const { isBlocked, isPrivate, left, isKickedFromGroup } = this.props; // deny sending of message if our app version is expired if (window.extension.expiredStatus() === true) { @@ -827,7 +827,7 @@ export class SessionCompositionBox extends React.Component { } } - if (!isPrivate && leftGroup) { + if (!isPrivate && left) { ToastUtils.pushYouLeftTheGroup(); return; } diff --git a/ts/components/session/conversation/SessionConversation.tsx b/ts/components/session/conversation/SessionConversation.tsx index a056ad889..2607ae168 100644 --- a/ts/components/session/conversation/SessionConversation.tsx +++ b/ts/components/session/conversation/SessionConversation.tsx @@ -346,7 +346,7 @@ export class SessionConversation extends React.Component { // tslint:disable-next-line: use-simple-attributes { members, subscriberCount: conversation.get('subscriberCount'), isKickedFromGroup: conversation.get('isKickedFromGroup'), + left: conversation.get('left'), expirationSettingName, showBackButton: Boolean(infoViewState || messageDetailShowProps), timerOptions: window.Whisper.ExpirationTimerOptions.map((item: any) => ({ @@ -561,10 +562,10 @@ export class SessionConversation extends React.Component { memberCount: members.length, phoneNumber: conversation.getNumber(), profileName: conversation.getProfileName(), - description: '', // TODO VINCE: ENSURE DESCRIPTION IS SET avatarPath: conversation.getAvatarPath(), amMod: conversation.isModerator(), - isKickedFromGroup: conversation.attributes.isKickedFromGroup, + isKickedFromGroup: conversation.get('isKickedFromGroup'), + left: conversation.get('left'), isGroup: !conversation.isPrivate(), isPublic: conversation.isPublic(), isAdmin, diff --git a/ts/components/session/conversation/SessionRightPanel.tsx b/ts/components/session/conversation/SessionRightPanel.tsx index 5c5659f92..ce70bd3de 100644 --- a/ts/components/session/conversation/SessionRightPanel.tsx +++ b/ts/components/session/conversation/SessionRightPanel.tsx @@ -31,6 +31,7 @@ interface Props { isAdmin: boolean; amMod: boolean; isKickedFromGroup: boolean; + left: boolean; isBlocked: boolean; isGroup: boolean; memberAvatars?: Array; // this is added by usingClosedConversationDetails @@ -235,6 +236,7 @@ class SessionRightPanel extends React.Component { this.props.onShowLightBox(options); } + // tslint:disable-next-line: cyclomatic-complexity public render() { const { memberCount, @@ -242,6 +244,7 @@ class SessionRightPanel extends React.Component { timerOptions, onLeaveGroup, isKickedFromGroup, + left, isPublic, isAdmin, amMod, @@ -250,12 +253,15 @@ class SessionRightPanel extends React.Component { } = this.props; const { documents, media, onItemClick } = this.state; const showMemberCount = !!(memberCount && memberCount > 0); - const hasDisappearingMessages = - !isPublic && !isKickedFromGroup && !isBlocked; + const commonNoShow = isKickedFromGroup || left || isBlocked; + + const hasDisappearingMessages = !isPublic && !commonNoShow; const leaveGroupString = isPublic ? window.i18n('leaveGroup') : isKickedFromGroup ? window.i18n('youGotKickedFromGroup') + : left + ? window.i18n('youLeftTheGroup') : window.i18n('leaveGroup'); const disappearingMessagesOptions = timerOptions.map(option => { @@ -268,11 +274,10 @@ class SessionRightPanel extends React.Component { }); const showUpdateGroupNameButton = - isPublic && !isKickedFromGroup - ? amMod && !isBlocked - : isAdmin && !isBlocked && !isKickedFromGroup; - const showUpdateGroupMembersButton = - !isPublic && !isKickedFromGroup && !isBlocked && isAdmin; + isPublic && !commonNoShow + ? amMod && !commonNoShow + : isAdmin && !commonNoShow; + const showUpdateGroupMembersButton = !isPublic && !commonNoShow && isAdmin; return (
@@ -326,7 +331,7 @@ class SessionRightPanel extends React.Component { @@ -349,10 +354,11 @@ class SessionRightPanel extends React.Component { name, profileName, phoneNumber, + left, } = this.props; const showInviteContacts = - (isPublic || isAdmin) && !isKickedFromGroup && !isBlocked; + (isPublic || isAdmin) && !isKickedFromGroup && !isBlocked && !left; const userName = name || profileName || phoneNumber; return ( diff --git a/ts/components/session/menu/ConversationHeaderMenu.tsx b/ts/components/session/menu/ConversationHeaderMenu.tsx index 2d776e219..e877daa7c 100644 --- a/ts/components/session/menu/ConversationHeaderMenu.tsx +++ b/ts/components/session/menu/ConversationHeaderMenu.tsx @@ -23,6 +23,7 @@ export type PropsConversationHeaderMenu = { isRss?: boolean; isClosable?: boolean; isKickedFromGroup?: boolean; + left?: boolean; isGroup: boolean; amMod: boolean; timerOptions: Array; @@ -57,6 +58,7 @@ export const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => { timerOptions, isBlocked, isPrivate, + left, onDeleteMessages, onDeleteContact, @@ -79,6 +81,7 @@ export const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => { isPublic, isRss, isKickedFromGroup, + left, isBlocked, timerOptions, onSetDisappearingMessages, @@ -126,11 +129,13 @@ export const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => { {getUpdateGroupNameMenuItem( amMod, isKickedFromGroup, + left, onUpdateGroupName, window.i18n )} {getLeaveGroupMenuItem( isKickedFromGroup, + left, isGroup, isPublic, isRss, diff --git a/ts/components/session/menu/ConversationListItemContextMenu.tsx b/ts/components/session/menu/ConversationListItemContextMenu.tsx index bcf2c620a..a8e414758 100644 --- a/ts/components/session/menu/ConversationListItemContextMenu.tsx +++ b/ts/components/session/menu/ConversationListItemContextMenu.tsx @@ -21,6 +21,7 @@ export type PropsContextConversationItem = { isBlocked?: boolean; hasNickname?: boolean; isKickedFromGroup?: boolean; + left?: boolean; onDeleteMessages?: () => void; onDeleteContact?: () => void; @@ -44,6 +45,7 @@ export const ConversationListItemContextMenu = ( isPublic, hasNickname, type, + left, isKickedFromGroup, onDeleteContact, onDeleteMessages, @@ -103,6 +105,7 @@ export const ConversationListItemContextMenu = ( )} {getLeaveGroupMenuItem( isKickedFromGroup, + left, type === 'group', isPublic, isRss, diff --git a/ts/components/session/menu/Menu.tsx b/ts/components/session/menu/Menu.tsx index e830bc7f5..052ef399a 100644 --- a/ts/components/session/menu/Menu.tsx +++ b/ts/components/session/menu/Menu.tsx @@ -7,9 +7,10 @@ function showTimerOptions( isPublic: boolean, isRss: boolean, isKickedFromGroup: boolean, + left: boolean, isBlocked: boolean ): boolean { - return !isPublic && !isRss && !isKickedFromGroup && !isBlocked; + return !isPublic && !isRss && !left && !isKickedFromGroup && !isBlocked; } function showMemberMenu( @@ -89,18 +90,20 @@ function showRemoveModerators( function showUpdateGroupName( amMod: boolean, - isKickedFromGroup: boolean + isKickedFromGroup: boolean, + left: boolean ): boolean { - return !isKickedFromGroup && amMod; + return !isKickedFromGroup && !left && amMod; } function showLeaveGroup( isKickedFromGroup: boolean, + left: boolean, isGroup: boolean, isPublic: boolean, isRss: boolean ): boolean { - return !isKickedFromGroup && isGroup && !isPublic && !isRss; + return !isKickedFromGroup && !left && isGroup && !isPublic && !isRss; } function showInviteContact(isGroup: boolean, isPublic: boolean): boolean { @@ -149,6 +152,7 @@ export function getDeleteContactMenuItem( export function getLeaveGroupMenuItem( isKickedFromGroup: boolean | undefined, + left: boolean | undefined, isGroup: boolean | undefined, isPublic: boolean | undefined, isRss: boolean | undefined, @@ -158,6 +162,7 @@ export function getLeaveGroupMenuItem( if ( showLeaveGroup( Boolean(isKickedFromGroup), + Boolean(left), Boolean(isGroup), Boolean(isPublic), Boolean(isRss) @@ -171,10 +176,17 @@ export function getLeaveGroupMenuItem( export function getUpdateGroupNameMenuItem( amMod: boolean | undefined, isKickedFromGroup: boolean | undefined, + left: boolean | undefined, action: any, i18n: LocalizerType ): JSX.Element | null { - if (showUpdateGroupName(Boolean(amMod), Boolean(isKickedFromGroup))) { + if ( + showUpdateGroupName( + Boolean(amMod), + Boolean(isKickedFromGroup), + Boolean(left) + ) + ) { return {i18n('editGroup')}; } return null; @@ -222,6 +234,7 @@ export function getDisappearingMenuItem( isPublic: boolean | undefined, isRss: boolean | undefined, isKickedFromGroup: boolean | undefined, + left: boolean | undefined, isBlocked: boolean | undefined, timerOptions: Array, action: any, @@ -232,6 +245,7 @@ export function getDisappearingMenuItem( Boolean(isPublic), Boolean(isRss), Boolean(isKickedFromGroup), + Boolean(left), Boolean(isBlocked) ) ) { diff --git a/ts/receiver/closedGroupsV2.ts b/ts/receiver/closedGroupsV2.ts index 173386a08..4aef11dd6 100644 --- a/ts/receiver/closedGroupsV2.ts +++ b/ts/receiver/closedGroupsV2.ts @@ -188,14 +188,16 @@ async function handleNewClosedGroupV2( const groupExists = !!maybeConvo; if (groupExists) { - if (maybeConvo && maybeConvo.get('isKickedFromGroup')) { + if ( + maybeConvo && + (maybeConvo.get('isKickedFromGroup') || maybeConvo.get('left')) + ) { // TODO: indicate that we've been re-invited // to the group if that is the case // Enable typing: maybeConvo.set('isKickedFromGroup', false); maybeConvo.set('left', false); - maybeConvo.updateTextInputState(); } else { log.warn( 'Ignoring a closed group v2 message of type NEW: the conversation already exists' @@ -305,7 +307,6 @@ async function handleUpdateClosedGroupV2( ); convo.set('isKickedFromGroup', true); // Disable typing: - convo.updateTextInputState(); window.SwarmPolling.removePubkey(groupPublicKey); } else { if (convo.get('isKickedFromGroup')) { @@ -314,7 +315,6 @@ async function handleUpdateClosedGroupV2( convo.set('left', false); // Subscribe to this group id window.SwarmPolling.addGroupId(new PubKey(groupPublicKey)); - convo.updateTextInputState(); } } diff --git a/ts/receiver/multidevice.ts b/ts/receiver/multidevice.ts index 6de639b03..2bac7cb41 100644 --- a/ts/receiver/multidevice.ts +++ b/ts/receiver/multidevice.ts @@ -179,7 +179,7 @@ async function handleAuthorisationForSelf( primaryDevicePubKey, 'private' ); - primaryConversation.trigger('change'); + await primaryConversation.commit(); Whisper.events.trigger('secondaryDeviceRegistration'); // Update profile if (dataMessage) { @@ -430,7 +430,6 @@ async function onContactReceived(details: any) { if (conversation.isPrivate()) { await BlockedNumberController.setBlocked(conversation.id, isBlocked); } - conversation.updateTextInputState(); await conversation.commit(); } catch (error) { diff --git a/ts/receiver/queuedJob.ts b/ts/receiver/queuedJob.ts index ece34a9bb..73f883315 100644 --- a/ts/receiver/queuedJob.ts +++ b/ts/receiver/queuedJob.ts @@ -420,9 +420,6 @@ async function handleRegularMessage( conversation.set({ active_at: now }); - // Re-enable typing if re-joined the group - conversation.updateTextInputState(); - // Handle expireTimer found directly as part of a regular message await handleExpireTimer( source, diff --git a/ts/session/conversations/ConversationController.ts b/ts/session/conversations/ConversationController.ts index 21f5543ec..cd542373b 100644 --- a/ts/session/conversations/ConversationController.ts +++ b/ts/session/conversations/ConversationController.ts @@ -33,7 +33,7 @@ export class ConversationController { return this.conversations.get(id); } - public getOrThrow(id: string) { + public getOrThrow(id: string): ConversationModel { if (!this._initialFetchComplete) { throw new Error( 'ConversationController.get() needs complete initial fetch' diff --git a/ts/session/groupv2/index.ts b/ts/session/groupv2/index.ts index 632ef12aa..7e73723ce 100644 --- a/ts/session/groupv2/index.ts +++ b/ts/session/groupv2/index.ts @@ -262,7 +262,6 @@ export async function updateOrCreateClosedGroupV2(details: GroupInfo) { } await conversation.commit(); - conversation.updateTextInputState(); const { expireTimer } = details; @@ -294,7 +293,7 @@ export async function leaveClosedGroupV2(groupId: string) { // FIXME audric, add a flag to conversation model when a group is destroyed if (isCurrentUserAdmin) { window.log.info('Admin left a closed group v2. We need to destroy it'); - convo.set({ left: true, isKickedFromGroup: true }); + convo.set({ left: true }); members = []; } else { convo.set({ left: true }); diff --git a/ts/state/ducks/conversations.ts b/ts/state/ducks/conversations.ts index d49e28c2e..c39307797 100644 --- a/ts/state/ducks/conversations.ts +++ b/ts/state/ducks/conversations.ts @@ -77,7 +77,7 @@ export type ConversationType = { primaryDevice: string; isBlocked: boolean; isKickedFromGroup: boolean; - leftGroup: boolean; + left: boolean; avatarPath?: string; // absolute filepath to the avatar }; export type ConversationLookupType = { diff --git a/ts/test/state/selectors/conversations_test.ts b/ts/test/state/selectors/conversations_test.ts index 1c35296eb..e8aff0475 100644 --- a/ts/test/state/selectors/conversations_test.ts +++ b/ts/test/state/selectors/conversations_test.ts @@ -31,7 +31,7 @@ describe('state/selectors/conversations', () => { isTyping: false, isBlocked: false, isKickedFromGroup: false, - leftGroup: false, + left: false, }, id2: { id: 'id2', @@ -52,7 +52,7 @@ describe('state/selectors/conversations', () => { isTyping: false, isBlocked: false, isKickedFromGroup: false, - leftGroup: false, + left: false, }, id3: { id: 'id3', @@ -73,7 +73,7 @@ describe('state/selectors/conversations', () => { isTyping: false, isBlocked: false, isKickedFromGroup: false, - leftGroup: false, + left: false, }, id4: { id: 'id4', @@ -93,7 +93,7 @@ describe('state/selectors/conversations', () => { isTyping: false, isBlocked: false, isKickedFromGroup: false, - leftGroup: false, + left: false, }, id5: { id: 'id5', @@ -114,7 +114,7 @@ describe('state/selectors/conversations', () => { isTyping: false, isBlocked: false, isKickedFromGroup: false, - leftGroup: false, + left: false, }, }; const comparator = _getConversationComparator(i18n, regionCode);