Fix and simplify screen sharing
This commit is contained in:
@@ -734,8 +734,7 @@ export const InCallView: FC<InCallViewProps> = ({
|
|||||||
<ShareScreenButton
|
<ShareScreenButton
|
||||||
key="share_screen"
|
key="share_screen"
|
||||||
className={styles.shareScreen}
|
className={styles.shareScreen}
|
||||||
disabled={sharingScreen === undefined}
|
enabled={sharingScreen}
|
||||||
enabled={sharingScreen === true}
|
|
||||||
onClick={vm.toggleScreenSharing}
|
onClick={vm.toggleScreenSharing}
|
||||||
onTouchEnd={onControlsTouchEnd}
|
onTouchEnd={onControlsTouchEnd}
|
||||||
data-testid="incall_screenshare"
|
data-testid="incall_screenshare"
|
||||||
|
|||||||
@@ -1275,8 +1275,7 @@ export class CallViewModel {
|
|||||||
public readonly sharingScreen$ = this.localMembership.sharingScreen$;
|
public readonly sharingScreen$ = this.localMembership.sharingScreen$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for toggling screen sharing. If null, screen sharing is not
|
* Callback to toggle screen sharing. If null, screen sharing is not possible.
|
||||||
* available.
|
|
||||||
*/
|
*/
|
||||||
// reassigned here to make it publicly accessible
|
// reassigned here to make it publicly accessible
|
||||||
public readonly toggleScreenSharing =
|
public readonly toggleScreenSharing =
|
||||||
|
|||||||
@@ -25,14 +25,11 @@ import {
|
|||||||
combineLatest,
|
combineLatest,
|
||||||
fromEvent,
|
fromEvent,
|
||||||
map,
|
map,
|
||||||
NEVER,
|
|
||||||
type Observable,
|
type Observable,
|
||||||
of,
|
of,
|
||||||
scan,
|
scan,
|
||||||
startWith,
|
startWith,
|
||||||
switchMap,
|
switchMap,
|
||||||
take,
|
|
||||||
takeWhile,
|
|
||||||
} from "rxjs";
|
} from "rxjs";
|
||||||
import { logger } from "matrix-js-sdk/lib/logger";
|
import { logger } from "matrix-js-sdk/lib/logger";
|
||||||
|
|
||||||
@@ -144,8 +141,10 @@ export const createLocalMembership$ = ({
|
|||||||
startTracks: () => Behavior<LocalTrack[]>;
|
startTracks: () => Behavior<LocalTrack[]>;
|
||||||
requestDisconnect: () => Observable<LocalMemberLivekitState> | null;
|
requestDisconnect: () => Observable<LocalMemberLivekitState> | null;
|
||||||
connectionState: LocalMemberConnectionState;
|
connectionState: LocalMemberConnectionState;
|
||||||
// Use null here since behavior cannot be initialised with undefined.
|
sharingScreen$: Behavior<boolean>;
|
||||||
sharingScreen$: Behavior<boolean | null>;
|
/**
|
||||||
|
* Callback to toggle screen sharing. If null, screen sharing is not possible.
|
||||||
|
*/
|
||||||
toggleScreenSharing: (() => void) | null;
|
toggleScreenSharing: (() => void) | null;
|
||||||
participant$: Behavior<LocalParticipant | null>;
|
participant$: Behavior<LocalParticipant | null>;
|
||||||
connection$: Behavior<Connection | null>;
|
connection$: Behavior<Connection | null>;
|
||||||
@@ -453,72 +452,40 @@ export const createLocalMembership$ = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns undefined if scrennSharing is not yet ready.
|
* Whether the user is currently sharing their screen.
|
||||||
*/
|
*/
|
||||||
const sharingScreen$ = scope.behavior(
|
const sharingScreen$ = scope.behavior(
|
||||||
connection$.pipe(
|
connection$.pipe(
|
||||||
switchMap((c) => {
|
switchMap((c) =>
|
||||||
if (!c) return of(null);
|
c === null
|
||||||
if (c.state$.value.state === "ConnectedToLkRoom")
|
? of(false)
|
||||||
return observeSharingScreen$(c.livekitRoom.localParticipant);
|
: observeSharingScreen$(c.livekitRoom.localParticipant),
|
||||||
return of(false);
|
),
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
null,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const toggleScreenSharing =
|
const toggleScreenSharing =
|
||||||
"getDisplayMedia" in (navigator.mediaDevices ?? {}) &&
|
"getDisplayMedia" in (navigator.mediaDevices ?? {}) &&
|
||||||
!getUrlParams().hideScreensharing
|
!getUrlParams().hideScreensharing
|
||||||
? (): void =>
|
? (): void =>
|
||||||
// If a connection is ready...
|
// If a connection is ready, toggle screen sharing.
|
||||||
void connection$
|
// We deliberately do nothing in the case of a null connection because
|
||||||
.pipe(
|
// it looks nice for the call control buttons to all become available
|
||||||
// I dont see why we need this. isnt the check later on superseeding it?
|
// at once upon joining the call, rather than introducing a disabled
|
||||||
takeWhile(
|
// state. The user can just click again.
|
||||||
(c) => c !== null && c.state$.value.state !== "FailedToStart",
|
// We also allow screen sharing to be toggled even if the connection
|
||||||
),
|
// is still initializing or publishing tracks, because there's no
|
||||||
switchMap((c) =>
|
// technical reason to disallow this. LiveKit will publish if it can.
|
||||||
c?.state$.value.state === "ConnectedToLkRoom" ? of(c) : NEVER,
|
void connection$.value?.livekitRoom.localParticipant
|
||||||
),
|
.setScreenShareEnabled(!sharingScreen$.value, {
|
||||||
take(1),
|
audio: true,
|
||||||
scope.bind(),
|
selfBrowserSurface: "include",
|
||||||
)
|
surfaceSwitching: "include",
|
||||||
// ...toggle screen sharing.
|
systemAudio: "include",
|
||||||
.subscribe(
|
})
|
||||||
(c) =>
|
.catch(logger.error)
|
||||||
void c.livekitRoom.localParticipant
|
|
||||||
.setScreenShareEnabled(!sharingScreen$.value, {
|
|
||||||
audio: true,
|
|
||||||
selfBrowserSurface: "include",
|
|
||||||
surfaceSwitching: "include",
|
|
||||||
systemAudio: "include",
|
|
||||||
})
|
|
||||||
.catch(logger.error),
|
|
||||||
)
|
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
// we do not need all the auto waiting since we can just check via sharingScreen$.value !== undefined
|
|
||||||
let alternativeScreenshareToggle: (() => void) | null = null;
|
|
||||||
if (
|
|
||||||
"getDisplayMedia" in (navigator.mediaDevices ?? {}) &&
|
|
||||||
!getUrlParams().hideScreensharing
|
|
||||||
) {
|
|
||||||
alternativeScreenshareToggle = (): void =>
|
|
||||||
void connection$.value?.livekitRoom.localParticipant
|
|
||||||
.setScreenShareEnabled(!sharingScreen$.value, {
|
|
||||||
audio: true,
|
|
||||||
selfBrowserSurface: "include",
|
|
||||||
surfaceSwitching: "include",
|
|
||||||
systemAudio: "include",
|
|
||||||
})
|
|
||||||
.catch(logger.error);
|
|
||||||
}
|
|
||||||
logger.log(
|
|
||||||
"alternativeScreenshareToggle so that it is used",
|
|
||||||
alternativeScreenshareToggle,
|
|
||||||
);
|
|
||||||
|
|
||||||
const participant$ = scope.behavior(
|
const participant$ = scope.behavior(
|
||||||
connection$.pipe(map((c) => c?.livekitRoom.localParticipant ?? null)),
|
connection$.pipe(map((c) => c?.livekitRoom.localParticipant ?? null)),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user