Merge branch 'develop' into sort-imports
Signed-off-by: Aaron Raimist <aaron@raim.ist>
This commit is contained in:
commit
7b94e13a84
642 changed files with 30052 additions and 8035 deletions
|
@ -16,20 +16,22 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { CallEvent, CallState, MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
|
||||
import { EventSubscription } from 'fbemitter';
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
import CallView from "./CallView";
|
||||
import RoomViewStore from '../../../stores/RoomViewStore';
|
||||
import CallHandler, { CallHandlerEvent } from '../../../CallHandler';
|
||||
import dis from '../../../dispatcher/dispatcher';
|
||||
import { ActionPayload } from '../../../dispatcher/payloads';
|
||||
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 { EventSubscription } from 'fbemitter';
|
||||
import PictureInPictureDragger from './PictureInPictureDragger';
|
||||
import dis from '../../../dispatcher/dispatcher';
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { WidgetLayoutStore } from '../../../stores/widgets/WidgetLayoutStore';
|
||||
|
||||
const SHOW_CALL_IN_STATES = [
|
||||
CallState.Connected,
|
||||
|
@ -58,7 +60,9 @@ interface IState {
|
|||
// (which should be a single element) of other calls.
|
||||
// The primary will be the one not on hold, or an arbitrary one
|
||||
// if they're all on hold)
|
||||
function getPrimarySecondaryCalls(calls: MatrixCall[]): [MatrixCall, MatrixCall[]] {
|
||||
function getPrimarySecondaryCallsForPip(roomId: string): [MatrixCall, MatrixCall[]] {
|
||||
const calls = CallHandler.instance.getAllActiveCallsForPip(roomId);
|
||||
|
||||
let primary: MatrixCall = null;
|
||||
let secondaries: MatrixCall[] = [];
|
||||
|
||||
|
@ -100,9 +104,7 @@ export default class CallPreview extends React.Component<IProps, IState> {
|
|||
|
||||
const roomId = RoomViewStore.getRoomId();
|
||||
|
||||
const [primaryCall, secondaryCalls] = getPrimarySecondaryCalls(
|
||||
CallHandler.sharedInstance().getAllActiveCallsNotInRoom(roomId),
|
||||
);
|
||||
const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(roomId);
|
||||
|
||||
this.state = {
|
||||
roomId,
|
||||
|
@ -112,53 +114,57 @@ export default class CallPreview extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
public componentDidMount() {
|
||||
CallHandler.sharedInstance().addListener(CallHandlerEvent.CallChangeRoom, this.updateCalls);
|
||||
CallHandler.instance.addListener(CallHandlerEvent.CallChangeRoom, this.updateCalls);
|
||||
CallHandler.instance.addListener(CallHandlerEvent.CallState, this.updateCalls);
|
||||
this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate);
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
MatrixClientPeg.get().on(CallEvent.RemoteHoldUnhold, this.onCallRemoteHold);
|
||||
const room = MatrixClientPeg.get()?.getRoom(this.state.roomId);
|
||||
if (room) {
|
||||
WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(room), this.updateCalls);
|
||||
}
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
CallHandler.sharedInstance().removeListener(CallHandlerEvent.CallChangeRoom, this.updateCalls);
|
||||
CallHandler.instance.removeListener(CallHandlerEvent.CallChangeRoom, this.updateCalls);
|
||||
CallHandler.instance.removeListener(CallHandlerEvent.CallState, this.updateCalls);
|
||||
MatrixClientPeg.get().removeListener(CallEvent.RemoteHoldUnhold, this.onCallRemoteHold);
|
||||
if (this.roomStoreToken) {
|
||||
this.roomStoreToken.remove();
|
||||
}
|
||||
dis.unregister(this.dispatcherRef);
|
||||
SettingsStore.unwatchSetting(this.settingsWatcherRef);
|
||||
const room = MatrixClientPeg.get().getRoom(this.state.roomId);
|
||||
if (room) {
|
||||
WidgetLayoutStore.instance.off(WidgetLayoutStore.emissionForRoom(room), this.updateCalls);
|
||||
}
|
||||
}
|
||||
|
||||
private onRoomViewStoreUpdate = () => {
|
||||
if (RoomViewStore.getRoomId() === this.state.roomId) return;
|
||||
|
||||
const roomId = RoomViewStore.getRoomId();
|
||||
const [primaryCall, secondaryCalls] = getPrimarySecondaryCalls(
|
||||
CallHandler.sharedInstance().getAllActiveCallsNotInRoom(roomId),
|
||||
);
|
||||
const newRoomId = RoomViewStore.getRoomId();
|
||||
const oldRoomId = this.state.roomId;
|
||||
if (newRoomId === oldRoomId) return;
|
||||
// The WidgetLayoutStore observer always tracks the currently viewed Room,
|
||||
// so we don't end up with multiple observers and know what observer to remove on unmount
|
||||
const oldRoom = MatrixClientPeg.get()?.getRoom(oldRoomId);
|
||||
if (oldRoom) {
|
||||
WidgetLayoutStore.instance.off(WidgetLayoutStore.emissionForRoom(oldRoom), this.updateCalls);
|
||||
}
|
||||
const newRoom = MatrixClientPeg.get()?.getRoom(newRoomId);
|
||||
if (newRoom) {
|
||||
WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(newRoom), this.updateCalls);
|
||||
}
|
||||
if (!newRoomId) return;
|
||||
|
||||
const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(newRoomId);
|
||||
this.setState({
|
||||
roomId,
|
||||
roomId: newRoomId,
|
||||
primaryCall: primaryCall,
|
||||
secondaryCall: secondaryCalls[0],
|
||||
});
|
||||
};
|
||||
|
||||
private onAction = (payload: ActionPayload) => {
|
||||
switch (payload.action) {
|
||||
case 'call_state': {
|
||||
// listen for call state changes to prod the render method, which
|
||||
// may hide the global CallView if the call it is tracking is dead
|
||||
|
||||
this.updateCalls();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private updateCalls = () => {
|
||||
const [primaryCall, secondaryCalls] = getPrimarySecondaryCalls(
|
||||
CallHandler.sharedInstance().getAllActiveCallsNotInRoom(this.state.roomId),
|
||||
);
|
||||
private updateCalls = (): void => {
|
||||
if (!this.state.roomId) return;
|
||||
const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(this.state.roomId);
|
||||
|
||||
this.setState({
|
||||
primaryCall: primaryCall,
|
||||
|
@ -167,9 +173,8 @@ export default class CallPreview extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
private onCallRemoteHold = () => {
|
||||
const [primaryCall, secondaryCalls] = getPrimarySecondaryCalls(
|
||||
CallHandler.sharedInstance().getAllActiveCallsNotInRoom(this.state.roomId),
|
||||
);
|
||||
if (!this.state.roomId) return;
|
||||
const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(this.state.roomId);
|
||||
|
||||
this.setState({
|
||||
primaryCall: primaryCall,
|
||||
|
@ -177,6 +182,13 @@ export default class CallPreview extends React.Component<IProps, IState> {
|
|||
});
|
||||
};
|
||||
|
||||
private onDoubleClick = (): void => {
|
||||
dis.dispatch({
|
||||
action: Action.ViewRoom,
|
||||
room_id: this.state.primaryCall.roomId,
|
||||
});
|
||||
};
|
||||
|
||||
public render() {
|
||||
const pipMode = true;
|
||||
if (this.state.primaryCall) {
|
||||
|
@ -184,6 +196,7 @@ export default class CallPreview extends React.Component<IProps, IState> {
|
|||
<PictureInPictureDragger
|
||||
className="mx_CallPreview"
|
||||
draggable={pipMode}
|
||||
onDoubleClick={this.onDoubleClick}
|
||||
>
|
||||
{ ({ onStartMoving, onResize }) => <CallView
|
||||
onMouseDownOnHeader={onStartMoving}
|
||||
|
|
|
@ -57,6 +57,8 @@ interface IProps {
|
|||
|
||||
// Used for dragging the PiP CallView
|
||||
onMouseDownOnHeader?: (event: React.MouseEvent<Element, MouseEvent>) => void;
|
||||
|
||||
showApps?: boolean;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
|
@ -327,20 +329,17 @@ export default class CallView extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
private onCallResumeClick = (): void => {
|
||||
const userFacingRoomId = CallHandler.sharedInstance().roomIdForCall(this.props.call);
|
||||
CallHandler.sharedInstance().setActiveCallRoomId(userFacingRoomId);
|
||||
const userFacingRoomId = CallHandler.instance.roomIdForCall(this.props.call);
|
||||
CallHandler.instance.setActiveCallRoomId(userFacingRoomId);
|
||||
};
|
||||
|
||||
private onTransferClick = (): void => {
|
||||
const transfereeCall = CallHandler.sharedInstance().getTransfereeForCallId(this.props.call.callId);
|
||||
const transfereeCall = CallHandler.instance.getTransfereeForCallId(this.props.call.callId);
|
||||
this.props.call.transferToCall(transfereeCall);
|
||||
};
|
||||
|
||||
private onHangupClick = (): void => {
|
||||
dis.dispatch({
|
||||
action: 'hangup',
|
||||
room_id: CallHandler.sharedInstance().roomIdForCall(this.props.call),
|
||||
});
|
||||
CallHandler.instance.hangupOrReject(CallHandler.instance.roomIdForCall(this.props.call));
|
||||
};
|
||||
|
||||
private onToggleSidebar = (): void => {
|
||||
|
@ -403,12 +402,12 @@ export default class CallView extends React.Component<IProps, IState> {
|
|||
|
||||
public render() {
|
||||
const client = MatrixClientPeg.get();
|
||||
const callRoomId = CallHandler.sharedInstance().roomIdForCall(this.props.call);
|
||||
const secondaryCallRoomId = CallHandler.sharedInstance().roomIdForCall(this.props.secondaryCall);
|
||||
const callRoomId = CallHandler.instance.roomIdForCall(this.props.call);
|
||||
const secondaryCallRoomId = CallHandler.instance.roomIdForCall(this.props.secondaryCall);
|
||||
const callRoom = client.getRoom(callRoomId);
|
||||
const secCallRoom = this.props.secondaryCall ? client.getRoom(secondaryCallRoomId) : null;
|
||||
const avatarSize = this.props.pipMode ? 76 : 160;
|
||||
const transfereeCall = CallHandler.sharedInstance().getTransfereeForCallId(this.props.call.callId);
|
||||
const transfereeCall = CallHandler.instance.getTransfereeForCallId(this.props.call.callId);
|
||||
const isOnHold = this.state.isLocalOnHold || this.state.isRemoteOnHold;
|
||||
const isScreensharing = this.props.call.isScreensharing();
|
||||
const sidebarShown = this.state.sidebarShown;
|
||||
|
@ -422,12 +421,12 @@ export default class CallView extends React.Component<IProps, IState> {
|
|||
|
||||
if (transfereeCall) {
|
||||
const transferTargetRoom = MatrixClientPeg.get().getRoom(
|
||||
CallHandler.sharedInstance().roomIdForCall(this.props.call),
|
||||
CallHandler.instance.roomIdForCall(this.props.call),
|
||||
);
|
||||
const transferTargetName = transferTargetRoom ? transferTargetRoom.name : _t("unknown person");
|
||||
|
||||
const transfereeRoom = MatrixClientPeg.get().getRoom(
|
||||
CallHandler.sharedInstance().roomIdForCall(transfereeCall),
|
||||
CallHandler.instance.roomIdForCall(transfereeCall),
|
||||
);
|
||||
const transfereeName = transfereeRoom ? transfereeRoom.name : _t("unknown person");
|
||||
|
||||
|
@ -448,7 +447,7 @@ export default class CallView extends React.Component<IProps, IState> {
|
|||
} else if (isOnHold) {
|
||||
let onHoldText = null;
|
||||
if (this.state.isRemoteOnHold) {
|
||||
const holdString = CallHandler.sharedInstance().hasAnyUnheldCall() ?
|
||||
const holdString = CallHandler.instance.hasAnyUnheldCall() ?
|
||||
_td("You held the call <a>Switch</a>") : _td("You held the call <a>Resume</a>");
|
||||
onHoldText = _t(holdString, {}, {
|
||||
a: sub => <AccessibleButton kind="link" onClick={this.onCallResumeClick}>
|
||||
|
@ -615,9 +614,14 @@ export default class CallView extends React.Component<IProps, IState> {
|
|||
);
|
||||
}
|
||||
|
||||
const myClassName = this.props.pipMode ? 'mx_CallView_pip' : 'mx_CallView_large';
|
||||
const callViewClasses = classNames({
|
||||
mx_CallView: true,
|
||||
mx_CallView_pip: this.props.pipMode,
|
||||
mx_CallView_large: !this.props.pipMode,
|
||||
mx_CallView_belowWidget: this.props.showApps, // css to correct the margins if the call is below the AppsDrawer.
|
||||
});
|
||||
|
||||
return <div className={"mx_CallView " + myClassName}>
|
||||
return <div className={callViewClasses}>
|
||||
<CallViewHeader
|
||||
onPipMouseDown={this.props.onMouseDownOnHeader}
|
||||
pipMode={this.props.pipMode}
|
||||
|
|
|
@ -40,6 +40,31 @@ const TOOLTIP_Y_OFFSET = -24;
|
|||
|
||||
const CONTROLS_HIDE_DELAY = 2000;
|
||||
|
||||
interface IButtonProps {
|
||||
state: boolean;
|
||||
className: string;
|
||||
onLabel: string;
|
||||
offLabel: string;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
const CallViewToggleButton: React.FC<IButtonProps> = ({ state: isOn, className, onLabel, offLabel, onClick }) => {
|
||||
const classes = classNames("mx_CallViewButtons_button", className, {
|
||||
mx_CallViewButtons_button_on: isOn,
|
||||
mx_CallViewButtons_button_off: !isOn,
|
||||
});
|
||||
|
||||
return (
|
||||
<AccessibleTooltipButton
|
||||
className={classes}
|
||||
onClick={onClick}
|
||||
title={isOn ? onLabel : offLabel}
|
||||
alignment={Alignment.Top}
|
||||
yOffset={TOOLTIP_Y_OFFSET}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
interface IProps {
|
||||
call: MatrixCall;
|
||||
pipMode: boolean;
|
||||
|
@ -143,113 +168,10 @@ export default class CallViewButtons extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
const micClasses = classNames("mx_CallViewButtons_button", {
|
||||
mx_CallViewButtons_button_micOn: !this.props.buttonsState.micMuted,
|
||||
mx_CallViewButtons_button_micOff: this.props.buttonsState.micMuted,
|
||||
});
|
||||
|
||||
const vidClasses = classNames("mx_CallViewButtons_button", {
|
||||
mx_CallViewButtons_button_vidOn: !this.props.buttonsState.vidMuted,
|
||||
mx_CallViewButtons_button_vidOff: this.props.buttonsState.vidMuted,
|
||||
});
|
||||
|
||||
const screensharingClasses = classNames("mx_CallViewButtons_button", {
|
||||
mx_CallViewButtons_button_screensharingOn: this.props.buttonsState.screensharing,
|
||||
mx_CallViewButtons_button_screensharingOff: !this.props.buttonsState.screensharing,
|
||||
});
|
||||
|
||||
const sidebarButtonClasses = classNames("mx_CallViewButtons_button", {
|
||||
mx_CallViewButtons_button_sidebarOn: this.props.buttonsState.sidebarShown,
|
||||
mx_CallViewButtons_button_sidebarOff: !this.props.buttonsState.sidebarShown,
|
||||
});
|
||||
|
||||
// Put the other states of the mic/video icons in the document to make sure they're cached
|
||||
// (otherwise the icon disappears briefly when toggled)
|
||||
const micCacheClasses = classNames("mx_CallViewButtons_button", "mx_CallViewButtons_button_invisible", {
|
||||
mx_CallViewButtons_button_micOn: this.props.buttonsState.micMuted,
|
||||
mx_CallViewButtons_button_micOff: !this.props.buttonsState.micMuted,
|
||||
});
|
||||
|
||||
const vidCacheClasses = classNames("mx_CallViewButtons_button", "mx_CallViewButtons_button_invisible", {
|
||||
mx_CallViewButtons_button_vidOn: this.props.buttonsState.micMuted,
|
||||
mx_CallViewButtons_button_vidOff: !this.props.buttonsState.micMuted,
|
||||
});
|
||||
|
||||
const callControlsClasses = classNames("mx_CallViewButtons", {
|
||||
mx_CallViewButtons_hidden: !this.state.visible,
|
||||
});
|
||||
|
||||
let vidMuteButton;
|
||||
if (this.props.buttonsVisibility.vidMute) {
|
||||
vidMuteButton = (
|
||||
<AccessibleTooltipButton
|
||||
className={vidClasses}
|
||||
onClick={this.props.handlers.onVidMuteClick}
|
||||
title={this.props.buttonsState.vidMuted ? _t("Start the camera") : _t("Stop the camera")}
|
||||
alignment={Alignment.Top}
|
||||
yOffset={TOOLTIP_Y_OFFSET}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
let screensharingButton;
|
||||
if (this.props.buttonsVisibility.screensharing) {
|
||||
screensharingButton = (
|
||||
<AccessibleTooltipButton
|
||||
className={screensharingClasses}
|
||||
onClick={this.props.handlers.onScreenshareClick}
|
||||
title={this.props.buttonsState.screensharing
|
||||
? _t("Stop sharing your screen")
|
||||
: _t("Start sharing your screen")
|
||||
}
|
||||
alignment={Alignment.Top}
|
||||
yOffset={TOOLTIP_Y_OFFSET}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
let sidebarButton;
|
||||
if (this.props.buttonsVisibility.sidebar) {
|
||||
sidebarButton = (
|
||||
<AccessibleTooltipButton
|
||||
className={sidebarButtonClasses}
|
||||
onClick={this.props.handlers.onToggleSidebarClick}
|
||||
title={this.props.buttonsState.sidebarShown ? _t("Hide sidebar") : _t("Show sidebar")}
|
||||
alignment={Alignment.Top}
|
||||
yOffset={TOOLTIP_Y_OFFSET}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
let contextMenuButton;
|
||||
if (this.props.buttonsVisibility.contextMenu) {
|
||||
contextMenuButton = (
|
||||
<ContextMenuTooltipButton
|
||||
className="mx_CallViewButtons_button mx_CallViewButtons_button_more"
|
||||
onClick={this.onMoreClick}
|
||||
inputRef={this.contextMenuButton}
|
||||
isExpanded={this.state.showMoreMenu}
|
||||
title={_t("More")}
|
||||
alignment={Alignment.Top}
|
||||
yOffset={TOOLTIP_Y_OFFSET}
|
||||
/>
|
||||
);
|
||||
}
|
||||
let dialpadButton;
|
||||
if (this.props.buttonsVisibility.dialpad) {
|
||||
dialpadButton = (
|
||||
<ContextMenuTooltipButton
|
||||
className="mx_CallViewButtons_button mx_CallViewButtons_dialpad"
|
||||
inputRef={this.dialpadButton}
|
||||
onClick={this.onDialpadClick}
|
||||
isExpanded={this.state.showDialpad}
|
||||
title={_t("Dialpad")}
|
||||
alignment={Alignment.Top}
|
||||
yOffset={TOOLTIP_Y_OFFSET}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
let dialPad;
|
||||
if (this.state.showDialpad) {
|
||||
dialPad = <DialpadContextMenu
|
||||
|
@ -290,20 +212,53 @@ export default class CallViewButtons extends React.Component<IProps, IState> {
|
|||
>
|
||||
{ dialPad }
|
||||
{ contextMenu }
|
||||
{ dialpadButton }
|
||||
<AccessibleTooltipButton
|
||||
className={micClasses}
|
||||
onClick={this.props.handlers.onMicMuteClick}
|
||||
title={this.props.buttonsState.micMuted ? _t("Unmute the microphone") : _t("Mute the microphone")}
|
||||
|
||||
{ this.props.buttonsVisibility.dialpad && <ContextMenuTooltipButton
|
||||
className="mx_CallViewButtons_button mx_CallViewButtons_dialpad"
|
||||
inputRef={this.dialpadButton}
|
||||
onClick={this.onDialpadClick}
|
||||
isExpanded={this.state.showDialpad}
|
||||
title={_t("Dialpad")}
|
||||
alignment={Alignment.Top}
|
||||
yOffset={TOOLTIP_Y_OFFSET}
|
||||
/> }
|
||||
<CallViewToggleButton
|
||||
state={!this.props.buttonsState.micMuted}
|
||||
className="mx_CallViewButtons_button_mic"
|
||||
onLabel={_t("Mute the microphone")}
|
||||
offLabel={_t("Unmute the microphone")}
|
||||
onClick={this.props.handlers.onMicMuteClick}
|
||||
/>
|
||||
{ vidMuteButton }
|
||||
<div className={micCacheClasses} />
|
||||
<div className={vidCacheClasses} />
|
||||
{ screensharingButton }
|
||||
{ sidebarButton }
|
||||
{ contextMenuButton }
|
||||
{ this.props.buttonsVisibility.vidMute && <CallViewToggleButton
|
||||
state={!this.props.buttonsState.vidMuted}
|
||||
className="mx_CallViewButtons_button_vid"
|
||||
onLabel={_t("Stop the camera")}
|
||||
offLabel={_t("Start the camera")}
|
||||
onClick={this.props.handlers.onVidMuteClick}
|
||||
/> }
|
||||
{ this.props.buttonsVisibility.screensharing && <CallViewToggleButton
|
||||
state={this.props.buttonsState.screensharing}
|
||||
className="mx_CallViewButtons_button_screensharing"
|
||||
onLabel={_t("Stop sharing your screen")}
|
||||
offLabel={_t("Start sharing your screen")}
|
||||
onClick={this.props.handlers.onScreenshareClick}
|
||||
/> }
|
||||
{ this.props.buttonsVisibility.sidebar && <CallViewToggleButton
|
||||
state={this.props.buttonsState.sidebarShown}
|
||||
className="mx_CallViewButtons_button_sidebar"
|
||||
onLabel={_t("Hide sidebar")}
|
||||
offLabel={_t("Show sidebar")}
|
||||
onClick={this.props.handlers.onToggleSidebarClick}
|
||||
/> }
|
||||
{ this.props.buttonsVisibility.contextMenu && <ContextMenuTooltipButton
|
||||
className="mx_CallViewButtons_button mx_CallViewButtons_button_more"
|
||||
onClick={this.onMoreClick}
|
||||
inputRef={this.contextMenuButton}
|
||||
isExpanded={this.state.showMoreMenu}
|
||||
title={_t("More")}
|
||||
alignment={Alignment.Top}
|
||||
yOffset={TOOLTIP_Y_OFFSET}
|
||||
/> }
|
||||
<AccessibleTooltipButton
|
||||
className="mx_CallViewButtons_button mx_CallViewButtons_button_hangup"
|
||||
onClick={this.props.handlers.onHangupClick}
|
||||
|
|
|
@ -17,12 +17,11 @@ limitations under the License.
|
|||
import { CallType } from 'matrix-js-sdk/src/webrtc/call';
|
||||
import { Room } from 'matrix-js-sdk/src/models/room';
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { _t, _td } from '../../../../languageHandler';
|
||||
import RoomAvatar from '../../avatars/RoomAvatar';
|
||||
import AccessibleButton from '../../elements/AccessibleButton';
|
||||
import dis from '../../../../dispatcher/dispatcher';
|
||||
import { Action } from '../../../../dispatcher/actions';
|
||||
import classNames from 'classnames';
|
||||
import AccessibleTooltipButton from '../../elements/AccessibleTooltipButton';
|
||||
|
||||
const callTypeTranslationByType: Record<CallType, string> = {
|
||||
|
@ -37,13 +36,6 @@ interface CallViewHeaderProps {
|
|||
onPipMouseDown: (event: React.MouseEvent<Element, MouseEvent>) => void;
|
||||
}
|
||||
|
||||
const onRoomAvatarClick = (roomId: string) => {
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: roomId,
|
||||
});
|
||||
};
|
||||
|
||||
const onFullscreenClick = () => {
|
||||
dis.dispatch({
|
||||
action: 'video_fullscreen',
|
||||
|
@ -53,7 +45,7 @@ const onFullscreenClick = () => {
|
|||
|
||||
const onExpandClick = (roomId: string) => {
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
action: Action.ViewRoom,
|
||||
room_id: roomId,
|
||||
});
|
||||
};
|
||||
|
@ -77,12 +69,10 @@ const CallViewHeaderControls: React.FC<CallControlsProps> = ({ pipMode = false,
|
|||
};
|
||||
const SecondaryCallInfo: React.FC<{ callRoom: Room }> = ({ callRoom }) => {
|
||||
return <span className="mx_CallViewHeader_secondaryCallInfo">
|
||||
<AccessibleButton element='span' onClick={() => onRoomAvatarClick(callRoom.roomId)}>
|
||||
<RoomAvatar room={callRoom} height={16} width={16} />
|
||||
<span className="mx_CallView_secondaryCall_roomName">
|
||||
{ _t("%(name)s on hold", { name: callRoom.name }) }
|
||||
</span>
|
||||
</AccessibleButton>
|
||||
<RoomAvatar room={callRoom} height={16} width={16} />
|
||||
<span className="mx_CallView_secondaryCall_roomName">
|
||||
{ _t("%(name)s on hold", { name: callRoom.name }) }
|
||||
</span>
|
||||
</span>;
|
||||
};
|
||||
|
||||
|
@ -118,9 +108,7 @@ const CallViewHeader: React.FC<CallViewHeaderProps> = ({
|
|||
className="mx_CallViewHeader"
|
||||
onMouseDown={onPipMouseDown}
|
||||
>
|
||||
<AccessibleButton onClick={() => onRoomAvatarClick(roomId)}>
|
||||
<RoomAvatar room={callRoom} height={32} width={32} />
|
||||
</AccessibleButton>
|
||||
<RoomAvatar room={callRoom} height={32} width={32} />
|
||||
<div className="mx_CallViewHeader_callInfo">
|
||||
<div className="mx_CallViewHeader_roomName">{ callRoomName }</div>
|
||||
<div className="mx_CallViewHeader_callTypeSmall">
|
||||
|
|
|
@ -16,11 +16,9 @@ limitations under the License.
|
|||
|
||||
import { CallState, MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
|
||||
import React from 'react';
|
||||
import { Resizable } from "re-resizable";
|
||||
|
||||
import CallHandler, { CallHandlerEvent } from '../../../CallHandler';
|
||||
import CallView from './CallView';
|
||||
import dis from '../../../dispatcher/dispatcher';
|
||||
import { Resizable } from "re-resizable";
|
||||
import ResizeNotifier from "../../../utils/ResizeNotifier";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
|
@ -29,6 +27,8 @@ interface IProps {
|
|||
roomId: string;
|
||||
|
||||
resizeNotifier: ResizeNotifier;
|
||||
|
||||
showApps?: boolean;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
|
@ -51,24 +51,15 @@ export default class CallViewForRoom extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
public componentDidMount() {
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
CallHandler.sharedInstance().addListener(CallHandlerEvent.CallChangeRoom, this.updateCall);
|
||||
CallHandler.instance.addListener(CallHandlerEvent.CallState, this.updateCall);
|
||||
CallHandler.instance.addListener(CallHandlerEvent.CallChangeRoom, this.updateCall);
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
dis.unregister(this.dispatcherRef);
|
||||
CallHandler.sharedInstance().removeListener(CallHandlerEvent.CallChangeRoom, this.updateCall);
|
||||
CallHandler.instance.removeListener(CallHandlerEvent.CallState, this.updateCall);
|
||||
CallHandler.instance.removeListener(CallHandlerEvent.CallChangeRoom, this.updateCall);
|
||||
}
|
||||
|
||||
private onAction = (payload) => {
|
||||
switch (payload.action) {
|
||||
case 'call_state': {
|
||||
this.updateCall();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private updateCall = () => {
|
||||
const newCall = this.getCall();
|
||||
if (newCall !== this.state.call) {
|
||||
|
@ -77,7 +68,7 @@ export default class CallViewForRoom extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
private getCall(): MatrixCall {
|
||||
const call = CallHandler.sharedInstance().getCallForRoom(this.props.roomId);
|
||||
const call = CallHandler.instance.getCallForRoom(this.props.roomId);
|
||||
|
||||
if (call && [CallState.Ended, CallState.Ringing].includes(call.state)) return null;
|
||||
return call;
|
||||
|
@ -122,6 +113,7 @@ export default class CallViewForRoom extends React.Component<IProps, IState> {
|
|||
<CallView
|
||||
call={this.state.call}
|
||||
pipMode={false}
|
||||
showApps={this.props.showApps}
|
||||
/>
|
||||
</Resizable>
|
||||
</div>
|
||||
|
|
|
@ -20,11 +20,9 @@ import { createRef } from "react";
|
|||
import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
|
||||
import Field from "../elements/Field";
|
||||
import DialPad from './DialPad';
|
||||
import dis from '../../../dispatcher/dispatcher';
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import { DialNumberPayload } from "../../../dispatcher/payloads/DialNumberPayload";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
import DialPadBackspaceButton from "../elements/DialPadBackspaceButton";
|
||||
import CallHandler from "../../../CallHandler";
|
||||
|
||||
interface IProps {
|
||||
onFinished: (boolean) => void;
|
||||
|
@ -82,12 +80,7 @@ export default class DialpadModal extends React.PureComponent<IProps, IState> {
|
|||
};
|
||||
|
||||
onDialPress = async () => {
|
||||
const payload: DialNumberPayload = {
|
||||
action: Action.DialNumber,
|
||||
number: this.state.value,
|
||||
};
|
||||
dis.dispatch(payload);
|
||||
|
||||
CallHandler.instance.dialNumber(this.state.value);
|
||||
this.props.onFinished(true);
|
||||
};
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ interface IProps {
|
|||
className?: string;
|
||||
children: ({ onStartMoving, onResize }: IChildrenOptions) => React.ReactNode;
|
||||
draggable: boolean;
|
||||
onDoubleClick?: () => void;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
|
@ -217,6 +218,7 @@ export default class PictureInPictureDragger extends React.Component<IProps, ISt
|
|||
className={this.props.className}
|
||||
style={this.props.draggable ? style : undefined}
|
||||
ref={this.callViewWrapper}
|
||||
onDoubleClick={this.props.onDoubleClick}
|
||||
>
|
||||
<>
|
||||
{ this.props.children({
|
||||
|
|
|
@ -46,7 +46,6 @@ interface IProps {
|
|||
interface IState {
|
||||
audioMuted: boolean;
|
||||
videoMuted: boolean;
|
||||
speaking: boolean;
|
||||
}
|
||||
|
||||
@replaceableComponent("views.voip.VideoFeed")
|
||||
|
@ -59,7 +58,6 @@ export default class VideoFeed extends React.PureComponent<IProps, IState> {
|
|||
this.state = {
|
||||
audioMuted: this.props.feed.isAudioMuted(),
|
||||
videoMuted: this.props.feed.isVideoMuted(),
|
||||
speaking: false,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -107,7 +105,6 @@ export default class VideoFeed extends React.PureComponent<IProps, IState> {
|
|||
this.props.feed.removeListener(CallFeedEvent.NewStream, this.onNewStream);
|
||||
this.props.feed.removeListener(CallFeedEvent.MuteStateChanged, this.onMuteStateChanged);
|
||||
if (this.props.feed.purpose === SDPStreamMetadataPurpose.Usermedia) {
|
||||
this.props.feed.removeListener(CallFeedEvent.Speaking, this.onSpeaking);
|
||||
this.props.feed.measureVolumeActivity(false);
|
||||
}
|
||||
this.stopMedia();
|
||||
|
@ -116,7 +113,6 @@ export default class VideoFeed extends React.PureComponent<IProps, IState> {
|
|||
this.props.feed.addListener(CallFeedEvent.NewStream, this.onNewStream);
|
||||
this.props.feed.addListener(CallFeedEvent.MuteStateChanged, this.onMuteStateChanged);
|
||||
if (this.props.feed.purpose === SDPStreamMetadataPurpose.Usermedia) {
|
||||
this.props.feed.addListener(CallFeedEvent.Speaking, this.onSpeaking);
|
||||
this.props.feed.measureVolumeActivity(true);
|
||||
}
|
||||
this.playMedia();
|
||||
|
@ -173,10 +169,6 @@ export default class VideoFeed extends React.PureComponent<IProps, IState> {
|
|||
});
|
||||
};
|
||||
|
||||
private onSpeaking = (speaking: boolean): void => {
|
||||
this.setState({ speaking });
|
||||
};
|
||||
|
||||
private onResize = (e) => {
|
||||
if (this.props.onResize && !this.props.feed.isLocal()) {
|
||||
this.props.onResize(e);
|
||||
|
@ -188,7 +180,6 @@ export default class VideoFeed extends React.PureComponent<IProps, IState> {
|
|||
|
||||
const wrapperClasses = classnames("mx_VideoFeed", {
|
||||
mx_VideoFeed_voice: this.state.videoMuted,
|
||||
mx_VideoFeed_speaking: this.state.speaking,
|
||||
});
|
||||
const micIconClasses = classnames("mx_VideoFeed_mic", {
|
||||
mx_VideoFeed_mic_muted: this.state.audioMuted,
|
||||
|
@ -196,7 +187,11 @@ export default class VideoFeed extends React.PureComponent<IProps, IState> {
|
|||
});
|
||||
|
||||
let micIcon;
|
||||
if (feed.purpose !== SDPStreamMetadataPurpose.Screenshare && !pipMode) {
|
||||
if (
|
||||
feed.purpose !== SDPStreamMetadataPurpose.Screenshare &&
|
||||
!primary &&
|
||||
!pipMode
|
||||
) {
|
||||
micIcon = (
|
||||
<div className={micIconClasses} />
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue