Merge pull request #2620 from matrix-org/bwindels/e2eiconsanddialog
Fixes and styling related to e2e icons and dialogs
This commit is contained in:
commit
875f792728
10 changed files with 67 additions and 53 deletions
|
@ -28,28 +28,28 @@ limitations under the License.
|
||||||
flex-direction: column;
|
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 {
|
.mx_UnknownDeviceDialog .mx_DeviceVerifyButtons {
|
||||||
float: right;
|
flex-direction: row !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_UnknownDeviceDialog .mx_Dialog_content {
|
.mx_UnknownDeviceDialog .mx_Dialog_content {
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_UnknownDeviceDialog .mx_MemberDeviceInfo {
|
.mx_UnknownDeviceDialog_deviceList > li {
|
||||||
float: right;
|
padding: 4px;
|
||||||
clear: both;
|
|
||||||
padding: 0px;
|
|
||||||
padding-top: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_UnknownDeviceDialog .mx_MemberDeviceInfo_textButton {
|
.mx_UnknownDeviceDialog_deviceList > li > * {
|
||||||
@mixin mx_DialogButton_small;
|
padding-bottom: 0;
|
||||||
background-color: $primary-bg-color;
|
|
||||||
color: $accent-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_UnknownDeviceDialog .mx_UnknownDeviceDialog_deviceList li {
|
|
||||||
height: 40px;
|
|
||||||
border-bottom: 1px solid $primary-hairline-color;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -533,7 +533,7 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_EventTile_e2eIcon {
|
.mx_EventTile_e2eIcon {
|
||||||
top: 7px;
|
top: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_EventTile_editButton {
|
.mx_EventTile_editButton {
|
||||||
|
|
|
@ -793,6 +793,7 @@ module.exports = React.createClass({
|
||||||
this._updateConfCallNotification();
|
this._updateConfCallNotification();
|
||||||
this._updateDMState();
|
this._updateDMState();
|
||||||
this._checkIfAlone(this.state.room);
|
this._checkIfAlone(this.state.room);
|
||||||
|
this._updateE2EStatus(this.state.room);
|
||||||
}, 500),
|
}, 500),
|
||||||
|
|
||||||
_checkIfAlone: function(room) {
|
_checkIfAlone: function(room) {
|
||||||
|
|
|
@ -90,6 +90,11 @@ module.exports = React.createClass({
|
||||||
this.closeMenu();
|
this.closeMenu();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
e2eInfoClicked: function() {
|
||||||
|
this.props.e2eInfoCallback();
|
||||||
|
this.closeMenu();
|
||||||
|
},
|
||||||
|
|
||||||
onViewSourceClick: function() {
|
onViewSourceClick: function() {
|
||||||
const ViewSource = sdk.getComponent('structures.ViewSource');
|
const ViewSource = sdk.getComponent('structures.ViewSource');
|
||||||
Modal.createTrackedDialog('View Event Source', '', ViewSource, {
|
Modal.createTrackedDialog('View Event Source', '', ViewSource, {
|
||||||
|
@ -332,6 +337,13 @@ module.exports = React.createClass({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let e2eInfo;
|
||||||
|
if (this.props.e2eInfoCallback) {
|
||||||
|
e2eInfo = <div className="mx_MessageContextMenu_field" onClick={this.e2eInfoClicked}>
|
||||||
|
{ _t('End-to-end encryption information') }
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_MessageContextMenu">
|
<div className="mx_MessageContextMenu">
|
||||||
{ resendButton }
|
{ resendButton }
|
||||||
|
@ -347,6 +359,7 @@ module.exports = React.createClass({
|
||||||
{ replyButton }
|
{ replyButton }
|
||||||
{ externalURLButton }
|
{ externalURLButton }
|
||||||
{ collapseReplyThread }
|
{ collapseReplyThread }
|
||||||
|
{ e2eInfo }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -25,35 +25,12 @@ import { _t } from '../../../languageHandler';
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import { markAllDevicesKnown } from '../../../cryptodevices';
|
import { markAllDevicesKnown } from '../../../cryptodevices';
|
||||||
|
|
||||||
function DeviceListEntry(props) {
|
|
||||||
const {userId, device} = props;
|
|
||||||
|
|
||||||
const DeviceVerifyButtons = sdk.getComponent('elements.DeviceVerifyButtons');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<li>
|
|
||||||
{ device.deviceId }
|
|
||||||
<DeviceVerifyButtons device={device} userId={userId} />
|
|
||||||
<br />
|
|
||||||
{ device.getDisplayName() }
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceListEntry.propTypes = {
|
|
||||||
userId: PropTypes.string.isRequired,
|
|
||||||
|
|
||||||
// deviceinfo
|
|
||||||
device: PropTypes.object.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
function UserUnknownDeviceList(props) {
|
function UserUnknownDeviceList(props) {
|
||||||
|
const MemberDeviceInfo = sdk.getComponent('rooms.MemberDeviceInfo');
|
||||||
const {userId, userDevices} = props;
|
const {userId, userDevices} = props;
|
||||||
|
|
||||||
const deviceListEntries = Object.keys(userDevices).map((deviceId) =>
|
const deviceListEntries = Object.keys(userDevices).map((deviceId) =>
|
||||||
<DeviceListEntry key={deviceId} userId={userId}
|
<li key={deviceId}><MemberDeviceInfo device={userDevices[deviceId]} userId={userId} showDeviceId={true} /></li>,
|
||||||
device={userDevices[deviceId]} />,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
|
|
||||||
export default function(props) {
|
export default function(props) {
|
||||||
const isWarning = props.status === "warning";
|
const isWarning = props.status === "warning";
|
||||||
|
@ -35,5 +36,10 @@ export default function(props) {
|
||||||
_t("All devices for this user are trusted") :
|
_t("All devices for this user are trusted") :
|
||||||
_t("All devices in this encrypted room are trusted");
|
_t("All devices in this encrypted room are trusted");
|
||||||
}
|
}
|
||||||
return (<div className={e2eIconClasses} title={e2eTitle} />);
|
const icon = (<div className={e2eIconClasses} title={e2eTitle} />);
|
||||||
|
if (props.onClick) {
|
||||||
|
return (<AccessibleButton onClick={props.onClick}>{ icon }</AccessibleButton>);
|
||||||
|
} else {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,6 +327,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
top: y,
|
top: y,
|
||||||
eventTileOps: tile && tile.getEventTileOps ? tile.getEventTileOps() : undefined,
|
eventTileOps: tile && tile.getEventTileOps ? tile.getEventTileOps() : undefined,
|
||||||
collapseReplyThread: replyThread && replyThread.canCollapse() ? replyThread.collapse : undefined,
|
collapseReplyThread: replyThread && replyThread.canCollapse() ? replyThread.collapse : undefined,
|
||||||
|
e2eInfoCallback: () => this.onCryptoClicked(),
|
||||||
onFinished: function() {
|
onFinished: function() {
|
||||||
self.setState({menu: false});
|
self.setState({menu: false});
|
||||||
},
|
},
|
||||||
|
@ -773,29 +774,31 @@ module.exports.haveTileForEvent = function(e) {
|
||||||
|
|
||||||
function E2ePadlockUndecryptable(props) {
|
function E2ePadlockUndecryptable(props) {
|
||||||
return (
|
return (
|
||||||
<E2ePadlock title={_t("Undecryptable")} icon="undecryptable" />
|
<E2ePadlock title={_t("Undecryptable")} icon="undecryptable" {...props} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function E2ePadlockUnverified(props) {
|
function E2ePadlockUnverified(props) {
|
||||||
return (
|
return (
|
||||||
<E2ePadlock title={_t("Encrypted by an unverified device")} icon="unverified" />
|
<E2ePadlock title={_t("Encrypted by an unverified device")} icon="unverified" {...props} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function E2ePadlockUnencrypted(props) {
|
function E2ePadlockUnencrypted(props) {
|
||||||
return (
|
return (
|
||||||
<E2ePadlock title={_t("Unencrypted message")} icon="unencrypted" />
|
<E2ePadlock title={_t("Unencrypted message")} icon="unencrypted" {...props} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function E2ePadlock(props) {
|
function E2ePadlock(props) {
|
||||||
if (SettingsStore.getValue("alwaysShowEncryptionIcons")) {
|
if (SettingsStore.getValue("alwaysShowEncryptionIcons")) {
|
||||||
return <div
|
return (<div
|
||||||
className={`mx_EventTile_e2eIcon mx_EventTile_e2eIcon_${props.icon}`}
|
className={`mx_EventTile_e2eIcon mx_EventTile_e2eIcon_${props.icon}`}
|
||||||
title={props.title} onClick={props.onClick} />;
|
title={props.title} onClick={props.onClick} />);
|
||||||
} else {
|
} else {
|
||||||
return <div className="mx_EventTile_e2eIcon mx_EventTile_e2eIcon_hidden" onClick={props.onClick} />;
|
return (<div
|
||||||
|
className={`mx_EventTile_e2eIcon mx_EventTile_e2eIcon_hidden mx_EventTile_e2eIcon_${props.icon}`}
|
||||||
|
onClick={props.onClick} />);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ export default class MemberDeviceInfo extends React.Component {
|
||||||
mx_MemberDeviceInfo_icon_unverified: this.props.device.isUnverified(),
|
mx_MemberDeviceInfo_icon_unverified: this.props.device.isUnverified(),
|
||||||
});
|
});
|
||||||
const indicator = (<div className={iconClasses} />);
|
const indicator = (<div className={iconClasses} />);
|
||||||
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() ? this.props.device.getDisplayName() : "") + " (" + this.props.device.deviceId + ")" :
|
||||||
this.props.device.getDisplayName();
|
this.props.device.getDisplayName();
|
||||||
|
|
||||||
|
|
|
@ -941,6 +941,8 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
let roomMemberDetails = null;
|
let roomMemberDetails = null;
|
||||||
|
let e2eIconElement;
|
||||||
|
|
||||||
if (this.props.member.roomId) { // is in room
|
if (this.props.member.roomId) { // is in room
|
||||||
const PowerSelector = sdk.getComponent('elements.PowerSelector');
|
const PowerSelector = sdk.getComponent('elements.PowerSelector');
|
||||||
roomMemberDetails = <div>
|
roomMemberDetails = <div>
|
||||||
|
@ -959,6 +961,11 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
{statusLabel}
|
{statusLabel}
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
|
|
||||||
|
const isEncrypted = this.props.matrixClient.isRoomEncrypted(this.props.member.roomId);
|
||||||
|
if (this.state.e2eStatus && isEncrypted) {
|
||||||
|
e2eIconElement = (<E2EIcon status={this.state.e2eStatus} isUser={true} />);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const avatarUrl = this.props.member.getMxcAvatarUrl();
|
const avatarUrl = this.props.member.getMxcAvatarUrl();
|
||||||
|
@ -967,7 +974,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
const httpUrl = this.props.matrixClient.mxcUrlToHttp(avatarUrl, 800, 800);
|
const httpUrl = this.props.matrixClient.mxcUrlToHttp(avatarUrl, 800, 800);
|
||||||
avatarElement = <div className="mx_MemberInfo_avatar">
|
avatarElement = <div className="mx_MemberInfo_avatar">
|
||||||
<img src={httpUrl} />
|
<img src={httpUrl} />
|
||||||
</div>
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
||||||
|
@ -979,7 +986,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this.onCancel}>
|
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this.onCancel}>
|
||||||
<img src={require("../../../../res/img/minimise.svg")} width="10" height="16" className="mx_filterFlipColor" alt={_t('Close')} />
|
<img src={require("../../../../res/img/minimise.svg")} width="10" height="16" className="mx_filterFlipColor" alt={_t('Close')} />
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
{ this.state.e2eStatus ? <E2EIcon status={this.state.e2eStatus} isUser={true} /> : undefined }
|
{ e2eIconElement }
|
||||||
<EmojiText element="h2">{ memberName }</EmojiText>
|
<EmojiText element="h2">{ memberName }</EmojiText>
|
||||||
</div>
|
</div>
|
||||||
{ avatarElement }
|
{ avatarElement }
|
||||||
|
|
|
@ -32,6 +32,7 @@ import {CancelButton} from './SimpleRoomHeader';
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import RoomHeaderButtons from '../right_panel/RoomHeaderButtons';
|
import RoomHeaderButtons from '../right_panel/RoomHeaderButtons';
|
||||||
import E2EIcon from './E2EIcon';
|
import E2EIcon from './E2EIcon';
|
||||||
|
import * as cryptodevices from '../../../cryptodevices';
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'RoomHeader',
|
displayName: 'RoomHeader',
|
||||||
|
@ -145,6 +146,12 @@ module.exports = React.createClass({
|
||||||
return !(currentPinEvent.getContent().pinned && currentPinEvent.getContent().pinned.length <= 0);
|
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() {
|
render: function() {
|
||||||
const RoomAvatar = sdk.getComponent("avatars.RoomAvatar");
|
const RoomAvatar = sdk.getComponent("avatars.RoomAvatar");
|
||||||
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||||
|
@ -156,7 +163,7 @@ module.exports = React.createClass({
|
||||||
let pinnedEventsButton = null;
|
let pinnedEventsButton = null;
|
||||||
|
|
||||||
const e2eIcon = this.props.e2eStatus ?
|
const e2eIcon = this.props.e2eStatus ?
|
||||||
<E2EIcon status={this.props.e2eStatus} /> :
|
<E2EIcon status={this.props.e2eStatus} onClick={this._onShowDevicesClick} /> :
|
||||||
undefined;
|
undefined;
|
||||||
|
|
||||||
if (this.props.onCancelClick) {
|
if (this.props.onCancelClick) {
|
||||||
|
|
Loading…
Reference in a new issue