refactor using enum vs jsx node

This commit is contained in:
Timo K
2026-06-15 14:42:45 +02:00
parent db26db266d
commit 164fb99ace
2 changed files with 31 additions and 21 deletions

View File

@@ -18,7 +18,11 @@ import {
type ReactNode, type ReactNode,
} from "react"; } from "react";
import { Heading, IconButton, Tooltip } from "@vector-im/compound-web"; import { Heading, IconButton, Tooltip } from "@vector-im/compound-web";
import { CollapseIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; import {
ArrowLeftIcon,
ChevronLeftIcon,
CollapseIcon,
} from "@vector-im/compound-design-tokens/assets/web/icons";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { logger } from "matrix-js-sdk/lib/logger"; import { logger } from "matrix-js-sdk/lib/logger";
@@ -29,9 +33,7 @@ import styles from "./AppBar.module.css";
interface AppBarContext { interface AppBarContext {
setTitle: (value: string) => void; setTitle: (value: string) => void;
setSecondaryButton: (value: ReactNode) => void; setSecondaryButton: (value: ReactNode) => void;
setPrimaryButtonIcon: ( setPrimaryButtonIconKind: (value: "back" | "minimise") => void;
value: ComponentType<React.SVGAttributes<SVGElement>> | null,
) => void;
setHidden: (value: boolean) => void; setHidden: (value: boolean) => void;
} }
@@ -57,20 +59,22 @@ export const AppBar: FC<Props> = ({ children }) => {
const [secondaryButton, setSecondaryButton] = useState<ReactNode | null>( const [secondaryButton, setSecondaryButton] = useState<ReactNode | null>(
null, null,
); );
const [PrimaryButtonIcon, setPrimaryButtonIcon] = useState<ComponentType< const [primaryButtonIcon, setPrimaryButtonIconKind] = useState<
React.SVGAttributes<SVGElement> "back" | "minimise"
> | null>(null); >("minimise");
const context = useMemo( const context = useMemo(
() => ({ () => ({
setTitle, setTitle,
setSecondaryButton, setSecondaryButton,
setHidden, setHidden,
setPrimaryButtonIcon, setPrimaryButtonIconKind,
}), }),
[setTitle, setHidden, setSecondaryButton, setPrimaryButtonIcon], [setTitle, setHidden, setSecondaryButton, setPrimaryButtonIconKind],
); );
const BackIcon = platform === "android" ? ArrowLeftIcon : ChevronLeftIcon;
return ( return (
<> <>
<div <div
@@ -84,9 +88,14 @@ export const AppBar: FC<Props> = ({ children }) => {
> >
<LeftNav> <LeftNav>
<Tooltip label={t("common.back")}> <Tooltip label={t("common.back")}>
<IconButton onClick={onBackClick}> <IconButton
{PrimaryButtonIcon ? ( // We render the back button (PrimaryButtonIcon) the same size as the native os.
<PrimaryButtonIcon aria-hidden /> // We render the minimise icon (default) smaller as per designs.
size={primaryButtonIcon === "back" ? "32px" : "24px"}
onClick={onBackClick}
>
{primaryButtonIcon === "back" ? (
<BackIcon aria-hidden />
) : ( ) : (
<CollapseIcon aria-hidden /> <CollapseIcon aria-hidden />
)} )}
@@ -128,14 +137,16 @@ export function useAppBarTitle(title: string): void {
* React hook which sets the title to be shown in the app bar, if present. It is * React hook which sets the title to be shown in the app bar, if present. It is
* an error to call this hook from multiple sites in the same component tree. * an error to call this hook from multiple sites in the same component tree.
*/ */
export function useAppBarPrimaryButtonIcon(icon: typeof CollapseIcon): void { export function useAppBarPrimaryButtonIconKind(
const setIcon = use(AppBarContext)?.setPrimaryButtonIcon; icon: "back" | "minimise",
): void {
const setIconKind = use(AppBarContext)?.setPrimaryButtonIconKind;
useEffect(() => { useEffect(() => {
if (setIcon !== undefined) { if (setIconKind !== undefined) {
setIcon(icon); setIconKind(icon);
return (): void => setIcon(null); return (): void => setIconKind("minimise");
} }
}, [setIcon, icon]); }, [setIconKind, icon]);
} }
/** /**

View File

@@ -26,7 +26,6 @@ import {
} from "livekit-client"; } from "livekit-client";
import { useObservableEagerState } from "observable-hooks"; import { useObservableEagerState } from "observable-hooks";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { ArrowLeftIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
import inCallStyles from "./InCallView.module.css"; import inCallStyles from "./InCallView.module.css";
import styles from "./LobbyView.module.css"; import styles from "./LobbyView.module.css";
@@ -54,7 +53,7 @@ import { createLobbyFooterViewModel } from "../components/CallFooterViewModel";
import { type ViewModel } from "../state/ViewModel"; import { type ViewModel } from "../state/ViewModel";
import { import {
useAppBarHidden, useAppBarHidden,
useAppBarPrimaryButtonIcon, useAppBarPrimaryButtonIconKind,
useAppBarTitle, useAppBarTitle,
} from "../AppBar"; } from "../AppBar";
@@ -95,7 +94,7 @@ export const LobbyView: FC<Props> = ({
useAppBarHidden(false); useAppBarHidden(false);
useAppBarTitle(matrixInfo.roomName); useAppBarTitle(matrixInfo.roomName);
useAppBarPrimaryButtonIcon(ArrowLeftIcon); useAppBarPrimaryButtonIconKind("back");
const audioEnabled = useBehavior(muteStates.audio.enabled$); const audioEnabled = useBehavior(muteStates.audio.enabled$);
const videoEnabled = useBehavior(muteStates.video.enabled$); const videoEnabled = useBehavior(muteStates.video.enabled$);
const toggleAudio = useBehavior(muteStates.audio.toggle$); const toggleAudio = useBehavior(muteStates.audio.toggle$);