Update unsupported browser react component to new designs (#27857)
This commit is contained in:
parent
31345ddd36
commit
59e526e318
16 changed files with 564 additions and 466 deletions
|
@ -1,149 +0,0 @@
|
|||
/*
|
||||
Copyright 2020 New Vector Ltd
|
||||
|
||||
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 React, { ReactNode } from "react";
|
||||
import SdkConfig from "matrix-react-sdk/src/SdkConfig";
|
||||
|
||||
import { _t } from "../../languageHandler";
|
||||
|
||||
// directly import the style here as this layer does not support rethemedex at this time so no matrix-react-sdk
|
||||
// PostCSS variables will be accessible.
|
||||
import "../../../res/css/structures/ErrorView.pcss";
|
||||
|
||||
interface IProps {
|
||||
onAccept(): void;
|
||||
}
|
||||
|
||||
const CompatibilityView: React.FC<IProps> = ({ onAccept }) => {
|
||||
const brand = SdkConfig.get("brand");
|
||||
const mobileBuilds = SdkConfig.get("mobile_builds");
|
||||
|
||||
let ios: JSX.Element | undefined;
|
||||
const iosCustomUrl = mobileBuilds?.ios;
|
||||
if (iosCustomUrl !== null) {
|
||||
// could be undefined or a string
|
||||
ios = (
|
||||
<>
|
||||
<p>
|
||||
<strong>iOS</strong> (iPhone or iPad)
|
||||
</p>
|
||||
<a href={iosCustomUrl} target="_blank" rel="noreferrer noopener" className="mx_ClearDecoration">
|
||||
<img height="48" src="themes/element/img/download/apple.svg" alt="Apple App Store" />
|
||||
</a>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
let android = [
|
||||
<p className="mx_Spacer" key="header">
|
||||
<strong>Android</strong>
|
||||
</p>,
|
||||
];
|
||||
const andCustomUrl = mobileBuilds?.android;
|
||||
const fdroidCustomUrl = mobileBuilds?.fdroid;
|
||||
if (andCustomUrl !== null) {
|
||||
// undefined or string
|
||||
android.push(
|
||||
<a
|
||||
href={andCustomUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
className="mx_ClearDecoration"
|
||||
key="android"
|
||||
>
|
||||
<img height="48" src="themes/element/img/download/google.svg" alt="Google Play Store" />
|
||||
</a>,
|
||||
);
|
||||
}
|
||||
if (fdroidCustomUrl !== null) {
|
||||
// undefined or string
|
||||
android.push(
|
||||
<a
|
||||
href={fdroidCustomUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
className="mx_ClearDecoration"
|
||||
key="fdroid"
|
||||
>
|
||||
<img height="48" src="themes/element/img/download/fdroid.svg" alt="F-Droid" />
|
||||
</a>,
|
||||
);
|
||||
}
|
||||
if (android.length === 1) {
|
||||
// just a header, meaning no links
|
||||
android = [];
|
||||
}
|
||||
|
||||
let mobileHeader: ReactNode = <h2 id="step2_heading">{_t("use_brand_on_mobile", { brand })}</h2>;
|
||||
if (!android.length && !ios) {
|
||||
mobileHeader = null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_ErrorView">
|
||||
<div className="mx_ErrorView_container">
|
||||
<div className="mx_HomePage_header">
|
||||
<span className="mx_HomePage_logo">
|
||||
<img height="42" src="themes/element/img/logos/element-logo.svg" alt="Element" />
|
||||
</span>
|
||||
<h1>{_t("incompatible_browser|title")}</h1>
|
||||
</div>
|
||||
|
||||
<div className="mx_HomePage_col">
|
||||
<div className="mx_HomePage_row">
|
||||
<div>
|
||||
<h2 id="step1_heading">{_t("incompatible_browser|summary", { brand })}</h2>
|
||||
<p>{_t("incompatible_browser|features", { brand })}</p>
|
||||
<p>
|
||||
{_t(
|
||||
"incompatible_browser|browser_links",
|
||||
{},
|
||||
{
|
||||
chromeLink: (sub) => <a href="https://www.google.com/chrome">{sub}</a>,
|
||||
firefoxLink: (sub) => <a href="https://firefox.com">{sub}</a>,
|
||||
safariLink: (sub) => <a href="https://apple.com/safari">{sub}</a>,
|
||||
},
|
||||
)}
|
||||
</p>
|
||||
<p>{_t("incompatible_browser|feature_warning")}</p>
|
||||
<button onClick={onAccept}>{_t("incompatible_browser|continue_warning")}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mx_HomePage_col">
|
||||
<div className="mx_HomePage_row">
|
||||
<div>
|
||||
{mobileHeader}
|
||||
{ios}
|
||||
{android}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mx_HomePage_row mx_Center mx_Spacer">
|
||||
<p className="mx_Spacer">
|
||||
<a href="https://element.io" target="_blank" className="mx_FooterLink">
|
||||
{_t("go_to_element_io")}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CompatibilityView;
|
|
@ -14,9 +14,16 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import * as React from "react";
|
||||
import React, { ReactNode } from "react";
|
||||
import { Text, Heading, Button, Separator } from "@vector-im/compound-web";
|
||||
import SdkConfig from "matrix-react-sdk/src/SdkConfig";
|
||||
import { Flex } from "matrix-react-sdk/src/components/utils/Flex";
|
||||
import PopOutIcon from "@vector-im/compound-design-tokens/assets/web/icons/pop-out";
|
||||
|
||||
import { _t } from "../../languageHandler";
|
||||
import { Icon as AppleIcon } from "../../../res/themes/element/img/compound/apple.svg";
|
||||
import { Icon as MicrosoftIcon } from "../../../res/themes/element/img/compound/microsoft.svg";
|
||||
import { Icon as LinuxIcon } from "../../../res/themes/element/img/compound/linux.svg";
|
||||
|
||||
// directly import the style here as this layer does not support rethemedex at this time so no matrix-react-sdk
|
||||
// PostCSS variables will be accessible.
|
||||
|
@ -26,36 +33,184 @@ interface IProps {
|
|||
// both of these should already be internationalised
|
||||
title: string;
|
||||
messages?: string[];
|
||||
footer?: ReactNode;
|
||||
}
|
||||
|
||||
const ErrorView: React.FC<IProps> = ({ title, messages }) => {
|
||||
export const ErrorView: React.FC<IProps> = ({ title, messages, footer, children }) => {
|
||||
return (
|
||||
<div className="mx_ErrorView">
|
||||
<div className="mx_ErrorView cpd-theme-light">
|
||||
<img
|
||||
className="mx_ErrorView_logo"
|
||||
height="160"
|
||||
src="themes/element/img/logos/element-app-logo.png"
|
||||
alt="Element"
|
||||
/>
|
||||
<div className="mx_ErrorView_container">
|
||||
<div className="mx_HomePage_header">
|
||||
<span className="mx_HomePage_logo">
|
||||
<img height="42" src="themes/element/img/logos/element-logo.svg" alt="Element" />
|
||||
</span>
|
||||
<h1>{_t("failed_to_start")}</h1>
|
||||
</div>
|
||||
<div className="mx_HomePage_col">
|
||||
<div className="mx_HomePage_row">
|
||||
<div>
|
||||
<h2 id="step1_heading">{title}</h2>
|
||||
{messages && messages.map((msg) => <p key={msg}>{msg}</p>)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx_HomePage_row mx_Center mx_Spacer">
|
||||
<p className="mx_Spacer">
|
||||
<a href="https://element.io" target="_blank" className="mx_FooterLink">
|
||||
{_t("go_to_element_io")}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<Heading size="md" weight="semibold">
|
||||
{title}
|
||||
</Heading>
|
||||
{messages?.map((message) => (
|
||||
<Text key={message} size="lg">
|
||||
{message}
|
||||
</Text>
|
||||
))}
|
||||
{children}
|
||||
</div>
|
||||
{footer}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ErrorView;
|
||||
const MobileAppLinks: React.FC<{
|
||||
appleAppStoreUrl?: string;
|
||||
googlePlayUrl?: string;
|
||||
fdroidUrl?: string;
|
||||
}> = ({ appleAppStoreUrl, googlePlayUrl, fdroidUrl }) => (
|
||||
<Flex gap="var(--cpd-space-6x)">
|
||||
{appleAppStoreUrl && (
|
||||
<a href={appleAppStoreUrl} target="_blank" rel="noreferrer noopener">
|
||||
<img height="64" src="themes/element/img/download/apple.svg" alt="Apple App Store" />
|
||||
</a>
|
||||
)}
|
||||
{googlePlayUrl && (
|
||||
<a href={googlePlayUrl} target="_blank" rel="noreferrer noopener" key="android">
|
||||
<img height="64" src="themes/element/img/download/google.svg" alt="Google Play Store" />
|
||||
</a>
|
||||
)}
|
||||
{fdroidUrl && (
|
||||
<a href={fdroidUrl} target="_blank" rel="noreferrer noopener" key="fdroid">
|
||||
<img height="64" src="themes/element/img/download/fdroid.svg" alt="F-Droid" />
|
||||
</a>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
|
||||
const DesktopAppLinks: React.FC<{
|
||||
macOsUrl?: string;
|
||||
win64Url?: string;
|
||||
win32Url?: string;
|
||||
linuxUrl?: string;
|
||||
}> = ({ macOsUrl, win64Url, win32Url, linuxUrl }) => {
|
||||
return (
|
||||
<Flex gap="var(--cpd-space-4x)">
|
||||
{macOsUrl && (
|
||||
<Button as="a" href={macOsUrl} kind="secondary" Icon={AppleIcon}>
|
||||
{_t("incompatible_browser|macos")}
|
||||
</Button>
|
||||
)}
|
||||
{win64Url && (
|
||||
<Button as="a" href={win64Url} kind="secondary" Icon={MicrosoftIcon}>
|
||||
{_t("incompatible_browser|windows", { bits: "64" })}
|
||||
</Button>
|
||||
)}
|
||||
{win32Url && (
|
||||
<Button as="a" href={win32Url} kind="secondary" Icon={MicrosoftIcon}>
|
||||
{_t("incompatible_browser|windows", { bits: "32" })}
|
||||
</Button>
|
||||
)}
|
||||
{linuxUrl && (
|
||||
<Button as="a" href={linuxUrl} kind="secondary" Icon={LinuxIcon}>
|
||||
{_t("incompatible_browser|linux")}
|
||||
</Button>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
const linkFactory =
|
||||
(link: string) =>
|
||||
(text: string): JSX.Element => (
|
||||
<a href={link} target="_blank" rel="noreferrer noopener">
|
||||
{text}
|
||||
</a>
|
||||
);
|
||||
|
||||
export const UnsupportedBrowserView: React.FC<{
|
||||
onAccept?(): void;
|
||||
}> = ({ onAccept }) => {
|
||||
const config = SdkConfig.get();
|
||||
const brand = config.brand ?? "Element";
|
||||
|
||||
const hasDesktopBuilds =
|
||||
config.desktop_builds?.available &&
|
||||
(config.desktop_builds?.url_macos ||
|
||||
config.desktop_builds?.url_win64 ||
|
||||
config.desktop_builds?.url_win32 ||
|
||||
config.desktop_builds?.url_linux);
|
||||
const hasMobileBuilds = Boolean(
|
||||
config.mobile_builds?.ios || config.mobile_builds?.android || config.mobile_builds?.fdroid,
|
||||
);
|
||||
|
||||
return (
|
||||
<ErrorView
|
||||
title={_t("incompatible_browser|title", { brand })}
|
||||
messages={[
|
||||
_t("incompatible_browser|description", {
|
||||
brand,
|
||||
detail: onAccept
|
||||
? _t("incompatible_browser|detail_can_continue")
|
||||
: _t("incompatible_browser|detail_no_continue"),
|
||||
}),
|
||||
]}
|
||||
footer={
|
||||
<>
|
||||
{/* We render the apps in the footer as they are wider than the 520px container */}
|
||||
{(hasDesktopBuilds || hasMobileBuilds) && <Separator />}
|
||||
|
||||
{hasDesktopBuilds && (
|
||||
<>
|
||||
<Heading as="h2" size="sm" weight="semibold">
|
||||
{_t("incompatible_browser|use_desktop_heading", { brand })}
|
||||
</Heading>
|
||||
<DesktopAppLinks
|
||||
macOsUrl={config.desktop_builds?.url_macos}
|
||||
win64Url={config.desktop_builds?.url_win64}
|
||||
win32Url={config.desktop_builds?.url_win32}
|
||||
linuxUrl={config.desktop_builds?.url_linux}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
{hasMobileBuilds && (
|
||||
<>
|
||||
<Heading as="h2" size="sm" weight="semibold">
|
||||
{hasDesktopBuilds
|
||||
? _t("incompatible_browser|use_mobile_heading_after_desktop")
|
||||
: _t("incompatible_browser|use_mobile_heading", { brand })}
|
||||
</Heading>
|
||||
<MobileAppLinks
|
||||
appleAppStoreUrl={config.mobile_builds?.ios ?? undefined}
|
||||
googlePlayUrl={config.mobile_builds?.android ?? undefined}
|
||||
fdroidUrl={config.mobile_builds?.fdroid ?? undefined}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Text size="lg">
|
||||
{_t(
|
||||
"incompatible_browser|supported_browsers",
|
||||
{},
|
||||
{
|
||||
Chrome: linkFactory("https://google.com/chrome"),
|
||||
Firefox: linkFactory("https://firefox.com"),
|
||||
Edge: linkFactory("https://microsoft.com/edge"),
|
||||
Safari: linkFactory("https://apple.com/safari"),
|
||||
},
|
||||
)}
|
||||
</Text>
|
||||
|
||||
<Flex gap="var(--cpd-space-4x)" className="mx_ErrorView_buttons">
|
||||
<Button Icon={PopOutIcon} kind="secondary" size="sm">
|
||||
{_t("incompatible_browser|learn_more")}
|
||||
</Button>
|
||||
{onAccept && (
|
||||
<Button kind="primary" size="sm" onClick={onAccept}>
|
||||
{_t("incompatible_browser|continue")}
|
||||
</Button>
|
||||
)}
|
||||
</Flex>
|
||||
</ErrorView>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue