Put a switch camera button on the local user's tile
This commit is contained in:
@@ -83,3 +83,25 @@ borders don't support gradients */
|
|||||||
.volumeSlider {
|
.volumeSlider {
|
||||||
width: 100%;
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import {
|
|||||||
UserProfileIcon,
|
UserProfileIcon,
|
||||||
ExpandIcon,
|
ExpandIcon,
|
||||||
VolumeOffSolidIcon,
|
VolumeOffSolidIcon,
|
||||||
|
SwitchCameraSolidIcon,
|
||||||
} from "@vector-im/compound-design-tokens/assets/web/icons";
|
} from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||||
import {
|
import {
|
||||||
ContextMenu,
|
ContextMenu,
|
||||||
@@ -64,6 +65,7 @@ interface UserMediaTileProps extends TileProps {
|
|||||||
vm: UserMediaViewModel;
|
vm: UserMediaViewModel;
|
||||||
mirror: boolean;
|
mirror: boolean;
|
||||||
locallyMuted: boolean;
|
locallyMuted: boolean;
|
||||||
|
primaryButton?: ReactNode;
|
||||||
menuStart?: ReactNode;
|
menuStart?: ReactNode;
|
||||||
menuEnd?: ReactNode;
|
menuEnd?: ReactNode;
|
||||||
}
|
}
|
||||||
@@ -73,6 +75,7 @@ const UserMediaTile: FC<UserMediaTileProps> = ({
|
|||||||
vm,
|
vm,
|
||||||
showSpeakingIndicators,
|
showSpeakingIndicators,
|
||||||
locallyMuted,
|
locallyMuted,
|
||||||
|
primaryButton,
|
||||||
menuStart,
|
menuStart,
|
||||||
menuEnd,
|
menuEnd,
|
||||||
className,
|
className,
|
||||||
@@ -159,20 +162,22 @@ const UserMediaTile: FC<UserMediaTileProps> = ({
|
|||||||
}
|
}
|
||||||
displayName={displayName}
|
displayName={displayName}
|
||||||
primaryButton={
|
primaryButton={
|
||||||
<Menu
|
primaryButton ?? (
|
||||||
open={menuOpen}
|
<Menu
|
||||||
onOpenChange={setMenuOpen}
|
open={menuOpen}
|
||||||
title={displayName}
|
onOpenChange={setMenuOpen}
|
||||||
trigger={
|
title={displayName}
|
||||||
<button aria-label={t("common.options")}>
|
trigger={
|
||||||
<OverflowHorizontalIcon aria-hidden width={20} height={20} />
|
<button aria-label={t("common.options")}>
|
||||||
</button>
|
<OverflowHorizontalIcon aria-hidden width={20} height={20} />
|
||||||
}
|
</button>
|
||||||
side="left"
|
}
|
||||||
align="start"
|
side="left"
|
||||||
>
|
align="start"
|
||||||
{menu}
|
>
|
||||||
</Menu>
|
{menu}
|
||||||
|
</Menu>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
raisedHandTime={handRaised ?? undefined}
|
raisedHandTime={handRaised ?? undefined}
|
||||||
currentReaction={reaction ?? undefined}
|
currentReaction={reaction ?? undefined}
|
||||||
@@ -207,6 +212,8 @@ const LocalUserMediaTile: FC<LocalUserMediaTileProps> = ({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const mirror = useObservableEagerState(vm.mirror$);
|
const mirror = useObservableEagerState(vm.mirror$);
|
||||||
const alwaysShow = useObservableEagerState(vm.alwaysShow$);
|
const alwaysShow = useObservableEagerState(vm.alwaysShow$);
|
||||||
|
const switchCamera = useObservableEagerState(vm.switchCamera$);
|
||||||
|
|
||||||
const latestAlwaysShow = useLatest(alwaysShow);
|
const latestAlwaysShow = useLatest(alwaysShow);
|
||||||
const onSelectAlwaysShow = useCallback(
|
const onSelectAlwaysShow = useCallback(
|
||||||
(e: Event) => {
|
(e: Event) => {
|
||||||
@@ -222,6 +229,17 @@ const LocalUserMediaTile: FC<LocalUserMediaTileProps> = ({
|
|||||||
vm={vm}
|
vm={vm}
|
||||||
locallyMuted={false}
|
locallyMuted={false}
|
||||||
mirror={mirror}
|
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={
|
menuStart={
|
||||||
<ToggleMenuItem
|
<ToggleMenuItem
|
||||||
Icon={VisibilityOnIcon}
|
Icon={VisibilityOnIcon}
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ unconditionally select the container so we can use cqmin units */
|
|||||||
|
|
||||||
.nameTag {
|
.nameTag {
|
||||||
grid-area: nameTag;
|
grid-area: nameTag;
|
||||||
|
place-self: end start;
|
||||||
padding: var(--cpd-space-1x);
|
padding: var(--cpd-space-1x);
|
||||||
padding-block: var(--cpd-space-1x);
|
padding-block: var(--cpd-space-1x);
|
||||||
color: var(--cpd-color-text-primary);
|
color: var(--cpd-color-text-primary);
|
||||||
@@ -173,7 +174,7 @@ unconditionally select the container so we can use cqmin units */
|
|||||||
}
|
}
|
||||||
|
|
||||||
.fg > button:active {
|
.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"] {
|
.fg > button[data-state="open"] {
|
||||||
|
|||||||
Reference in New Issue
Block a user