Removes some Backbone views
This commit is contained in:
parent
93bc094342
commit
94d116c621
22 changed files with 160 additions and 656 deletions
|
@ -61,7 +61,6 @@
|
||||||
<script type='text/x-tmpl-mustache' id='two-column'>
|
<script type='text/x-tmpl-mustache' id='two-column'>
|
||||||
<div class='module-title-bar-drag-area'></div>
|
<div class='module-title-bar-drag-area'></div>
|
||||||
|
|
||||||
<div class='call-manager-placeholder'></div>
|
|
||||||
<div class='inbox-container'>
|
<div class='inbox-container'>
|
||||||
<div class='gutter'>
|
<div class='gutter'>
|
||||||
<div class='left-pane-placeholder'></div>
|
<div class='left-pane-placeholder'></div>
|
||||||
|
@ -120,10 +119,6 @@
|
||||||
<button class='finish' tabIndex='1'><span class='icon'></span></button>
|
<button class='finish' tabIndex='1'><span class='icon'></span></button>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type='text/x-tmpl-mustache' id='safety-number-change-dialog'>
|
|
||||||
<div class='safety-number-change-dialog-wrapper'></div>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script type='text/x-tmpl-mustache' id='identicon-svg'>
|
<script type='text/x-tmpl-mustache' id='identicon-svg'>
|
||||||
<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'>
|
<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'>
|
||||||
<circle cx='50' cy='50' r='40' fill='{{ color }}' />
|
<circle cx='50' cy='50' r='40' fill='{{ color }}' />
|
||||||
|
@ -342,18 +337,13 @@
|
||||||
<script type='text/javascript' src='js/expiring_tap_to_view_messages.js'></script>
|
<script type='text/javascript' src='js/expiring_tap_to_view_messages.js'></script>
|
||||||
|
|
||||||
<script type='text/javascript' src='js/views/react_wrapper_view.js'></script>
|
<script type='text/javascript' src='js/views/react_wrapper_view.js'></script>
|
||||||
<script type='text/javascript' src='js/views/list_view.js'></script>
|
|
||||||
<script type='text/javascript' src='js/views/contact_list_view.js'></script>
|
|
||||||
<script type='text/javascript' src='js/views/key_verification_view.js'></script>
|
<script type='text/javascript' src='js/views/key_verification_view.js'></script>
|
||||||
<script type='text/javascript' src='js/views/group_member_list_view.js'></script>
|
|
||||||
<script type='text/javascript' src='js/views/recorder_view.js'></script>
|
<script type='text/javascript' src='js/views/recorder_view.js'></script>
|
||||||
<script type='text/javascript' src='js/views/inbox_view.js'></script>
|
<script type='text/javascript' src='js/views/inbox_view.js'></script>
|
||||||
<script type='text/javascript' src='ts/shims/showConfirmationDialog.js'></script>
|
<script type='text/javascript' src='ts/shims/showConfirmationDialog.js'></script>
|
||||||
<script type='text/javascript' src='js/views/identicon_svg_view.js'></script>
|
<script type='text/javascript' src='js/views/identicon_svg_view.js'></script>
|
||||||
<script type='text/javascript' src='js/views/install_view.js'></script>
|
<script type='text/javascript' src='js/views/install_view.js'></script>
|
||||||
<script type='text/javascript' src='js/views/banner_view.js'></script>
|
|
||||||
<script type="text/javascript" src="js/views/phone-input-view.js"></script>
|
<script type="text/javascript" src="js/views/phone-input-view.js"></script>
|
||||||
<script type='text/javascript' src='js/views/safety_number_change_dialog_view.js'></script>
|
|
||||||
<script type='text/javascript' src='js/views/standalone_registration_view.js'></script>
|
<script type='text/javascript' src='js/views/standalone_registration_view.js'></script>
|
||||||
<script type='text/javascript' src='js/views/clear_data_view.js'></script>
|
<script type='text/javascript' src='js/views/clear_data_view.js'></script>
|
||||||
|
|
||||||
|
|
|
@ -51,9 +51,6 @@ const {
|
||||||
} = require('../../ts/components/conversation/MessageDetail');
|
} = require('../../ts/components/conversation/MessageDetail');
|
||||||
const { Quote } = require('../../ts/components/conversation/Quote');
|
const { Quote } = require('../../ts/components/conversation/Quote');
|
||||||
const { ProgressModal } = require('../../ts/components/ProgressModal');
|
const { ProgressModal } = require('../../ts/components/ProgressModal');
|
||||||
const {
|
|
||||||
SafetyNumberChangeDialog,
|
|
||||||
} = require('../../ts/components/SafetyNumberChangeDialog');
|
|
||||||
const {
|
const {
|
||||||
StagedLinkPreview,
|
StagedLinkPreview,
|
||||||
} = require('../../ts/components/conversation/StagedLinkPreview');
|
} = require('../../ts/components/conversation/StagedLinkPreview');
|
||||||
|
@ -79,13 +76,9 @@ const {
|
||||||
createConversationHeader,
|
createConversationHeader,
|
||||||
} = require('../../ts/state/roots/createConversationHeader');
|
} = require('../../ts/state/roots/createConversationHeader');
|
||||||
const { createApp } = require('../../ts/state/roots/createApp');
|
const { createApp } = require('../../ts/state/roots/createApp');
|
||||||
const { createCallManager } = require('../../ts/state/roots/createCallManager');
|
|
||||||
const {
|
const {
|
||||||
createForwardMessageModal,
|
createForwardMessageModal,
|
||||||
} = require('../../ts/state/roots/createForwardMessageModal');
|
} = require('../../ts/state/roots/createForwardMessageModal');
|
||||||
const {
|
|
||||||
createGlobalModalContainer,
|
|
||||||
} = require('../../ts/state/roots/createGlobalModalContainer');
|
|
||||||
const {
|
const {
|
||||||
createGroupLinkManagement,
|
createGroupLinkManagement,
|
||||||
} = require('../../ts/state/roots/createGroupLinkManagement');
|
} = require('../../ts/state/roots/createGroupLinkManagement');
|
||||||
|
@ -347,7 +340,6 @@ exports.setup = (options = {}) => {
|
||||||
MessageDetail,
|
MessageDetail,
|
||||||
Quote,
|
Quote,
|
||||||
ProgressModal,
|
ProgressModal,
|
||||||
SafetyNumberChangeDialog,
|
|
||||||
StagedLinkPreview,
|
StagedLinkPreview,
|
||||||
DisappearingTimeDialog,
|
DisappearingTimeDialog,
|
||||||
Types: {
|
Types: {
|
||||||
|
@ -357,14 +349,12 @@ exports.setup = (options = {}) => {
|
||||||
|
|
||||||
const Roots = {
|
const Roots = {
|
||||||
createApp,
|
createApp,
|
||||||
createCallManager,
|
|
||||||
createChatColorPicker,
|
createChatColorPicker,
|
||||||
createCompositionArea,
|
createCompositionArea,
|
||||||
createContactModal,
|
createContactModal,
|
||||||
createConversationDetails,
|
createConversationDetails,
|
||||||
createConversationHeader,
|
createConversationHeader,
|
||||||
createForwardMessageModal,
|
createForwardMessageModal,
|
||||||
createGlobalModalContainer,
|
|
||||||
createGroupLinkManagement,
|
createGroupLinkManagement,
|
||||||
createGroupV1MigrationModal,
|
createGroupV1MigrationModal,
|
||||||
createGroupV2JoinModal,
|
createGroupV2JoinModal,
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
// Copyright 2017-2020 Signal Messenger, LLC
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
/* global Whisper, $ */
|
|
||||||
|
|
||||||
// eslint-disable-next-line func-names
|
|
||||||
(function () {
|
|
||||||
window.Whisper = window.Whisper || {};
|
|
||||||
|
|
||||||
Whisper.BannerView = Whisper.View.extend({
|
|
||||||
className: 'banner',
|
|
||||||
template: () => $('#banner').html(),
|
|
||||||
events: {
|
|
||||||
'click .dismiss': 'onDismiss',
|
|
||||||
'click .body': 'onClick',
|
|
||||||
},
|
|
||||||
initialize(options) {
|
|
||||||
this.message = options.message;
|
|
||||||
this.callbacks = {
|
|
||||||
onDismiss: options.onDismiss,
|
|
||||||
onClick: options.onClick,
|
|
||||||
};
|
|
||||||
this.render();
|
|
||||||
},
|
|
||||||
render_attributes() {
|
|
||||||
return {
|
|
||||||
message: this.message,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
onDismiss(e) {
|
|
||||||
this.callbacks.onDismiss();
|
|
||||||
e.stopPropagation();
|
|
||||||
},
|
|
||||||
onClick() {
|
|
||||||
this.callbacks.onClick();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})();
|
|
|
@ -1,49 +0,0 @@
|
||||||
// Copyright 2015-2020 Signal Messenger, LLC
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
/* global Whisper, textsecure, $ */
|
|
||||||
|
|
||||||
// eslint-disable-next-line func-names
|
|
||||||
(function () {
|
|
||||||
window.Whisper = window.Whisper || {};
|
|
||||||
|
|
||||||
Whisper.ContactListView = Whisper.ListView.extend({
|
|
||||||
tagName: 'div',
|
|
||||||
itemView: Whisper.View.extend({
|
|
||||||
tagName: 'div',
|
|
||||||
className: 'contact',
|
|
||||||
template: () => $('#contact').html(),
|
|
||||||
initialize(options) {
|
|
||||||
this.ourNumber = textsecure.storage.user.getNumber();
|
|
||||||
this.listenBack = options.listenBack;
|
|
||||||
this.loading = false;
|
|
||||||
this.conversation = options.conversation;
|
|
||||||
|
|
||||||
this.listenTo(this.model, 'change', this.render);
|
|
||||||
},
|
|
||||||
render() {
|
|
||||||
if (this.contactView) {
|
|
||||||
this.contactView.remove();
|
|
||||||
this.contactView = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const formattedContact = this.model.format();
|
|
||||||
|
|
||||||
this.contactView = new Whisper.ReactWrapperView({
|
|
||||||
className: 'contact-wrapper',
|
|
||||||
Component: window.Signal.Components.ContactListItem,
|
|
||||||
props: {
|
|
||||||
...formattedContact,
|
|
||||||
onClick: () =>
|
|
||||||
this.conversation.trigger(
|
|
||||||
'show-contact-modal',
|
|
||||||
formattedContact.id
|
|
||||||
),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
this.$el.append(this.contactView.el);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
})();
|
|
|
@ -1,42 +0,0 @@
|
||||||
// Copyright 2015-2020 Signal Messenger, LLC
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
/* global Whisper, i18n, $ */
|
|
||||||
|
|
||||||
// eslint-disable-next-line func-names
|
|
||||||
(function () {
|
|
||||||
window.Whisper = window.Whisper || {};
|
|
||||||
|
|
||||||
Whisper.GroupMemberList = Whisper.View.extend({
|
|
||||||
className: 'group-member-list panel',
|
|
||||||
template: () => $('#group-member-list').html(),
|
|
||||||
initialize(options) {
|
|
||||||
this.needVerify = options.needVerify;
|
|
||||||
|
|
||||||
this.render();
|
|
||||||
|
|
||||||
this.member_list_view = new Whisper.ContactListView({
|
|
||||||
collection: this.model,
|
|
||||||
className: 'members',
|
|
||||||
toInclude: {
|
|
||||||
listenBack: options.listenBack,
|
|
||||||
conversation: options.conversation,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
this.member_list_view.render();
|
|
||||||
|
|
||||||
this.$('.container').append(this.member_list_view.el);
|
|
||||||
},
|
|
||||||
render_attributes() {
|
|
||||||
let summary;
|
|
||||||
if (this.needVerify) {
|
|
||||||
summary = i18n('membersNeedingVerification');
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
members: i18n('groupMembers'),
|
|
||||||
summary,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})();
|
|
|
@ -137,8 +137,6 @@
|
||||||
this.startConnectionListener();
|
this.startConnectionListener();
|
||||||
} else {
|
} else {
|
||||||
this.setupLeftPane();
|
this.setupLeftPane();
|
||||||
this.setupCallManagerUI();
|
|
||||||
this.setupGlobalModalContainer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Whisper.events.on('pack-install-failed', () => {
|
Whisper.events.on('pack-install-failed', () => {
|
||||||
|
@ -155,28 +153,6 @@
|
||||||
events: {
|
events: {
|
||||||
click: 'onClick',
|
click: 'onClick',
|
||||||
},
|
},
|
||||||
setupCallManagerUI() {
|
|
||||||
if (this.callManagerView) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.callManagerView = new Whisper.ReactWrapperView({
|
|
||||||
className: 'call-manager-wrapper',
|
|
||||||
JSX: Signal.State.Roots.createCallManager(window.reduxStore),
|
|
||||||
});
|
|
||||||
this.$('.call-manager-placeholder').append(this.callManagerView.el);
|
|
||||||
},
|
|
||||||
setupGlobalModalContainer() {
|
|
||||||
if (this.globalModalContainerView) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.globalModalContainerView = new Whisper.ReactWrapperView({
|
|
||||||
JSX: Signal.State.Roots.createGlobalModalContainer(window.reduxStore),
|
|
||||||
});
|
|
||||||
const node = document.querySelector('.inbox-container');
|
|
||||||
if (node) {
|
|
||||||
node.appendChild(this.globalModalContainerView.el);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setupLeftPane() {
|
setupLeftPane() {
|
||||||
if (this.leftPaneView) {
|
if (this.leftPaneView) {
|
||||||
return;
|
return;
|
||||||
|
@ -217,8 +193,6 @@
|
||||||
},
|
},
|
||||||
onEmpty() {
|
onEmpty() {
|
||||||
this.setupLeftPane();
|
this.setupLeftPane();
|
||||||
this.setupCallManagerUI();
|
|
||||||
this.setupGlobalModalContainer();
|
|
||||||
|
|
||||||
const view = this.appLoadingScreen;
|
const view = this.appLoadingScreen;
|
||||||
if (view) {
|
if (view) {
|
||||||
|
@ -241,14 +215,6 @@
|
||||||
this.$('#header, .gutter').addClass('inactive');
|
this.$('#header, .gutter').addClass('inactive');
|
||||||
this.$('.conversation-stack').removeClass('inactive');
|
this.$('.conversation-stack').removeClass('inactive');
|
||||||
},
|
},
|
||||||
focusHeader() {
|
|
||||||
this.$('.conversation-stack').addClass('inactive');
|
|
||||||
this.$('#header, .gutter').removeClass('inactive');
|
|
||||||
this.$('.conversation:first .menu').trigger('close');
|
|
||||||
},
|
|
||||||
reloadBackgroundPage() {
|
|
||||||
window.location.reload();
|
|
||||||
},
|
|
||||||
closeRecording(e) {
|
closeRecording(e) {
|
||||||
if (e && this.$(e.target).closest('.capture-audio').length > 0) {
|
if (e && this.$(e.target).closest('.capture-audio').length > 0) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
// Copyright 2014-2020 Signal Messenger, LLC
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
/* global Backbone, Whisper, _ */
|
|
||||||
|
|
||||||
// eslint-disable-next-line func-names
|
|
||||||
(function () {
|
|
||||||
window.Whisper = window.Whisper || {};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Generic list view that watches a given collection, wraps its members in
|
|
||||||
* a given child view and adds the child view elements to its own element.
|
|
||||||
*/
|
|
||||||
Whisper.ListView = Backbone.View.extend({
|
|
||||||
tagName: 'ul',
|
|
||||||
itemView: Backbone.View,
|
|
||||||
initialize(options) {
|
|
||||||
this.options = options || {};
|
|
||||||
this.listenTo(this.collection, 'add', this.addOne);
|
|
||||||
this.listenTo(this.collection, 'reset', this.addAll);
|
|
||||||
},
|
|
||||||
|
|
||||||
addOne(model) {
|
|
||||||
if (this.itemView) {
|
|
||||||
const options = _.extend({}, this.options.toInclude, { model });
|
|
||||||
// eslint-disable-next-line new-cap
|
|
||||||
const view = new this.itemView(options);
|
|
||||||
this.$el.append(view.render().el);
|
|
||||||
this.$el.trigger('add');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
addAll() {
|
|
||||||
this.$el.html('');
|
|
||||||
this.collection.each(this.addOne, this);
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
|
||||||
this.addAll();
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})();
|
|
|
@ -1,41 +0,0 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
/* global Whisper, Signal, $ */
|
|
||||||
|
|
||||||
// eslint-disable-next-line func-names
|
|
||||||
(function () {
|
|
||||||
window.Whisper = window.Whisper || {};
|
|
||||||
|
|
||||||
Whisper.SafetyNumberChangeDialogView = Whisper.View.extend({
|
|
||||||
template: () => $('#safety-number-change-dialog').html(),
|
|
||||||
initialize(options) {
|
|
||||||
const dialog = new Whisper.ReactWrapperView({
|
|
||||||
Component: window.Signal.Components.SafetyNumberChangeDialog,
|
|
||||||
props: {
|
|
||||||
confirmText: options.confirmText,
|
|
||||||
contacts: options.contacts.map(contact => contact.format()),
|
|
||||||
i18n: window.i18n,
|
|
||||||
onCancel: () => {
|
|
||||||
dialog.remove();
|
|
||||||
this.remove();
|
|
||||||
options.reject();
|
|
||||||
},
|
|
||||||
onConfirm: () => {
|
|
||||||
dialog.remove();
|
|
||||||
this.remove();
|
|
||||||
options.resolve();
|
|
||||||
},
|
|
||||||
renderSafetyNumber(props) {
|
|
||||||
return Signal.State.Roots.createSafetyNumberViewer(
|
|
||||||
window.reduxStore,
|
|
||||||
props
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$('.safety-number-change-dialog-wrapper').append(dialog.el);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})();
|
|
|
@ -43,7 +43,6 @@
|
||||||
<script type='text/x-tmpl-mustache' id='two-column'>
|
<script type='text/x-tmpl-mustache' id='two-column'>
|
||||||
<div class='module-title-bar-drag-area'></div>
|
<div class='module-title-bar-drag-area'></div>
|
||||||
|
|
||||||
<div class='call-manager-placeholder'></div>
|
|
||||||
<div class='inbox-container'>
|
<div class='inbox-container'>
|
||||||
<div class='gutter'>
|
<div class='gutter'>
|
||||||
<div class='left-pane-placeholder'></div>
|
<div class='left-pane-placeholder'></div>
|
||||||
|
@ -92,30 +91,14 @@
|
||||||
<script type='text/x-tmpl-mustache' id='conversation'>
|
<script type='text/x-tmpl-mustache' id='conversation'>
|
||||||
<div class='conversation-header'></div>
|
<div class='conversation-header'></div>
|
||||||
<div class='main panel'>
|
<div class='main panel'>
|
||||||
<div class='discussion-container'>
|
<div class='timeline-placeholder' aria-live='polite'></div>
|
||||||
<div class='bar-container hide'>
|
|
||||||
<div class='bar active progress-bar-striped progress-bar'></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class='bottom-bar' id='footer'>
|
<div class='bottom-bar' id='footer'>
|
||||||
<div class='emoji-panel-container'></div>
|
<div class='compose'>
|
||||||
<div class='attachment-list'></div>
|
<form class='send clearfix file-input'>
|
||||||
<div class='compose'>
|
<input type="file" class="file-input" multiple="multiple">
|
||||||
<form class='send clearfix file-input'>
|
<div class='composition-area-placeholder'></div>
|
||||||
<div class='flex'>
|
</form>
|
||||||
<button class='emoji'></button>
|
</div>
|
||||||
<textarea class='send-message' placeholder='{{ send-message }}' rows='1' dir='auto'></textarea>
|
|
||||||
<div class='capture-audio'>
|
|
||||||
<button class='microphone'></button>
|
|
||||||
</div>
|
|
||||||
<div class='choose-file'>
|
|
||||||
<button class='paperclip thumbnail'></button>
|
|
||||||
<input type='file' class='file-input' multiple='multiple'>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
@ -131,10 +114,6 @@
|
||||||
<button class='close'><span class='icon'></span></button>
|
<button class='close'><span class='icon'></span></button>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type='text/x-tmpl-mustache' id='safety-number-change-dialog'>
|
|
||||||
<div class='safety-number-change-dialog-wrapper'></div>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script type='text/x-tmpl-mustache' id='identicon-svg'>
|
<script type='text/x-tmpl-mustache' id='identicon-svg'>
|
||||||
<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'>
|
<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'>
|
||||||
<circle cx='50' cy='50' r='40' fill='{{ color }}' />
|
<circle cx='50' cy='50' r='40' fill='{{ color }}' />
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
// Copyright 2014-2020 Signal Messenger, LLC
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
/* global Backbone, Whisper */
|
|
||||||
|
|
||||||
describe('ListView', () => {
|
|
||||||
let collection;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
collection = new Backbone.Collection();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add children to the list element as they are added to the collection', () => {
|
|
||||||
const view = new Whisper.ListView({ collection });
|
|
||||||
collection.add('hello');
|
|
||||||
assert.equal(view.$el.children().length, 1);
|
|
||||||
collection.add('world');
|
|
||||||
assert.equal(view.$el.children().length, 2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add all the children to the list element on reset', () => {
|
|
||||||
const view = new Whisper.ListView({ collection });
|
|
||||||
collection.reset(['goodbye', 'world']);
|
|
||||||
assert.equal(view.$el.children().length, 2);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import { AppViewType } from '../state/ducks/app';
|
import { AppViewType } from '../state/ducks/app';
|
||||||
|
@ -10,12 +10,16 @@ import { ThemeType } from '../types/Util';
|
||||||
export type PropsType = {
|
export type PropsType = {
|
||||||
appView: AppViewType;
|
appView: AppViewType;
|
||||||
hasInitialLoadCompleted: boolean;
|
hasInitialLoadCompleted: boolean;
|
||||||
|
renderCallManager: () => JSX.Element;
|
||||||
|
renderGlobalModalContainer: () => JSX.Element;
|
||||||
theme: ThemeType;
|
theme: ThemeType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const App = ({
|
export const App = ({
|
||||||
appView,
|
appView,
|
||||||
hasInitialLoadCompleted,
|
hasInitialLoadCompleted,
|
||||||
|
renderCallManager,
|
||||||
|
renderGlobalModalContainer,
|
||||||
theme,
|
theme,
|
||||||
}: PropsType): JSX.Element => {
|
}: PropsType): JSX.Element => {
|
||||||
let contents;
|
let contents;
|
||||||
|
@ -28,6 +32,20 @@ export const App = ({
|
||||||
contents = <Inbox hasInitialLoadCompleted={hasInitialLoadCompleted} />;
|
contents = <Inbox hasInitialLoadCompleted={hasInitialLoadCompleted} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is here so that themes are properly applied to anything that is
|
||||||
|
// created in a portal and exists outside of the <App /> container.
|
||||||
|
useEffect(() => {
|
||||||
|
document.body.classList.remove('light-theme');
|
||||||
|
document.body.classList.remove('dark-theme');
|
||||||
|
|
||||||
|
if (theme === ThemeType.dark) {
|
||||||
|
document.body.classList.add('dark-theme');
|
||||||
|
}
|
||||||
|
if (theme === ThemeType.light) {
|
||||||
|
document.body.classList.add('light-theme');
|
||||||
|
}
|
||||||
|
}, [theme]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames({
|
className={classNames({
|
||||||
|
@ -36,6 +54,8 @@ export const App = ({
|
||||||
'dark-theme': theme === ThemeType.dark,
|
'dark-theme': theme === ThemeType.dark,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
|
{renderGlobalModalContainer()}
|
||||||
|
{renderCallManager()}
|
||||||
{contents}
|
{contents}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -19,14 +19,13 @@ export type GroupV2Membership = {
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
canAddNewMembers: boolean;
|
canAddNewMembers: boolean;
|
||||||
|
i18n: LocalizerType;
|
||||||
|
maxShownMemberCount?: number;
|
||||||
memberships: Array<GroupV2Membership>;
|
memberships: Array<GroupV2Membership>;
|
||||||
showContactModal: (conversationId: string) => void;
|
showContactModal: (conversationId: string) => void;
|
||||||
startAddingNewMembers: () => void;
|
startAddingNewMembers?: () => void;
|
||||||
i18n: LocalizerType;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const MAX_MEMBER_COUNT = 5;
|
|
||||||
|
|
||||||
const collator = new Intl.Collator(undefined, { sensitivity: 'base' });
|
const collator = new Intl.Collator(undefined, { sensitivity: 'base' });
|
||||||
function sortConversationTitles(
|
function sortConversationTitles(
|
||||||
left: GroupV2Membership,
|
left: GroupV2Membership,
|
||||||
|
@ -68,18 +67,20 @@ function sortMemberships(
|
||||||
|
|
||||||
export const ConversationDetailsMembershipList: React.ComponentType<Props> = ({
|
export const ConversationDetailsMembershipList: React.ComponentType<Props> = ({
|
||||||
canAddNewMembers,
|
canAddNewMembers,
|
||||||
|
i18n,
|
||||||
|
maxShownMemberCount = 5,
|
||||||
memberships,
|
memberships,
|
||||||
showContactModal,
|
showContactModal,
|
||||||
startAddingNewMembers,
|
startAddingNewMembers,
|
||||||
i18n,
|
|
||||||
}) => {
|
}) => {
|
||||||
const [showAllMembers, setShowAllMembers] = React.useState<boolean>(false);
|
const [showAllMembers, setShowAllMembers] = React.useState<boolean>(false);
|
||||||
const sortedMemberships = sortMemberships(memberships);
|
const sortedMemberships = sortMemberships(memberships);
|
||||||
|
|
||||||
const shouldHideRestMembers = sortedMemberships.length - MAX_MEMBER_COUNT > 1;
|
const shouldHideRestMembers =
|
||||||
|
sortedMemberships.length - maxShownMemberCount > 1;
|
||||||
const membersToShow =
|
const membersToShow =
|
||||||
shouldHideRestMembers && !showAllMembers
|
shouldHideRestMembers && !showAllMembers
|
||||||
? MAX_MEMBER_COUNT
|
? maxShownMemberCount
|
||||||
: sortedMemberships.length;
|
: sortedMemberships.length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -94,7 +95,7 @@ export const ConversationDetailsMembershipList: React.ComponentType<Props> = ({
|
||||||
<div className="module-conversation-details-membership-list__add-members-icon" />
|
<div className="module-conversation-details-membership-list__add-members-icon" />
|
||||||
}
|
}
|
||||||
label={i18n('ConversationDetailsMembershipList--add-members')}
|
label={i18n('ConversationDetailsMembershipList--add-members')}
|
||||||
onClick={startAddingNewMembers}
|
onClick={() => startAddingNewMembers?.()}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{sortedMemberships.slice(0, membersToShow).map(({ isAdmin, member }) => (
|
{sortedMemberships.slice(0, membersToShow).map(({ isAdmin, member }) => (
|
||||||
|
|
|
@ -5405,23 +5405,3 @@ const sortConversationTitles = (
|
||||||
) => {
|
) => {
|
||||||
return collator.compare(left.getTitle(), right.getTitle());
|
return collator.compare(left.getTitle(), right.getTitle());
|
||||||
};
|
};
|
||||||
|
|
||||||
// We need a custom collection here to get the sorting we need
|
|
||||||
window.Whisper.GroupConversationCollection = window.Backbone.Collection.extend({
|
|
||||||
model: window.Whisper.GroupMemberConversation,
|
|
||||||
|
|
||||||
initialize() {
|
|
||||||
this.collator = new Intl.Collator(undefined, { sensitivity: 'base' });
|
|
||||||
},
|
|
||||||
|
|
||||||
comparator(left: WhatIsThis, right: WhatIsThis) {
|
|
||||||
if (left.isAdmin && !right.isAdmin) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!left.isAdmin && right.isAdmin) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sortConversationTitles(left, right, this.collator);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
|
@ -17,8 +17,8 @@ type ConfirmationDialogViewProps = {
|
||||||
resolve: () => void;
|
resolve: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
let confirmationDialogViewNode: HTMLElement | null = null;
|
let confirmationDialogViewNode: HTMLElement | undefined;
|
||||||
let confirmationDialogPreviousFocus: HTMLElement | null = null;
|
let confirmationDialogPreviousFocus: HTMLElement | undefined;
|
||||||
|
|
||||||
function removeConfirmationDialog() {
|
function removeConfirmationDialog() {
|
||||||
if (!confirmationDialogViewNode) {
|
if (!confirmationDialogViewNode) {
|
||||||
|
@ -34,7 +34,7 @@ function removeConfirmationDialog() {
|
||||||
) {
|
) {
|
||||||
confirmationDialogPreviousFocus.focus();
|
confirmationDialogPreviousFocus.focus();
|
||||||
}
|
}
|
||||||
confirmationDialogViewNode = null;
|
confirmationDialogViewNode = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function showConfirmationDialog(options: ConfirmationDialogViewProps) {
|
function showConfirmationDialog(options: ConfirmationDialogViewProps) {
|
||||||
|
|
67
ts/shims/showSafetyNumberChangeDialog.tsx
Normal file
67
ts/shims/showSafetyNumberChangeDialog.tsx
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
// This file is here temporarily while we're switching off of Backbone into
|
||||||
|
// React. In the future, and in React-land, please just import and use
|
||||||
|
// the component directly. This is the thin API layer to bridge the gap
|
||||||
|
// while we convert things over. Please delete this file once all usages are
|
||||||
|
// ported over.
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { unmountComponentAtNode, render } from 'react-dom';
|
||||||
|
import { ConversationModel } from '../models/conversations';
|
||||||
|
import { SafetyNumberChangeDialog } from '../components/SafetyNumberChangeDialog';
|
||||||
|
|
||||||
|
export type SafetyNumberChangeViewProps = {
|
||||||
|
confirmText?: string;
|
||||||
|
contacts: Array<ConversationModel>;
|
||||||
|
reject: () => void;
|
||||||
|
resolve: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
let dialogContainerNode: HTMLElement | undefined;
|
||||||
|
|
||||||
|
function removeDialog() {
|
||||||
|
if (!dialogContainerNode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unmountComponentAtNode(dialogContainerNode);
|
||||||
|
document.body.removeChild(dialogContainerNode);
|
||||||
|
|
||||||
|
dialogContainerNode = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function showSafetyNumberChangeDialog(
|
||||||
|
options: SafetyNumberChangeViewProps
|
||||||
|
): void {
|
||||||
|
if (dialogContainerNode) {
|
||||||
|
removeDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogContainerNode = document.createElement('div');
|
||||||
|
document.body.appendChild(dialogContainerNode);
|
||||||
|
|
||||||
|
render(
|
||||||
|
<SafetyNumberChangeDialog
|
||||||
|
confirmText={options.confirmText}
|
||||||
|
contacts={options.contacts.map(contact => contact.format())}
|
||||||
|
i18n={window.i18n}
|
||||||
|
onCancel={() => {
|
||||||
|
options.reject();
|
||||||
|
removeDialog();
|
||||||
|
}}
|
||||||
|
onConfirm={() => {
|
||||||
|
options.resolve();
|
||||||
|
removeDialog();
|
||||||
|
}}
|
||||||
|
renderSafetyNumber={props => {
|
||||||
|
return window.Signal.State.Roots.createSafetyNumberViewer(
|
||||||
|
window.reduxStore,
|
||||||
|
props
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
dialogContainerNode
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,15 +0,0 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import { Provider } from 'react-redux';
|
|
||||||
|
|
||||||
import { Store } from 'redux';
|
|
||||||
|
|
||||||
import { SmartCallManager } from '../smart/CallManager';
|
|
||||||
|
|
||||||
export const createCallManager = (store: Store): React.ReactElement => (
|
|
||||||
<Provider store={store}>
|
|
||||||
<SmartCallManager />
|
|
||||||
</Provider>
|
|
||||||
);
|
|
|
@ -1,17 +0,0 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import { Provider } from 'react-redux';
|
|
||||||
|
|
||||||
import { Store } from 'redux';
|
|
||||||
|
|
||||||
import { SmartGlobalModalContainer } from '../smart/GlobalModalContainer';
|
|
||||||
|
|
||||||
export const createGlobalModalContainer = (
|
|
||||||
store: Store
|
|
||||||
): React.ReactElement => (
|
|
||||||
<Provider store={store}>
|
|
||||||
<SmartGlobalModalContainer />
|
|
||||||
</Provider>
|
|
||||||
);
|
|
|
@ -1,21 +0,0 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import { App } from '../../components/App';
|
|
||||||
import { StateType } from '../reducer';
|
|
||||||
import { getIntl, getTheme } from '../selectors/user';
|
|
||||||
import { mapDispatchToProps } from '../actions';
|
|
||||||
|
|
||||||
const mapStateToProps = (state: StateType) => {
|
|
||||||
return {
|
|
||||||
...state.app,
|
|
||||||
i18n: getIntl(state),
|
|
||||||
theme: getTheme(state),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const smart = connect(mapStateToProps, mapDispatchToProps);
|
|
||||||
|
|
||||||
export const SmartApp = smart(App);
|
|
25
ts/state/smart/App.tsx
Normal file
25
ts/state/smart/App.tsx
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { App, PropsType } from '../../components/App';
|
||||||
|
import { SmartCallManager } from './CallManager';
|
||||||
|
import { SmartGlobalModalContainer } from './GlobalModalContainer';
|
||||||
|
import { StateType } from '../reducer';
|
||||||
|
import { getTheme } from '../selectors/user';
|
||||||
|
import { mapDispatchToProps } from '../actions';
|
||||||
|
|
||||||
|
const mapStateToProps = (state: StateType): PropsType => {
|
||||||
|
return {
|
||||||
|
...state.app,
|
||||||
|
renderCallManager: () => <SmartCallManager />,
|
||||||
|
renderGlobalModalContainer: () => <SmartGlobalModalContainer />,
|
||||||
|
theme: getTheme(state),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const smart = connect(mapStateToProps, mapDispatchToProps);
|
||||||
|
|
||||||
|
export const SmartApp = smart(App);
|
|
@ -252,22 +252,6 @@
|
||||||
"updated": "2020-08-21T11:29:29.636Z",
|
"updated": "2020-08-21T11:29:29.636Z",
|
||||||
"reasonDetail": "Interacting with already-existing DOM nodes"
|
"reasonDetail": "Interacting with already-existing DOM nodes"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"rule": "jQuery-$(",
|
|
||||||
"path": "js/views/banner_view.js",
|
|
||||||
"line": " template: () => $('#banner').html(),",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Static selector, read-only access"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rule": "jQuery-html(",
|
|
||||||
"path": "js/views/banner_view.js",
|
|
||||||
"line": " template: () => $('#banner').html(),",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Static selector, read-only access"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/clear_data_view.js",
|
"path": "js/views/clear_data_view.js",
|
||||||
|
@ -284,30 +268,6 @@
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Static selector, read-only access"
|
"reasonDetail": "Static selector, read-only access"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"rule": "jQuery-$(",
|
|
||||||
"path": "js/views/contact_list_view.js",
|
|
||||||
"line": " template: () => $('#contact').html(),",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Static selector, read-only access"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rule": "jQuery-append(",
|
|
||||||
"path": "js/views/contact_list_view.js",
|
|
||||||
"line": " this.$el.append(this.contactView.el);",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2019-07-31T00:19:18.696Z",
|
|
||||||
"reasonDetail": "Known DOM elements"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rule": "jQuery-html(",
|
|
||||||
"path": "js/views/contact_list_view.js",
|
|
||||||
"line": " template: () => $('#contact').html(),",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Static selector, read-only access"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/debug_log_view.js",
|
"path": "js/views/debug_log_view.js",
|
||||||
|
@ -420,38 +380,6 @@
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Static selector, read-only access"
|
"reasonDetail": "Static selector, read-only access"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"rule": "jQuery-$(",
|
|
||||||
"path": "js/views/group_member_list_view.js",
|
|
||||||
"line": " this.$('.container').append(this.member_list_view.el);",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Static selector, adding sub-view to DOM"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rule": "jQuery-$(",
|
|
||||||
"path": "js/views/group_member_list_view.js",
|
|
||||||
"line": " template: () => $('#group-member-list').html(),",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Static selector, read-only access"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rule": "jQuery-append(",
|
|
||||||
"path": "js/views/group_member_list_view.js",
|
|
||||||
"line": " this.$('.container').append(this.member_list_view.el);",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Static selector, adding sub-view to DOM"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rule": "jQuery-html(",
|
|
||||||
"path": "js/views/group_member_list_view.js",
|
|
||||||
"line": " template: () => $('#group-member-list').html(),",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Static selector, read-only access"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/identicon_svg_view.js",
|
"path": "js/views/identicon_svg_view.js",
|
||||||
|
@ -476,14 +404,6 @@
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Static selector, read-only access"
|
"reasonDetail": "Static selector, read-only access"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"rule": "jQuery-$(",
|
|
||||||
"path": "js/views/inbox_view.js",
|
|
||||||
"line": " this.$('.call-manager-placeholder').append(this.callManagerView.el);",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Adding sub-view to DOM"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/inbox_view.js",
|
"path": "js/views/inbox_view.js",
|
||||||
|
@ -500,14 +420,6 @@
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Providing reference to DOM for sub-view"
|
"reasonDetail": "Providing reference to DOM for sub-view"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"rule": "jQuery-$(",
|
|
||||||
"path": "js/views/inbox_view.js",
|
|
||||||
"line": " this.$('#header, .gutter').addClass('inactive');",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Static selector, adding or removing classes"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/inbox_view.js",
|
"path": "js/views/inbox_view.js",
|
||||||
|
@ -516,22 +428,6 @@
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Static selector, adding or removing classes"
|
"reasonDetail": "Static selector, adding or removing classes"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"rule": "jQuery-$(",
|
|
||||||
"path": "js/views/inbox_view.js",
|
|
||||||
"line": " this.$('.conversation-stack').addClass('inactive');",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Static selector, adding or removing classes"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rule": "jQuery-$(",
|
|
||||||
"path": "js/views/inbox_view.js",
|
|
||||||
"line": " this.$('#header, .gutter').removeClass('inactive');",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Static selector, adding or removing classes"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/inbox_view.js",
|
"path": "js/views/inbox_view.js",
|
||||||
|
@ -583,18 +479,9 @@
|
||||||
{
|
{
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/inbox_view.js",
|
"path": "js/views/inbox_view.js",
|
||||||
"line": " this.$('.conversation:first .menu').trigger('close');",
|
"line": " this.$('#header, .gutter').addClass('inactive');",
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-06-15T23:46:51.629Z"
|
||||||
"reasonDetail": "Static selector, trigging DOM event"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rule": "jQuery-append(",
|
|
||||||
"path": "js/views/inbox_view.js",
|
|
||||||
"line": " this.$('.call-manager-placeholder').append(this.callManagerView.el);",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Adding sub-view to DOM"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"rule": "jQuery-append(",
|
"rule": "jQuery-append(",
|
||||||
|
@ -812,22 +699,6 @@
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Static selector, read-only access"
|
"reasonDetail": "Static selector, read-only access"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"rule": "jQuery-append(",
|
|
||||||
"path": "js/views/list_view.js",
|
|
||||||
"line": " this.$el.append(view.render().el);",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2018-09-19T18:13:29.628Z",
|
|
||||||
"reasonDetail": "Interacting with already-existing DOM nodes"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rule": "jQuery-html(",
|
|
||||||
"path": "js/views/list_view.js",
|
|
||||||
"line": " this.$el.html('');",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2018-09-15T00:38:04.183Z",
|
|
||||||
"reasonDetail": "Hard-coded value"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/phone-input-view.js",
|
"path": "js/views/phone-input-view.js",
|
||||||
|
@ -932,36 +803,6 @@
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
"updated": "2021-02-26T18:44:56.450Z",
|
||||||
"reasonDetail": "Static selector, read-only access"
|
"reasonDetail": "Static selector, read-only access"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"rule": "jQuery-$(",
|
|
||||||
"path": "js/views/safety_number_change_dialog_view.js",
|
|
||||||
"line": " this.$('.safety-number-change-dialog-wrapper').append(dialog.el);",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2020-06-23T06:48:06.829Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rule": "jQuery-$(",
|
|
||||||
"path": "js/views/safety_number_change_dialog_view.js",
|
|
||||||
"line": " template: () => $('#safety-number-change-dialog').html(),",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Static selector, read-only access"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rule": "jQuery-append(",
|
|
||||||
"path": "js/views/safety_number_change_dialog_view.js",
|
|
||||||
"line": " this.$('.safety-number-change-dialog-wrapper').append(dialog.el);",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2020-06-23T06:48:06.829Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rule": "jQuery-html(",
|
|
||||||
"path": "js/views/safety_number_change_dialog_view.js",
|
|
||||||
"line": " template: () => $('#safety-number-change-dialog').html(),",
|
|
||||||
"reasonCategory": "usageTrusted",
|
|
||||||
"updated": "2021-02-26T18:44:56.450Z",
|
|
||||||
"reasonDetail": "Static selector, read-only access"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"rule": "jQuery-$(",
|
"rule": "jQuery-$(",
|
||||||
"path": "js/views/settings_view.js",
|
"path": "js/views/settings_view.js",
|
||||||
|
|
|
@ -21,7 +21,6 @@ import { GroupNameCollisionsWithIdsByTitle } from '../util/groupMemberNameCollis
|
||||||
import {
|
import {
|
||||||
isDirectConversation,
|
isDirectConversation,
|
||||||
isGroupV1,
|
isGroupV1,
|
||||||
isGroupV2,
|
|
||||||
isMe,
|
isMe,
|
||||||
} from '../util/whatTypeOfConversation';
|
} from '../util/whatTypeOfConversation';
|
||||||
import {
|
import {
|
||||||
|
@ -31,6 +30,8 @@ import {
|
||||||
isOutgoing,
|
isOutgoing,
|
||||||
isTapToView,
|
isTapToView,
|
||||||
} from '../state/selectors/message';
|
} from '../state/selectors/message';
|
||||||
|
import { ConversationDetailsMembershipList } from '../components/conversation/conversation-details/ConversationDetailsMembershipList';
|
||||||
|
import { showSafetyNumberChangeDialog } from '../shims/showSafetyNumberChangeDialog';
|
||||||
|
|
||||||
type GetLinkPreviewImageResult = {
|
type GetLinkPreviewImageResult = {
|
||||||
data: ArrayBuffer;
|
data: ArrayBuffer;
|
||||||
|
@ -367,7 +368,6 @@ Whisper.ConversationView = Whisper.View.extend({
|
||||||
|
|
||||||
// Events on Conversation model
|
// Events on Conversation model
|
||||||
this.listenTo(this.model, 'destroy', this.stopListening);
|
this.listenTo(this.model, 'destroy', this.stopListening);
|
||||||
this.listenTo(this.model, 'change:verified', this.onVerifiedChange);
|
|
||||||
this.listenTo(this.model, 'newmessage', this.lazyUpdateVerified);
|
this.listenTo(this.model, 'newmessage', this.lazyUpdateVerified);
|
||||||
|
|
||||||
// These are triggered by InboxView
|
// These are triggered by InboxView
|
||||||
|
@ -573,8 +573,8 @@ Whisper.ConversationView = Whisper.View.extend({
|
||||||
onShowAllMedia: () => {
|
onShowAllMedia: () => {
|
||||||
this.showAllMedia();
|
this.showAllMedia();
|
||||||
},
|
},
|
||||||
onShowGroupMembers: async () => {
|
onShowGroupMembers: () => {
|
||||||
await this.showMembers();
|
this.showGV1Members();
|
||||||
},
|
},
|
||||||
onGoBack: () => {
|
onGoBack: () => {
|
||||||
this.resetPanel();
|
this.resetPanel();
|
||||||
|
@ -1446,9 +1446,6 @@ Whisper.ConversationView = Whisper.View.extend({
|
||||||
if (this.captureAudioView) {
|
if (this.captureAudioView) {
|
||||||
this.captureAudioView.remove();
|
this.captureAudioView.remove();
|
||||||
}
|
}
|
||||||
if (this.banner) {
|
|
||||||
this.banner.remove();
|
|
||||||
}
|
|
||||||
if (this.lastSeenIndicator) {
|
if (this.lastSeenIndicator) {
|
||||||
this.lastSeenIndicator.remove();
|
this.lastSeenIndicator.remove();
|
||||||
}
|
}
|
||||||
|
@ -2132,55 +2129,6 @@ Whisper.ConversationView = Whisper.View.extend({
|
||||||
return Promise.all(untrusted.map((contact: any) => contact.setApproved()));
|
return Promise.all(untrusted.map((contact: any) => contact.setApproved()));
|
||||||
},
|
},
|
||||||
|
|
||||||
openSafetyNumberScreens(unverified: any) {
|
|
||||||
if (unverified.length === 1) {
|
|
||||||
this.showSafetyNumber(unverified.at(0).id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.showMembers(null, unverified, { needVerify: true });
|
|
||||||
},
|
|
||||||
|
|
||||||
onVerifiedChange() {
|
|
||||||
const { model }: { model: ConversationModel } = this;
|
|
||||||
if (model.isUnverified()) {
|
|
||||||
const unverified = model.getUnverified();
|
|
||||||
let message;
|
|
||||||
if (!unverified.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (unverified.length > 1) {
|
|
||||||
message = window.i18n('multipleNoLongerVerified');
|
|
||||||
} else {
|
|
||||||
message = window.i18n('noLongerVerified', [
|
|
||||||
unverified.at(0).getTitle(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Need to re-add, since unverified set may have changed
|
|
||||||
if (this.banner) {
|
|
||||||
this.banner.remove();
|
|
||||||
this.banner = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.banner = new Whisper.BannerView({
|
|
||||||
message,
|
|
||||||
onDismiss: () => {
|
|
||||||
this.markAllAsVerifiedDefault(unverified);
|
|
||||||
},
|
|
||||||
onClick: () => {
|
|
||||||
this.openSafetyNumberScreens(unverified);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const container = this.$('.discussion-container');
|
|
||||||
container.append(this.banner.el);
|
|
||||||
} else if (this.banner) {
|
|
||||||
this.banner.remove();
|
|
||||||
this.banner = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleMicrophone() {
|
toggleMicrophone() {
|
||||||
this.compositionApi.current.setShowMic(!this.hasFiles());
|
this.compositionApi.current.setShowMic(!this.hasFiles());
|
||||||
},
|
},
|
||||||
|
@ -2314,7 +2262,6 @@ Whisper.ConversationView = Whisper.View.extend({
|
||||||
this.statusFetch = statusPromise.then(() =>
|
this.statusFetch = statusPromise.then(() =>
|
||||||
// eslint-disable-next-line more/no-then
|
// eslint-disable-next-line more/no-then
|
||||||
model.updateVerified().then(() => {
|
model.updateVerified().then(() => {
|
||||||
this.onVerifiedChange();
|
|
||||||
this.statusFetch = null;
|
this.statusFetch = null;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -2736,35 +2683,32 @@ Whisper.ConversationView = Whisper.View.extend({
|
||||||
this.compositionApi.current.resetEmojiResults(false);
|
this.compositionApi.current.resetEmojiResults(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
async showMembers(
|
showGV1Members() {
|
||||||
_e: unknown,
|
|
||||||
providedMembers: void | Backbone.Collection<ConversationModel>,
|
|
||||||
options: any = {}
|
|
||||||
) {
|
|
||||||
const { model }: { model: ConversationModel } = this;
|
const { model }: { model: ConversationModel } = this;
|
||||||
window._.defaults(options, { needVerify: false });
|
const { contactCollection } = model;
|
||||||
|
|
||||||
let contactCollection = providedMembers || model.contactCollection;
|
const memberships =
|
||||||
|
contactCollection?.map((conversation: ConversationModel) => {
|
||||||
|
return {
|
||||||
|
isAdmin: false,
|
||||||
|
member: conversation.format(),
|
||||||
|
};
|
||||||
|
}) || [];
|
||||||
|
|
||||||
if (!providedMembers && isGroupV2(model.attributes)) {
|
const view = new Whisper.ReactWrapperView({
|
||||||
contactCollection = new Whisper.GroupConversationCollection(
|
className: 'group-member-list panel',
|
||||||
this.model.get('membersV2').map(({ conversationId, role }: any) => ({
|
Component: ConversationDetailsMembershipList,
|
||||||
conversation: window.ConversationController.get(conversationId),
|
props: {
|
||||||
isAdmin:
|
canAddNewMembers: false,
|
||||||
role === window.textsecure.protobuf.Member.Role.ADMINISTRATOR,
|
i18n: window.i18n,
|
||||||
}))
|
maxShownMemberCount: 32,
|
||||||
);
|
memberships,
|
||||||
}
|
showContactModal: this.showContactModal.bind(this),
|
||||||
|
},
|
||||||
const view = new Whisper.GroupMemberList({
|
|
||||||
model: contactCollection,
|
|
||||||
// we pass this in to allow nested panels
|
|
||||||
listenBack: this.listenBack.bind(this),
|
|
||||||
needVerify: options.needVerify,
|
|
||||||
conversation: model,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.listenBack(view);
|
this.listenBack(view);
|
||||||
|
view.render();
|
||||||
},
|
},
|
||||||
|
|
||||||
forceSend({
|
forceSend({
|
||||||
|
@ -3695,7 +3639,7 @@ Whisper.ConversationView = Whisper.View.extend({
|
||||||
confirmText?: string
|
confirmText?: string
|
||||||
) {
|
) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const dialog = new Whisper.SafetyNumberChangeDialogView({
|
showSafetyNumberChangeDialog({
|
||||||
confirmText,
|
confirmText,
|
||||||
contacts,
|
contacts,
|
||||||
reject: () => {
|
reject: () => {
|
||||||
|
@ -3705,8 +3649,6 @@ Whisper.ConversationView = Whisper.View.extend({
|
||||||
resolve(true);
|
resolve(true);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$el.prepend(dialog.el);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
5
ts/window.d.ts
vendored
5
ts/window.d.ts
vendored
|
@ -48,14 +48,12 @@ import { ConversationController } from './ConversationController';
|
||||||
import { ReduxActions } from './state/types';
|
import { ReduxActions } from './state/types';
|
||||||
import { createStore } from './state/createStore';
|
import { createStore } from './state/createStore';
|
||||||
import { createApp } from './state/roots/createApp';
|
import { createApp } from './state/roots/createApp';
|
||||||
import { createCallManager } from './state/roots/createCallManager';
|
|
||||||
import { createChatColorPicker } from './state/roots/createChatColorPicker';
|
import { createChatColorPicker } from './state/roots/createChatColorPicker';
|
||||||
import { createCompositionArea } from './state/roots/createCompositionArea';
|
import { createCompositionArea } from './state/roots/createCompositionArea';
|
||||||
import { createContactModal } from './state/roots/createContactModal';
|
import { createContactModal } from './state/roots/createContactModal';
|
||||||
import { createConversationDetails } from './state/roots/createConversationDetails';
|
import { createConversationDetails } from './state/roots/createConversationDetails';
|
||||||
import { createConversationHeader } from './state/roots/createConversationHeader';
|
import { createConversationHeader } from './state/roots/createConversationHeader';
|
||||||
import { createForwardMessageModal } from './state/roots/createForwardMessageModal';
|
import { createForwardMessageModal } from './state/roots/createForwardMessageModal';
|
||||||
import { createGlobalModalContainer } from './state/roots/createGlobalModalContainer';
|
|
||||||
import { createGroupLinkManagement } from './state/roots/createGroupLinkManagement';
|
import { createGroupLinkManagement } from './state/roots/createGroupLinkManagement';
|
||||||
import { createGroupV1MigrationModal } from './state/roots/createGroupV1MigrationModal';
|
import { createGroupV1MigrationModal } from './state/roots/createGroupV1MigrationModal';
|
||||||
import { createGroupV2JoinModal } from './state/roots/createGroupV2JoinModal';
|
import { createGroupV2JoinModal } from './state/roots/createGroupV2JoinModal';
|
||||||
|
@ -480,14 +478,12 @@ declare global {
|
||||||
createStore: typeof createStore;
|
createStore: typeof createStore;
|
||||||
Roots: {
|
Roots: {
|
||||||
createApp: typeof createApp;
|
createApp: typeof createApp;
|
||||||
createCallManager: typeof createCallManager;
|
|
||||||
createChatColorPicker: typeof createChatColorPicker;
|
createChatColorPicker: typeof createChatColorPicker;
|
||||||
createCompositionArea: typeof createCompositionArea;
|
createCompositionArea: typeof createCompositionArea;
|
||||||
createContactModal: typeof createContactModal;
|
createContactModal: typeof createContactModal;
|
||||||
createConversationDetails: typeof createConversationDetails;
|
createConversationDetails: typeof createConversationDetails;
|
||||||
createConversationHeader: typeof createConversationHeader;
|
createConversationHeader: typeof createConversationHeader;
|
||||||
createForwardMessageModal: typeof createForwardMessageModal;
|
createForwardMessageModal: typeof createForwardMessageModal;
|
||||||
createGlobalModalContainer: typeof createGlobalModalContainer;
|
|
||||||
createGroupLinkManagement: typeof createGroupLinkManagement;
|
createGroupLinkManagement: typeof createGroupLinkManagement;
|
||||||
createGroupV1MigrationModal: typeof createGroupV1MigrationModal;
|
createGroupV1MigrationModal: typeof createGroupV1MigrationModal;
|
||||||
createGroupV2JoinModal: typeof createGroupV2JoinModal;
|
createGroupV2JoinModal: typeof createGroupV2JoinModal;
|
||||||
|
@ -658,7 +654,6 @@ export type WhisperType = {
|
||||||
reject: Function
|
reject: Function
|
||||||
) => void;
|
) => void;
|
||||||
};
|
};
|
||||||
GroupConversationCollection: typeof ConversationModelCollectionType;
|
|
||||||
ConversationCollection: typeof ConversationModelCollectionType;
|
ConversationCollection: typeof ConversationModelCollectionType;
|
||||||
ConversationCollectionType: ConversationModelCollectionType;
|
ConversationCollectionType: ConversationModelCollectionType;
|
||||||
Conversation: typeof ConversationModel;
|
Conversation: typeof ConversationModel;
|
||||||
|
|
Loading…
Add table
Reference in a new issue