Skip to content

Commit

Permalink
[VEUE-864] adds mobX in MediaDeck
Browse files Browse the repository at this point in the history
  • Loading branch information
Sirbuland committed Jun 21, 2021
1 parent a8f1a71 commit 4b35ea0
Show file tree
Hide file tree
Showing 33 changed files with 321 additions and 263 deletions.
42 changes: 12 additions & 30 deletions app/javascript/components/media_deck.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,31 @@ import ScreenShare from "components/media_deck/screen_share";
import AddScreenShare from "components/media_deck/add_screen_share";
import CameraShare from "components/media_deck/camera_share";
import AddWebcamSource from "components/media_deck/add_webcam_source";
import { observer } from "mobx-preact";
import ScreenSourceStore from "components/media_deck/secreen_source";
import WebcamSourceStore from "components/media_deck/webcam_source";

type State = {
isScreenVisible: boolean;
webcamShared: boolean;
screenShared: boolean;
};

export default class MediaDeck extends Component<unknown, State> {
constructor() {
super();
this.setState({
isScreenVisible: true,
webcamShared: false,
screenShared: false,
})
}

const MediaDeck = observer(class MediaDeck extends Component<unknown, unknown> {
render(): VNode {
return (
<div class="MediaDeck">
<div class="MediaDeck__sources">
<ScreenShare
screenShared={this.state.screenShared}
isVisible={this.state.isScreenVisible}
toggleVisibility={() => this.setState({isScreenVisible: !this.state.isScreenVisible})}
screenSourceStore={ScreenSourceStore}
/>
<CameraShare webcamShared={this.state.webcamShared} />
</div>
<CameraShare webcamSourceStore={WebcamSourceStore} />
</div>
<div class="MediaDeck__controls">
<AddScreenShare
isScreenVisible={this.state.isScreenVisible}
screenSourceAttached={this.state.screenShared}
addScreenCaptureSource={() => this.setState({ screenShared: true })}
stopSharing={() => this.setState(({ screenShared: false }))}
toggleVisibility={() => this.setState({ isScreenVisible: !this.state.isScreenVisible})}
screenSourceStore={ScreenSourceStore}
/>
<AddWebcamSource
webcamSourceAttached={this.state.webcamShared}
addWebcamCaptureSource={() => this.setState({ webcamShared: true })}
stopSharing={() => this.setState({webcamShared: false})}
webcamSourceStore={WebcamSourceStore}
/>
</div>
</div>
);
}
}
});

export default MediaDeck;
24 changes: 13 additions & 11 deletions app/javascript/components/media_deck/add_screen_share.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
import { Component, h, VNode } from "preact";
import { ScreenSourceStore } from "components/media_deck/secreen_source";

type Props = {
isScreenVisible: boolean;
screenSourceAttached: boolean;
addScreenCaptureSource(): void;
stopSharing(): void;
toggleVisibility(): void;
screenSourceStore: ScreenSourceStore;
};
import { observer } from "mobx-preact";

