Calls fixes
This commit is contained in:
parent
a479add37e
commit
17713f26b2
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ export class GroupCallParticipantContextMenu {
|
|||||||
let appendTo: HTMLElement = document.body;
|
let appendTo: HTMLElement = document.body;
|
||||||
addFullScreenListener(document.body, () => {
|
addFullScreenListener(document.body, () => {
|
||||||
const isFull = isFullScreen();
|
const isFull = isFullScreen();
|
||||||
appendTo = isFull ? (PopupElement.getPopup(PopupGroupCall) as PopupGroupCall).getContainer(): document.body;
|
appendTo = isFull ? (PopupElement.getPopups(PopupGroupCall) as PopupGroupCall[])[0].getContainer(): document.body;
|
||||||
|
|
||||||
if(!isFull) {
|
if(!isFull) {
|
||||||
closeBtnMenu();
|
closeBtnMenu();
|
||||||
@ -150,7 +150,7 @@ export class GroupCallParticipantContextMenu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onOpenProfileClick = () => {
|
private onOpenProfileClick = () => {
|
||||||
const popup = PopupElement.getPopup(PopupGroupCall);
|
const popup = PopupElement.getPopups(PopupGroupCall)[0];
|
||||||
if(popup) {
|
if(popup) {
|
||||||
popup.hide();
|
popup.hide();
|
||||||
}
|
}
|
||||||
|
@ -255,8 +255,8 @@ export default class PopupElement<T extends EventListenerListeners = {}> extends
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getPopup(popupConstructor: PopupElementConstructable) {
|
public static getPopups(popupConstructor: PopupElementConstructable) {
|
||||||
return this.POPUPS.find(element => element instanceof popupConstructor);
|
return this.POPUPS.filter(element => element instanceof popupConstructor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,12 @@ export default class StackedAvatars {
|
|||||||
|
|
||||||
public render(peerIds: PeerId[], loadPromises?: Promise<any>[]) {
|
public render(peerIds: PeerId[], loadPromises?: Promise<any>[]) {
|
||||||
const children = this.container.children;
|
const children = this.container.children;
|
||||||
peerIds.slice().reverse().forEach((peerId, idx) => {
|
peerIds = peerIds.slice().reverse();
|
||||||
|
if(peerIds.length > 3) {
|
||||||
|
peerIds = peerIds.slice(-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
peerIds.forEach((peerId, idx) => {
|
||||||
let avatarContainer = children[idx] as HTMLElement;
|
let avatarContainer = children[idx] as HTMLElement;
|
||||||
if(!avatarContainer) {
|
if(!avatarContainer) {
|
||||||
avatarContainer = document.createElement('div');
|
avatarContainer = document.createElement('div');
|
||||||
|
@ -258,7 +258,7 @@ export default class TopbarCall {
|
|||||||
|
|
||||||
attachClickEvent(container, () => {
|
attachClickEvent(container, () => {
|
||||||
if(this.instance instanceof GroupCallInstance) {
|
if(this.instance instanceof GroupCallInstance) {
|
||||||
if(PopupElement.getPopup(PopupGroupCall)) {
|
if(PopupElement.getPopups(PopupGroupCall).length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,8 +268,8 @@ export default class TopbarCall {
|
|||||||
appChatsManager: this.appChatsManager
|
appChatsManager: this.appChatsManager
|
||||||
}).show();
|
}).show();
|
||||||
} else if(this.instance instanceof CallInstance) {
|
} else if(this.instance instanceof CallInstance) {
|
||||||
const hasPopup = PopupElement.getPopup(PopupCall) as PopupCall;
|
const popups = PopupElement.getPopups(PopupCall) as PopupCall[];
|
||||||
if(hasPopup && hasPopup.getCallInstance() === this.instance) {
|
if(popups.find(popup => popup.getCallInstance() === this.instance)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,6 +244,10 @@
|
|||||||
// html.emoji-supported & {
|
// html.emoji-supported & {
|
||||||
.call-emojis {
|
.call-emojis {
|
||||||
transform: scale(1.125);
|
transform: scale(1.125);
|
||||||
|
|
||||||
|
.emoji {
|
||||||
|
margin: 0 .125rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -262,6 +266,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-party-state {
|
&-party-state {
|
||||||
|
Loading…
Reference in New Issue
Block a user