Update toast styles to match Figma (#12833)

* Warn users on unsupported browsers before they lack features

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update Learn more link

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update toast styles to match Figma

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Remove test code

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* update tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update snapshots

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski
2024-07-30 13:57:15 +01:00
committed by GitHub
parent a1897583b1
commit b0392b8fc3
29 changed files with 156 additions and 114 deletions

View File

@@ -17,6 +17,7 @@ limitations under the License.
import { logger } from "matrix-js-sdk/src/logger";
import browserlist from "browserslist";
import electronToChromium from "electron-to-chromium/versions";
import PopOutIcon from "@vector-im/compound-design-tokens/assets/web/icons/pop-out";
import { DeviceType, parseUserAgent } from "./utils/device/parseUserAgent";
import ToastStore from "./stores/ToastStore";
@@ -112,10 +113,11 @@ export function checkBrowserSupport(): void {
title: _t("unsupported_browser|title", { brand }),
props: {
description: _t("unsupported_browser|description", { brand }),
acceptLabel: _t("action|learn_more"),
onAccept: onLearnMoreClick,
rejectLabel: _t("action|dismiss"),
onReject: onDismissClick,
secondaryLabel: _t("action|learn_more"),
SecondaryIcon: PopOutIcon,
onSecondaryClick: onLearnMoreClick,
primaryLabel: _t("action|dismiss"),
onPrimaryClick: onDismissClick,
},
component: GenericToast,
priority: 40,

View File

@@ -1390,8 +1390,8 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
title: userNotice.title,
props: {
description: <Linkify>{userNotice.description}</Linkify>,
acceptLabel: _t("action|ok"),
onAccept: () => {
primaryLabel: _t("action|ok"),
onPrimaryClick: () => {
ToastStore.sharedInstance().dismissToast(key);
localStorage.setItem(key, "1");
},

View File

@@ -16,6 +16,7 @@ limitations under the License.
import * as React from "react";
import classNames from "classnames";
import { Text } from "@vector-im/compound-web";
import ToastStore, { IToast } from "../../stores/ToastStore";
@@ -78,7 +79,9 @@ export default class ToastContainer extends React.Component<{}, IState> {
if (title) {
titleElement = (
<div className="mx_Toast_title">
<h2>{title}</h2>
<Text size="lg" weight="semibold" as="h2">
{title}
</Text>
<span className="mx_Toast_title_countIndicator">{countIndicator}</span>
</div>
);

View File

@@ -31,9 +31,9 @@ const SECOND = 1000;
const GenericExpiringToast: React.FC<IProps> = ({
description,
acceptLabel,
primaryLabel,
dismissLabel,
onAccept,
onPrimaryClick,
onDismiss,
toastKey,
numSeconds,
@@ -52,10 +52,10 @@ const GenericExpiringToast: React.FC<IProps> = ({
return (
<GenericToast
description={description}
acceptLabel={acceptLabel}
onAccept={onAccept}
rejectLabel={rejectLabel}
onReject={onReject}
primaryLabel={primaryLabel}
onPrimaryClick={onPrimaryClick}
secondaryLabel={rejectLabel}
onSecondaryClick={onReject}
/>
);
};

View File

@@ -14,31 +14,37 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { ReactNode } from "react";
import React, { ComponentType, ReactNode } from "react";
import { Button } from "@vector-im/compound-web";
import AccessibleButton from "../elements/AccessibleButton";
import { XOR } from "../../../@types/common";
export interface IProps {
description: ReactNode;
detail?: ReactNode;
acceptLabel: string;
primaryLabel: string;
PrimaryIcon?: ComponentType<React.SVGAttributes<SVGElement>>;
onAccept(): void;
onPrimaryClick(): void;
}
interface IPropsExtended extends IProps {
rejectLabel: string;
onReject(): void;
secondaryLabel: string;
SecondaryIcon?: ComponentType<React.SVGAttributes<SVGElement>>;
destructive?: "primary" | "secondary";
onSecondaryClick(): void;
}
const GenericToast: React.FC<XOR<IPropsExtended, IProps>> = ({
description,
detail,
acceptLabel,
rejectLabel,
onAccept,
onReject,
primaryLabel,
PrimaryIcon,
secondaryLabel,
SecondaryIcon,
destructive,
onPrimaryClick,
onSecondaryClick,
}) => {
const detailContent = detail ? <div className="mx_Toast_detail">{detail}</div> : null;
@@ -49,14 +55,24 @@ const GenericToast: React.FC<XOR<IPropsExtended, IProps>> = ({
{detailContent}
</div>
<div className="mx_Toast_buttons" aria-live="off">
{onReject && rejectLabel && (
<AccessibleButton kind="danger_outline" onClick={onReject}>
{rejectLabel}
</AccessibleButton>
{onSecondaryClick && secondaryLabel && (
<Button
onClick={onSecondaryClick}
kind={destructive === "secondary" ? "destructive" : "secondary"}
Icon={SecondaryIcon}
size="sm"
>
{secondaryLabel}
</Button>
)}
<AccessibleButton onClick={onAccept} kind="primary">
{acceptLabel}
</AccessibleButton>
<Button
onClick={onPrimaryClick}
kind={destructive === "primary" ? "destructive" : "primary"}
Icon={PrimaryIcon}
size="sm"
>
{primaryLabel}
</Button>
</div>
</div>
);

View File

@@ -185,14 +185,14 @@ export default class VerificationRequestToast extends React.PureComponent<IProps
<GenericToast
description={description}
detail={detail}
acceptLabel={
primaryLabel={
request.isSelfVerification || !request.roomId
? _t("encryption|verification|request_toast_accept")
: _t("encryption|verification|request_toast_accept_user")
}
onAccept={this.accept}
rejectLabel={declineLabel}
onReject={this.cancel}
onPrimaryClick={this.accept}
secondaryLabel={declineLabel}
onSecondaryClick={this.cancel}
/>
);
}

View File

@@ -114,8 +114,8 @@ async function checkServerVersions(): Promise<void> {
version: MINIMUM_MATRIX_VERSION,
brand: SdkConfig.get().brand,
}),
acceptLabel: _t("action|ok"),
onAccept: () => {
primaryLabel: _t("action|ok"),
onPrimaryClick: () => {
ToastStore.sharedInstance().dismissToast(toastKey);
},
},

View File

@@ -87,10 +87,10 @@ export const showToast = (): void => {
// them to opt in again.
props = {
description: _t("analytics|consent_migration"),
acceptLabel: _t("analytics|accept_button"),
onAccept,
rejectLabel: _t("action|learn_more"),
onReject: onLearnMorePreviouslyOptedIn,
primaryLabel: _t("analytics|accept_button"),
onPrimaryClick: onAccept,
secondaryLabel: _t("action|learn_more"),
onSecondaryClick: onLearnMorePreviouslyOptedIn,
};
} else if (legacyAnalyticsOptIn === null || legacyAnalyticsOptIn === undefined) {
// The user had no analytics setting previously set, so we just need to prompt to opt-in, rather than
@@ -102,10 +102,10 @@ export const showToast = (): void => {
);
props = {
description: _t("analytics|learn_more", {}, { LearnMoreLink: learnMoreLink }),
acceptLabel: _t("action|yes"),
onAccept,
rejectLabel: _t("action|no"),
onReject,
primaryLabel: _t("action|yes"),
onPrimaryClick: onAccept,
secondaryLabel: _t("action|no"),
onSecondaryClick: onReject,
};
} else {
// false

View File

@@ -44,10 +44,10 @@ export const showToast = (deviceIds: Set<string>): void => {
icon: "verification_warning",
props: {
description: _t("encryption|verification|unverified_sessions_toast_description"),
acceptLabel: _t("action|review"),
onAccept,
rejectLabel: _t("encryption|verification|unverified_sessions_toast_reject"),
onReject,
primaryLabel: _t("action|review"),
onPrimaryClick: onAccept,
secondaryLabel: _t("encryption|verification|unverified_sessions_toast_reject"),
onSecondaryClick: onReject,
},
component: GenericToast,
priority: 50,

View File

@@ -44,10 +44,10 @@ export const showToast = (fromMessageSend: boolean): void => {
: _t("notifications|enable_prompt_toast_title"),
props: {
description: _t("notifications|enable_prompt_toast_description"),
acceptLabel: _t("action|enable"),
onAccept,
rejectLabel: _t("action|dismiss"),
onReject,
primaryLabel: _t("action|enable"),
onPrimaryClick: onAccept,
secondaryLabel: _t("action|dismiss"),
onSecondaryClick: onReject,
},
component: GenericToast,
priority: 30,

View File

@@ -45,10 +45,10 @@ export const showToast = (): void => {
title: _t("mobile_guide|toast_title"),
props: {
description: _t("mobile_guide|toast_description", { brand }),
acceptLabel: _t("mobile_guide|toast_accept"),
onAccept,
rejectLabel: _t("action|dismiss"),
onReject,
primaryLabel: _t("mobile_guide|toast_accept"),
onPrimaryClick: onAccept,
secondaryLabel: _t("action|dismiss"),
onSecondaryClick: onReject,
},
component: GenericToast,
priority: 99,

View File

@@ -47,8 +47,8 @@ export const showToast = (
{errorText} {contactText}
</React.Fragment>
),
acceptLabel: _t("action|ok"),
onAccept: () => {
primaryLabel: _t("action|ok"),
onPrimaryClick: () => {
hideToast();
if (onHideToast) onHideToast();
},

View File

@@ -114,10 +114,11 @@ export const showToast = (kind: Kind): void => {
icon: getIcon(kind),
props: {
description: getDescription(kind),
acceptLabel: getSetupCaption(kind),
onAccept,
rejectLabel: _t("encryption|verification|unverified_sessions_toast_reject"),
onReject,
primaryLabel: getSetupCaption(kind),
onPrimaryClick: onAccept,
secondaryLabel: _t("encryption|verification|unverified_sessions_toast_reject"),
onSecondaryClick: onReject,
destructive: "secondary",
},
component: GenericToast,
priority: kind === Kind.VERIFY_THIS_SESSION ? 95 : 40,

View File

@@ -59,10 +59,11 @@ export const showToast = async (deviceId: string): Promise<void> => {
props: {
description: device.display_name,
detail: <DeviceMetaData device={extendedDevice} />,
acceptLabel: _t("encryption|verification|unverified_session_toast_accept"),
onAccept,
rejectLabel: _t("action|no"),
onReject,
primaryLabel: _t("encryption|verification|unverified_session_toast_accept"),
onPrimaryClick: onAccept,
secondaryLabel: _t("action|no"),
onSecondaryClick: onReject,
destructive: "secondary",
},
component: GenericToast,
priority: 80,

View File

@@ -83,10 +83,10 @@ export const showToast = (version: string, newVersion: string, releaseNotes?: st
title: _t("update|toast_title", { brand }),
props: {
description: _t("update|toast_description", { brand }),
acceptLabel,
onAccept,
rejectLabel: _t("action|dismiss"),
onReject,
primaryLabel: acceptLabel,
onPrimaryClick: onAccept,
secondaryLabel: _t("action|dismiss"),
onSecondaryClick: onReject,
},
component: GenericToast,
priority: 20,