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