Merge pull request #635 from matrix-org/matthew/warn-unknown-devices
very barebones support for warning users when rooms contain unknown devicespull/21833/head
commit
e45ac36a3b
|
@ -177,7 +177,7 @@ class ModalManager {
|
|||
|
||||
var modal = this._modals[0];
|
||||
var dialog = (
|
||||
<div className={"mx_Dialog_wrapper " + modal.className}>
|
||||
<div className={"mx_Dialog_wrapper " + (modal.className ? modal.className : '') }>
|
||||
<div className="mx_Dialog">
|
||||
{modal.elem}
|
||||
</div>
|
||||
|
|
|
@ -16,17 +16,26 @@ limitations under the License.
|
|||
|
||||
var MatrixClientPeg = require('./MatrixClientPeg');
|
||||
var dis = require('./dispatcher');
|
||||
var sdk = require('./index');
|
||||
var Modal = require('./Modal');
|
||||
|
||||
module.exports = {
|
||||
resend: function(event) {
|
||||
MatrixClientPeg.get().resendEvent(
|
||||
event, MatrixClientPeg.get().getRoom(event.getRoomId())
|
||||
).done(function() {
|
||||
).done(function(res) {
|
||||
dis.dispatch({
|
||||
action: 'message_sent',
|
||||
event: event
|
||||
});
|
||||
}, function() {
|
||||
}, function(err) {
|
||||
if (err.name === "UnknownDeviceError") {
|
||||
var UnknownDeviceDialog = sdk.getComponent("dialogs.UnknownDeviceDialog");
|
||||
Modal.createDialog(UnknownDeviceDialog, {
|
||||
devices: err.devices
|
||||
}, "mx_Dialog_unknownDevice");
|
||||
}
|
||||
|
||||
dis.dispatch({
|
||||
action: 'message_send_failed',
|
||||
event: event
|
||||
|
|
|
@ -89,6 +89,8 @@ import views$dialogs$SetDisplayNameDialog from './components/views/dialogs/SetDi
|
|||
views$dialogs$SetDisplayNameDialog && (module.exports.components['views.dialogs.SetDisplayNameDialog'] = views$dialogs$SetDisplayNameDialog);
|
||||
import views$dialogs$TextInputDialog from './components/views/dialogs/TextInputDialog';
|
||||
views$dialogs$TextInputDialog && (module.exports.components['views.dialogs.TextInputDialog'] = views$dialogs$TextInputDialog);
|
||||
import views$dialogs$UnknownDeviceDialog from './components/views/dialogs/UnknownDeviceDialog';
|
||||
views$dialogs$UnknownDeviceDialog && (module.exports.components['views.dialogs.UnknownDeviceDialog'] = views$dialogs$UnknownDeviceDialog);
|
||||
import views$elements$AccessibleButton from './components/views/elements/AccessibleButton';
|
||||
views$elements$AccessibleButton && (module.exports.components['views.elements.AccessibleButton'] = views$elements$AccessibleButton);
|
||||
import views$elements$AddressSelector from './components/views/elements/AddressSelector';
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import sdk from '../../../index';
|
||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import GeminiScrollbar from 'react-gemini-scrollbar';
|
||||
|
||||
function UserUnknownDeviceList(props) {
|
||||
const {userDevices} = props;
|
||||
|
||||
const deviceListEntries = Object.keys(userDevices).map((deviceId) =>
|
||||
<li key={ deviceId }>
|
||||
{ deviceId } ( { userDevices[deviceId].getDisplayName() } )
|
||||
</li>,
|
||||
);
|
||||
|
||||
return <ul>{deviceListEntries}</ul>;
|
||||
}
|
||||
|
||||
UserUnknownDeviceList.propTypes = {
|
||||
// map from deviceid -> deviceinfo
|
||||
userDevices: React.PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
|
||||
function UnknownDeviceList(props) {
|
||||
const {devices} = props;
|
||||
|
||||
const userListEntries = Object.keys(devices).map((userId) =>
|
||||
<li key={ userId }>
|
||||
<p>{ userId }:</p>
|
||||
<UserUnknownDeviceList userDevices={devices[userId]} />
|
||||
</li>,
|
||||
);
|
||||
|
||||
return <ul>{userListEntries}</ul>;
|
||||
}
|
||||
|
||||
UnknownDeviceList.propTypes = {
|
||||
// map from userid -> deviceid -> deviceinfo
|
||||
devices: React.PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
|
||||
export default React.createClass({
|
||||
displayName: 'UnknownEventDialog',
|
||||
|
||||
propTypes: {
|
||||
// map from userid -> deviceid -> deviceinfo
|
||||
devices: React.PropTypes.object.isRequired,
|
||||
onFinished: React.PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
// Given we've now shown the user the unknown device, it is no longer
|
||||
// unknown to them. Therefore mark it as 'known'.
|
||||
Object.keys(this.props.devices).forEach((userId) => {
|
||||
Object.keys(this.props.devices[userId]).map((deviceId) => {
|
||||
MatrixClientPeg.get().setDeviceKnown(userId, deviceId, true);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||
return (
|
||||
<BaseDialog className='mx_UnknownDeviceDialog'
|
||||
onFinished={this.props.onFinished}
|
||||
title='Room contains unknown devices'
|
||||
>
|
||||
<GeminiScrollbar autoshow={false} className="mx_Dialog_content">
|
||||
<h4>This room contains devices which have not been
|
||||
verified.</h4>
|
||||
<p>
|
||||
This means there is no guarantee that the devices belong
|
||||
to a rightful user of the room.
|
||||
</p><p>
|
||||
We recommend you go through the verification process
|
||||
for each device before continuing, but you can resend
|
||||
the message without verifying if you prefer.
|
||||
</p>
|
||||
<p>Unknown devices:</p>
|
||||
<UnknownDeviceList devices={this.props.devices} />
|
||||
</GeminiScrollbar>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button className="mx_Dialog_primary" autoFocus={ true }
|
||||
onClick={ this.props.onFinished } >
|
||||
OK
|
||||
</button>
|
||||
</div>
|
||||
</BaseDialog>
|
||||
);
|
||||
},
|
||||
});
|
|
@ -40,6 +40,7 @@ import * as HtmlUtils from '../../../HtmlUtils';
|
|||
import Autocomplete from './Autocomplete';
|
||||
import {Completion} from "../../../autocomplete/Autocompleter";
|
||||
import Markdown from '../../../Markdown';
|
||||
import {onSendMessageFailed} from './MessageComposerInputOld';
|
||||
|
||||
const TYPING_USER_TIMEOUT = 10000, TYPING_SERVER_TIMEOUT = 30000;
|
||||
|
||||
|
@ -553,15 +554,11 @@ export default class MessageComposerInput extends React.Component {
|
|||
sendMessagePromise = sendTextFn.call(this.client, this.props.room.roomId, contentText);
|
||||
}
|
||||
|
||||
sendMessagePromise.then(() => {
|
||||
sendMessagePromise.done((res) => {
|
||||
dis.dispatch({
|
||||
action: 'message_sent',
|
||||
});
|
||||
}, () => {
|
||||
dis.dispatch({
|
||||
action: 'message_send_failed',
|
||||
});
|
||||
});
|
||||
}, onSendMessageFailed);
|
||||
|
||||
this.setState({
|
||||
editorState: this.createEditorState(),
|
||||
|
|
|
@ -29,10 +29,22 @@ var TYPING_USER_TIMEOUT = 10000;
|
|||
var TYPING_SERVER_TIMEOUT = 30000;
|
||||
var MARKDOWN_ENABLED = true;
|
||||
|
||||
export function onSendMessageFailed(err) {
|
||||
if (err.name === "UnknownDeviceError") {
|
||||
const UnknownDeviceDialog = sdk.getComponent("dialogs.UnknownDeviceDialog");
|
||||
Modal.createDialog(UnknownDeviceDialog, {
|
||||
devices: err.devices,
|
||||
}, "mx_Dialog_unknownDevice");
|
||||
}
|
||||
dis.dispatch({
|
||||
action: 'message_send_failed',
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* The textInput part of the MessageComposer
|
||||
*/
|
||||
module.exports = React.createClass({
|
||||
export default React.createClass({
|
||||
displayName: 'MessageComposerInput',
|
||||
|
||||
statics: {
|
||||
|
@ -337,15 +349,12 @@ module.exports = React.createClass({
|
|||
MatrixClientPeg.get().sendTextMessage(this.props.room.roomId, contentText);
|
||||
}
|
||||
|
||||
sendMessagePromise.done(function() {
|
||||
sendMessagePromise.done(function(res) {
|
||||
dis.dispatch({
|
||||
action: 'message_sent'
|
||||
});
|
||||
}, function() {
|
||||
dis.dispatch({
|
||||
action: 'message_send_failed'
|
||||
});
|
||||
});
|
||||
}, onSendMessageFailed);
|
||||
|
||||
this.refs.textarea.value = '';
|
||||
this.resizeInput();
|
||||
ev.preventDefault();
|
||||
|
|
Loading…
Reference in New Issue