diff --git a/src/Platform.ts b/src/Platform.ts new file mode 100644 index 00000000..0e5b71f1 --- /dev/null +++ b/src/Platform.ts @@ -0,0 +1,38 @@ +/* +Copyright 2023 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. +*/ + +/** + * The platform on which the application is running. + */ +// The granularity of this value is kind of arbitrary: it distinguishes exactly +// the platforms that the app needs to know about in order to correctly +// implement the designs and work around platform-specific browser weirdness. +// Feel free to increase or decrease that granularity in the future as project +// requirements change. +export let platform: "android" | "ios" | "desktop"; + +if (/android/i.test(navigator.userAgent)) { + platform = "android"; + // We include 'Mac' here and double-check for touch support because iPads on + // iOS 13 pretend to be a MacOS desktop +} else if ( + /iPad|iPhone|iPod|Mac/.test(navigator.userAgent) && + "ontouchend" in document +) { + platform = "ios"; +} else { + platform = "desktop"; +} diff --git a/src/index.css b/src/index.css index c1e9fe1a..025e93db 100644 --- a/src/index.css +++ b/src/index.css @@ -25,12 +25,6 @@ limitations under the License. @import "@vector-im/compound-web/dist/style.css"; :root { - --font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", - "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", - "Helvetica Neue", sans-serif; - --inter-unicode-range: U+0000-20e2, U+20e4-23ce, U+23d0-24c1, U+24c3-259f, - U+25c2-2664, U+2666-2763, U+2765-2b05, U+2b07-2b1b, U+2b1d-10FFFF; - --font-scale: 1; --font-size-micro: calc(10px * var(--font-scale)); --font-size-caption: calc(12px * var(--font-scale)); @@ -149,7 +143,6 @@ body { color: var(--cpd-color-text-primary); color-scheme: dark; margin: 0; - font-family: var(--font-family); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } @@ -165,6 +158,19 @@ body, flex-direction: column; } +/* On Android and iOS, prefer native system fonts */ +body[data-platform="android"] { + --cpd-font-family-sans: "Roboto", "Noto", "Inter", sans-serif; +} + +body[data-platform="ios"] { + --cpd-font-family-sans: -apple-system, BlinkMacSystemFont, "Inter", sans-serif; +} + +body[data-platform="desktop"] { + --cpd-font-family-sans: "Inter", sans-serif; +} + h1, h2, h3, diff --git a/src/initializer.tsx b/src/initializer.tsx index 8e282c37..f4fc99e0 100644 --- a/src/initializer.tsx +++ b/src/initializer.tsx @@ -24,6 +24,7 @@ import * as Sentry from "@sentry/react"; import { getUrlParams } from "./UrlParams"; import { Config } from "./config/Config"; import { ElementCallOpenTelemetry } from "./otel/otel"; +import { platform } from "./Platform"; enum LoadState { None, @@ -107,6 +108,9 @@ export class Initializer { fonts.map((f) => `"${f}"`).join(", ") ); } + + // Add the platform to the DOM, so CSS can query it + document.body.setAttribute("data-platform", platform); } public static init(): Promise | null { diff --git a/src/room/usePageUnload.ts b/src/room/usePageUnload.ts index a6db816d..bae58d27 100644 --- a/src/room/usePageUnload.ts +++ b/src/room/usePageUnload.ts @@ -16,21 +16,7 @@ limitations under the License. import { useEffect } from "react"; -// https://stackoverflow.com/a/9039885 -function isIOS() { - return ( - [ - "iPad Simulator", - "iPhone Simulator", - "iPod Simulator", - "iPad", - "iPhone", - "iPod", - ].includes(navigator.platform) || - // iPad on iOS 13 detection - (navigator.userAgent.includes("Mac") && "ontouchend" in document) - ); -} +import { platform } from "../Platform"; export function usePageUnload(callback: () => void) { useEffect(() => { @@ -53,7 +39,7 @@ export function usePageUnload(callback: () => void) { } // iOS doesn't fire beforeunload event, so leave the call when you hide the page. - if (isIOS()) { + if (platform === "ios") { window.addEventListener("pagehide", onBeforeUnload); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore