From 8cc9b7b54b2438134eaa1b300ec8c22f2a2789f8 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Fri, 16 Nov 2018 13:29:31 +1100 Subject: [PATCH 01/12] Added blocked number model and collection. Added blocked number controller. Hooked up BlockedNumberController loading. --- background.html | 1 + js/background.js | 2 + js/blocked_number_controller.js | 72 +++++++++++++++++++++++++++++++++ js/models/blockedNumbers.js | 38 ++++++++++++++++- js/signal_protocol_store.js | 4 +- test/index.html | 1 + 6 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 js/blocked_number_controller.js diff --git a/background.html b/background.html index d17fcf7e4..a37e90fe1 100644 --- a/background.html +++ b/background.html @@ -614,6 +614,7 @@ + diff --git a/js/background.js b/js/background.js index 1c1afbc9d..b5a1df155 100644 --- a/js/background.js +++ b/js/background.js @@ -9,6 +9,7 @@ textsecure, WebAPI Whisper, + BlockedNumberController */ // eslint-disable-next-line func-names @@ -418,6 +419,7 @@ try { await ConversationController.load(); + BlockedNumberController.load(); } catch (error) { window.log.error( 'background.js: ConversationController failed to load:', diff --git a/js/blocked_number_controller.js b/js/blocked_number_controller.js new file mode 100644 index 000000000..24cfedd76 --- /dev/null +++ b/js/blocked_number_controller.js @@ -0,0 +1,72 @@ +/* global , Whisper, storage */ +/* global textsecure: false */ + +/* eslint-disable more/no-then */ + +// eslint-disable-next-line func-names +(function() { + 'use strict'; + + window.Whisper = window.Whisper || {}; + + const blockedNumbers = new Whisper.BlockedNumberCollection(); + window.getBlockedNumbers = () => blockedNumbers; + + window.BlockedNumberController = { + reset() { + blockedNumbers.reset([]); + }, + load() { + window.log.info('BlockedNumberController: starting initial fetch'); + + if (blockedNumbers.length) { + throw new Error('BlockedNumberController: Already loaded!'); + } + + if (!storage) { + throw new Error('BlockedNumberController: Could not load blocked numbers'); + } + + // Add the numbers to the collection + const numbers = storage.getBlockedNumbers(); + blockedNumbers.add( + numbers.map(number => ({ number })) + ); + }, + block(number) { + const ourNumber = textsecure.storage.user.getNumber(); + + // Make sure we don't block ourselves + if (ourNumber === number) { + window.log.info('BlockedNumberController: Cannot block yourself!'); + return null; + } + + storage.addBlockedNumber(number); + + // Make sure we don't add duplicates + const exists = blockedNumbers.getNumber(number); + if (exists) + return exists; + + return blockedNumbers.add({ number }); + }, + unblock(number) { + storage.removeBlockedNumber(number); + + // Make sure we don't add duplicates + const exists = blockedNumbers.getNumber(number); + if (exists) { + blockedNumbers.remove(exists); + return exists; + } + + return null; + }, + isBlocked(number) { + return storage.isBlocked(number); + }, + + }; + })(); + \ No newline at end of file diff --git a/js/models/blockedNumbers.js b/js/models/blockedNumbers.js index 10ef67f0f..7e1f79914 100644 --- a/js/models/blockedNumbers.js +++ b/js/models/blockedNumbers.js @@ -1,9 +1,19 @@ /* global storage, _ */ +/* global _: false */ +/* global Backbone: false */ + +/* global BlockedNumberController: false */ +/* global storage: false */ +/* global Whisper: false */ + +/* eslint-disable more/no-then */ // eslint-disable-next-line func-names (function() { 'use strict'; + window.Whisper = window.Whisper || {}; + const BLOCKED_NUMBERS_ID = 'blocked'; const BLOCKED_GROUPS_ID = 'blocked-groups'; @@ -12,6 +22,7 @@ return _.include(numbers, number); }; + storage.getBlockedNumbers = () => storage.get(BLOCKED_NUMBERS_ID, []); storage.addBlockedNumber = number => { const numbers = storage.get(BLOCKED_NUMBERS_ID, []); if (_.include(numbers, number)) { @@ -54,4 +65,29 @@ window.log.info(`removing group(${groupId} from blocked list`); storage.put(BLOCKED_GROUPS_ID, _.without(groupIds, groupId)); }; -})(); + + Whisper.BlockedNumber = Backbone.Model.extend({ + defaults() { + return { + number: '', + }; + }, + block() { + return BlockedNumberController.block(this.number); + }, + unblock() { + return BlockedNumberController.unblock(this.number); + }, + }); + + Whisper.BlockedNumberCollection = Backbone.Collection.extend({ + model: Whisper.BlockedNumber, + comparator(m) { + return m.get('number'); + }, + getNumber(number) { + return this.model.find(m => m.number === number); + }, + }); + +})(); \ No newline at end of file diff --git a/js/signal_protocol_store.js b/js/signal_protocol_store.js index 760f9c99e..80185d238 100644 --- a/js/signal_protocol_store.js +++ b/js/signal_protocol_store.js @@ -1,5 +1,5 @@ /* global - dcodeIO, Backbone, _, libsignal, textsecure, ConversationController, stringObject */ + dcodeIO, Backbone, _, libsignal, textsecure, ConversationController, stringObject, BlockedNumberController */ /* eslint-disable no-proto */ @@ -955,7 +955,9 @@ await window.storage.fetch(); ConversationController.reset(); + BlockedNumberController.reset(); await ConversationController.load(); + BlockedNumberController.load(); }, async removeAllConfiguration() { await window.Signal.Data.removeAllConfiguration(); diff --git a/test/index.html b/test/index.html index 64964f896..e03ce96cf 100644 --- a/test/index.html +++ b/test/index.html @@ -345,6 +345,7 @@ + From ae2e2fa2ae1f46d977287130932cb4d6e6916354 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Fri, 16 Nov 2018 14:42:42 +1100 Subject: [PATCH 02/12] Updated UI in conversation to support user blocking behaviour. --- _locales/en/messages.json | 6 ++++++ js/models/blockedNumbers.js | 2 +- js/models/conversations.js | 15 +++++++++++++-- js/views/conversation_view.js | 9 +++++++++ stylesheets/_modules.scss | 5 +++++ stylesheets/_theme_dark.scss | 4 ++++ ts/components/ConversationListItem.tsx | 6 ++++-- ts/components/conversation/ConversationHeader.tsx | 14 ++++++++++++++ 8 files changed, 56 insertions(+), 5 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index fe19c3d27..471ffe52c 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1619,5 +1619,11 @@ "example": "Bob" } } + }, + "blockUser": { + "message": "Block user" + }, + "unblockUser": { + "message": "Unblock user" } } diff --git a/js/models/blockedNumbers.js b/js/models/blockedNumbers.js index 7e1f79914..b31d24e58 100644 --- a/js/models/blockedNumbers.js +++ b/js/models/blockedNumbers.js @@ -86,7 +86,7 @@ return m.get('number'); }, getNumber(number) { - return this.model.find(m => m.number === number); + return this.models.find(m => m.number === number); }, }); diff --git a/js/models/conversations.js b/js/models/conversations.js index 47be7e3e2..d15fea527 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -1,6 +1,6 @@ /* global _: false */ /* global Backbone: false */ -/* global libphonenumber: false */ +/* global BlockedNumberController: false */ /* global ConversationController: false */ /* global libsignal: false */ @@ -147,7 +147,17 @@ isMe() { return this.id === this.ourNumber; }, - + isBlocked() { + return BlockedNumberController.isBlocked(this.id); + }, + block() { + BlockedNumberController.block(this.id); + this.trigger('change'); + }, + unblock() { + BlockedNumberController.unblock(this.id); + this.trigger('change'); + }, async cleanup() { await window.Signal.Types.Conversation.deleteExternalFiles( this.attributes, @@ -280,6 +290,7 @@ unreadCount: this.get('unreadCount') || 0, isSelected: this.isSelected, showFriendRequestIndicator: this.pendingFriendRequest, + isBlocked: this.isBlocked(), lastMessage: { status: this.lastMessageStatus, text: this.lastMessage, diff --git a/js/views/conversation_view.js b/js/views/conversation_view.js index 35099e78b..6dd0cdca6 100644 --- a/js/views/conversation_view.js +++ b/js/views/conversation_view.js @@ -7,6 +7,7 @@ /* global Signal: false */ /* global storage: false */ /* global Whisper: false */ +/* global BlockNumberConversation: false */ // eslint-disable-next-line func-names (function() { @@ -170,6 +171,7 @@ isVerified: this.model.isVerified(), isKeysPending: this.model.isKeyExchangeCompleted() === false, isMe: this.model.isMe(), + isBlocked: this.model.isBlocked(), isGroup: !this.model.isPrivate(), expirationSettingName, showBackButton: Boolean(this.panels && this.panels.length), @@ -200,6 +202,13 @@ this.resetPanel(); this.updateHeader(); }, + + onBlockUser: () => { + this.model.block(); + }, + onUnblockUser: () => { + this.model.unblock(); + }, }; }; this.titleView = new Whisper.ReactWrapperView({ diff --git a/stylesheets/_modules.scss b/stylesheets/_modules.scss index 5430952bd..d4c1dfe56 100644 --- a/stylesheets/_modules.scss +++ b/stylesheets/_modules.scss @@ -1831,6 +1831,11 @@ border-left: 4px solid $color-conversation-indigo; } +.module-conversation-list-item--is-blocked { + padding-left: 12px; + border-left: 4px solid $color-conversation-red; +} + .module-conversation-list-item--is-selected { background-color: $color-gray-05; } diff --git a/stylesheets/_theme_dark.scss b/stylesheets/_theme_dark.scss index 190c077a9..87dc3f85e 100644 --- a/stylesheets/_theme_dark.scss +++ b/stylesheets/_theme_dark.scss @@ -1269,6 +1269,10 @@ body.dark-theme { border-left: 4px solid $color-conversation-indigo; } + .module-conversation-list-item--is-blocked { + border-left: 4px solid $color-conversation-red; + } + .module-conversation-list-item--is-selected { background-color: $color-dark-70; } diff --git a/ts/components/ConversationListItem.tsx b/ts/components/ConversationListItem.tsx index a2e9cf644..574b626d6 100644 --- a/ts/components/ConversationListItem.tsx +++ b/ts/components/ConversationListItem.tsx @@ -24,6 +24,7 @@ interface Props { text: string; }; showFriendRequestIndicator?: boolean; + isBlocked: boolean; i18n: Localizer; onClick?: () => void; @@ -157,7 +158,7 @@ export class ConversationListItem extends React.Component { } public render() { - const { unreadCount, onClick, isSelected, showFriendRequestIndicator } = this.props; + const { unreadCount, onClick, isSelected, showFriendRequestIndicator, isBlocked } = this.props; return (
{ 'module-conversation-list-item', unreadCount > 0 ? 'module-conversation-list-item--has-unread' : null, isSelected ? 'module-conversation-list-item--is-selected' : null, - showFriendRequestIndicator ? 'module-conversation-list-item--has-friend-request' : null + showFriendRequestIndicator ? 'module-conversation-list-item--has-friend-request' : null, + isBlocked ? 'module-conversation-list-item--is-blocked' : null, )} > {this.renderAvatar()} diff --git a/ts/components/conversation/ConversationHeader.tsx b/ts/components/conversation/ConversationHeader.tsx index 705973309..49a99a6ed 100644 --- a/ts/components/conversation/ConversationHeader.tsx +++ b/ts/components/conversation/ConversationHeader.tsx @@ -30,6 +30,7 @@ interface Props { color: string; avatarPath?: string; + isBlocked: boolean; isMe: boolean; isGroup: boolean; expirationSettingName?: string; @@ -44,6 +45,9 @@ interface Props { onShowAllMedia: () => void; onShowGroupMembers: () => void; onGoBack: () => void; + + onBlockUser: () => void; + onUnblockUser: () => void; } export class ConversationHeader extends React.Component { @@ -182,6 +186,7 @@ export class ConversationHeader extends React.Component { public renderMenu(triggerId: string) { const { i18n, + isBlocked, isMe, isGroup, onDeleteMessages, @@ -191,10 +196,15 @@ export class ConversationHeader extends React.Component { onShowGroupMembers, onShowSafetyNumber, timerOptions, + onBlockUser, + onUnblockUser, } = this.props; const disappearingTitle = i18n('disappearingMessages') as any; + const blockTitle = isBlocked ? i18n('unblockUser') : i18n('blockUser'); + const blockHandler = isBlocked ? onUnblockUser : onBlockUser; + return ( @@ -223,6 +233,10 @@ export class ConversationHeader extends React.Component { {!isGroup ? ( {i18n('resetSession')} ) : null} + {/* Only show the block on other conversations */} + {!isMe ? ( + {blockTitle} + ) : null} {i18n('deleteMessages')} ); From a82999818a087584272e67b56c2330576a2906ed Mon Sep 17 00:00:00 2001 From: Mikunj Date: Fri, 16 Nov 2018 15:28:10 +1100 Subject: [PATCH 03/12] Added blocking/unblocking from friend request. Fixed incoming messages being deleted. --- app/sql.js | 4 +++- js/background.js | 5 +++++ js/blocked_number_controller.js | 8 +++++++- js/models/messages.js | 14 +++++++++++++- js/views/settings_view.js | 1 + settings.html | 4 ++++ ts/components/conversation/FriendRequest.tsx | 8 +++++++- 7 files changed, 40 insertions(+), 4 deletions(-) diff --git a/app/sql.js b/app/sql.js index 79d51f3b5..623f487f1 100644 --- a/app/sql.js +++ b/app/sql.js @@ -1302,7 +1302,9 @@ async function getMessageBySender({ source, sourceDevice, sent_at }) { async function getAllUnsentMessages() { const rows = await db.all(` - SELECT json FROM messages WHERE NOT sent + SELECT json FROM messages WHERE + type IN ('outgoing', 'friend-request') AND + NOT sent ORDER BY sent_at DESC; `); return map(rows, row => jsonToObject(row.json)); diff --git a/js/background.js b/js/background.js index b5a1df155..4e8f20433 100644 --- a/js/background.js +++ b/js/background.js @@ -338,6 +338,11 @@ 'expirationStartTimestamp' ); + // Make sure we only target outgoing messages + if (message.isFriendRequest() && message.get('direction') === 'incoming') { + return; + } + if (message.hasErrors()) { return; } diff --git a/js/blocked_number_controller.js b/js/blocked_number_controller.js index 24cfedd76..4e4fac2d0 100644 --- a/js/blocked_number_controller.js +++ b/js/blocked_number_controller.js @@ -63,10 +63,16 @@ return null; }, + unblockAll() { + const all = blockedNumbers.models; + all.forEach(number => { + storage.removeBlockedNumber(number); + blockedNumbers.remove(number); + }) + }, isBlocked(number) { return storage.isBlocked(number); }, - }; })(); \ No newline at end of file diff --git a/js/models/messages.js b/js/models/messages.js index f3860f648..56ff9bc40 100644 --- a/js/models/messages.js +++ b/js/models/messages.js @@ -331,15 +331,27 @@ window.Whisper.events.trigger('deleteConversation', conversation); }; + const onBlockUser = () => { + conversation.block(); + this.trigger('change'); + }; + + const onUnblockUser = () => { + conversation.unblock(); + this.trigger('change'); + }; + return { text: this.createNonBreakingLastSeparator(this.get('body')), status: this.getMessagePropStatus(), direction, friendStatus, + isBlocked: conversation.isBlocked(), onAccept, onDecline, onDeleteConversation, - onRetrySend: () => this.retrySend(), + onBlockUser, + onUnblockUser, } }, findContact(phoneNumber) { diff --git a/js/views/settings_view.js b/js/views/settings_view.js index 6d2439071..52675463f 100644 --- a/js/views/settings_view.js +++ b/js/views/settings_view.js @@ -150,6 +150,7 @@ mediaPermissionsDescription: i18n('mediaPermissionsDescription'), spellCheckHeader: i18n('spellCheck'), spellCheckDescription: i18n('spellCheckDescription'), + blockedHeader: 'Blocked Users', }; }, onClose() { diff --git a/settings.html b/settings.html index ebc33d209..24586d0c9 100644 --- a/settings.html +++ b/settings.html @@ -109,6 +109,10 @@

{{ clearDataExplanation }}

+
+
+

{{ blockedHeader }}

+
diff --git a/ts/components/conversation/FriendRequest.tsx b/ts/components/conversation/FriendRequest.tsx index 71f27b251..67975d92a 100644 --- a/ts/components/conversation/FriendRequest.tsx +++ b/ts/components/conversation/FriendRequest.tsx @@ -10,10 +10,13 @@ interface Props { status: string; friendStatus: 'pending' | 'accepted' | 'declined'; i18n: Localizer; + isBlocked: boolean; onAccept: () => void; onDecline: () => void; onDeleteConversation: () => void; onRetrySend: () => void; + onBlockUser: () => void; + onUnblockUser: () => void; } export class FriendRequest extends React.Component { @@ -50,7 +53,7 @@ export class FriendRequest extends React.Component { } public renderButtons() { - const { friendStatus, direction, status, onAccept, onDecline, onDeleteConversation, onRetrySend } = this.props; + const { i18n, friendStatus, direction, status, onAccept, onDecline, onDeleteConversation, onRetrySend, isBlocked, onBlockUser, onUnblockUser } = this.props; if (direction === 'incoming') { if (friendStatus === 'pending') { @@ -67,6 +70,8 @@ export class FriendRequest extends React.Component { ); } else if (friendStatus === 'declined') { + const blockTitle = isBlocked ? i18n('unblockUser') : i18n('blockUser'); + const blockHandler = isBlocked ? onUnblockUser : onBlockUser; return (
{ )} > +
); } From 658b2b033208a2f036a0eab5dff281fc75befbd0 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Mon, 19 Nov 2018 12:22:35 +1100 Subject: [PATCH 04/12] List blocked users in settings. --- js/blocked_number_controller.js | 8 +++++ js/settings_start.js | 4 ++- js/views/blocked_number_view.js | 56 +++++++++++++++++++++++++++++++++ js/views/settings_view.js | 4 +++ settings.html | 16 +++++++++- 5 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 js/views/blocked_number_view.js diff --git a/js/blocked_number_controller.js b/js/blocked_number_controller.js index 4e4fac2d0..ab71238c5 100644 --- a/js/blocked_number_controller.js +++ b/js/blocked_number_controller.js @@ -13,6 +13,14 @@ window.getBlockedNumbers = () => blockedNumbers; window.BlockedNumberController = { + getAll() { + try { + this.load(); + } catch (e) { + console.warn(e); + } + return blockedNumbers; + }, reset() { blockedNumbers.reset([]); }, diff --git a/js/settings_start.js b/js/settings_start.js index c81438577..f29d09224 100644 --- a/js/settings_start.js +++ b/js/settings_start.js @@ -1,4 +1,4 @@ -/* global $, Whisper */ +/* global $, Whisper, storage */ $(document).on('keyup', e => { 'use strict'; @@ -35,6 +35,8 @@ window.initialRequest = getInitialData(); window.initialRequest.then(data => { 'use strict'; + storage.fetch(); + window.initialData = data; window.view = new Whisper.SettingsView(); window.view.$el.appendTo($body); diff --git a/js/views/blocked_number_view.js b/js/views/blocked_number_view.js new file mode 100644 index 000000000..98837cae6 --- /dev/null +++ b/js/views/blocked_number_view.js @@ -0,0 +1,56 @@ +/* global BlockedNumberController: false */ +/* global Whisper: false */ +/* global storage: false */ +/* global $: false */ + +/* eslint-disable no-new */ + +// eslint-disable-next-line func-names +(function() { + 'use strict'; + + window.Whisper = window.Whisper || {}; + + Whisper.BlockedNumberView = Whisper.View.extend({ + templateName: 'blockedUserSettings', + className: 'blockedUserSettings', + events: { + 'click .sync': 'sync', + }, + initialize() { + storage.onready(() => { + this.collection = BlockedNumberController.getAll(); + this.listView = new Whisper.BlockedNumberListView({ + collection: this.collection, + }); + + this.listView.render(); + this.$('.content').append(this.listView.el); + }); + }, + render_attributes() { + return { + blockedHeader: 'Blocked Users', + }; + }, + }); + + + Whisper.BlockedNumberListView = Whisper.ListView.extend({ + tagName: 'div', + itemView: Whisper.View.extend({ + tagName: 'div', + templateName: 'blockedNumber', + initialize() { + this.listenTo(this.model, 'change', this.render); + }, + render_attributes() { + const number = (this.model && this.model.get('number')) || '-'; + return { + number, + } + }, + }), + }); + })(); + \ No newline at end of file diff --git a/js/views/settings_view.js b/js/views/settings_view.js index 52675463f..5604e8599 100644 --- a/js/views/settings_view.js +++ b/js/views/settings_view.js @@ -117,6 +117,10 @@ value: window.initialData.mediaPermissions, setFn: window.setMediaPermissions, }); + + const blockedNumberView = new Whisper.BlockedNumberView().render(); + this.$('.blocked-user-setting').append(blockedNumberView.el); + if (!window.initialData.isPrimary) { const syncView = new SyncView().render(); this.$('.sync-setting').append(syncView.el); diff --git a/settings.html b/settings.html index 24586d0c9..95f834449 100644 --- a/settings.html +++ b/settings.html @@ -34,6 +34,15 @@

+ + + + + + + + From ba390e354bb81ea689dd0ec329e0fb4ca2a5dc55 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Mon, 19 Nov 2018 14:14:17 +1100 Subject: [PATCH 05/12] Added unblocking. Added styling. Trigger changes on both conversation and messages when we block/unblock. --- js/blocked_number_controller.js | 13 ++++++------ js/models/blockedNumbers.js | 2 +- js/models/conversations.js | 6 ++++-- js/views/blocked_number_view.js | 22 ++++++++++++++------- main.js | 6 ++++++ preload.js | 15 ++++++++++++++ settings.html | 6 ++++-- settings_preload.js | 4 ++++ stylesheets/_settings.scss | 35 +++++++++++++++++++++++++++++++++ 9 files changed, 90 insertions(+), 19 deletions(-) diff --git a/js/blocked_number_controller.js b/js/blocked_number_controller.js index ab71238c5..ad0142fa6 100644 --- a/js/blocked_number_controller.js +++ b/js/blocked_number_controller.js @@ -1,4 +1,4 @@ -/* global , Whisper, storage */ +/* global , Whisper, storage, ConversationController */ /* global textsecure: false */ /* eslint-disable more/no-then */ @@ -6,12 +6,12 @@ // eslint-disable-next-line func-names (function() { 'use strict'; - + window.Whisper = window.Whisper || {}; - + const blockedNumbers = new Whisper.BlockedNumberCollection(); window.getBlockedNumbers = () => blockedNumbers; - + window.BlockedNumberController = { getAll() { try { @@ -26,7 +26,7 @@ }, load() { window.log.info('BlockedNumberController: starting initial fetch'); - + if (blockedNumbers.length) { throw new Error('BlockedNumberController: Already loaded!'); } @@ -82,5 +82,4 @@ return storage.isBlocked(number); }, }; - })(); - \ No newline at end of file + })(); \ No newline at end of file diff --git a/js/models/blockedNumbers.js b/js/models/blockedNumbers.js index b31d24e58..b26a04290 100644 --- a/js/models/blockedNumbers.js +++ b/js/models/blockedNumbers.js @@ -89,5 +89,5 @@ return this.models.find(m => m.number === number); }, }); - + })(); \ No newline at end of file diff --git a/js/models/conversations.js b/js/models/conversations.js index d15fea527..193f08426 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -129,7 +129,7 @@ setTimeout(() => { this.setFriendRequestTimer(); }, 0); - + const sealedSender = this.get('sealedSender'); if (sealedSender === undefined) { this.set({ sealedSender: SEALED_SENDER.UNKNOWN }); @@ -153,10 +153,12 @@ block() { BlockedNumberController.block(this.id); this.trigger('change'); + this.messageCollection.forEach(m => m.trigger('change')); }, unblock() { BlockedNumberController.unblock(this.id); this.trigger('change'); + this.messageCollection.forEach(m => m.trigger('change')); }, async cleanup() { await window.Signal.Types.Conversation.deleteExternalFiles( @@ -254,7 +256,7 @@ // Go through the messages and check for any pending friend requests const messages = await window.Signal.Data.getMessagesByConversation( this.id, - { + { type: 'friend-request', MessageCollection: Whisper.MessageCollection, } diff --git a/js/views/blocked_number_view.js b/js/views/blocked_number_view.js index 98837cae6..a7b23d80a 100644 --- a/js/views/blocked_number_view.js +++ b/js/views/blocked_number_view.js @@ -8,7 +8,7 @@ // eslint-disable-next-line func-names (function() { 'use strict'; - + window.Whisper = window.Whisper || {}; Whisper.BlockedNumberView = Whisper.View.extend({ @@ -25,7 +25,7 @@ }); this.listView.render(); - this.$('.content').append(this.listView.el); + this.$('.blocked-user-settings').append(this.listView.el); }); }, render_attributes() { @@ -37,12 +37,11 @@ Whisper.BlockedNumberListView = Whisper.ListView.extend({ - tagName: 'div', itemView: Whisper.View.extend({ - tagName: 'div', + tagName: 'li', templateName: 'blockedNumber', - initialize() { - this.listenTo(this.model, 'change', this.render); + events: { + 'click .unblock-button': 'onUnblock', }, render_attributes() { const number = (this.model && this.model.get('number')) || '-'; @@ -50,7 +49,16 @@ number, } }, + onUnblock() { + const number = this.model && this.model.get('number'); + if (!number) return; + + if (BlockedNumberController.isBlocked(number)) { + BlockedNumberController.unblock(number); + window.onUnblockNumber(number); + this.remove(); + } + }, }), }); })(); - \ No newline at end of file diff --git a/main.js b/main.js index 6eccb7b9a..33ab52a21 100644 --- a/main.js +++ b/main.js @@ -930,6 +930,12 @@ ipc.on('set-media-permissions', (event, value) => { event.sender.send('set-success-media-permissions', null); }); +ipc.on('on-unblock-number', (event, number) => { + if (mainWindow && mainWindow.webContents) { + mainWindow.webContents.send('on-unblock-number', number); + } +}); + installSettingsGetter('is-primary'); installSettingsGetter('sync-request'); installSettingsGetter('sync-time'); diff --git a/preload.js b/preload.js index a5ac6586a..e7f5d6093 100644 --- a/preload.js +++ b/preload.js @@ -77,6 +77,21 @@ window.setMediaPermissions = enabled => ipc.send('set-media-permissions', enabled); window.getMediaPermissions = () => ipc.sendSync('get-media-permissions'); +// Events for updating block number states across different windows +// In this case we need these to update the blocked number collection on the main window from the settings window +window.onUnblockNumber = number => ipc.send('on-unblock-number', number); + +ipc.on('on-unblock-number', (event, number) => { + if (window.ConversationController) { + try { + const conversation = window.ConversationController.get(number); + conversation.unblock(); + } catch (e) { + window.log.info('IPC on unblock: failed to fetch conversation for number: ', number); + } + } +}); + window.closeAbout = () => ipc.send('close-about'); window.updateTrayIcon = unreadCount => diff --git a/settings.html b/settings.html index 95f834449..a16727e00 100644 --- a/settings.html +++ b/settings.html @@ -35,12 +35,14 @@ -