Merge pull request #1912 from robintown/unencrypted-indicator
Show a warning on unencrypted media
This commit is contained in:
@@ -292,6 +292,7 @@ export const InCallView: FC<InCallViewProps> = ({
|
|||||||
data={maximisedParticipant.data}
|
data={maximisedParticipant.data}
|
||||||
showSpeakingIndicator={false}
|
showSpeakingIndicator={false}
|
||||||
showConnectionStats={showConnectionStats}
|
showConnectionStats={showConnectionStats}
|
||||||
|
matrixInfo={matrixInfo}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -310,6 +311,7 @@ export const InCallView: FC<InCallViewProps> = ({
|
|||||||
onToggleFullscreen={toggleFullscreen}
|
onToggleFullscreen={toggleFullscreen}
|
||||||
showSpeakingIndicator={items.length > 2}
|
showSpeakingIndicator={items.length > 2}
|
||||||
showConnectionStats={showConnectionStats}
|
showConnectionStats={showConnectionStats}
|
||||||
|
matrixInfo={matrixInfo}
|
||||||
{...props}
|
{...props}
|
||||||
ref={props.ref as Ref<HTMLDivElement>}
|
ref={props.ref as Ref<HTMLDivElement>}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -88,11 +88,11 @@ limitations under the License.
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nameTag > svg[data-muted="true"] {
|
.muteIcon[data-muted="true"] {
|
||||||
color: var(--cpd-color-icon-secondary);
|
color: var(--cpd-color-icon-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nameTag > svg[data-muted="false"] {
|
.muteIcon[data-muted="false"] {
|
||||||
color: var(--cpd-color-icon-primary);
|
color: var(--cpd-color-icon-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,6 +103,10 @@ limitations under the License.
|
|||||||
padding-inline: var(--cpd-space-2x);
|
padding-inline: var(--cpd-space-2x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.errorIcon {
|
||||||
|
color: var(--cpd-color-icon-critical-primary);
|
||||||
|
}
|
||||||
|
|
||||||
.toolbar {
|
.toolbar {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|||||||
@@ -36,13 +36,15 @@ import {
|
|||||||
} from "matrix-js-sdk/src/models/room-member";
|
} from "matrix-js-sdk/src/models/room-member";
|
||||||
import MicOnSolidIcon from "@vector-im/compound-design-tokens/icons/mic-on-solid.svg?react";
|
import MicOnSolidIcon from "@vector-im/compound-design-tokens/icons/mic-on-solid.svg?react";
|
||||||
import MicOffSolidIcon from "@vector-im/compound-design-tokens/icons/mic-off-solid.svg?react";
|
import MicOffSolidIcon from "@vector-im/compound-design-tokens/icons/mic-off-solid.svg?react";
|
||||||
import { Text } from "@vector-im/compound-web";
|
import ErrorIcon from "@vector-im/compound-design-tokens/icons/error.svg?react";
|
||||||
|
import { Text, Tooltip } from "@vector-im/compound-web";
|
||||||
|
|
||||||
import { Avatar } from "../Avatar";
|
import { Avatar } from "../Avatar";
|
||||||
import styles from "./VideoTile.module.css";
|
import styles from "./VideoTile.module.css";
|
||||||
import { useReactiveState } from "../useReactiveState";
|
import { useReactiveState } from "../useReactiveState";
|
||||||
import { AudioButton, FullscreenButton } from "../button/Button";
|
import { AudioButton, FullscreenButton } from "../button/Button";
|
||||||
import { VideoTileSettingsModal } from "./VideoTileSettingsModal";
|
import { VideoTileSettingsModal } from "./VideoTileSettingsModal";
|
||||||
|
import { MatrixInfo } from "../room/VideoPreview";
|
||||||
|
|
||||||
export interface ItemData {
|
export interface ItemData {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -68,6 +70,9 @@ interface Props {
|
|||||||
style?: ComponentProps<typeof animated.div>["style"];
|
style?: ComponentProps<typeof animated.div>["style"];
|
||||||
showSpeakingIndicator: boolean;
|
showSpeakingIndicator: boolean;
|
||||||
showConnectionStats: boolean;
|
showConnectionStats: boolean;
|
||||||
|
// TODO: This dependency in particular should probably not be here. We can fix
|
||||||
|
// this with a view model.
|
||||||
|
matrixInfo: MatrixInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VideoTile = forwardRef<HTMLDivElement, Props>(
|
export const VideoTile = forwardRef<HTMLDivElement, Props>(
|
||||||
@@ -83,6 +88,7 @@ export const VideoTile = forwardRef<HTMLDivElement, Props>(
|
|||||||
targetHeight,
|
targetHeight,
|
||||||
showSpeakingIndicator,
|
showSpeakingIndicator,
|
||||||
showConnectionStats,
|
showConnectionStats,
|
||||||
|
matrixInfo,
|
||||||
},
|
},
|
||||||
tileRef,
|
tileRef,
|
||||||
) => {
|
) => {
|
||||||
@@ -108,13 +114,22 @@ export const VideoTile = forwardRef<HTMLDivElement, Props>(
|
|||||||
}
|
}
|
||||||
}, [member, setDisplayName]);
|
}, [member, setDisplayName]);
|
||||||
|
|
||||||
const muted =
|
const audioInfo = useMediaTrack(
|
||||||
useMediaTrack(
|
|
||||||
content === TileContent.UserMedia
|
content === TileContent.UserMedia
|
||||||
? Track.Source.Microphone
|
? Track.Source.Microphone
|
||||||
: Track.Source.ScreenShareAudio,
|
: Track.Source.ScreenShareAudio,
|
||||||
sfuParticipant,
|
sfuParticipant,
|
||||||
).isMuted !== false;
|
);
|
||||||
|
const videoInfo = useMediaTrack(
|
||||||
|
content === TileContent.UserMedia
|
||||||
|
? Track.Source.Camera
|
||||||
|
: Track.Source.ScreenShare,
|
||||||
|
sfuParticipant,
|
||||||
|
);
|
||||||
|
const muted = audioInfo.isMuted !== false;
|
||||||
|
const encrypted =
|
||||||
|
audioInfo.publication?.isEncrypted !== false &&
|
||||||
|
videoInfo.publication?.isEncrypted !== false;
|
||||||
|
|
||||||
const MicIcon = muted ? MicOffSolidIcon : MicOnSolidIcon;
|
const MicIcon = muted ? MicOffSolidIcon : MicOnSolidIcon;
|
||||||
|
|
||||||
@@ -202,12 +217,29 @@ export const VideoTile = forwardRef<HTMLDivElement, Props>(
|
|||||||
height={20}
|
height={20}
|
||||||
aria-label={muted ? t("microphone_off") : t("microphone_on")}
|
aria-label={muted ? t("microphone_off") : t("microphone_on")}
|
||||||
data-muted={muted}
|
data-muted={muted}
|
||||||
|
className={styles.muteIcon}
|
||||||
/>
|
/>
|
||||||
<Text as="span" size="sm" weight="medium">
|
<Text as="span" size="sm" weight="medium">
|
||||||
{sfuParticipant.isLocal
|
{sfuParticipant.isLocal
|
||||||
? t("video_tile.sfu_participant_local")
|
? t("video_tile.sfu_participant_local")
|
||||||
: displayName}
|
: displayName}
|
||||||
</Text>
|
</Text>
|
||||||
|
{matrixInfo.roomEncrypted && !encrypted && (
|
||||||
|
<Tooltip label={t("common.unencrypted")} side="bottom">
|
||||||
|
<ErrorIcon
|
||||||
|
width={20}
|
||||||
|
height={20}
|
||||||
|
aria-label={t("common.unencrypted")}
|
||||||
|
className={styles.errorIcon}
|
||||||
|
// Make the icon focusable so that the tooltip can be opened
|
||||||
|
// with keyboard navigation
|
||||||
|
// TODO: Replace this with the solution from
|
||||||
|
// https://github.com/vector-im/compound-web/pull/130 once it
|
||||||
|
// lands
|
||||||
|
tabIndex={0}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
{showConnectionStats && (
|
{showConnectionStats && (
|
||||||
<ConnectionQualityIndicator participant={sfuParticipant} />
|
<ConnectionQualityIndicator participant={sfuParticipant} />
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user