export default class AddScreenShare extends Component<Props, unknown> {
const AddScreenShare = observer(class AddScreenShare extends Component<Props, unknown> {
render(): VNode {
return (
<div>
{this.renderVisibilityControls()}
{
!this.props.screenSourceAttached ?
<button onClick={() => this.props.addScreenCaptureSource()}>
!this.props.screenSourceStore.screenCaptureSource ?
<button onClick={() => this.props.screenSourceStore.connectScreenShareSource()}>
Share Your Screen
</button> : <button onClick={() => this.props.stopSharing()}>Stop Sharing</button>
</button> : <button onClick={() => this.props.screenSourceStore.disconnectScreenShareSource()}>Stop Sharing</button>
}
</div>
);
}

renderVisibilityControls(): VNode {
if (!this.props.screenSourceAttached) {
if (!this.props.screenSourceStore.screenCaptureSource) {
return <span />;
}

return (
<button
onClick={() => {
this.props.toggleVisibility();
this.props.screenSourceStore.toggleVisibility();
}}
>
{this.props.isScreenVisible ? "Hide Screen" : "Make Visible"}
{this.props.screenSourceStore.isScreenVisible ? "Hide Screen" : "Make Visible"}
</button>
);
}
}
});

export default AddScreenShare;
16 changes: 11 additions & 5 deletions app/javascript/components/media_deck/add_webcam_source.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import { Component, h, VNode } from "preact";
import { WebcamSourceStore } from "components/media_deck/webcam_source";
import { observer } from "mobx-preact";

type Props = {
webcamSourceAttached: boolean;
addWebcamCaptureSource(): void;
stopSharing(): void;
webcamSourceStore: WebcamSourceStore
}
export default class AddWebcamSource extends Component<Props, any> {

const AddWebcamSource = observer(class AddWebcamSource extends Component<Props, unknown> {
render(): VNode {
return (
<div>
{
!this.props.webcamSourceAttached ?
<button onClick={() => this.props.addWebcamCaptureSource()}>
!this.props.webcamSourceStore.webcamCaptureSource ?
<button onClick={() => this.props.webcamSourceStore.toggleWebcamDialogue()}>
Attach Another Camera
</button> :
<button onClick={() => this.props.stopSharing()}>Stop Camera Stream</button>
<button onClick={() => this.props.webcamSourceStore.stopWebcamStream()}>Stop Camera Stream</button>
}
</div>
);
}
}
});

export default AddWebcamSource;
67 changes: 10 additions & 57 deletions app/javascript/components/media_deck/camera_share.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,20 @@
import { Component, h, VNode } from "preact";
import EventBus from "event_bus";
import { RemoveCaptureSourceEvent } from "helpers/broadcast/capture_source_manager";
import { WebcamCaptureSource } from "helpers/broadcast/capture_sources/webcam";
import { WebcamSourceStore } from "components/media_deck/webcam_source";
import { observer } from "mobx-preact";

type Props = { webcamShared: boolean };
type State = { deviceId: string; streamStarted: boolean; webcamCaptureSource: WebcamCaptureSource; }
type Props = { webcamShared: boolean; webcamSourceStore: WebcamSourceStore; };

export default class CameraShare extends Component<Props, State> {
private videoTag: HTMLVideoElement;
private webcamDevices: MediaDeviceInfo[];

constructor(props: Props) {
super(props);

this.setState({
deviceId: null,
streamStarted: false,
webcamCaptureSource: null,
});
}
const CameraShare = observer(class CameraShare extends Component<Props, unknown> {

render(): VNode {
return (
<div class="MediaDeck__camera-stream">
<div class="MediaDeck__screen-share__video">
<video
data-connected={!!this.props.webcamShared}
ref={(videoTag) => {
this.videoTag = videoTag;
}}
/>
{this.props.webcamSourceStore.renderVideo()}
</div>
{
this.props.webcamShared && !this.state.streamStarted ?
this.props.webcamSourceStore.webcamDialogueVisible && !this.props.webcamSourceStore.webcamCaptureSource ?
<div class="MediaDeck__webcam-share">
{this.renderWebcamDevices()}
</div> : null
Expand All @@ -41,26 +23,9 @@ export default class CameraShare extends Component<Props, State> {
);
}

async componentDidMount(): Promise<void> {
const devices = await navigator.mediaDevices.enumerateDevices();
this.webcamDevices = devices.filter((d: MediaDeviceInfo) => d.kind === "videoinput");
}

async componentDidUpdate(prevProps: Props): Promise<void> {
if (prevProps.webcamShared === this.props.webcamShared)
return;

if (!this.props.webcamShared) {
EventBus.dispatch(RemoveCaptureSourceEvent, this.state.webcamCaptureSource);
this.state.webcamCaptureSource.stop();
this.videoTag.srcObject = null;
this.setState({ webcamCaptureSource: null });
}
}

private renderWebcamDevices(): VNode[] {
const devicesMarkup = [];
this.webcamDevices.forEach((device: MediaDeviceInfo) => {
this.props.webcamSourceStore.webcamDevices.forEach((device: MediaDeviceInfo) => {
devicesMarkup.push(this.deviceMarkup(device));
});
return devicesMarkup;
Expand All @@ -71,24 +36,12 @@ export default class CameraShare extends Component<Props, State> {
<div
class="MediaDeck__webcam-share--item"
data-media-id={device.deviceId}
onClick={() => this.startWebcamStream(device.deviceId)}
onClick={() => this.props.webcamSourceStore.startWebcamStream(device.deviceId)}
>
{device.label}
</div>
);
}
});

private async startWebcamStream(deviceId: string): Promise<void> {
const webcamCaptureSource = await WebcamCaptureSource.connect(
this.state.deviceId,
this.videoTag
);

this.setState({
deviceId: deviceId,
streamStarted: true,
webcamCaptureSource,
});

}
}
export default CameraShare;
68 changes: 18 additions & 50 deletions app/javascript/components/media_deck/screen_share.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
import { Component, h, VNode } from "preact";
import { ScreenCaptureSource } from "helpers/broadcast/capture_sources/screen";
import {
NewCaptureSourceEvent,
RemoveCaptureSourceEvent,
} from "helpers/broadcast/capture_source_manager";
import hiddenIcon from "images/visible-false.svg";
import EventBus from "event_bus";
import { observer } from "mobx-preact";
import { ScreenSourceStore } from "components/media_deck/secreen_source";

type State = { screenCaptureSource: ScreenCaptureSource; };
type Props = { screenShared: boolean; isVisible: boolean; toggleVisibility(): void; };
type Props = { screenSourceStore: ScreenSourceStore };

export default class ScreenShare extends Component<Props, State> {
const ScreenShare = observer(class ScreenShare extends Component<Props, unknown> {
private videoTag: HTMLVideoElement;

constructor(props: Props) {
super(props);

this.state = {
screenCaptureSource: null,
};
}

render(): VNode {
return (
<div
Expand All @@ -29,75 +21,51 @@ export default class ScreenShare extends Component<Props, State> {
this.toggleVisibility();
}}
>
{this.props.isVisible ? null : (
{this.props.screenSourceStore.isScreenVisible ? null : (
<div class="MediaDeck__screen-share__hidden-cover">
<img src={hiddenIcon} alt="hidden icon" />
</div>
)}
<div class="MediaDeck__screen-share__video">
<video
data-connected={this.props.screenShared}
ref={(videoTag) => {
this.videoTag = videoTag;
}}
/>
{this.props.screenSourceStore.renderVideo()}
</div>
</div>
);
}

async componentDidUpdate(prevProps: Props): Promise<void> {
if (prevProps.screenShared === this.props.screenShared)
return;

if (this.props.screenShared) {
const screenCaptureSource = await ScreenCaptureSource.connect(
this.videoTag
);

this.setState({
screenCaptureSource,
});
this.props.toggleVisibility()
} else {
EventBus.dispatch(RemoveCaptureSourceEvent, this.state.screenCaptureSource);
this.state.screenCaptureSource.stop();
this.videoTag.srcObject = null;
this.setState({ screenCaptureSource: null });
}
}

renderVisibilityControls(): VNode {
if (!this.state.screenCaptureSource) {
if (!this.props.screenSourceStore.screenCaptureSource) {
return <span />;
}

return (
<button
onClick={() => {
this.toggleVisibility();
this.props.screenSourceStore.toggleVisibility();
}}
>
{this.props.isVisible ? "Hide Screen" : "Make Visible"}
{this.props.screenSourceStore.isScreenVisible ? "Hide Screen" : "Make Visible"}
</button>
);
}

private toggleVisibility() {
if (this.state.screenCaptureSource) {
if (this.props.isVisible) {
if (this.props.screenSourceStore.screenCaptureSource) {
if (this.props.screenSourceStore.isScreenVisible) {
EventBus.dispatch(
RemoveCaptureSourceEvent,
this.state.screenCaptureSource
this.props.screenSourceStore.screenCaptureSource
);
this.props.toggleVisibility();
this.props.screenSourceStore.toggleVisibility();
} else {
EventBus.dispatch(
NewCaptureSourceEvent,
this.state.screenCaptureSource
this.props.screenSourceStore.screenCaptureSource
);
}
this.props.toggleVisibility();
this.props.screenSourceStore.toggleVisibility();
}
}
}
});

export default ScreenShare;
Loading

0 comments on commit 4b35ea0

Please sign in to comment.