diff --git a/res/css/views/dialogs/_UnknownDeviceDialog.scss b/res/css/views/dialogs/_UnknownDeviceDialog.scss index a924704769..02e0fb1fe5 100644 --- a/res/css/views/dialogs/_UnknownDeviceDialog.scss +++ b/res/css/views/dialogs/_UnknownDeviceDialog.scss @@ -28,28 +28,28 @@ limitations under the License. flex-direction: column; } +.mx_UnknownDeviceDialog ul { + list-style: none; + padding: 0; +} +// userid +.mx_UnknownDeviceDialog p { + font-weight: bold; + font-size: 16px; +} + .mx_UnknownDeviceDialog .mx_DeviceVerifyButtons { - float: right; + flex-direction: row !important; } .mx_UnknownDeviceDialog .mx_Dialog_content { margin-bottom: 24px; } -.mx_UnknownDeviceDialog .mx_MemberDeviceInfo { - float: right; - clear: both; - padding: 0px; - padding-top: 8px; +.mx_UnknownDeviceDialog_deviceList > li { + padding: 4px; } -.mx_UnknownDeviceDialog .mx_MemberDeviceInfo_textButton { - @mixin mx_DialogButton_small; - background-color: $primary-bg-color; - color: $accent-color; -} - -.mx_UnknownDeviceDialog .mx_UnknownDeviceDialog_deviceList li { - height: 40px; - border-bottom: 1px solid $primary-hairline-color; +.mx_UnknownDeviceDialog_deviceList > li > * { + padding-bottom: 0; } diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 7c9a6babea..a8f34565b5 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -533,7 +533,7 @@ limitations under the License. } .mx_EventTile_e2eIcon { - top: 7px; + top: 3px; } .mx_EventTile_editButton { diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index b233662898..8e32802d0a 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -793,6 +793,7 @@ module.exports = React.createClass({ this._updateConfCallNotification(); this._updateDMState(); this._checkIfAlone(this.state.room); + this._updateE2EStatus(this.state.room); }, 500), _checkIfAlone: function(room) { diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index c990b5705d..ffa2a0bf5c 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -90,6 +90,11 @@ module.exports = React.createClass({ this.closeMenu(); }, + e2eInfoClicked: function() { + this.props.e2eInfoCallback(); + this.closeMenu(); + }, + onViewSourceClick: function() { const ViewSource = sdk.getComponent('structures.ViewSource'); Modal.createTrackedDialog('View Event Source', '', ViewSource, { @@ -332,6 +337,13 @@ module.exports = React.createClass({ ); } + let e2eInfo; + if (this.props.e2eInfoCallback) { + e2eInfo =
+ { _t('End-to-end encryption information') } +
; + } + return (
{ resendButton } @@ -347,6 +359,7 @@ module.exports = React.createClass({ { replyButton } { externalURLButton } { collapseReplyThread } + { e2eInfo }
); }, diff --git a/src/components/views/dialogs/UnknownDeviceDialog.js b/src/components/views/dialogs/UnknownDeviceDialog.js index 959c14cc7d..09b967c72f 100644 --- a/src/components/views/dialogs/UnknownDeviceDialog.js +++ b/src/components/views/dialogs/UnknownDeviceDialog.js @@ -25,35 +25,12 @@ import { _t } from '../../../languageHandler'; import SettingsStore from "../../../settings/SettingsStore"; import { markAllDevicesKnown } from '../../../cryptodevices'; -function DeviceListEntry(props) { - const {userId, device} = props; - - const DeviceVerifyButtons = sdk.getComponent('elements.DeviceVerifyButtons'); - - return ( -
  • - { device.deviceId } - -
    - { device.getDisplayName() } -
  • - ); -} - -DeviceListEntry.propTypes = { - userId: PropTypes.string.isRequired, - - // deviceinfo - device: PropTypes.object.isRequired, -}; - - function UserUnknownDeviceList(props) { + const MemberDeviceInfo = sdk.getComponent('rooms.MemberDeviceInfo'); const {userId, userDevices} = props; const deviceListEntries = Object.keys(userDevices).map((deviceId) => - , +
  • , ); return ( diff --git a/src/components/views/rooms/E2EIcon.js b/src/components/views/rooms/E2EIcon.js index 30891e84b7..54260e4ee2 100644 --- a/src/components/views/rooms/E2EIcon.js +++ b/src/components/views/rooms/E2EIcon.js @@ -16,6 +16,7 @@ limitations under the License. import classNames from 'classnames'; import { _t } from '../../../languageHandler'; +import AccessibleButton from '../elements/AccessibleButton'; export default function(props) { const isWarning = props.status === "warning"; @@ -35,5 +36,10 @@ export default function(props) { _t("All devices for this user are trusted") : _t("All devices in this encrypted room are trusted"); } - return (
    ); + const icon = (
    ); + if (props.onClick) { + return ({ icon }); + } else { + return icon; + } } diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 8520d804e0..8e1fb5af9f 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -327,6 +327,7 @@ module.exports = withMatrixClient(React.createClass({ top: y, eventTileOps: tile && tile.getEventTileOps ? tile.getEventTileOps() : undefined, collapseReplyThread: replyThread && replyThread.canCollapse() ? replyThread.collapse : undefined, + e2eInfoCallback: () => this.onCryptoClicked(), onFinished: function() { self.setState({menu: false}); }, @@ -773,29 +774,31 @@ module.exports.haveTileForEvent = function(e) { function E2ePadlockUndecryptable(props) { return ( - + ); } function E2ePadlockUnverified(props) { return ( - + ); } function E2ePadlockUnencrypted(props) { return ( - + ); } function E2ePadlock(props) { if (SettingsStore.getValue("alwaysShowEncryptionIcons")) { - return
    ; + return (
    ); } else { - return
    ; + return (
    ); } } diff --git a/src/components/views/rooms/MemberDeviceInfo.js b/src/components/views/rooms/MemberDeviceInfo.js index 67f99e4d1d..ff88c6f6e6 100644 --- a/src/components/views/rooms/MemberDeviceInfo.js +++ b/src/components/views/rooms/MemberDeviceInfo.js @@ -30,7 +30,7 @@ export default class MemberDeviceInfo extends React.Component { mx_MemberDeviceInfo_icon_unverified: this.props.device.isUnverified(), }); const indicator = (
    ); - const deviceName = this.props.device.ambiguous ? + const deviceName = (this.props.device.ambiguous || this.props.showDeviceId) ? (this.props.device.getDisplayName() ? this.props.device.getDisplayName() : "") + " (" + this.props.device.deviceId + ")" : this.props.device.getDisplayName(); diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 5df0da7491..f4c600af8d 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -941,6 +941,8 @@ module.exports = withMatrixClient(React.createClass({ } let roomMemberDetails = null; + let e2eIconElement; + if (this.props.member.roomId) { // is in room const PowerSelector = sdk.getComponent('elements.PowerSelector'); roomMemberDetails =
    @@ -959,6 +961,11 @@ module.exports = withMatrixClient(React.createClass({ {statusLabel}
    ; + + const isEncrypted = this.props.matrixClient.isRoomEncrypted(this.props.member.roomId); + if (this.state.e2eStatus && isEncrypted) { + e2eIconElement = (); + } } const avatarUrl = this.props.member.getMxcAvatarUrl(); @@ -967,7 +974,7 @@ module.exports = withMatrixClient(React.createClass({ const httpUrl = this.props.matrixClient.mxcUrlToHttp(avatarUrl, 800, 800); avatarElement =
    -
    +
    ; } const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper"); @@ -979,7 +986,7 @@ module.exports = withMatrixClient(React.createClass({ {_t('Close')} - { this.state.e2eStatus ? : undefined } + { e2eIconElement } { memberName }
    { avatarElement } diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index e25b25d110..6e5ccab7f9 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -32,6 +32,7 @@ import {CancelButton} from './SimpleRoomHeader'; import SettingsStore from "../../../settings/SettingsStore"; import RoomHeaderButtons from '../right_panel/RoomHeaderButtons'; import E2EIcon from './E2EIcon'; +import * as cryptodevices from '../../../cryptodevices'; module.exports = React.createClass({ displayName: 'RoomHeader', @@ -145,6 +146,12 @@ module.exports = React.createClass({ return !(currentPinEvent.getContent().pinned && currentPinEvent.getContent().pinned.length <= 0); }, + _onShowDevicesClick: function() { + if (this.props.e2eStatus === "warning") { + cryptodevices.showUnknownDeviceDialogForMessages(MatrixClientPeg.get(), this.props.room); + } + }, + render: function() { const RoomAvatar = sdk.getComponent("avatars.RoomAvatar"); const TintableSvg = sdk.getComponent("elements.TintableSvg"); @@ -156,7 +163,7 @@ module.exports = React.createClass({ let pinnedEventsButton = null; const e2eIcon = this.props.e2eStatus ? - : + : undefined; if (this.props.onCancelClick) {