Merge remote-tracking branch 'upstream/develop' into fix/17130/draggable-pip
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
commit
91d208d514
802 changed files with 12931 additions and 11005 deletions
|
@ -14,32 +14,38 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, {createRef} from 'react';
|
||||
import React, { createRef } from 'react';
|
||||
import { CallFeed, CallFeedEvent } from 'matrix-js-sdk/src/webrtc/callFeed';
|
||||
import { logger } from 'matrix-js-sdk/src/logger';
|
||||
import CallMediaHandler from "../../../CallMediaHandler";
|
||||
import MediaDeviceHandler, { MediaDeviceHandlerEvent } from "../../../MediaDeviceHandler";
|
||||
|
||||
interface IProps {
|
||||
feed: CallFeed,
|
||||
feed: CallFeed;
|
||||
}
|
||||
|
||||
export default class AudioFeed extends React.Component<IProps> {
|
||||
private element = createRef<HTMLAudioElement>();
|
||||
|
||||
componentDidMount() {
|
||||
MediaDeviceHandler.instance.addListener(
|
||||
MediaDeviceHandlerEvent.AudioOutputChanged,
|
||||
this.onAudioOutputChanged,
|
||||
);
|
||||
this.props.feed.addListener(CallFeedEvent.NewStream, this.onNewStream);
|
||||
this.playMedia();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
MediaDeviceHandler.instance.removeListener(
|
||||
MediaDeviceHandlerEvent.AudioOutputChanged,
|
||||
this.onAudioOutputChanged,
|
||||
);
|
||||
this.props.feed.removeListener(CallFeedEvent.NewStream, this.onNewStream);
|
||||
this.stopMedia();
|
||||
}
|
||||
|
||||
private playMedia() {
|
||||
private onAudioOutputChanged = (audioOutput: string) => {
|
||||
const element = this.element.current;
|
||||
const audioOutput = CallMediaHandler.getAudioOutput();
|
||||
|
||||
if (audioOutput) {
|
||||
try {
|
||||
// This seems quite unreliable in Chrome, although I haven't yet managed to make a jsfiddle where
|
||||
|
@ -52,7 +58,11 @@ export default class AudioFeed extends React.Component<IProps> {
|
|||
logger.warn("Couldn't set requested audio output device: using default", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private playMedia() {
|
||||
const element = this.element.current;
|
||||
this.onAudioOutputChanged(MediaDeviceHandler.getAudioOutput());
|
||||
element.muted = false;
|
||||
element.srcObject = this.props.feed.stream;
|
||||
element.autoplay = true;
|
||||
|
@ -67,7 +77,7 @@ export default class AudioFeed extends React.Component<IProps> {
|
|||
// should serialise the ones that need to be serialised but then be able to interrupt
|
||||
// them with another load() which will cancel the pending one, but since we don't call
|
||||
// load() explicitly, it shouldn't be a problem. - Dave
|
||||
element.play()
|
||||
element.play();
|
||||
} catch (e) {
|
||||
logger.info("Failed to play media element with feed", this.props.feed, e);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
import AudioFeed from "./AudioFeed"
|
||||
import AudioFeed from "./AudioFeed";
|
||||
import { CallEvent, MatrixCall } from "matrix-js-sdk/src/webrtc/call";
|
||||
import { CallFeed } from "matrix-js-sdk/src/webrtc/callFeed";
|
||||
|
||||
|
@ -48,7 +48,7 @@ export default class AudioFeedArrayForCall extends React.Component<IProps, IStat
|
|||
this.setState({
|
||||
feeds: this.props.call.getRemoteFeeds(),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return this.state.feeds.map((feed, i) => {
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import IncomingCallBox from './IncomingCallBox';
|
||||
import CallPreview from './CallPreview';
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
interface IProps {
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ import PersistentApp from "../elements/PersistentApp";
|
|||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { CallEvent, CallState, MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
|
||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import UIStore from '../../../stores/UIStore';
|
||||
import { lerp } from '../../../utils/AnimationUtils';
|
||||
|
||||
|
@ -41,7 +41,7 @@ const PADDING = {
|
|||
bottom: 58,
|
||||
left: 76,
|
||||
right: 8,
|
||||
}
|
||||
};
|
||||
|
||||
const SHOW_CALL_IN_STATES = [
|
||||
CallState.Connected,
|
||||
|
@ -52,7 +52,6 @@ const SHOW_CALL_IN_STATES = [
|
|||
CallState.WaitLocalMedia,
|
||||
];
|
||||
|
||||
|
||||
interface IProps {
|
||||
}
|
||||
|
||||
|
@ -177,7 +176,7 @@ export default class CallPreview extends React.Component<IProps, IState> {
|
|||
translationY: lerp(this.state.translationY, this.desiredTranslationY, amt),
|
||||
});
|
||||
requestAnimationFrame(this.animationCallback);
|
||||
}
|
||||
};
|
||||
|
||||
private setTranslation(inTranslationX: number, inTranslationY: number) {
|
||||
const width = this.callViewWrapper.current?.clientWidth || PIP_VIEW_WIDTH;
|
||||
|
@ -234,7 +233,7 @@ export default class CallPreview extends React.Component<IProps, IState> {
|
|||
// We start animating here because we want the PiP to move when we're
|
||||
// resizing the window
|
||||
requestAnimationFrame(this.animationCallback);
|
||||
}
|
||||
};
|
||||
|
||||
private onRoomViewStoreUpdate = (payload) => {
|
||||
if (RoomViewStore.getRoomId() === this.state.roomId) return;
|
||||
|
|
|
@ -18,27 +18,27 @@ limitations under the License.
|
|||
import React, { createRef, CSSProperties } from 'react';
|
||||
import dis from '../../../dispatcher/dispatcher';
|
||||
import CallHandler from '../../../CallHandler';
|
||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||
import { _t, _td } from '../../../languageHandler';
|
||||
import VideoFeed from './VideoFeed';
|
||||
import RoomAvatar from "../avatars/RoomAvatar";
|
||||
import { CallState, CallType, MatrixCall, CallEvent } from 'matrix-js-sdk/src/webrtc/call';
|
||||
import classNames from 'classnames';
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import {isOnlyCtrlOrCmdKeyEvent, Key} from '../../../Keyboard';
|
||||
import {alwaysAboveLeftOf, alwaysAboveRightOf, ChevronFace, ContextMenuButton} from '../../structures/ContextMenu';
|
||||
import { isOnlyCtrlOrCmdKeyEvent, Key } from '../../../Keyboard';
|
||||
import { alwaysAboveLeftOf, alwaysAboveRightOf, ChevronFace, ContextMenuButton } from '../../structures/ContextMenu';
|
||||
import CallContextMenu from '../context_menus/CallContextMenu';
|
||||
import { avatarUrlForMember } from '../../../Avatar';
|
||||
import DialpadContextMenu from '../context_menus/DialpadContextMenu';
|
||||
import { CallFeed } from 'matrix-js-sdk/src/webrtc/callFeed';
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
interface IProps {
|
||||
// The call for us to display
|
||||
call: MatrixCall,
|
||||
call: MatrixCall;
|
||||
|
||||
// Another ongoing call to display information about
|
||||
secondaryCall?: MatrixCall,
|
||||
secondaryCall?: MatrixCall;
|
||||
|
||||
// a callback which is called when the content in the CallView changes
|
||||
// in a way that is likely to cause a resize.
|
||||
|
@ -55,15 +55,15 @@ interface IProps {
|
|||
}
|
||||
|
||||
interface IState {
|
||||
isLocalOnHold: boolean,
|
||||
isRemoteOnHold: boolean,
|
||||
micMuted: boolean,
|
||||
vidMuted: boolean,
|
||||
callState: CallState,
|
||||
controlsVisible: boolean,
|
||||
showMoreMenu: boolean,
|
||||
showDialpad: boolean,
|
||||
feeds: CallFeed[],
|
||||
isLocalOnHold: boolean;
|
||||
isRemoteOnHold: boolean;
|
||||
micMuted: boolean;
|
||||
vidMuted: boolean;
|
||||
callState: CallState;
|
||||
controlsVisible: boolean;
|
||||
showMoreMenu: boolean;
|
||||
showDialpad: boolean;
|
||||
feeds: CallFeed[];
|
||||
}
|
||||
|
||||
function getFullScreenElement() {
|
||||
|
@ -120,7 +120,7 @@ export default class CallView extends React.Component<IProps, IState> {
|
|||
showMoreMenu: false,
|
||||
showDialpad: false,
|
||||
feeds: this.props.call.getFeeds(),
|
||||
}
|
||||
};
|
||||
|
||||
this.updateCallListeners(null, this.props.call);
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ export default class CallView extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
private onFeedsChanged = (newFeeds: Array<CallFeed>) => {
|
||||
this.setState({feeds: newFeeds});
|
||||
this.setState({ feeds: newFeeds });
|
||||
};
|
||||
|
||||
private onCallLocalHoldUnhold = () => {
|
||||
|
@ -231,11 +231,11 @@ export default class CallView extends React.Component<IProps, IState> {
|
|||
this.setState({
|
||||
controlsVisible: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private onMouseMove = () => {
|
||||
this.showControls();
|
||||
}
|
||||
};
|
||||
|
||||
private showControls() {
|
||||
if (this.state.showMoreMenu || this.state.showDialpad) return;
|
||||
|
@ -272,21 +272,21 @@ export default class CallView extends React.Component<IProps, IState> {
|
|||
showDialpad: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private onMicMuteClick = () => {
|
||||
const newVal = !this.state.micMuted;
|
||||
|
||||
this.props.call.setMicrophoneMuted(newVal);
|
||||
this.setState({micMuted: newVal});
|
||||
}
|
||||
this.setState({ micMuted: newVal });
|
||||
};
|
||||
|
||||
private onVidMuteClick = () => {
|
||||
const newVal = !this.state.vidMuted;
|
||||
|
||||
this.props.call.setLocalVideoMuted(newVal);
|
||||
this.setState({vidMuted: newVal});
|
||||
}
|
||||
this.setState({ vidMuted: newVal });
|
||||
};
|
||||
|
||||
private onMoreClick = () => {
|
||||
if (this.controlsHideTimer) {
|
||||
|
@ -298,21 +298,21 @@ export default class CallView extends React.Component<IProps, IState> {
|
|||
showMoreMenu: true,
|
||||
controlsVisible: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private closeDialpad = () => {
|
||||
this.setState({
|
||||
showDialpad: false,
|
||||
});
|
||||
this.controlsHideTimer = window.setTimeout(this.onControlsHideTimer, CONTROLS_HIDE_DELAY);
|
||||
}
|
||||
};
|
||||
|
||||
private closeContextMenu = () => {
|
||||
this.setState({
|
||||
showMoreMenu: false,
|
||||
});
|
||||
this.controlsHideTimer = window.setTimeout(this.onControlsHideTimer, CONTROLS_HIDE_DELAY);
|
||||
}
|
||||
};
|
||||
|
||||
// we register global shortcuts here, they *must not conflict* with local shortcuts elsewhere or both will fire
|
||||
// Note that this assumes we always have a CallView on screen at any given time
|
||||
|
@ -353,7 +353,7 @@ export default class CallView extends React.Component<IProps, IState> {
|
|||
action: 'view_room',
|
||||
room_id: userFacingRoomId,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private onSecondaryRoomAvatarClick = () => {
|
||||
const userFacingRoomId = CallHandler.sharedInstance().roomIdForCall(this.props.secondaryCall);
|
||||
|
@ -362,17 +362,17 @@ export default class CallView extends React.Component<IProps, IState> {
|
|||
action: 'view_room',
|
||||
room_id: userFacingRoomId,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private onCallResumeClick = () => {
|
||||
const userFacingRoomId = CallHandler.sharedInstance().roomIdForCall(this.props.call);
|
||||
CallHandler.sharedInstance().setActiveCallRoomId(userFacingRoomId);
|
||||
}
|
||||
};
|
||||
|
||||
private onTransferClick = () => {
|
||||
const transfereeCall = CallHandler.sharedInstance().getTransfereeForCallId(this.props.call.callId);
|
||||
this.props.call.transferToCall(transfereeCall);
|
||||
}
|
||||
};
|
||||
|
||||
public render() {
|
||||
const client = MatrixClientPeg.get();
|
||||
|
@ -573,7 +573,7 @@ export default class CallView extends React.Component<IProps, IState> {
|
|||
<div className="mx_CallView_voice_avatarsContainer">
|
||||
<div
|
||||
className="mx_CallView_voice_avatarContainer"
|
||||
style={{width: avatarSize, height: avatarSize}}
|
||||
style={{ width: avatarSize, height: avatarSize }}
|
||||
>
|
||||
<RoomAvatar
|
||||
room={callRoom}
|
||||
|
@ -617,7 +617,7 @@ export default class CallView extends React.Component<IProps, IState> {
|
|||
contentView = <div className={classes} onMouseMove={this.onMouseMove}>
|
||||
{feeds}
|
||||
<div className="mx_CallView_voice_avatarsContainer">
|
||||
<div className="mx_CallView_voice_avatarContainer" style={{width: avatarSize, height: avatarSize}}>
|
||||
<div className="mx_CallView_voice_avatarContainer" style={{ width: avatarSize, height: avatarSize }}>
|
||||
<RoomAvatar
|
||||
room={callRoom}
|
||||
height={avatarSize}
|
||||
|
|
|
@ -19,22 +19,22 @@ import React from 'react';
|
|||
import CallHandler, { CallHandlerEvent } from '../../../CallHandler';
|
||||
import CallView from './CallView';
|
||||
import dis from '../../../dispatcher/dispatcher';
|
||||
import {Resizable} from "re-resizable";
|
||||
import { Resizable } from "re-resizable";
|
||||
import ResizeNotifier from "../../../utils/ResizeNotifier";
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
interface IProps {
|
||||
// What room we should display the call for
|
||||
roomId: string,
|
||||
roomId: string;
|
||||
|
||||
// maxHeight style attribute for the video panel
|
||||
maxVideoHeight?: number;
|
||||
|
||||
resizeNotifier: ResizeNotifier,
|
||||
resizeNotifier: ResizeNotifier;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
call: MatrixCall,
|
||||
call: MatrixCall;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -74,7 +74,7 @@ export default class CallViewForRoom extends React.Component<IProps, IState> {
|
|||
private updateCall = () => {
|
||||
const newCall = this.getCall();
|
||||
if (newCall !== this.state.call) {
|
||||
this.setState({call: newCall});
|
||||
this.setState({ call: newCall });
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -121,7 +121,7 @@ export default class CallViewForRoom extends React.Component<IProps, IState> {
|
|||
onResize={this.onResize}
|
||||
onResizeStop={this.onResizeStop}
|
||||
className="mx_CallViewForRoom_ResizeWrapper"
|
||||
handleClasses={{bottom: "mx_CallViewForRoom_ResizeHandle"}}
|
||||
handleClasses={{ bottom: "mx_CallViewForRoom_ResizeHandle" }}
|
||||
>
|
||||
<CallView
|
||||
call={this.state.call}
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
|
||||
import * as React from "react";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
const BUTTONS = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '0', '#'];
|
||||
|
||||
|
@ -35,7 +35,7 @@ interface IButtonProps {
|
|||
class DialPadButton extends React.PureComponent<IButtonProps> {
|
||||
onClick = () => {
|
||||
this.props.onButtonPress(this.props.digit);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
switch (this.props.kind) {
|
||||
|
|
|
@ -20,7 +20,7 @@ import AccessibleButton from "../elements/AccessibleButton";
|
|||
import Field from "../elements/Field";
|
||||
import DialPad from './DialPad';
|
||||
import dis from '../../../dispatcher/dispatcher';
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import { DialNumberPayload } from "../../../dispatcher/payloads/DialNumberPayload";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
|
||||
|
@ -38,30 +38,30 @@ export default class DialpadModal extends React.PureComponent<IProps, IState> {
|
|||
super(props);
|
||||
this.state = {
|
||||
value: '',
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
onCancelClick = () => {
|
||||
this.props.onFinished(false);
|
||||
}
|
||||
};
|
||||
|
||||
onChange = (ev) => {
|
||||
this.setState({value: ev.target.value});
|
||||
}
|
||||
this.setState({ value: ev.target.value });
|
||||
};
|
||||
|
||||
onFormSubmit = (ev) => {
|
||||
ev.preventDefault();
|
||||
this.onDialPress();
|
||||
}
|
||||
};
|
||||
|
||||
onDigitPress = (digit) => {
|
||||
this.setState({value: this.state.value + digit});
|
||||
}
|
||||
this.setState({ value: this.state.value + digit });
|
||||
};
|
||||
|
||||
onDeletePress = () => {
|
||||
if (this.state.value.length === 0) return;
|
||||
this.setState({value: this.state.value.slice(0, -1)});
|
||||
}
|
||||
this.setState({ value: this.state.value.slice(0, -1) });
|
||||
};
|
||||
|
||||
onDialPress = async () => {
|
||||
const payload: DialNumberPayload = {
|
||||
|
@ -71,7 +71,7 @@ export default class DialpadModal extends React.PureComponent<IProps, IState> {
|
|||
dis.dispatch(payload);
|
||||
|
||||
this.props.onFinished(true);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div className="mx_DialPadModal">
|
||||
|
|
|
@ -17,15 +17,15 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||
import dis from '../../../dispatcher/dispatcher';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import { ActionPayload } from '../../../dispatcher/payloads';
|
||||
import CallHandler, { AudioID } from '../../../CallHandler';
|
||||
import RoomAvatar from '../avatars/RoomAvatar';
|
||||
import FormButton from '../elements/FormButton';
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import { CallState } from 'matrix-js-sdk/src/webrtc/call';
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import AccessibleTooltipButton from '../elements/AccessibleTooltipButton';
|
||||
import classNames from 'classnames';
|
||||
|
||||
|
@ -91,10 +91,10 @@ export default class IncomingCallBox extends React.Component<IProps, IState> {
|
|||
|
||||
private onSilenceClick: React.MouseEventHandler = (e) => {
|
||||
e.stopPropagation();
|
||||
const newState = !this.state.silenced
|
||||
this.setState({silenced: newState});
|
||||
const newState = !this.state.silenced;
|
||||
this.setState({ silenced: newState });
|
||||
newState ? CallHandler.sharedInstance().pause(AudioID.Ring) : CallHandler.sharedInstance().play(AudioID.Ring);
|
||||
}
|
||||
};
|
||||
|
||||
public render() {
|
||||
if (!this.state.incomingCall) {
|
||||
|
@ -143,21 +143,22 @@ export default class IncomingCallBox extends React.Component<IProps, IState> {
|
|||
/>
|
||||
</div>
|
||||
<div className="mx_IncomingCallBox_buttons">
|
||||
<FormButton
|
||||
<AccessibleButton
|
||||
className={"mx_IncomingCallBox_decline"}
|
||||
onClick={this.onRejectClick}
|
||||
kind="danger"
|
||||
label={_t("Decline")}
|
||||
/>
|
||||
>
|
||||
{ _t("Decline") }
|
||||
</AccessibleButton>
|
||||
<div className="mx_IncomingCallBox_spacer" />
|
||||
<FormButton
|
||||
<AccessibleButton
|
||||
className={"mx_IncomingCallBox_accept"}
|
||||
onClick={this.onAnswerClick}
|
||||
kind="primary"
|
||||
label={_t("Accept")}
|
||||
/>
|
||||
>
|
||||
{ _t("Accept") }
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,17 +16,17 @@ limitations under the License.
|
|||
|
||||
import classnames from 'classnames';
|
||||
import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
|
||||
import React, {createRef} from 'react';
|
||||
import React, { createRef } from 'react';
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { CallFeed, CallFeedEvent } from 'matrix-js-sdk/src/webrtc/callFeed';
|
||||
import { logger } from 'matrix-js-sdk/src/logger';
|
||||
import MemberAvatar from "../avatars/MemberAvatar"
|
||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||
import MemberAvatar from "../avatars/MemberAvatar";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
interface IProps {
|
||||
call: MatrixCall,
|
||||
call: MatrixCall;
|
||||
|
||||
feed: CallFeed,
|
||||
feed: CallFeed;
|
||||
|
||||
// Whether this call view is for picture-in-picture mode
|
||||
// otherwise, it's the larger call view when viewing the room the call is in.
|
||||
|
@ -36,7 +36,7 @@ interface IProps {
|
|||
|
||||
// a callback which is called when the video element is resized
|
||||
// due to a change in video metadata
|
||||
onResize?: (e: Event) => void,
|
||||
onResize?: (e: Event) => void;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
|
@ -85,7 +85,7 @@ export default class VideoFeed extends React.Component<IProps, IState> {
|
|||
// should serialise the ones that need to be serialised but then be able to interrupt
|
||||
// them with another load() which will cancel the pending one, but since we don't call
|
||||
// load() explicitly, it shouldn't be a problem. - Dave
|
||||
element.play()
|
||||
element.play();
|
||||
} catch (e) {
|
||||
logger.info("Failed to play media element with feed", this.props.feed, e);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue