Put a switch camera button on the local user's tile

This commit is contained in:
Robin
2025-06-12 21:33:04 -04:00
parent f53558cb81
commit 31bb46485f
3 changed files with 56 additions and 15 deletions

View File

@@ -83,3 +83,25 @@ borders don't support gradients */
.volumeSlider {
width: 100%;
}
.tile .switchCamera {
opacity: 1;
background: var(--cpd-color-bg-action-secondary-rest);
border: 1px solid var(--cpd-color-border-interactive-secondary);
}
.tile .switchCamera > svg {
color: var(--cpd-color-icon-primary);
}
@media (hover) {
.tile .switchCamera:hover {
background: var(--cpd-color-bg-subtle-secondary);
border-color: var(--cpd-color-border-interactive-hovered);
}
}
.tile .switchCamera:active {
background: var(--cpd-color-bg-subtle-primary);
border-color: var(--cpd-color-border-interactive-hovered);
}

View File

@@ -28,6 +28,7 @@ import {
UserProfileIcon,
ExpandIcon,
VolumeOffSolidIcon,
SwitchCameraSolidIcon,
} from "@vector-im/compound-design-tokens/assets/web/icons";
import {
ContextMenu,
@@ -64,6 +65,7 @@ interface UserMediaTileProps extends TileProps {
vm: UserMediaViewModel;
mirror: boolean;
locallyMuted: boolean;
primaryButton?: ReactNode;
menuStart?: ReactNode;
menuEnd?: ReactNode;
}
@@ -73,6 +75,7 @@ const UserMediaTile: FC<UserMediaTileProps> = ({
vm,
showSpeakingIndicators,
locallyMuted,
primaryButton,
menuStart,
menuEnd,
className,
@@ -159,20 +162,22 @@ const UserMediaTile: FC<UserMediaTileProps> = ({
}
displayName={displayName}
primaryButton={
<Menu
open={menuOpen}
onOpenChange={setMenuOpen}
title={displayName}
trigger={
<button aria-label={t("common.options")}>
<OverflowHorizontalIcon aria-hidden width={20} height={20} />
</button>
}
side="left"
align="start"
>
{menu}
</Menu>
primaryButton ?? (
<Menu
open={menuOpen}
onOpenChange={setMenuOpen}
title={displayName}
trigger={
<button aria-label={t("common.options")}>
<OverflowHorizontalIcon aria-hidden width={20} height={20} />
</button>
}
side="left"
align="start"
>
{menu}
</Menu>
)
}
raisedHandTime={handRaised ?? undefined}
currentReaction={reaction ?? undefined}
@@ -207,6 +212,8 @@ const LocalUserMediaTile: FC<LocalUserMediaTileProps> = ({
const { t } = useTranslation();
const mirror = useObservableEagerState(vm.mirror$);
const alwaysShow = useObservableEagerState(vm.alwaysShow$);
const switchCamera = useObservableEagerState(vm.switchCamera$);
const latestAlwaysShow = useLatest(alwaysShow);
const onSelectAlwaysShow = useCallback(
(e: Event) => {
@@ -222,6 +229,17 @@ const LocalUserMediaTile: FC<LocalUserMediaTileProps> = ({
vm={vm}
locallyMuted={false}
mirror={mirror}
primaryButton={
switchCamera === null ? undefined : (
<button
className={styles.switchCamera}
aria-label={t("switch_camera")}
onClick={switchCamera}
>
<SwitchCameraSolidIcon aria-hidden width={20} height={20} />
</button>
)
}
menuStart={
<ToggleMenuItem
Icon={VisibilityOnIcon}

View File

@@ -85,6 +85,7 @@ unconditionally select the container so we can use cqmin units */
.nameTag {
grid-area: nameTag;
place-self: end start;
padding: var(--cpd-space-1x);
padding-block: var(--cpd-space-1x);
color: var(--cpd-color-text-primary);
@@ -173,7 +174,7 @@ unconditionally select the container so we can use cqmin units */
}
.fg > button:active {
background: var(--cpd-color-bg-action-primary-pressed) !important;
background: var(--cpd-color-bg-action-primary-pressed);
}
.fg > button[data-state="open"] {