Merge branch 'develop' into sort-imports
Signed-off-by: Aaron Raimist <aaron@raim.ist>
This commit is contained in:
commit
7b94e13a84
642 changed files with 30052 additions and 8035 deletions
|
@ -22,33 +22,98 @@ import { _t } from '../../../languageHandler';
|
|||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||
import { formatDate } from '../../../DateUtils';
|
||||
import StyledCheckbox from '../elements/StyledCheckbox';
|
||||
import { CheckboxStyle } from '../elements/StyledCheckbox';
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import EditableTextContainer from "../elements/EditableTextContainer";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import Field from "../elements/Field";
|
||||
import TextWithTooltip from "../elements/TextWithTooltip";
|
||||
import Modal from "../../../Modal";
|
||||
import SetupEncryptionDialog from '../dialogs/security/SetupEncryptionDialog';
|
||||
import VerificationRequestDialog from '../../views/dialogs/VerificationRequestDialog';
|
||||
import LogoutDialog from '../dialogs/LogoutDialog';
|
||||
|
||||
interface IProps {
|
||||
device?: IMyDevice;
|
||||
onDeviceToggled?: (device: IMyDevice) => void;
|
||||
selected?: boolean;
|
||||
device: IMyDevice;
|
||||
isOwnDevice: boolean;
|
||||
verified: boolean | null;
|
||||
canBeVerified: boolean;
|
||||
onDeviceChange: () => void;
|
||||
onDeviceToggled: (device: IMyDevice) => void;
|
||||
selected: boolean;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
renaming: boolean;
|
||||
displayName: string;
|
||||
}
|
||||
|
||||
@replaceableComponent("views.settings.DevicesPanelEntry")
|
||||
export default class DevicesPanelEntry extends React.Component<IProps> {
|
||||
public static defaultProps = {
|
||||
onDeviceToggled: () => {},
|
||||
export default class DevicesPanelEntry extends React.Component<IProps, IState> {
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
renaming: false,
|
||||
displayName: props.device.display_name,
|
||||
};
|
||||
}
|
||||
|
||||
private onDeviceToggled = (): void => {
|
||||
this.props.onDeviceToggled(this.props.device);
|
||||
};
|
||||
|
||||
private onDisplayNameChanged = (value: string): Promise<{}> => {
|
||||
const device = this.props.device;
|
||||
return MatrixClientPeg.get().setDeviceDetails(device.device_id, {
|
||||
display_name: value,
|
||||
private onRename = (): void => {
|
||||
this.setState({ renaming: true });
|
||||
};
|
||||
|
||||
private onChangeDisplayName = (ev: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({
|
||||
displayName: ev.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
private onRenameSubmit = async () => {
|
||||
this.setState({ renaming: false });
|
||||
await MatrixClientPeg.get().setDeviceDetails(this.props.device.device_id, {
|
||||
display_name: this.state.displayName,
|
||||
}).catch((e) => {
|
||||
logger.error("Error setting session display name", e);
|
||||
throw new Error(_t("Failed to set display name"));
|
||||
});
|
||||
this.props.onDeviceChange();
|
||||
};
|
||||
|
||||
private onDeviceToggled = (): void => {
|
||||
this.props.onDeviceToggled(this.props.device);
|
||||
private onRenameCancel = (): void => {
|
||||
this.setState({ renaming: false });
|
||||
};
|
||||
|
||||
private onOwnDeviceSignOut = (): void => {
|
||||
Modal.createTrackedDialog('Logout from device list', '', LogoutDialog,
|
||||
/* props= */{}, /* className= */null,
|
||||
/* isPriority= */false, /* isStatic= */true);
|
||||
};
|
||||
|
||||
private verify = async () => {
|
||||
if (this.props.isOwnDevice) {
|
||||
Modal.createTrackedDialog("Verify session", "Verify session", SetupEncryptionDialog, {
|
||||
onFinished: this.props.onDeviceChange,
|
||||
});
|
||||
} else {
|
||||
const cli = MatrixClientPeg.get();
|
||||
const userId = cli.getUserId();
|
||||
const verificationRequestPromise = cli.requestVerification(
|
||||
userId,
|
||||
[this.props.device.device_id],
|
||||
);
|
||||
Modal.createTrackedDialog('New Session Verification', 'Starting dialog', VerificationRequestDialog, {
|
||||
verificationRequestPromise,
|
||||
member: cli.getUser(userId),
|
||||
onFinished: async () => {
|
||||
const request = await verificationRequestPromise;
|
||||
request.cancel();
|
||||
this.props.onDeviceChange();
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
|
@ -56,34 +121,87 @@ export default class DevicesPanelEntry extends React.Component<IProps> {
|
|||
|
||||
let lastSeen = "";
|
||||
if (device.last_seen_ts) {
|
||||
const lastSeenDate = formatDate(new Date(device.last_seen_ts));
|
||||
lastSeen = device.last_seen_ip + " @ " +
|
||||
lastSeenDate.toLocaleString();
|
||||
const lastSeenDate = new Date(device.last_seen_ts);
|
||||
lastSeen = _t("Last seen %(date)s at %(ip)s", {
|
||||
date: formatDate(lastSeenDate),
|
||||
ip: device.last_seen_ip,
|
||||
});
|
||||
}
|
||||
|
||||
let myDeviceClass = '';
|
||||
if (device.device_id === MatrixClientPeg.get().getDeviceId()) {
|
||||
myDeviceClass = " mx_DevicesPanel_myDevice";
|
||||
const myDeviceClass = this.props.isOwnDevice ? " mx_DevicesPanel_myDevice" : '';
|
||||
|
||||
let iconClass = '';
|
||||
let verifyButton: JSX.Element;
|
||||
if (this.props.verified !== null) {
|
||||
iconClass = this.props.verified ? "mx_E2EIcon_verified" : "mx_E2EIcon_warning";
|
||||
if (!this.props.verified && this.props.canBeVerified) {
|
||||
verifyButton = <AccessibleButton kind="primary" onClick={this.verify}>
|
||||
{ _t("Verify") }
|
||||
</AccessibleButton>;
|
||||
}
|
||||
}
|
||||
|
||||
let signOutButton: JSX.Element;
|
||||
if (this.props.isOwnDevice) {
|
||||
signOutButton = <AccessibleButton kind="danger_outline" onClick={this.onOwnDeviceSignOut}>
|
||||
{ _t("Sign Out") }
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
const left = this.props.isOwnDevice ?
|
||||
<div className="mx_DevicesPanel_deviceTrust">
|
||||
<span className={"mx_DevicesPanel_icon mx_E2EIcon " + iconClass} />
|
||||
</div> :
|
||||
<div className="mx_DevicesPanel_checkbox">
|
||||
<StyledCheckbox kind={CheckboxStyle.Outline} onChange={this.onDeviceToggled} checked={this.props.selected} />
|
||||
</div>;
|
||||
|
||||
const deviceName = device.display_name ?
|
||||
<React.Fragment>
|
||||
<TextWithTooltip tooltip={device.display_name + " (" + device.device_id + ")"}>
|
||||
{ device.display_name }
|
||||
</TextWithTooltip>
|
||||
</React.Fragment> :
|
||||
<React.Fragment>
|
||||
{ device.device_id }
|
||||
</React.Fragment>;
|
||||
|
||||
const buttons = this.state.renaming ?
|
||||
<form className="mx_DevicesPanel_renameForm" onSubmit={this.onRenameSubmit}>
|
||||
<Field
|
||||
label={_t("Display Name")}
|
||||
type="text"
|
||||
value={this.state.displayName}
|
||||
autoComplete="off"
|
||||
onChange={this.onChangeDisplayName}
|
||||
autoFocus
|
||||
/>
|
||||
<AccessibleButton onClick={this.onRenameSubmit} kind="confirm_sm" />
|
||||
<AccessibleButton onClick={this.onRenameCancel} kind="cancel_sm" />
|
||||
</form> :
|
||||
<React.Fragment>
|
||||
{ signOutButton }
|
||||
{ verifyButton }
|
||||
<AccessibleButton kind="primary_outline" onClick={this.onRename}>
|
||||
{ _t("Rename") }
|
||||
</AccessibleButton>
|
||||
</React.Fragment>;
|
||||
|
||||
return (
|
||||
<tr className={"mx_DevicesPanel_device" + myDeviceClass}>
|
||||
<td className="mx_DevicesPanel_deviceId">
|
||||
{ device.device_id }
|
||||
</td>
|
||||
<td className="mx_DevicesPanel_deviceName">
|
||||
<EditableTextContainer initialValue={device.display_name}
|
||||
onSubmit={this.onDisplayNameChanged}
|
||||
placeholder={device.device_id}
|
||||
/>
|
||||
</td>
|
||||
<td className="mx_DevicesPanel_lastSeen">
|
||||
{ lastSeen }
|
||||
</td>
|
||||
<td className="mx_DevicesPanel_deviceButtons">
|
||||
<StyledCheckbox onChange={this.onDeviceToggled} checked={this.props.selected} />
|
||||
</td>
|
||||
</tr>
|
||||
<div className={"mx_DevicesPanel_device" + myDeviceClass}>
|
||||
{ left }
|
||||
<div className="mx_DevicesPanel_deviceInfo">
|
||||
<div className="mx_DevicesPanel_deviceName">
|
||||
{ deviceName }
|
||||
</div>
|
||||
<div className="mx_DevicesPanel_lastSeen">
|
||||
{ lastSeen }
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx_DevicesPanel_deviceButtons">
|
||||
{ buttons }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue