mirror of https://github.com/vector-im/riot-web
Merge remote-tracking branch 'origin/develop' into develop
commit
c11635172e
44
src/Modal.js
44
src/Modal.js
|
@ -81,7 +81,11 @@ class ModalManager {
|
|||
constructor() {
|
||||
this._counter = 0;
|
||||
|
||||
/** list of the modals we have stacked up, with the most recent at [0] */
|
||||
// The modal to prioritise over all others. If this is set, only show
|
||||
// this modal. Remove all other modals from the stack when this modal
|
||||
// is closed.
|
||||
this._priorityModal = null;
|
||||
// A list of the modals we have stacked up, with the most recent at [0]
|
||||
this._modals = [
|
||||
/* {
|
||||
elem: React component for this dialog
|
||||
|
@ -105,18 +109,18 @@ class ModalManager {
|
|||
return container;
|
||||
}
|
||||
|
||||
createTrackedDialog(analyticsAction, analyticsInfo, Element, props, className) {
|
||||
createTrackedDialog(analyticsAction, analyticsInfo, ...rest) {
|
||||
Analytics.trackEvent('Modal', analyticsAction, analyticsInfo);
|
||||
return this.createDialog(Element, props, className);
|
||||
return this.createDialog(...rest);
|
||||
}
|
||||
|
||||
createDialog(Element, props, className) {
|
||||
return this.createDialogAsync((cb) => {cb(Element);}, props, className);
|
||||
createDialog(Element, ...rest) {
|
||||
return this.createDialogAsync((cb) => {cb(Element);}, ...rest);
|
||||
}
|
||||
|
||||
createTrackedDialogAsync(analyticsAction, analyticsInfo, loader, props, className) {
|
||||
createTrackedDialogAsync(analyticsAction, analyticsInfo, ...rest) {
|
||||
Analytics.trackEvent('Modal', analyticsAction, analyticsInfo);
|
||||
return this.createDialogAsync(loader, props, className);
|
||||
return this.createDialogAsync(...rest);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -137,8 +141,13 @@ class ModalManager {
|
|||
* component. (We will also pass an 'onFinished' property.)
|
||||
*
|
||||
* @param {String} className CSS class to apply to the modal wrapper
|
||||
*
|
||||
* @param {boolean} isPriorityModal if true, this modal will be displayed regardless
|
||||
* of other modals that are currently in the stack.
|
||||
* Also, when closed, all modals will be removed
|
||||
* from the stack.
|
||||
*/
|
||||
createDialogAsync(loader, props, className) {
|
||||
createDialogAsync(loader, props, className, isPriorityModal) {
|
||||
const self = this;
|
||||
const modal = {};
|
||||
|
||||
|
@ -151,6 +160,14 @@ class ModalManager {
|
|||
if (i >= 0) {
|
||||
self._modals.splice(i, 1);
|
||||
}
|
||||
|
||||
if (self._priorityModal === modal) {
|
||||
self._priorityModal = null;
|
||||
|
||||
// XXX: This is destructive
|
||||
self._modals = [];
|
||||
}
|
||||
|
||||
self._reRender();
|
||||
};
|
||||
|
||||
|
@ -167,7 +184,12 @@ class ModalManager {
|
|||
modal.onFinished = props ? props.onFinished : null;
|
||||
modal.className = className;
|
||||
|
||||
this._modals.unshift(modal);
|
||||
if (isPriorityModal) {
|
||||
// XXX: This is destructive
|
||||
this._priorityModal = modal;
|
||||
} else {
|
||||
this._modals.unshift(modal);
|
||||
}
|
||||
|
||||
this._reRender();
|
||||
return {close: closeDialog};
|
||||
|
@ -188,7 +210,7 @@ class ModalManager {
|
|||
}
|
||||
|
||||
_reRender() {
|
||||
if (this._modals.length == 0) {
|
||||
if (this._modals.length == 0 && !this._priorityModal) {
|
||||
// If there is no modal to render, make all of Riot available
|
||||
// to screen reader users again
|
||||
dis.dispatch({
|
||||
|
@ -205,7 +227,7 @@ class ModalManager {
|
|||
action: 'aria_hide_main_app',
|
||||
});
|
||||
|
||||
const modal = this._modals[0];
|
||||
const modal = this._priorityModal ? this._priorityModal : this._modals[0];
|
||||
const dialog = (
|
||||
<div className={"mx_Dialog_wrapper " + (modal.className ? modal.className : '')}>
|
||||
<div className="mx_Dialog">
|
||||
|
|
|
@ -1232,6 +1232,28 @@ export default React.createClass({
|
|||
action: 'logout',
|
||||
});
|
||||
});
|
||||
cli.on('no_consent', function(message, consentUri) {
|
||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
Modal.createTrackedDialog('No Consent Dialog', '', QuestionDialog, {
|
||||
title: _t('Terms and Conditions'),
|
||||
description: <div>
|
||||
<p> { _t(
|
||||
'To continue using the %(homeserverDomain)s homeserver ' +
|
||||
'you must review and agree to our terms and conditions.',
|
||||
{ homeserverDomain: cli.getDomain() },
|
||||
) }
|
||||
</p>
|
||||
</div>,
|
||||
button: _t('Review terms and conditions'),
|
||||
cancelButton: _t('Dismiss'),
|
||||
onFinished: (confirmed) => {
|
||||
if (confirmed) {
|
||||
window.open(consentUri, '_blank');
|
||||
}
|
||||
},
|
||||
}, null, true);
|
||||
});
|
||||
|
||||
cli.on("accountData", function(ev) {
|
||||
if (ev.getType() === 'im.vector.web.settings') {
|
||||
if (ev.getContent() && ev.getContent().theme) {
|
||||
|
|
|
@ -67,6 +67,7 @@ export default React.createClass({
|
|||
{ this.props.description }
|
||||
</div>
|
||||
<DialogButtons primaryButton={this.props.button || _t('OK')}
|
||||
cancelButton={this.props.cancelButton}
|
||||
onPrimaryButtonClick={this.onOk}
|
||||
primaryButtonClass={primaryButtonClass}
|
||||
focus={this.props.focus}
|
||||
|
|
|
@ -29,6 +29,9 @@ module.exports = React.createClass({
|
|||
// The primary button which is styled differently and has default focus.
|
||||
primaryButton: PropTypes.node.isRequired,
|
||||
|
||||
// A node to insert into the cancel button instead of default "Cancel"
|
||||
cancelButton: PropTypes.node,
|
||||
|
||||
// onClick handler for the primary button.
|
||||
onPrimaryButtonClick: PropTypes.func.isRequired,
|
||||
|
||||
|
@ -60,9 +63,9 @@ module.exports = React.createClass({
|
|||
primaryButtonClassName += " " + this.props.primaryButtonClass;
|
||||
}
|
||||
let cancelButton;
|
||||
if (this.props.hasCancel) {
|
||||
if (this.props.cancelButton || this.props.hasCancel) {
|
||||
cancelButton = <button onClick={this._onCancelClick} disabled={this.props.disabled}>
|
||||
{ _t("Cancel") }
|
||||
{ this.props.cancelButton || _t("Cancel") }
|
||||
</button>;
|
||||
}
|
||||
return (
|
||||
|
|
|
@ -944,6 +944,9 @@
|
|||
"Failed to leave room": "Failed to leave room",
|
||||
"Signed Out": "Signed Out",
|
||||
"For security, this session has been signed out. Please sign in again.": "For security, this session has been signed out. Please sign in again.",
|
||||
"Terms and Conditions": "Terms and Conditions",
|
||||
"To continue using the %(homeserverDomain)s homeserver you must review and agree to our terms and conditions.": "To continue using the %(homeserverDomain)s homeserver you must review and agree to our terms and conditions.",
|
||||
"Review terms and conditions": "Review terms and conditions",
|
||||
"Old cryptography data detected": "Old cryptography data detected",
|
||||
"Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.",
|
||||
"Logout": "Logout",
|
||||
|
|
Loading…
Reference in New Issue