mirror of
https://github.com/vector-im/element-call.git
synced 2026-02-02 04:05:56 +00:00
devtool: quick display of focus URL in stats tile
This commit is contained in:
@@ -19,10 +19,26 @@ import mediaViewStyles from "../src/tile/MediaView.module.css";
|
||||
interface Props {
|
||||
audio?: RTCInboundRtpStreamStats | RTCOutboundRtpStreamStats;
|
||||
video?: RTCInboundRtpStreamStats | RTCOutboundRtpStreamStats;
|
||||
focusUrl?: string;
|
||||
}
|
||||
|
||||
const extractDomain = (url: string): string => {
|
||||
try {
|
||||
const parsedUrl = new URL(url);
|
||||
return parsedUrl.hostname; // Returns "kdk.cpm"
|
||||
} catch (error) {
|
||||
console.error("Invalid URL:", error);
|
||||
return url;
|
||||
}
|
||||
};
|
||||
|
||||
// This is only used in developer mode for debugging purposes, so we don't need full localization
|
||||
export const RTCConnectionStats: FC<Props> = ({ audio, video, ...rest }) => {
|
||||
export const RTCConnectionStats: FC<Props> = ({
|
||||
audio,
|
||||
video,
|
||||
focusUrl,
|
||||
...rest
|
||||
}) => {
|
||||
const [showModal, setShowModal] = useState(false);
|
||||
const [modalContents, setModalContents] = useState<
|
||||
"video" | "audio" | "none"
|
||||
@@ -55,6 +71,13 @@ export const RTCConnectionStats: FC<Props> = ({ audio, video, ...rest }) => {
|
||||
</pre>
|
||||
</div>
|
||||
</Modal>
|
||||
{focusUrl && (
|
||||
<div>
|
||||
<Text as="span" size="xs" title="focusURL">
|
||||
{extractDomain(focusUrl)}
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
{audio && (
|
||||
<div>
|
||||
<Button
|
||||
|
||||
@@ -750,7 +750,11 @@ export class CallViewModel extends ViewModel {
|
||||
scan((prevItems, [participantsByRoom, duplicateTiles]) => {
|
||||
const newItems: Map<string, UserMedia | ScreenShare> = new Map(
|
||||
function* (this: CallViewModel): Iterable<[string, MediaItem]> {
|
||||
for (const { livekitRoom, participants } of participantsByRoom) {
|
||||
for (const {
|
||||
livekitRoom,
|
||||
participants,
|
||||
url,
|
||||
} of participantsByRoom) {
|
||||
for (const { id, participant, member } of participants) {
|
||||
for (let i = 0; i < 1 + duplicateTiles; i++) {
|
||||
const mediaId = `${id}:${i}`;
|
||||
@@ -770,6 +774,7 @@ export class CallViewModel extends ViewModel {
|
||||
participant,
|
||||
this.options.encryptionSystem,
|
||||
livekitRoom,
|
||||
url,
|
||||
this.mediaDevices,
|
||||
this.pretendToBeDisconnected$,
|
||||
this.memberDisplaynames$.pipe(
|
||||
@@ -791,6 +796,7 @@ export class CallViewModel extends ViewModel {
|
||||
participant,
|
||||
this.options.encryptionSystem,
|
||||
livekitRoom,
|
||||
url,
|
||||
this.pretendToBeDisconnected$,
|
||||
this.memberDisplaynames$.pipe(
|
||||
map((m) => m.get(id) ?? "[👻]"),
|
||||
|
||||
@@ -266,6 +266,7 @@ abstract class BaseMediaViewModel extends ViewModel {
|
||||
audioSource: AudioSource,
|
||||
videoSource: VideoSource,
|
||||
livekitRoom: LivekitRoom,
|
||||
public readonly focusURL: string,
|
||||
public readonly displayName$: Behavior<string>,
|
||||
) {
|
||||
super();
|
||||
@@ -407,6 +408,7 @@ abstract class BaseUserMediaViewModel extends BaseMediaViewModel {
|
||||
participant$: Observable<LocalParticipant | RemoteParticipant | undefined>,
|
||||
encryptionSystem: EncryptionSystem,
|
||||
livekitRoom: LivekitRoom,
|
||||
focusUrl: string,
|
||||
displayName$: Behavior<string>,
|
||||
public readonly handRaised$: Behavior<Date | null>,
|
||||
public readonly reaction$: Behavior<ReactionOption | null>,
|
||||
@@ -419,6 +421,7 @@ abstract class BaseUserMediaViewModel extends BaseMediaViewModel {
|
||||
Track.Source.Microphone,
|
||||
Track.Source.Camera,
|
||||
livekitRoom,
|
||||
focusUrl,
|
||||
displayName$,
|
||||
);
|
||||
|
||||
@@ -539,6 +542,7 @@ export class LocalUserMediaViewModel extends BaseUserMediaViewModel {
|
||||
participant$: Behavior<LocalParticipant | undefined>,
|
||||
encryptionSystem: EncryptionSystem,
|
||||
livekitRoom: LivekitRoom,
|
||||
focusURL: string,
|
||||
private readonly mediaDevices: MediaDevices,
|
||||
displayName$: Behavior<string>,
|
||||
handRaised$: Behavior<Date | null>,
|
||||
@@ -550,6 +554,7 @@ export class LocalUserMediaViewModel extends BaseUserMediaViewModel {
|
||||
participant$,
|
||||
encryptionSystem,
|
||||
livekitRoom,
|
||||
focusURL,
|
||||
displayName$,
|
||||
handRaised$,
|
||||
reaction$,
|
||||
@@ -645,6 +650,7 @@ export class RemoteUserMediaViewModel extends BaseUserMediaViewModel {
|
||||
participant$: Observable<RemoteParticipant | undefined>,
|
||||
encryptionSystem: EncryptionSystem,
|
||||
livekitRoom: LivekitRoom,
|
||||
focusUrl: string,
|
||||
private readonly pretendToBeDisconnected$: Behavior<boolean>,
|
||||
displayname$: Behavior<string>,
|
||||
handRaised$: Behavior<Date | null>,
|
||||
@@ -656,6 +662,7 @@ export class RemoteUserMediaViewModel extends BaseUserMediaViewModel {
|
||||
participant$,
|
||||
encryptionSystem,
|
||||
livekitRoom,
|
||||
focusUrl,
|
||||
displayname$,
|
||||
handRaised$,
|
||||
reaction$,
|
||||
@@ -740,6 +747,7 @@ export class ScreenShareViewModel extends BaseMediaViewModel {
|
||||
participant$: Observable<LocalParticipant | RemoteParticipant>,
|
||||
encryptionSystem: EncryptionSystem,
|
||||
livekitRoom: LivekitRoom,
|
||||
focusUrl: string,
|
||||
private readonly pretendToBeDisconnected$: Behavior<boolean>,
|
||||
displayname$: Behavior<string>,
|
||||
public readonly local: boolean,
|
||||
@@ -752,6 +760,7 @@ export class ScreenShareViewModel extends BaseMediaViewModel {
|
||||
Track.Source.ScreenShareAudio,
|
||||
Track.Source.ScreenShare,
|
||||
livekitRoom,
|
||||
focusUrl,
|
||||
displayname$,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ export class ScreenShare {
|
||||
participant: LocalParticipant | RemoteParticipant,
|
||||
encryptionSystem: EncryptionSystem,
|
||||
livekitRoom: LivekitRoom,
|
||||
focusUrl: string,
|
||||
pretendToBeDisconnected$: Behavior<boolean>,
|
||||
displayName$: Observable<string>,
|
||||
) {
|
||||
@@ -42,6 +43,7 @@ export class ScreenShare {
|
||||
this.participant$.asObservable(),
|
||||
encryptionSystem,
|
||||
livekitRoom,
|
||||
focusUrl,
|
||||
pretendToBeDisconnected$,
|
||||
this.scope.behavior(displayName$),
|
||||
participant.isLocal,
|
||||
|
||||
@@ -47,6 +47,7 @@ export class UserMedia {
|
||||
participant: LocalParticipant | RemoteParticipant | undefined,
|
||||
encryptionSystem: EncryptionSystem,
|
||||
livekitRoom: LivekitRoom,
|
||||
focusURL: string,
|
||||
mediaDevices: MediaDevices,
|
||||
pretendToBeDisconnected$: Behavior<boolean>,
|
||||
displayname$: Observable<string>,
|
||||
@@ -62,6 +63,7 @@ export class UserMedia {
|
||||
this.participant$ as Behavior<LocalParticipant>,
|
||||
encryptionSystem,
|
||||
livekitRoom,
|
||||
focusURL,
|
||||
mediaDevices,
|
||||
this.scope.behavior(displayname$),
|
||||
this.scope.behavior(handRaised$),
|
||||
@@ -76,6 +78,7 @@ export class UserMedia {
|
||||
>,
|
||||
encryptionSystem,
|
||||
livekitRoom,
|
||||
focusURL,
|
||||
pretendToBeDisconnected$,
|
||||
this.scope.behavior(displayname$),
|
||||
this.scope.behavior(handRaised$),
|
||||
|
||||
@@ -190,6 +190,7 @@ const UserMediaTile: FC<UserMediaTileProps> = ({
|
||||
currentReaction={reaction ?? undefined}
|
||||
raisedHandOnClick={raisedHandOnClick}
|
||||
localParticipant={vm.local}
|
||||
focusUrl={vm.focusURL}
|
||||
audioStreamStats={audioStreamStats}
|
||||
videoStreamStats={videoStreamStats}
|
||||
{...props}
|
||||
|
||||
@@ -46,6 +46,8 @@ interface Props extends ComponentProps<typeof animated.div> {
|
||||
localParticipant: boolean;
|
||||
audioStreamStats?: RTCInboundRtpStreamStats | RTCOutboundRtpStreamStats;
|
||||
videoStreamStats?: RTCInboundRtpStreamStats | RTCOutboundRtpStreamStats;
|
||||
// The focus url, mainly for debugging purposes
|
||||
focusUrl?: string;
|
||||
}
|
||||
|
||||
export const MediaView: FC<Props> = ({
|
||||
@@ -71,6 +73,7 @@ export const MediaView: FC<Props> = ({
|
||||
localParticipant,
|
||||
audioStreamStats,
|
||||
videoStreamStats,
|
||||
focusUrl,
|
||||
...props
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
@@ -134,6 +137,7 @@ export const MediaView: FC<Props> = ({
|
||||
<RTCConnectionStats
|
||||
audio={audioStreamStats}
|
||||
video={videoStreamStats}
|
||||
focusUrl={focusUrl}
|
||||
/>
|
||||
)}
|
||||
{/* TODO: Bring this back once encryption status is less broken */}
|
||||
|
||||
@@ -78,7 +78,7 @@ const SpotlightLocalUserMediaItem: FC<SpotlightLocalUserMediaItemProps> = ({
|
||||
...props
|
||||
}) => {
|
||||
const mirror = useBehavior(vm.mirror$);
|
||||
return <MediaView mirror={mirror} {...props} />;
|
||||
return <MediaView mirror={mirror} focusUrl={vm.focusURL} {...props} />;
|
||||
};
|
||||
|
||||
SpotlightLocalUserMediaItem.displayName = "SpotlightLocalUserMediaItem";
|
||||
|
||||
@@ -274,6 +274,7 @@ export async function withLocalMedia(
|
||||
kind: E2eeType.PER_PARTICIPANT,
|
||||
},
|
||||
mockLivekitRoom({ localParticipant }),
|
||||
"https://rtc-example.org",
|
||||
mediaDevices,
|
||||
constant(roomMember.rawDisplayName ?? "nodisplayname"),
|
||||
constant(null),
|
||||
@@ -314,6 +315,7 @@ export async function withRemoteMedia(
|
||||
kind: E2eeType.PER_PARTICIPANT,
|
||||
},
|
||||
mockLivekitRoom({}, { remoteParticipants$: of([remoteParticipant]) }),
|
||||
"https://rtc-example.org",
|
||||
constant(false),
|
||||
constant(roomMember.rawDisplayName ?? "nodisplayname"),
|
||||
constant(null),
|
||||
|
||||
Reference in New Issue
Block a user