Add primary button icon configuration and set it left arrow in lobby

This commit is contained in:
Timo K
2026-06-09 17:17:25 +02:00
parent 65bd51fe92
commit abf9022fd9
2 changed files with 37 additions and 7 deletions

View File

@@ -6,15 +6,16 @@ Please see LICENSE in the repository root for full details.
*/ */
import { import {
createContext,
type FC,
type MouseEvent,
type ReactNode,
use, use,
useCallback, useCallback,
useEffect, useEffect,
useMemo, useMemo,
useState, useState,
createContext,
type ComponentType,
type FC,
type MouseEvent,
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 { CollapseIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
@@ -28,6 +29,9 @@ 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: (
value: ComponentType<React.SVGAttributes<SVGElement>> | null,
) => void;
setHidden: (value: boolean) => void; setHidden: (value: boolean) => void;
} }
@@ -53,9 +57,18 @@ 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<
React.SVGAttributes<SVGElement>
> | null>(null);
const context = useMemo( const context = useMemo(
() => ({ setTitle, setSecondaryButton, setHidden }), () => ({
[setTitle, setHidden, setSecondaryButton], setTitle,
setSecondaryButton,
setHidden,
setPrimaryButtonIcon,
}),
[setTitle, setHidden, setSecondaryButton, setPrimaryButtonIcon],
); );
return ( return (
@@ -72,7 +85,7 @@ export const AppBar: FC<Props> = ({ children }) => {
<LeftNav> <LeftNav>
<Tooltip label={t("common.back")}> <Tooltip label={t("common.back")}>
<IconButton size="24px" onClick={onBackClick}> <IconButton size="24px" onClick={onBackClick}>
<CollapseIcon aria-hidden /> {PrimaryButtonIcon ? <PrimaryButtonIcon /> : <CollapseIcon />}
</IconButton> </IconButton>
</Tooltip> </Tooltip>
</LeftNav> </LeftNav>
@@ -107,6 +120,20 @@ export function useAppBarTitle(title: string): void {
}, [title, setTitle]); }, [title, setTitle]);
} }
/**
* 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.
*/
export function useAppBarPrimaryButtonIcon(icon: typeof CollapseIcon): void {
const setIcon = use(AppBarContext)?.setPrimaryButtonIcon;
useEffect(() => {
if (setIcon !== undefined) {
setIcon(icon);
return (): void => setIcon(null);
}
}, [setIcon, icon]);
}
/** /**
* 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.

View File

@@ -26,6 +26,7 @@ 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";
@@ -51,6 +52,7 @@ import { CallFooter, type FooterSnapshot } from "../components/CallFooter";
import { useCallViewKeyboardShortcuts } from "../useCallViewKeyboardShortcuts"; import { useCallViewKeyboardShortcuts } from "../useCallViewKeyboardShortcuts";
import { createLobbyFooterViewModel } from "../components/CallFooterViewModel"; import { createLobbyFooterViewModel } from "../components/CallFooterViewModel";
import { type ViewModel } from "../state/ViewModel"; import { type ViewModel } from "../state/ViewModel";
import { useAppBarPrimaryButtonIcon } from "../AppBar";
interface Props { interface Props {
client: MatrixClient; client: MatrixClient;
@@ -87,6 +89,7 @@ export const LobbyView: FC<Props> = ({
const { t } = useTranslation(); const { t } = useTranslation();
usePageTitle(matrixInfo.roomName); usePageTitle(matrixInfo.roomName);
useAppBarPrimaryButtonIcon(ArrowLeftIcon);
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$);