Fix ident
This commit is contained in:
parent
838d9105c9
commit
a0b0a91d08
4 changed files with 174 additions and 174 deletions
|
@ -144,8 +144,8 @@ export default class CallPreview extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
private onAction = (payload: ActionPayload) => {
|
private onAction = (payload: ActionPayload) => {
|
||||||
switch (payload.action) {
|
switch (payload.action) {
|
||||||
// listen for call state changes to prod the render method, which
|
// listen for call state changes to prod the render method, which
|
||||||
// may hide the global CallView if the call it is tracking is dead
|
// may hide the global CallView if the call it is tracking is dead
|
||||||
case 'call_state': {
|
case 'call_state': {
|
||||||
this.updateCalls();
|
this.updateCalls();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -40,23 +40,23 @@ import CallViewSidebar from './CallViewSidebar';
|
||||||
import { CallViewHeader } from './CallView/CallViewHeader';
|
import { CallViewHeader } from './CallView/CallViewHeader';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
// The call for us to display
|
// The call for us to display
|
||||||
call: MatrixCall;
|
call: MatrixCall;
|
||||||
|
|
||||||
// Another ongoing call to display information about
|
// Another ongoing call to display information about
|
||||||
secondaryCall?: MatrixCall;
|
secondaryCall?: MatrixCall;
|
||||||
|
|
||||||
// a callback which is called when the content in the CallView changes
|
// a callback which is called when the content in the CallView changes
|
||||||
// in a way that is likely to cause a resize.
|
// in a way that is likely to cause a resize.
|
||||||
onResize?: any;
|
onResize?: any;
|
||||||
|
|
||||||
// Whether this call view is for picture-in-picture mode
|
// 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.
|
// otherwise, it's the larger call view when viewing the room the call is in.
|
||||||
// This is sort of a proxy for a number of things but we currently have no
|
// This is sort of a proxy for a number of things but we currently have no
|
||||||
// need to control those things separately, so this is simpler.
|
// need to control those things separately, so this is simpler.
|
||||||
pipMode?: boolean;
|
pipMode?: boolean;
|
||||||
|
|
||||||
// Used for dragging the PiP CallView
|
// Used for dragging the PiP CallView
|
||||||
onMouseDownOnHeader?: (event: React.MouseEvent<Element, MouseEvent>) => void;
|
onMouseDownOnHeader?: (event: React.MouseEvent<Element, MouseEvent>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,37 +26,37 @@ import { IApp } from '../../../../stores/WidgetStore';
|
||||||
import WidgetUtils from '../../../../utils/WidgetUtils';
|
import WidgetUtils from '../../../../utils/WidgetUtils';
|
||||||
|
|
||||||
const callTypeTranslationByType: Record<CallType | 'widget', (app?: IApp) => string> = {
|
const callTypeTranslationByType: Record<CallType | 'widget', (app?: IApp) => string> = {
|
||||||
[CallType.Video]: () => _t("Video Call"),
|
[CallType.Video]: () => _t("Video Call"),
|
||||||
[CallType.Voice]: () => _t("Voice Call"),
|
[CallType.Voice]: () => _t("Voice Call"),
|
||||||
'widget': (app: IApp) => WidgetUtils.getWidgetName(app),
|
'widget': (app: IApp) => WidgetUtils.getWidgetName(app),
|
||||||
};
|
};
|
||||||
|
|
||||||
interface CallViewHeaderProps {
|
interface CallViewHeaderProps {
|
||||||
pipMode: boolean;
|
pipMode: boolean;
|
||||||
type: CallType | 'widget';
|
type: CallType | 'widget';
|
||||||
callRooms?: Room[];
|
callRooms?: Room[];
|
||||||
app?: IApp;
|
app?: IApp;
|
||||||
onPipMouseDown: (event: React.MouseEvent<Element, MouseEvent>) => void;
|
onPipMouseDown: (event: React.MouseEvent<Element, MouseEvent>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const onRoomAvatarClick = (roomId: string) => {
|
const onRoomAvatarClick = (roomId: string) => {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'view_room',
|
action: 'view_room',
|
||||||
room_id: roomId,
|
room_id: roomId,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onFullscreenClick = () => {
|
const onFullscreenClick = () => {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'video_fullscreen',
|
action: 'video_fullscreen',
|
||||||
fullscreen: true,
|
fullscreen: true,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onExpandClick = (roomId: string) => {
|
const onExpandClick = (roomId: string) => {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'view_room',
|
action: 'view_room',
|
||||||
room_id: roomId,
|
room_id: roomId,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,12 +97,12 @@ function getAvatarBasedOnRoomType(roomOrWidget: Room | IApp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CallViewHeader: React.FC<CallViewHeaderProps> = ({
|
export const CallViewHeader: React.FC<CallViewHeaderProps> = ({
|
||||||
type,
|
type,
|
||||||
pipMode = false,
|
pipMode = false,
|
||||||
callRooms = [],
|
callRooms = [],
|
||||||
app,
|
app,
|
||||||
onPipMouseDown,
|
onPipMouseDown,
|
||||||
}) {
|
}) => {
|
||||||
const [callRoom, onHoldCallRoom] = callRooms;
|
const [callRoom, onHoldCallRoom] = callRooms;
|
||||||
const callTypeText = callTypeTranslationByType[type](app);
|
const callTypeText = callTypeTranslationByType[type](app);
|
||||||
const avatar = getAvatarBasedOnRoomType(callRoom ?? app);
|
const avatar = getAvatarBasedOnRoomType(callRoom ?? app);
|
||||||
|
@ -132,4 +132,4 @@ export const CallViewHeader: React.FC<CallViewHeaderProps> = ({
|
||||||
<CallControls roomId={roomId} pipMode={pipMode} type={type} />
|
<CallControls roomId={roomId} pipMode={pipMode} type={type} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
|
@ -27,23 +27,23 @@ const MOVING_AMT = 0.2;
|
||||||
const SNAPPING_AMT = 0.05;
|
const SNAPPING_AMT = 0.05;
|
||||||
|
|
||||||
const PADDING = {
|
const PADDING = {
|
||||||
top: 58,
|
top: 58,
|
||||||
bottom: 58,
|
bottom: 58,
|
||||||
left: 76,
|
left: 76,
|
||||||
right: 8,
|
right: 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
children: (startMovingEventHandler: (event: React.MouseEvent<Element, MouseEvent>) => void) => React.ReactNode;
|
children: (startMovingEventHandler: (event: React.MouseEvent<Element, MouseEvent>) => void) => React.ReactNode;
|
||||||
draggable: boolean;
|
draggable: boolean;
|
||||||
app?: IApp;
|
app?: IApp;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
// Position of the PictureInPictureDragger
|
// Position of the PictureInPictureDragger
|
||||||
translationX: number;
|
translationX: number;
|
||||||
translationY: number;
|
translationY: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,157 +52,157 @@ interface IState {
|
||||||
*/
|
*/
|
||||||
@replaceableComponent("views.voip.PictureInPictureDragger")
|
@replaceableComponent("views.voip.PictureInPictureDragger")
|
||||||
export class PictureInPictureDragger extends React.Component<IProps, IState> {
|
export class PictureInPictureDragger extends React.Component<IProps, IState> {
|
||||||
private callViewWrapper = createRef<HTMLDivElement>();
|
private callViewWrapper = createRef<HTMLDivElement>();
|
||||||
private initX = 0;
|
private initX = 0;
|
||||||
private initY = 0;
|
private initY = 0;
|
||||||
private desiredTranslationX = UIStore.instance.windowWidth - PADDING.right - PIP_VIEW_WIDTH;
|
private desiredTranslationX = UIStore.instance.windowWidth - PADDING.right - PIP_VIEW_WIDTH;
|
||||||
private desiredTranslationY = UIStore.instance.windowHeight - PADDING.bottom - PIP_VIEW_WIDTH;
|
private desiredTranslationY = UIStore.instance.windowHeight - PADDING.bottom - PIP_VIEW_WIDTH;
|
||||||
private moving = false;
|
private moving = false;
|
||||||
private scheduledUpdate = new MarkedExecution(
|
private scheduledUpdate = new MarkedExecution(
|
||||||
() => this.animationCallback(),
|
() => this.animationCallback(),
|
||||||
() => requestAnimationFrame(() => this.scheduledUpdate.trigger()),
|
() => requestAnimationFrame(() => this.scheduledUpdate.trigger()),
|
||||||
);
|
);
|
||||||
|
|
||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
translationX: UIStore.instance.windowWidth - PADDING.right - PIP_VIEW_WIDTH,
|
translationX: UIStore.instance.windowWidth - PADDING.right - PIP_VIEW_WIDTH,
|
||||||
translationY: UIStore.instance.windowHeight - PADDING.bottom - PIP_VIEW_WIDTH,
|
translationY: UIStore.instance.windowHeight - PADDING.bottom - PIP_VIEW_WIDTH,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentDidMount() {
|
public componentDidMount() {
|
||||||
document.addEventListener("mousemove", this.onMoving);
|
document.addEventListener("mousemove", this.onMoving);
|
||||||
document.addEventListener("mouseup", this.onEndMoving);
|
document.addEventListener("mouseup", this.onEndMoving);
|
||||||
window.addEventListener("resize", this.snap);
|
window.addEventListener("resize", this.snap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentWillUnmount() {
|
public componentWillUnmount() {
|
||||||
document.removeEventListener("mousemove", this.onMoving);
|
document.removeEventListener("mousemove", this.onMoving);
|
||||||
document.removeEventListener("mouseup", this.onEndMoving);
|
document.removeEventListener("mouseup", this.onEndMoving);
|
||||||
window.removeEventListener("resize", this.snap);
|
window.removeEventListener("resize", this.snap);
|
||||||
}
|
}
|
||||||
|
|
||||||
private animationCallback = () => {
|
private animationCallback = () => {
|
||||||
// If the PiP isn't being dragged and there is only a tiny difference in
|
// If the PiP isn't being dragged and there is only a tiny difference in
|
||||||
// the desiredTranslation and translation, quit the animationCallback
|
// the desiredTranslation and translation, quit the animationCallback
|
||||||
// loop. If that is the case, it means the PiP has snapped into its
|
// loop. If that is the case, it means the PiP has snapped into its
|
||||||
// position and there is nothing to do. Not doing this would cause an
|
// position and there is nothing to do. Not doing this would cause an
|
||||||
// infinite loop
|
// infinite loop
|
||||||
if (
|
if (
|
||||||
!this.moving &&
|
!this.moving &&
|
||||||
Math.abs(this.state.translationX - this.desiredTranslationX) <= 1 &&
|
Math.abs(this.state.translationX - this.desiredTranslationX) <= 1 &&
|
||||||
Math.abs(this.state.translationY - this.desiredTranslationY) <= 1
|
Math.abs(this.state.translationY - this.desiredTranslationY) <= 1
|
||||||
) return;
|
) return;
|
||||||
|
|
||||||
const amt = this.moving ? MOVING_AMT : SNAPPING_AMT;
|
const amt = this.moving ? MOVING_AMT : SNAPPING_AMT;
|
||||||
this.setState({
|
this.setState({
|
||||||
translationX: lerp(this.state.translationX, this.desiredTranslationX, amt),
|
translationX: lerp(this.state.translationX, this.desiredTranslationX, amt),
|
||||||
translationY: lerp(this.state.translationY, this.desiredTranslationY, amt),
|
translationY: lerp(this.state.translationY, this.desiredTranslationY, amt),
|
||||||
});
|
});
|
||||||
this.scheduledUpdate.mark();
|
this.scheduledUpdate.mark();
|
||||||
};
|
};
|
||||||
|
|
||||||
private setTranslation(inTranslationX: number, inTranslationY: number) {
|
private setTranslation(inTranslationX: number, inTranslationY: number) {
|
||||||
const width = this.callViewWrapper.current?.clientWidth || PIP_VIEW_WIDTH;
|
const width = this.callViewWrapper.current?.clientWidth || PIP_VIEW_WIDTH;
|
||||||
const height = this.callViewWrapper.current?.clientHeight || PIP_VIEW_HEIGHT;
|
const height = this.callViewWrapper.current?.clientHeight || PIP_VIEW_HEIGHT;
|
||||||
|
|
||||||
// Avoid overflow on the x axis
|
// Avoid overflow on the x axis
|
||||||
if (inTranslationX + width >= UIStore.instance.windowWidth) {
|
if (inTranslationX + width >= UIStore.instance.windowWidth) {
|
||||||
this.desiredTranslationX = UIStore.instance.windowWidth - width;
|
this.desiredTranslationX = UIStore.instance.windowWidth - width;
|
||||||
} else if (inTranslationX <= 0) {
|
} else if (inTranslationX <= 0) {
|
||||||
this.desiredTranslationX = 0;
|
this.desiredTranslationX = 0;
|
||||||
} else {
|
} else {
|
||||||
this.desiredTranslationX = inTranslationX;
|
this.desiredTranslationX = inTranslationX;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid overflow on the y axis
|
// Avoid overflow on the y axis
|
||||||
if (inTranslationY + height >= UIStore.instance.windowHeight) {
|
if (inTranslationY + height >= UIStore.instance.windowHeight) {
|
||||||
this.desiredTranslationY = UIStore.instance.windowHeight - height;
|
this.desiredTranslationY = UIStore.instance.windowHeight - height;
|
||||||
} else if (inTranslationY <= 0) {
|
} else if (inTranslationY <= 0) {
|
||||||
this.desiredTranslationY = 0;
|
this.desiredTranslationY = 0;
|
||||||
} else {
|
} else {
|
||||||
this.desiredTranslationY = inTranslationY;
|
this.desiredTranslationY = inTranslationY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private snap = () => {
|
private snap = () => {
|
||||||
const translationX = this.desiredTranslationX;
|
const translationX = this.desiredTranslationX;
|
||||||
const translationY = this.desiredTranslationY;
|
const translationY = this.desiredTranslationY;
|
||||||
// We subtract the PiP size from the window size in order to calculate
|
// We subtract the PiP size from the window size in order to calculate
|
||||||
// the position to snap to from the PiP center and not its top-left
|
// the position to snap to from the PiP center and not its top-left
|
||||||
// corner
|
// corner
|
||||||
const windowWidth = (
|
const windowWidth = (
|
||||||
UIStore.instance.windowWidth -
|
UIStore.instance.windowWidth -
|
||||||
(this.callViewWrapper.current?.clientWidth || PIP_VIEW_WIDTH)
|
(this.callViewWrapper.current?.clientWidth || PIP_VIEW_WIDTH)
|
||||||
);
|
);
|
||||||
const windowHeight = (
|
const windowHeight = (
|
||||||
UIStore.instance.windowHeight -
|
UIStore.instance.windowHeight -
|
||||||
(this.callViewWrapper.current?.clientHeight || PIP_VIEW_HEIGHT)
|
(this.callViewWrapper.current?.clientHeight || PIP_VIEW_HEIGHT)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (translationX >= windowWidth / 2 && translationY >= windowHeight / 2) {
|
if (translationX >= windowWidth / 2 && translationY >= windowHeight / 2) {
|
||||||
this.desiredTranslationX = windowWidth - PADDING.right;
|
this.desiredTranslationX = windowWidth - PADDING.right;
|
||||||
this.desiredTranslationY = windowHeight - PADDING.bottom;
|
this.desiredTranslationY = windowHeight - PADDING.bottom;
|
||||||
} else if (translationX >= windowWidth / 2 && translationY <= windowHeight / 2) {
|
} else if (translationX >= windowWidth / 2 && translationY <= windowHeight / 2) {
|
||||||
this.desiredTranslationX = windowWidth - PADDING.right;
|
this.desiredTranslationX = windowWidth - PADDING.right;
|
||||||
this.desiredTranslationY = PADDING.top;
|
this.desiredTranslationY = PADDING.top;
|
||||||
} else if (translationX <= windowWidth / 2 && translationY >= windowHeight / 2) {
|
} else if (translationX <= windowWidth / 2 && translationY >= windowHeight / 2) {
|
||||||
this.desiredTranslationX = PADDING.left;
|
this.desiredTranslationX = PADDING.left;
|
||||||
this.desiredTranslationY = windowHeight - PADDING.bottom;
|
this.desiredTranslationY = windowHeight - PADDING.bottom;
|
||||||
} else {
|
} else {
|
||||||
this.desiredTranslationX = PADDING.left;
|
this.desiredTranslationX = PADDING.left;
|
||||||
this.desiredTranslationY = PADDING.top;
|
this.desiredTranslationY = PADDING.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We start animating here because we want the PiP to move when we're
|
// We start animating here because we want the PiP to move when we're
|
||||||
// resizing the window
|
// resizing the window
|
||||||
this.scheduledUpdate.mark();
|
this.scheduledUpdate.mark();
|
||||||
};
|
};
|
||||||
|
|
||||||
private onStartMoving = (event: React.MouseEvent | MouseEvent) => {
|
private onStartMoving = (event: React.MouseEvent | MouseEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
this.moving = true;
|
this.moving = true;
|
||||||
this.initX = event.pageX - this.desiredTranslationX;
|
this.initX = event.pageX - this.desiredTranslationX;
|
||||||
this.initY = event.pageY - this.desiredTranslationY;
|
this.initY = event.pageY - this.desiredTranslationY;
|
||||||
this.scheduledUpdate.mark();
|
this.scheduledUpdate.mark();
|
||||||
};
|
};
|
||||||
|
|
||||||
private onMoving = (event: React.MouseEvent | MouseEvent) => {
|
private onMoving = (event: React.MouseEvent | MouseEvent) => {
|
||||||
if (!this.moving) return;
|
if (!this.moving) return;
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
this.setTranslation(event.pageX - this.initX, event.pageY - this.initY);
|
this.setTranslation(event.pageX - this.initX, event.pageY - this.initY);
|
||||||
};
|
};
|
||||||
|
|
||||||
private onEndMoving = () => {
|
private onEndMoving = () => {
|
||||||
this.moving = false;
|
this.moving = false;
|
||||||
this.snap();
|
this.snap();
|
||||||
};
|
};
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const translatePixelsX = this.state.translationX + "px";
|
const translatePixelsX = this.state.translationX + "px";
|
||||||
const translatePixelsY = this.state.translationY + "px";
|
const translatePixelsY = this.state.translationY + "px";
|
||||||
const style = {
|
const style = {
|
||||||
transform: `translateX(${translatePixelsX})
|
transform: `translateX(${translatePixelsX})
|
||||||
translateY(${translatePixelsY})`,
|
translateY(${translatePixelsY})`,
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={this.props.className}
|
className={this.props.className}
|
||||||
style={this.props.draggable ? style : undefined}
|
style={this.props.draggable ? style : undefined}
|
||||||
ref={this.callViewWrapper}
|
ref={this.callViewWrapper}
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
{ this.props.children(this.onStartMoving) }
|
{ this.props.children(this.onStartMoving) }
|
||||||
</>
|
</>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue