Move confirmation_dialog_view to ts and React
* Moves confirmation_dialog_view to ts and React * showConfirmationDialog API
This commit is contained in:
parent
031a1fcc3d
commit
2529e208c1
16 changed files with 154 additions and 254 deletions
|
@ -114,18 +114,6 @@
|
|||
<button class='finish' tabIndex='1'><span class='icon'></span></button>
|
||||
</script>
|
||||
|
||||
<script type='text/x-tmpl-mustache' id='confirmation-dialog'>
|
||||
<div class="content">
|
||||
<div class='message'>{{ message }}</div>
|
||||
<div class='buttons'>
|
||||
<button class='ok' tabindex='2'>{{ ok }}</button>
|
||||
{{ #showCancel }}
|
||||
<button class='cancel' tabindex='1'>{{ cancel }}</button>
|
||||
{{ /showCancel }}
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type='text/x-tmpl-mustache' id='safety-number-change-dialog'>
|
||||
<div class='safety-number-change-dialog-wrapper'></div>
|
||||
</script>
|
||||
|
@ -361,7 +349,7 @@
|
|||
<script type='text/javascript' src='js/views/recorder_view.js'></script>
|
||||
<script type='text/javascript' src='ts/views/conversation_view.js'></script>
|
||||
<script type='text/javascript' src='js/views/inbox_view.js'></script>
|
||||
<script type='text/javascript' src='js/views/confirmation_dialog_view.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/install_view.js'></script>
|
||||
<script type='text/javascript' src='js/views/banner_view.js'></script>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2018-2020 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
/* global $, Whisper, i18n */
|
||||
/* global $, i18n */
|
||||
|
||||
$(document).on('keydown', e => {
|
||||
if (e.keyCode === 27) {
|
||||
|
@ -35,7 +35,8 @@ if (window.forCalling) {
|
|||
message = i18n('audioPermissionNeeded');
|
||||
}
|
||||
|
||||
window.view = new Whisper.ConfirmationDialogView({
|
||||
window.showConfirmationDialog({
|
||||
confirmStyle: 'affirmative',
|
||||
message,
|
||||
okText: i18n('allowAccess'),
|
||||
resolve: () => {
|
||||
|
@ -48,5 +49,3 @@ window.view = new Whisper.ConfirmationDialogView({
|
|||
},
|
||||
reject: window.closePermissionsPopup,
|
||||
});
|
||||
|
||||
window.view.$el.appendTo($body);
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
// Copyright 2015-2020 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
/* global Backbone, Whisper, i18n */
|
||||
|
||||
// eslint-disable-next-line func-names
|
||||
(function () {
|
||||
window.Whisper = window.Whisper || {};
|
||||
|
||||
Whisper.ConfirmationDialogView = Whisper.View.extend({
|
||||
className: 'confirmation-dialog modal',
|
||||
templateName: 'confirmation-dialog',
|
||||
initialize(options) {
|
||||
this.previousFocus = document.activeElement;
|
||||
|
||||
this.message = options.message;
|
||||
this.hideCancel = options.hideCancel;
|
||||
|
||||
this.resolve = options.resolve;
|
||||
this.okText = options.okText || i18n('ok');
|
||||
|
||||
this.reject = options.reject;
|
||||
this.cancelText = options.cancelText || i18n('cancel');
|
||||
|
||||
if (Whisper.activeConfirmationView) {
|
||||
Whisper.activeConfirmationView.remove();
|
||||
Whisper.activeConfirmationView = null;
|
||||
}
|
||||
|
||||
Whisper.activeConfirmationView = this;
|
||||
|
||||
this.render();
|
||||
},
|
||||
events: {
|
||||
keydown: 'onKeydown',
|
||||
'click .ok': 'ok',
|
||||
'click .cancel': 'cancel',
|
||||
},
|
||||
remove() {
|
||||
if (this.previousFocus && this.previousFocus.focus) {
|
||||
this.previousFocus.focus();
|
||||
}
|
||||
Backbone.View.prototype.remove.call(this);
|
||||
},
|
||||
render_attributes() {
|
||||
return {
|
||||
message: this.message,
|
||||
showCancel: !this.hideCancel,
|
||||
cancel: this.cancelText,
|
||||
ok: this.okText,
|
||||
};
|
||||
},
|
||||
ok() {
|
||||
this.remove();
|
||||
if (this.resolve) {
|
||||
this.resolve();
|
||||
}
|
||||
},
|
||||
cancel() {
|
||||
this.remove();
|
||||
if (this.reject) {
|
||||
this.reject(new Error('User clicked cancel button'));
|
||||
}
|
||||
},
|
||||
onKeydown(event) {
|
||||
if (event.key === 'Escape' || event.key === 'Esc') {
|
||||
this.cancel();
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
},
|
||||
focusCancel() {
|
||||
// We delay this call because we might be called inside click handlers
|
||||
// which would set focus to themselves afterwards!
|
||||
setTimeout(() => this.$('.cancel').focus(), 1);
|
||||
},
|
||||
});
|
||||
})();
|
|
@ -54,14 +54,12 @@
|
|||
},
|
||||
confirm(message, okText) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const dialog = new Whisper.ConfirmationDialogView({
|
||||
window.showConfirmationDialog({
|
||||
message,
|
||||
okText,
|
||||
resolve,
|
||||
reject,
|
||||
});
|
||||
this.$el.append(dialog.el);
|
||||
dialog.focusCancel();
|
||||
});
|
||||
},
|
||||
},
|
||||
|
|
|
@ -23,20 +23,9 @@
|
|||
</head>
|
||||
<body class='permissions-popup'>
|
||||
</body>
|
||||
<script type='text/x-tmpl-mustache' id='confirmation-dialog'>
|
||||
<div class="content">
|
||||
<div class='message'>{{ message }}</div>
|
||||
<div class='buttons'>
|
||||
{{ #showCancel }}
|
||||
<button class='cancel' tabindex='2'>{{ cancel }}</button>
|
||||
{{ /showCancel }}
|
||||
<button class='ok' tabindex='1'>{{ ok }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<script type='text/javascript' src='js/components.js'></script>
|
||||
<script type='text/javascript' src='ts/backboneJquery.js'></script>
|
||||
<script type='text/javascript' src='js/views/whisper_view.js'></script>
|
||||
<script type='text/javascript' src='js/views/confirmation_dialog_view.js'></script>
|
||||
<script type='text/javascript' src='ts/shims/showConfirmationDialog.js'></script>
|
||||
<script type='text/javascript' src='js/permissions_popup_start.js'></script>
|
||||
</html>
|
||||
|
|
|
@ -3,9 +3,13 @@
|
|||
|
||||
/* global window */
|
||||
|
||||
window.React = require('react');
|
||||
window.ReactDOM = require('react-dom');
|
||||
|
||||
const { ipcRenderer, remote } = require('electron');
|
||||
const url = require('url');
|
||||
const i18n = require('./js/modules/i18n');
|
||||
const { ConfirmationModal } = require('./ts/components/ConfirmationModal');
|
||||
const { makeGetter, makeSetter } = require('./preload_utils');
|
||||
|
||||
const { nativeTheme } = remote.require('electron');
|
||||
|
@ -20,6 +24,11 @@ window.theme = config.theme;
|
|||
window.i18n = i18n.setup(locale, localeMessages);
|
||||
window.forCalling = config.forCalling === 'true';
|
||||
window.forCamera = config.forCamera === 'true';
|
||||
window.Signal = {
|
||||
Components: {
|
||||
ConfirmationModal,
|
||||
},
|
||||
};
|
||||
|
||||
function setSystemTheme() {
|
||||
window.systemTheme = nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
|
||||
|
|
|
@ -292,79 +292,10 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.confirmation-dialog {
|
||||
.content {
|
||||
max-width: 350px;
|
||||
margin: 100px auto;
|
||||
padding: 1em;
|
||||
|
||||
border-radius: 5px;
|
||||
overflow: auto;
|
||||
|
||||
@include light-theme {
|
||||
background: $color-white;
|
||||
box-shadow: 0px 0px 15px 0px $color-black-alpha-20;
|
||||
}
|
||||
@include dark-theme {
|
||||
background: $color-black;
|
||||
color: $color-gray-02;
|
||||
box-shadow: 0px 0px 15px 0px $color-white-alpha-20;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
margin-top: 10px;
|
||||
|
||||
button {
|
||||
float: right;
|
||||
margin-left: 10px;
|
||||
padding: 5px 8px;
|
||||
border-radius: 5px;
|
||||
|
||||
outline: none;
|
||||
@include keyboard-mode {
|
||||
&:focus {
|
||||
outline: -webkit-focus-ring-color auto 5px;
|
||||
}
|
||||
}
|
||||
|
||||
@include light-theme {
|
||||
background-color: $color-gray-02;
|
||||
border: 1px solid $color-gray-15;
|
||||
}
|
||||
@include dark-theme {
|
||||
background-color: $color-gray-90;
|
||||
border: 1px solid $color-gray-45;
|
||||
color: $color-gray-02;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@include light-theme {
|
||||
background-color: $color-gray-15;
|
||||
border-color: $color-gray-25;
|
||||
}
|
||||
@include dark-theme {
|
||||
background-color: $color-gray-75;
|
||||
border-color: $color-gray-45;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.permissions-popup,
|
||||
.debug-log-window {
|
||||
.modal {
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.confirmation-dialog .content {
|
||||
box-shadow: 0px 0px 0px 0px;
|
||||
max-width: 1000px;
|
||||
margin: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8308,7 +8308,8 @@ button.module-image__border-overlay:focus {
|
|||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 5;
|
||||
// THIS Z-INDEX IS OVER NINE THOUSAND. OVER NINE THOUSAND?! THAT CAN'T BE!
|
||||
z-index: 9001;
|
||||
}
|
||||
|
||||
&__container {
|
||||
|
|
|
@ -125,16 +125,8 @@
|
|||
<button class='close'><span class='icon'></span></button>
|
||||
</script>
|
||||
|
||||
<script type='text/x-tmpl-mustache' id='confirmation-dialog'>
|
||||
<div class="content">
|
||||
<div class='message'>{{ message }}</div>
|
||||
<div class='buttons'>
|
||||
{{ #showCancel }}
|
||||
<button class='cancel' tabindex='2'>{{ cancel }}</button>
|
||||
{{ /showCancel }}
|
||||
<button class='ok' tabindex='1'>{{ ok }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<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'>
|
||||
|
|
|
@ -241,15 +241,14 @@ type WhatIsThis = import('./window.d').WhatIsThis;
|
|||
|
||||
try {
|
||||
await new Promise((resolve, reject) => {
|
||||
const dialog = new window.Whisper.ConfirmationDialogView({
|
||||
window.showConfirmationDialog({
|
||||
cancelText: window.i18n('quit'),
|
||||
confirmStyle: 'negative',
|
||||
message: window.i18n('deleteOldIndexedDBData'),
|
||||
okText: window.i18n('deleteOldData'),
|
||||
cancelText: window.i18n('quit'),
|
||||
resolve,
|
||||
reject,
|
||||
reject: () => reject(),
|
||||
resolve: () => resolve(),
|
||||
});
|
||||
document.body.append(dialog.el);
|
||||
dialog.focusCancel();
|
||||
});
|
||||
} catch (error) {
|
||||
window.log.info(
|
||||
|
|
|
@ -12,9 +12,8 @@ import enMessages from '../../_locales/en/messages.json';
|
|||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
||||
storiesOf('Components/ConfirmationDialog', module).add(
|
||||
'ConfirmationDialog',
|
||||
() => {
|
||||
storiesOf('Components/ConfirmationDialog', module)
|
||||
.add('ConfirmationDialog', () => {
|
||||
return (
|
||||
<ConfirmationDialog
|
||||
i18n={i18n}
|
||||
|
@ -36,5 +35,23 @@ storiesOf('Components/ConfirmationDialog', module).add(
|
|||
{text('Child text', 'asdf blip')}
|
||||
</ConfirmationDialog>
|
||||
);
|
||||
}
|
||||
);
|
||||
})
|
||||
.add('Custom cancel text', () => {
|
||||
return (
|
||||
<ConfirmationDialog
|
||||
cancelText="Nah"
|
||||
i18n={i18n}
|
||||
onClose={action('onClose')}
|
||||
title={text('Title', 'Foo bar banana baz?')}
|
||||
actions={[
|
||||
{
|
||||
text: 'Maybe',
|
||||
style: 'affirmative',
|
||||
action: action('affirmative'),
|
||||
},
|
||||
]}
|
||||
>
|
||||
{text('Child text', 'asdf blip')}
|
||||
</ConfirmationDialog>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -12,11 +12,12 @@ export type ActionSpec = {
|
|||
};
|
||||
|
||||
export type OwnProps = {
|
||||
readonly i18n: LocalizerType;
|
||||
readonly children: React.ReactNode;
|
||||
readonly title?: string | React.ReactNode;
|
||||
readonly actions: Array<ActionSpec>;
|
||||
readonly cancelText?: string;
|
||||
readonly children?: React.ReactNode;
|
||||
readonly i18n: LocalizerType;
|
||||
readonly onClose: () => unknown;
|
||||
readonly title?: string | React.ReactNode;
|
||||
};
|
||||
|
||||
export type Props = OwnProps;
|
||||
|
@ -28,7 +29,7 @@ function focusRef(el: HTMLElement | null) {
|
|||
}
|
||||
|
||||
export const ConfirmationDialog = React.memo(
|
||||
({ i18n, onClose, children, title, actions }: Props) => {
|
||||
({ i18n, onClose, cancelText, children, title, actions }: Props) => {
|
||||
React.useEffect(() => {
|
||||
const handler = ({ key }: KeyboardEvent) => {
|
||||
if (key === 'Escape') {
|
||||
|
@ -81,7 +82,7 @@ export const ConfirmationDialog = React.memo(
|
|||
ref={focusRef}
|
||||
className="module-confirmation-dialog__container__buttons__button"
|
||||
>
|
||||
{i18n('confirmation-dialog--Cancel')}
|
||||
{cancelText || i18n('confirmation-dialog--Cancel')}
|
||||
</button>
|
||||
{actions.map((action, i) => (
|
||||
<button
|
||||
|
|
77
ts/shims/showConfirmationDialog.tsx
Normal file
77
ts/shims/showConfirmationDialog.tsx
Normal file
|
@ -0,0 +1,77 @@
|
|||
// Copyright 2015-2020 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
|
||||
// ConfirmationModal 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. Note: this file cannot have any imports/exports since it is
|
||||
// being included in a <script /> tag.
|
||||
|
||||
type ConfirmationDialogViewProps = {
|
||||
cancelText?: string;
|
||||
confirmStyle?: 'affirmative' | 'negative';
|
||||
message: string;
|
||||
okText: string;
|
||||
reject?: () => void;
|
||||
resolve: () => void;
|
||||
};
|
||||
|
||||
let confirmationDialogViewNode: HTMLElement | null = null;
|
||||
let confirmationDialogPreviousFocus: HTMLElement | null = null;
|
||||
|
||||
function removeConfirmationDialog() {
|
||||
if (!confirmationDialogViewNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.ReactDOM.unmountComponentAtNode(confirmationDialogViewNode);
|
||||
document.body.removeChild(confirmationDialogViewNode);
|
||||
|
||||
if (
|
||||
confirmationDialogPreviousFocus &&
|
||||
typeof confirmationDialogPreviousFocus.focus === 'function'
|
||||
) {
|
||||
confirmationDialogPreviousFocus.focus();
|
||||
}
|
||||
confirmationDialogViewNode = null;
|
||||
}
|
||||
|
||||
function showConfirmationDialog(options: ConfirmationDialogViewProps) {
|
||||
if (confirmationDialogViewNode) {
|
||||
removeConfirmationDialog();
|
||||
}
|
||||
|
||||
confirmationDialogViewNode = document.createElement('div');
|
||||
document.body.appendChild(confirmationDialogViewNode);
|
||||
|
||||
confirmationDialogPreviousFocus = document.activeElement as HTMLElement;
|
||||
|
||||
window.ReactDOM.render(
|
||||
// eslint-disable-next-line react/react-in-jsx-scope, react/jsx-no-undef
|
||||
<window.Signal.Components.ConfirmationModal
|
||||
actions={[
|
||||
{
|
||||
action: () => {
|
||||
removeConfirmationDialog();
|
||||
options.resolve();
|
||||
},
|
||||
style: options.confirmStyle,
|
||||
text: options.okText || window.i18n('ok'),
|
||||
},
|
||||
]}
|
||||
cancelText={options.cancelText || window.i18n('cancel')}
|
||||
i18n={window.i18n}
|
||||
onClose={() => {
|
||||
removeConfirmationDialog();
|
||||
if (options.reject) {
|
||||
options.reject();
|
||||
}
|
||||
}}
|
||||
title={options.message}
|
||||
/>,
|
||||
confirmationDialogViewNode
|
||||
);
|
||||
}
|
||||
|
||||
window.showConfirmationDialog = showConfirmationDialog;
|
|
@ -286,15 +286,6 @@
|
|||
"updated": "2018-09-19T21:59:32.770Z",
|
||||
"reasonDetail": "Protected from arbitrary input"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-appendTo(",
|
||||
"path": "js/permissions_popup_start.js",
|
||||
"line": "window.view.$el.appendTo($body);",
|
||||
"lineNumber": 52,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-06-02T21:51:34.813Z",
|
||||
"reasonDetail": "Interacting with already-existing DOM nodes"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "js/settings_start.js",
|
||||
|
@ -357,15 +348,6 @@
|
|||
"updated": "2018-09-19T18:13:29.628Z",
|
||||
"reasonDetail": "Interacting with already-existing DOM nodes"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "js/views/confirmation_dialog_view.js",
|
||||
"line": " setTimeout(() => this.$('.cancel').focus(), 1);",
|
||||
"lineNumber": 76,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2019-12-07T02:04:56.987Z",
|
||||
"reasonDetail": "Protected from arbitrary input"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-append(",
|
||||
"path": "js/views/contact_list_view.js",
|
||||
|
@ -1359,20 +1341,11 @@
|
|||
"updated": "2018-09-15T00:38:04.183Z",
|
||||
"reasonDetail": "Value set came directly from Mustache tempating engine"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-append(",
|
||||
"path": "js/views/whisper_view.js",
|
||||
"line": " this.$el.append(dialog.el);",
|
||||
"lineNumber": 63,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2018-09-19T18:13:29.628Z",
|
||||
"reasonDetail": "Interacting with already-existing DOM nodes"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "js/views/whisper_view.js",
|
||||
"line": " $('script[type=\"text/x-tmpl-mustache\"]').each((i, el) => {",
|
||||
"lineNumber": 72,
|
||||
"lineNumber": 70,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2018-09-19T21:59:32.770Z",
|
||||
"reasonDetail": "Protected from arbitrary input"
|
||||
|
@ -1381,7 +1354,7 @@
|
|||
"rule": "jQuery-$(",
|
||||
"path": "js/views/whisper_view.js",
|
||||
"line": " const $el = $(el);",
|
||||
"lineNumber": 73,
|
||||
"lineNumber": 71,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2018-09-19T21:59:32.770Z",
|
||||
"reasonDetail": "Protected from arbitrary input"
|
||||
|
@ -1390,7 +1363,7 @@
|
|||
"rule": "jQuery-html(",
|
||||
"path": "js/views/whisper_view.js",
|
||||
"line": " templates[id] = $el.html();",
|
||||
"lineNumber": 75,
|
||||
"lineNumber": 73,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2018-09-15T00:38:04.183Z",
|
||||
"reasonDetail": "Getting the value, not setting it"
|
||||
|
|
|
@ -2034,7 +2034,8 @@ Whisper.ConversationView = Whisper.View.extend({
|
|||
this.$('.microphone').hide();
|
||||
},
|
||||
handleAudioConfirm(blob: any, lostFocus: any) {
|
||||
const dialog = new Whisper.ConfirmationDialogView({
|
||||
window.showConfirmationDialog({
|
||||
confirmStyle: 'negative',
|
||||
cancelText: window.i18n('discard'),
|
||||
message: lostFocus
|
||||
? window.i18n('voiceRecordingInterruptedBlur')
|
||||
|
@ -2044,9 +2045,6 @@ Whisper.ConversationView = Whisper.View.extend({
|
|||
await this.handleAudioCapture(blob);
|
||||
},
|
||||
});
|
||||
|
||||
this.$el.prepend(dialog.el);
|
||||
dialog.focusCancel();
|
||||
},
|
||||
async handleAudioCapture(blob: any) {
|
||||
if (this.hasFiles()) {
|
||||
|
@ -2346,7 +2344,8 @@ Whisper.ConversationView = Whisper.View.extend({
|
|||
throw new Error(`forceSend: Did not find message for id ${messageId}`);
|
||||
}
|
||||
|
||||
const dialog = new Whisper.ConfirmationDialogView({
|
||||
window.showConfirmationDialog({
|
||||
confirmStyle: 'negative',
|
||||
message: window.i18n('identityKeyErrorOnSend', {
|
||||
name1: contact.getTitle(),
|
||||
name2: contact.getTitle(),
|
||||
|
@ -2367,9 +2366,6 @@ Whisper.ConversationView = Whisper.View.extend({
|
|||
message.resend(contact.getSendTarget());
|
||||
},
|
||||
});
|
||||
|
||||
this.$el.prepend(dialog.el);
|
||||
dialog.focusCancel();
|
||||
},
|
||||
|
||||
showSafetyNumber(id: any) {
|
||||
|
@ -2513,7 +2509,8 @@ Whisper.ConversationView = Whisper.View.extend({
|
|||
);
|
||||
}
|
||||
|
||||
const dialog = new Whisper.ConfirmationDialogView({
|
||||
window.showConfirmationDialog({
|
||||
confirmStyle: 'negative',
|
||||
message: window.i18n('deleteWarning'),
|
||||
okText: window.i18n('delete'),
|
||||
resolve: () => {
|
||||
|
@ -2530,9 +2527,6 @@ Whisper.ConversationView = Whisper.View.extend({
|
|||
this.resetPanel();
|
||||
},
|
||||
});
|
||||
|
||||
this.$el.prepend(dialog.el);
|
||||
dialog.focusCancel();
|
||||
},
|
||||
|
||||
deleteMessageForEveryone(messageId: string) {
|
||||
|
@ -2543,7 +2537,8 @@ Whisper.ConversationView = Whisper.View.extend({
|
|||
);
|
||||
}
|
||||
|
||||
const dialog = new Whisper.ConfirmationDialogView({
|
||||
window.showConfirmationDialog({
|
||||
confirmStyle: 'negative',
|
||||
message: window.i18n('deleteForEveryoneWarning'),
|
||||
okText: window.i18n('delete'),
|
||||
resolve: async () => {
|
||||
|
@ -2551,9 +2546,6 @@ Whisper.ConversationView = Whisper.View.extend({
|
|||
this.resetPanel();
|
||||
},
|
||||
});
|
||||
|
||||
this.$el.prepend(dialog.el);
|
||||
dialog.focusCancel();
|
||||
},
|
||||
|
||||
showStickerPackPreview(packId: any, packKey: any) {
|
||||
|
|
15
ts/window.d.ts
vendored
15
ts/window.d.ts
vendored
|
@ -64,6 +64,7 @@ import { MessageModel } from './models/messages';
|
|||
import { ConversationModel } from './models/conversations';
|
||||
import { combineNames } from './util';
|
||||
import { BatcherType } from './util/batcher';
|
||||
import { ConfirmationModal } from './components/ConfirmationModal';
|
||||
import { ErrorModal } from './components/ErrorModal';
|
||||
import { ProgressModal } from './components/ProgressModal';
|
||||
import { ContactModal } from './components/conversation/ContactModal';
|
||||
|
@ -74,6 +75,17 @@ type TaskResultType = any;
|
|||
|
||||
export type WhatIsThis = any;
|
||||
|
||||
// Synced with the type in ts/shims/showConfirmationDialog
|
||||
// we are duplicating it here because that file cannot import/export.
|
||||
type ConfirmationDialogViewProps = {
|
||||
cancelText?: string;
|
||||
confirmStyle?: 'affirmative' | 'negative';
|
||||
message: string;
|
||||
okText: string;
|
||||
reject?: () => void;
|
||||
resolve: () => void;
|
||||
};
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
_: typeof Underscore;
|
||||
|
@ -160,6 +172,7 @@ declare global {
|
|||
setAutoHideMenuBar: (value: WhatIsThis) => void;
|
||||
setBadgeCount: (count: number) => void;
|
||||
setMenuBarVisibility: (value: WhatIsThis) => void;
|
||||
showConfirmationDialog: (options: ConfirmationDialogViewProps) => void;
|
||||
showKeyboardShortcuts: () => void;
|
||||
storage: {
|
||||
addBlockedGroup: (group: string) => void;
|
||||
|
@ -397,6 +410,7 @@ declare global {
|
|||
Components: {
|
||||
AttachmentList: any;
|
||||
CaptionEditor: any;
|
||||
ConfirmationModal: typeof ConfirmationModal;
|
||||
ContactDetail: any;
|
||||
ErrorModal: typeof ErrorModal;
|
||||
ContactModal: typeof ContactModal;
|
||||
|
@ -600,7 +614,6 @@ export type WhisperType = {
|
|||
MessageType: MessageModel;
|
||||
GroupMemberConversation: WhatIsThis;
|
||||
KeyChangeListener: WhatIsThis;
|
||||
ConfirmationDialogView: WhatIsThis;
|
||||
ClearDataView: WhatIsThis;
|
||||
ReactWrapperView: WhatIsThis;
|
||||
activeConfirmationView: WhatIsThis;
|
||||
|
|
Loading…
Add table
Reference in a new issue