|
|
@ -10,6 +10,7 @@ import { attachClickEvent } from "../../helpers/dom/clickEvent"; |
|
|
|
import ControlsHover from "../../helpers/dom/controlsHover"; |
|
|
|
import ControlsHover from "../../helpers/dom/controlsHover"; |
|
|
|
import findUpClassName from "../../helpers/dom/findUpClassName"; |
|
|
|
import findUpClassName from "../../helpers/dom/findUpClassName"; |
|
|
|
import { addFullScreenListener, cancelFullScreen, isFullScreen, requestFullScreen } from "../../helpers/dom/fullScreen"; |
|
|
|
import { addFullScreenListener, cancelFullScreen, isFullScreen, requestFullScreen } from "../../helpers/dom/fullScreen"; |
|
|
|
|
|
|
|
import { onMediaLoad } from "../../helpers/files"; |
|
|
|
import { MediaSize } from "../../helpers/mediaSizes"; |
|
|
|
import { MediaSize } from "../../helpers/mediaSizes"; |
|
|
|
import MovablePanel from "../../helpers/movablePanel"; |
|
|
|
import MovablePanel from "../../helpers/movablePanel"; |
|
|
|
import safeAssign from "../../helpers/object/safeAssign"; |
|
|
|
import safeAssign from "../../helpers/object/safeAssign"; |
|
|
@ -36,11 +37,16 @@ import callVideoCanvasBlur from "./videoCanvasBlur"; |
|
|
|
|
|
|
|
|
|
|
|
const className = 'call'; |
|
|
|
const className = 'call'; |
|
|
|
|
|
|
|
|
|
|
|
let previousState: MovableState = { |
|
|
|
const MIN_WIDTH = 400; |
|
|
|
width: 400, |
|
|
|
const MIN_HEIGHT = 580; |
|
|
|
height: 580 |
|
|
|
|
|
|
|
|
|
|
|
const INIT_STATE: MovableState = { |
|
|
|
|
|
|
|
width: MIN_WIDTH, |
|
|
|
|
|
|
|
height: MIN_HEIGHT |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let previousState: MovableState = {...INIT_STATE}; |
|
|
|
|
|
|
|
|
|
|
|
export default class PopupCall extends PopupElement { |
|
|
|
export default class PopupCall extends PopupElement { |
|
|
|
private instance: CallInstance; |
|
|
|
private instance: CallInstance; |
|
|
|
private appCallsManager: AppCallsManager; |
|
|
|
private appCallsManager: AppCallsManager; |
|
|
@ -169,8 +175,8 @@ export default class PopupCall extends PopupElement { |
|
|
|
this.movablePanel = new MovablePanel({ |
|
|
|
this.movablePanel = new MovablePanel({ |
|
|
|
listenerSetter, |
|
|
|
listenerSetter, |
|
|
|
movableOptions: { |
|
|
|
movableOptions: { |
|
|
|
minWidth: 400, |
|
|
|
minWidth: MIN_WIDTH, |
|
|
|
minHeight: 580, |
|
|
|
minHeight: MIN_HEIGHT, |
|
|
|
element: this.element, |
|
|
|
element: this.element, |
|
|
|
verifyTouchTarget: (e) => { |
|
|
|
verifyTouchTarget: (e) => { |
|
|
|
const target = e.target; |
|
|
|
const target = e.target; |
|
|
@ -184,7 +190,11 @@ export default class PopupCall extends PopupElement { |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
// onResize: () => this.toggleBigLayout(),
|
|
|
|
// onResize: () => this.toggleBigLayout(),
|
|
|
|
previousState |
|
|
|
previousState: !this.instance.wasTryingToJoin && !this.instance.isOutgoing ? {...INIT_STATE} : previousState |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.listenerSetter.add(this.movablePanel.movable)('resize', () => { |
|
|
|
|
|
|
|
this.resizeVideoContainers(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
const controlsHover = this.controlsHover = new ControlsHover(); |
|
|
|
const controlsHover = this.controlsHover = new ControlsHover(); |
|
|
@ -308,6 +318,8 @@ export default class PopupCall extends PopupElement { |
|
|
|
animationIntersector.checkAnimations(isFull); |
|
|
|
animationIntersector.checkAnimations(isFull); |
|
|
|
|
|
|
|
|
|
|
|
rootScope.setThemeColor(isFull ? '#000000' : undefined); |
|
|
|
rootScope.setThemeColor(isFull ? '#000000' : undefined); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.resizeVideoContainers(); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
@ -331,6 +343,8 @@ export default class PopupCall extends PopupElement { |
|
|
|
big.style.cssText = container.style.cssText; |
|
|
|
big.style.cssText = container.style.cssText; |
|
|
|
container.classList.remove('small'); |
|
|
|
container.classList.remove('small'); |
|
|
|
container.style.cssText = ''; |
|
|
|
container.style.cssText = ''; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.resizeVideoContainers(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
const canvas = callVideoCanvasBlur(video); |
|
|
|
const canvas = callVideoCanvasBlur(video); |
|
|
@ -389,10 +403,24 @@ export default class PopupCall extends PopupElement { |
|
|
|
SetTransition(this.partyMutedState, 'is-visible', !!outputState?.muted, 300); |
|
|
|
SetTransition(this.partyMutedState, 'is-visible', !!outputState?.muted, 300); |
|
|
|
|
|
|
|
|
|
|
|
const containers = this.videoContainers; |
|
|
|
const containers = this.videoContainers; |
|
|
|
|
|
|
|
const oldContainers = {...containers}; |
|
|
|
['input' as const, 'output' as const].forEach(type => { |
|
|
|
['input' as const, 'output' as const].forEach(type => { |
|
|
|
const mediaState = instance.getMediaState(type); |
|
|
|
const mediaState = instance.getMediaState(type); |
|
|
|
const video = instance.getVideoElement(type) as HTMLVideoElement; |
|
|
|
const video = instance.getVideoElement(type) as HTMLVideoElement; |
|
|
|
const isActive = !!video && !!(mediaState && (mediaState.videoState === 'active' || mediaState.screencastState === 'active')); |
|
|
|
|
|
|
|
|
|
|
|
const hasFrame = !!(video && video.videoWidth && video.videoHeight); |
|
|
|
|
|
|
|
if(video && !hasFrame && !video.dataset.hasPromise) { |
|
|
|
|
|
|
|
video.dataset.hasPromise = '1'; |
|
|
|
|
|
|
|
// container.classList.add('hide');
|
|
|
|
|
|
|
|
onMediaLoad(video).then(() => { |
|
|
|
|
|
|
|
delete video.dataset.hasPromise; |
|
|
|
|
|
|
|
this.updateInstance(); |
|
|
|
|
|
|
|
// this.resizeVideoContainers();
|
|
|
|
|
|
|
|
// container.classList.remove('hide');
|
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const isActive = !!video && hasFrame && !!(mediaState && (mediaState.videoState === 'active' || mediaState.screencastState === 'active')); |
|
|
|
let videoContainer = containers[type]; |
|
|
|
let videoContainer = containers[type]; |
|
|
|
|
|
|
|
|
|
|
|
if(isActive && video && !videoContainer) { |
|
|
|
if(isActive && video && !videoContainer) { |
|
|
@ -406,25 +434,20 @@ export default class PopupCall extends PopupElement { |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
const inputVideoContainer = containers.input; |
|
|
|
{ |
|
|
|
if(inputVideoContainer) { |
|
|
|
const input = containers.input; |
|
|
|
const isSmall = !!containers.output; |
|
|
|
const output = containers.output; |
|
|
|
inputVideoContainer.classList.toggle('small', isSmall); |
|
|
|
if(Object.keys(oldContainers).length !== Object.keys(containers).length && input) { |
|
|
|
|
|
|
|
input.classList.toggle('small', !!output); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const video = instance.getVideoElement('input') as HTMLVideoElement; |
|
|
|
if(output && !input) { |
|
|
|
if(isSmall) { |
|
|
|
output.classList.remove('small'); |
|
|
|
const mediaSize = new MediaSize(120, 80); |
|
|
|
|
|
|
|
const aspected = mediaSize.aspectFitted(new MediaSize(video.videoWidth, video.videoHeight)); |
|
|
|
|
|
|
|
// inputVideoContainer.style.width = aspected.width + 'px';
|
|
|
|
|
|
|
|
// inputVideoContainer.style.height = aspected.height + 'px';
|
|
|
|
|
|
|
|
// const ratio = 120 / 80;
|
|
|
|
|
|
|
|
inputVideoContainer.style.width = '120px'; |
|
|
|
|
|
|
|
inputVideoContainer.style.height = '80px'; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
inputVideoContainer.style.cssText = ''; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.resizeVideoContainers(); |
|
|
|
|
|
|
|
|
|
|
|
this.container.classList.toggle('no-video', !Object.keys(containers).length); |
|
|
|
this.container.classList.toggle('no-video', !Object.keys(containers).length); |
|
|
|
|
|
|
|
|
|
|
|
if(!this.emojisSubtitle.textContent && connectionState < CALL_STATE.EXCHANGING_KEYS) { |
|
|
|
if(!this.emojisSubtitle.textContent && connectionState < CALL_STATE.EXCHANGING_KEYS) { |
|
|
@ -436,6 +459,31 @@ export default class PopupCall extends PopupElement { |
|
|
|
this.setDescription(); |
|
|
|
this.setDescription(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private resizeVideoContainers() { |
|
|
|
|
|
|
|
Object.values(this.videoContainers).forEach(container => { |
|
|
|
|
|
|
|
const isSmall = container.classList.contains('small'); |
|
|
|
|
|
|
|
if(isSmall) { |
|
|
|
|
|
|
|
const video = container.querySelector('video'); |
|
|
|
|
|
|
|
const popupWidth = this.movablePanel.state; |
|
|
|
|
|
|
|
const MAX_WIDTH_PX = 240; |
|
|
|
|
|
|
|
const MAX_HEIGHT_PX = 240; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const isVertical = video.videoHeight > video.videoWidth; |
|
|
|
|
|
|
|
const MAX_SIZE = isVertical ? MAX_HEIGHT_PX : MAX_WIDTH_PX; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const biggestSideSize = 1 / 3 * (isFullScreen() ? 0xFFFF : (isVertical ? popupWidth.height : popupWidth.width)); |
|
|
|
|
|
|
|
const widthRatio = isVertical ? video.videoWidth / video.videoHeight : 1; |
|
|
|
|
|
|
|
const heightRatio = isVertical ? 1 : video.videoHeight / video.videoWidth; |
|
|
|
|
|
|
|
container.style.width = biggestSideSize * widthRatio + 'px'; |
|
|
|
|
|
|
|
container.style.height = biggestSideSize * heightRatio + 'px'; |
|
|
|
|
|
|
|
container.style.maxWidth = MAX_SIZE * widthRatio + 'px'; |
|
|
|
|
|
|
|
container.style.maxHeight = MAX_SIZE * heightRatio + 'px'; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
container.style.cssText = ''; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private setDescription() { |
|
|
|
private setDescription() { |
|
|
|
this.description.update(this.instance); |
|
|
|
this.description.update(this.instance); |
|
|
|
} |
|
|
|
} |
|
|
|