mirror of
https://github.com/vector-im/element-call.git
synced 2026-10-16 23:45:50 +00:00
- The camera menu leads with the user's own camera, with the effect in force, full width at sixteen by nine: a background is judged by how it looks rather than by its thumbnail. - It shows the pipeline's own track again, not a second capture. Each provider keeps the camera its pipeline is synced to, before joining and after, and hands it out with its state, so two calls on a page keep their own. It is reported again only when it changes, which keeps the preview from blanking on every change of state. - It and the pre-join preview share useAttachedTrack, which detaches only its own element: the pre-join preview detached every element showing its track, the menu's among them. - Paid for out of the list's share of the call, so a menu with it is no taller: at the top where the list keeps its floor after paying, else first among the options, scrolling away with them. Its size comes from the tokens the stylesheets draw it with, so it is placed once. - While the first effect is prepared the preview shows the wait; with the camera off it says so, and an effect can still be chosen. - The video is rounded itself as well as clipped by its frame: Firefox composites it on a layer of its own, which the frame's rounded clip didn't reach at 100% zoom. Confirmed by hand, as headless Firefox draws it rounded either way. - Every camera story shows the preview, with a stand-in camera drawn to a stream. End to end on Chromium and Firefox, the lobby's menu shows the camera and then the chosen picture. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
37 lines
1.0 KiB
TypeScript
37 lines
1.0 KiB
TypeScript
/*
|
|
Copyright 2026 Element Creations Ltd.
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
Please see LICENSE in the repository root for full details.
|
|
*/
|
|
|
|
import { type FC } from "react";
|
|
import { type LocalVideoTrack } from "livekit-client";
|
|
import { VideoCallOffIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
|
|
|
import styles from "./SelfPreview.module.css";
|
|
import { useAttachedTrack } from "../useAttachedTrack";
|
|
|
|
interface Props {
|
|
/** The camera as the pipeline has it, or none while the camera is off. */
|
|
track: LocalVideoTrack | null;
|
|
}
|
|
|
|
/**
|
|
* The user's own camera with the effect in force: the pipeline's own track,
|
|
* shown a second time rather than captured again.
|
|
*/
|
|
export const SelfPreview: FC<Props> = ({ track }) => {
|
|
const { videoRef, mirrored } = useAttachedTrack(track);
|
|
|
|
if (!track) return <VideoCallOffIcon width={32} height={32} />;
|
|
return (
|
|
<video
|
|
ref={videoRef}
|
|
muted
|
|
playsInline
|
|
className={mirrored ? styles.mirrored : undefined}
|
|
/>
|
|
);
|
|
};
|