/* Copyright 2020-2024 New Vector Ltd. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ import React, { ReactNode } from "react"; import { Text, Heading, Button, Separator } from "@vector-im/compound-web"; import PopOutIcon from "@vector-im/compound-design-tokens/assets/web/icons/pop-out"; import SdkConfig from "../../SdkConfig"; import { Flex } from "../../components/utils/Flex"; 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. import "../../../res/css/structures/ErrorView.pcss"; interface IProps { // both of these should already be internationalised title: string; messages?: string[]; footer?: ReactNode; children?: ReactNode; } export const ErrorView: React.FC = ({ title, messages, footer, children }) => { return (
Element
{title} {messages?.map((message) => ( {message} ))} {children}
{footer}
); }; const MobileAppLinks: React.FC<{ appleAppStoreUrl?: string; googlePlayUrl?: string; fdroidUrl?: string; }> = ({ appleAppStoreUrl, googlePlayUrl, fdroidUrl }) => ( {appleAppStoreUrl && ( Apple App Store )} {googlePlayUrl && ( Google Play Store )} {fdroidUrl && ( F-Droid )} ); const DesktopAppLinks: React.FC<{ macOsUrl?: string; win64Url?: string; win32Url?: string; linuxUrl?: string; }> = ({ macOsUrl, win64Url, win32Url, linuxUrl }) => { return ( {macOsUrl && ( )} {win64Url && ( )} {win32Url && ( )} {linuxUrl && ( )} ); }; const linkFactory = (link: string) => (text: string): JSX.Element => ( {text} ); 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 ( {/* We render the apps in the footer as they are wider than the 520px container */} {(hasDesktopBuilds || hasMobileBuilds) && } {hasDesktopBuilds && ( <> {_t("incompatible_browser|use_desktop_heading", { brand })} )} {hasMobileBuilds && ( <> {hasDesktopBuilds ? _t("incompatible_browser|use_mobile_heading_after_desktop") : _t("incompatible_browser|use_mobile_heading", { brand })} )} } > {_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"), }, )} {onAccept && ( )} ); };