Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Device manager - current device design and copy tweaks #9801

Merged
merged 8 commits into from
Dec 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions res/css/_components.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
@import "./components/views/location/_ZoomButtons.pcss";
@import "./components/views/messages/_MBeaconBody.pcss";
@import "./components/views/messages/shared/_MediaProcessingError.pcss";
@import "./components/views/settings/devices/_CurrentDeviceSection.pcss";
@import "./components/views/settings/devices/_DeviceDetailHeading.pcss";
@import "./components/views/settings/devices/_DeviceDetails.pcss";
@import "./components/views/settings/devices/_DeviceExpandDetailsButton.pcss";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.

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.
*/

.mx_CurrentDeviceSection_deviceDetails {
// align with text of session tile
margin-left: 56px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ limitations under the License.
flex-direction: column;
box-sizing: border-box;

width: 100%;

margin-top: $spacing-16;
padding: $spacing-24;
border-radius: 8px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,8 @@ limitations under the License.
flex-direction: row;
gap: $spacing-8;
}

.mx_FilteredDeviceList_deviceDetails {
// align with text of session tile
margin-left: 88px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,16 @@ const CurrentDeviceSection: React.FC<Props> = ({
onVerifyDevice={onVerifyCurrentDevice}
onSignOutDevice={onSignOutCurrentDevice}
saveDeviceName={saveDeviceName}
className="mx_CurrentDeviceSection_deviceDetails"
/>
) : (
<>
<br />
<DeviceVerificationStatusCard device={device} onVerifyDevice={onVerifyCurrentDevice} />
<DeviceVerificationStatusCard
device={device}
onVerifyDevice={onVerifyCurrentDevice}
isCurrentDevice
/>
</>
)}
</>
Expand Down
9 changes: 7 additions & 2 deletions src/components/views/settings/devices/DeviceDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ limitations under the License.
*/

import React from "react";
import classNames from "classnames";
import { IPusher } from "matrix-js-sdk/src/@types/PushRules";
import { PUSHER_ENABLED } from "matrix-js-sdk/src/@types/event";
import { LocalNotificationSettings } from "matrix-js-sdk/src/@types/local_notifications";
Expand All @@ -38,6 +39,8 @@ interface Props {
saveDeviceName: (deviceName: string) => Promise<void>;
setPushNotifications?: (deviceId: string, enabled: boolean) => Promise<void> | undefined;
supportsMSC3881?: boolean | undefined;
className?: string;
isCurrentDevice?: boolean;
}

interface MetadataTable {
Expand All @@ -56,6 +59,8 @@ const DeviceDetails: React.FC<Props> = ({
saveDeviceName,
setPushNotifications,
supportsMSC3881,
className,
isCurrentDevice,
}) => {
const metadata: MetadataTable[] = [
{
Expand Down Expand Up @@ -113,10 +118,10 @@ const DeviceDetails: React.FC<Props> = ({
}

return (
<div className="mx_DeviceDetails" data-testid={`device-detail-${device.device_id}`}>
<div className={classNames("mx_DeviceDetails", className)} data-testid={`device-detail-${device.device_id}`}>
<section className="mx_DeviceDetails_section">
<DeviceDetailHeading device={device} saveDeviceName={saveDeviceName} />
<DeviceVerificationStatusCard device={device} onVerifyDevice={onVerifyDevice} />
<DeviceVerificationStatusCard device={device} onVerifyDevice={onVerifyDevice} isCurrentDevice />
</section>
<section className="mx_DeviceDetails_section">
<p className="mx_DeviceDetails_sectionHeading">{_t("Session details")}</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,30 @@ import DeviceSecurityCard from "./DeviceSecurityCard";
import { DeviceSecurityLearnMore } from "./DeviceSecurityLearnMore";
import { DeviceSecurityVariation, ExtendedDevice } from "./types";

interface Props {
export interface DeviceVerificationStatusCardProps {
device: ExtendedDevice;
isCurrentDevice?: boolean;
onVerifyDevice?: () => void;
}

const getCardProps = (
device: ExtendedDevice,
isCurrentDevice?: boolean,
): {
variation: DeviceSecurityVariation;
heading: string;
description: React.ReactNode;
} => {
if (device.isVerified) {
const descriptionText = isCurrentDevice
? _t("Your current session is ready for secure messaging.")
: _t("This session is ready for secure messaging.");
return {
variation: DeviceSecurityVariation.Verified,
heading: _t("Verified session"),
description: (
<>
{_t("This session is ready for secure messaging.")}
{descriptionText}
<DeviceSecurityLearnMore variation={DeviceSecurityVariation.Verified} />
</>
),
Expand All @@ -59,20 +64,27 @@ const getCardProps = (
};
}

const descriptionText = isCurrentDevice
? _t("Verify your current session for enhanced secure messaging.")
: _t("Verify or sign out from this session for best security and reliability.");
return {
variation: DeviceSecurityVariation.Unverified,
heading: _t("Unverified session"),
description: (
<>
{_t("Verify or sign out from this session for best security and reliability.")}
{descriptionText}
<DeviceSecurityLearnMore variation={DeviceSecurityVariation.Unverified} />
</>
),
};
};

export const DeviceVerificationStatusCard: React.FC<Props> = ({ device, onVerifyDevice }) => {
const securityCardProps = getCardProps(device);
export const DeviceVerificationStatusCard: React.FC<DeviceVerificationStatusCardProps> = ({
device,
isCurrentDevice,
onVerifyDevice,
}) => {
const securityCardProps = getCardProps(device, isCurrentDevice);

return (
<DeviceSecurityCard {...securityCardProps}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ const DeviceListItem: React.FC<{
saveDeviceName={saveDeviceName}
setPushNotifications={setPushNotifications}
supportsMSC3881={supportsMSC3881}
className="mx_FilteredDeviceList_deviceDetails"
/>
)}
</li>
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1817,9 +1817,11 @@
"Mobile session": "Mobile session",
"Web session": "Web session",
"Unknown session type": "Unknown session type",
"Verified session": "Verified session",
"Your current session is ready for secure messaging.": "Your current session is ready for secure messaging.",
"This session is ready for secure messaging.": "This session is ready for secure messaging.",
"Verified session": "Verified session",
"This session doesn't support encryption and thus can't be verified.": "This session doesn't support encryption and thus can't be verified.",
"Verify your current session for enhanced secure messaging.": "Verify your current session for enhanced secure messaging.",
"Verify or sign out from this session for best security and reliability.": "Verify or sign out from this session for best security and reliability.",
"Verify session": "Verify session",
"For best security, sign out from any session that you don't recognize or use anymore.": "For best security, sign out from any session that you don't recognize or use anymore.",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.

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 { render } from "@testing-library/react";
import React from "react";

import {
DeviceVerificationStatusCard,
DeviceVerificationStatusCardProps,
} from "../../../../../src/components/views/settings/devices/DeviceVerificationStatusCard";
import { ExtendedDevice } from "../../../../../src/components/views/settings/devices/types";
import { DeviceType } from "../../../../../src/utils/device/parseUserAgent";

describe("<DeviceVerificationStatusCard />", () => {
const deviceId = "test-device";
const unverifiedDevice: ExtendedDevice = {
device_id: deviceId,
isVerified: false,
deviceType: DeviceType.Unknown,
};
const verifiedDevice: ExtendedDevice = {
...unverifiedDevice,
isVerified: true,
};
const unverifiableDevice: ExtendedDevice = {
...unverifiedDevice,
isVerified: null,
};
const defaultProps = {
device: unverifiedDevice,
onVerifyDevice: jest.fn(),
};
const getComponent = (props: Partial<DeviceVerificationStatusCardProps> = {}) => (
<DeviceVerificationStatusCard {...defaultProps} {...props} />
);

const verifyButtonTestId = `verification-status-button-${deviceId}`;

describe("for the current device", () => {
// current device uses different copy
it("renders an unverified device", () => {
const { getByText } = render(getComponent({ isCurrentDevice: true }));
expect(getByText("Verify your current session for enhanced secure messaging.")).toBeTruthy();
});

it("renders an unverifiable device", () => {
const { getByText } = render(
getComponent({
device: unverifiableDevice,
isCurrentDevice: true,
}),
);
expect(getByText("This session doesn't support encryption and thus can't be verified.")).toBeTruthy();
});

it("renders a verified device", () => {
const { getByText } = render(
getComponent({
device: verifiedDevice,
isCurrentDevice: true,
}),
);
expect(getByText("Your current session is ready for secure messaging.")).toBeTruthy();
});
});

it("renders an unverified device", () => {
const { container } = render(getComponent());
expect(container).toMatchSnapshot();
});

it("renders an unverifiable device", () => {
const { container, queryByTestId } = render(getComponent({ device: unverifiableDevice }));
expect(container).toMatchSnapshot();
expect(queryByTestId(verifyButtonTestId)).toBeFalsy();
});

it("renders a verified device", () => {
const { container, queryByTestId } = render(getComponent({ device: verifiedDevice }));
expect(container).toMatchSnapshot();
expect(queryByTestId(verifyButtonTestId)).toBeFalsy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
exports[`<CurrentDeviceSection /> displays device details on toggle click 1`] = `
HTMLCollection [
<div
class="mx_DeviceDetails"
class="mx_DeviceDetails mx_CurrentDeviceSection_deviceDetails"
data-testid="device-detail-alices_device"
>
<section
Expand Down Expand Up @@ -49,7 +49,7 @@ HTMLCollection [
<p
class="mx_DeviceSecurityCard_description"
>
Verify or sign out from this session for best security and reliability.
Verify your current session for enhanced secure messaging.
<div
class="mx_AccessibleButton mx_LearnMore_button mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
role="button"
Expand Down Expand Up @@ -272,7 +272,7 @@ exports[`<CurrentDeviceSection /> renders device and correct security card when
<p
class="mx_DeviceSecurityCard_description"
>
Verify or sign out from this session for best security and reliability.
Verify your current session for enhanced secure messaging.
<div
class="mx_AccessibleButton mx_LearnMore_button mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
role="button"
Expand Down Expand Up @@ -415,7 +415,7 @@ exports[`<CurrentDeviceSection /> renders device and correct security card when
<p
class="mx_DeviceSecurityCard_description"
>
Verify or sign out from this session for best security and reliability.
Verify your current session for enhanced secure messaging.
<div
class="mx_AccessibleButton mx_LearnMore_button mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
role="button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ exports[`<DeviceDetails /> renders a verified device 1`] = `
<p
class="mx_DeviceSecurityCard_description"
>
This session is ready for secure messaging.
Your current session is ready for secure messaging.
<div
class="mx_AccessibleButton mx_LearnMore_button mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
role="button"
Expand Down Expand Up @@ -158,7 +158,7 @@ exports[`<DeviceDetails /> renders device with metadata 1`] = `
<p
class="mx_DeviceSecurityCard_description"
>
Verify or sign out from this session for best security and reliability.
Verify your current session for enhanced secure messaging.
<div
class="mx_AccessibleButton mx_LearnMore_button mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
role="button"
Expand Down Expand Up @@ -367,7 +367,7 @@ exports[`<DeviceDetails /> renders device without metadata 1`] = `
<p
class="mx_DeviceSecurityCard_description"
>
Verify or sign out from this session for best security and reliability.
Verify your current session for enhanced secure messaging.
<div
class="mx_AccessibleButton mx_LearnMore_button mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
role="button"
Expand Down
Loading