Commit b0526d9d authored by Muhammadali's avatar Muhammadali

update-

parent 1db3176d
{
"name": "boxdialer",
"version": "4.8.68",
"version": "4.8.69",
"description": "",
"main": "src/boxDialer.js",
"scripts": {
......
/** @format */
import React, {useCallback, useEffect, useState} from 'react';
import ModalPhoneNumpadStyle, {NumberButton, Input} from './style';
import React, { useCallback, useEffect, useState } from 'react';
import ModalPhoneNumpadStyle, { NumberButton, Input } from './style';
import numbers from '../../lib/numbers';
import CallIcon from '@mui/icons-material/Call';
import {toast} from 'react-hot-toast';
import { toast } from 'react-hot-toast';
import DropDown from '../DropDown';
import {CommentsDisabledOutlined} from '@mui/icons-material';
import { CommentsDisabledOutlined } from '@mui/icons-material';
import CallHistoryInputDropdown from '../CallHistoryInputDropdown';
import KeyboardControlKeyIcon from '@mui/icons-material/KeyboardControlKey';
import {Text, useTranslator} from '@eo-locale/react';
import { Text, useTranslator } from '@eo-locale/react';
import SettingsIcon from '@mui/icons-material/Settings';
import {useColorConfig} from "../../storage/globalColorConfig"
import { useColorConfig } from '../../storage/globalColorConfig';
const ModalPhoneNumpad = ({
phoneModal,
modalState,
reasons,
reason,
onSetDnd,
dynamicValue,
position,
variant,
extnums,
setSettingHidden,
settingHidden
}) => {
const boxDialer = window.BoxDialer;
phoneModal,
modalState,
reasons,
reason,
onSetDnd,
dynamicValue,
position,
variant,
extnums,
setSettingHidden,
settingHidden,
}) => {
const boxDialer = window.BoxDialer;
const useColorConfigStore = useColorConfig((store) => store)
const [inputValue, setInputValue] = useState('');
const [call_history, setCall_history] = useState([]);
const [numberSelectHistory, setNumberSelectHistory] = useState(0);
const [exNum, setExNum] = useState();
const translator = useTranslator();
const useColorConfigStore = useColorConfig((store) => store);
const [inputValue, setInputValue] = useState('');
const [call_history, setCall_history] = useState([]);
const [numberSelectHistory, setNumberSelectHistory] = useState(0);
const [exNum, setExNum] = useState();
const translator = useTranslator();
useEffect(() => {
let currentCalls = localStorage.getItem('callhistory') ? JSON.parse(localStorage.getItem('callhistory')) : false;
if (currentCalls) {
setCall_history(currentCalls);
}
}, [localStorage.getItem('callhistory'), inputValue]);
useEffect(() => {
let currentCalls = localStorage.getItem('callhistory')
? JSON.parse(localStorage.getItem('callhistory'))
: false;
if (currentCalls) {
setCall_history(currentCalls);
}
}, [localStorage.getItem('callhistory'), inputValue]);
useEffect(() => {
if (!modalState.bool) setInputValue('');
}, [modalState.bool]);
useEffect(() => {
if (!modalState.bool) setInputValue('');
}, [modalState.bool]);
useEffect(() => {
if (!phoneModal) setSettingHidden(false)
}, [phoneModal])
useEffect(() => {
if (!phoneModal) setSettingHidden(false);
}, [phoneModal]);
const inputController = ({value, type, from}) => {
boxDialer.onSoundType({type: 'pick', bool: true});
switch (type) {
case 'add':
if (value.match(/^[a-zA-Z0-9!@#\$%\^\&*\)\(+=._-]+$/g).join('').length) {
if (from === 'input') return setInputValue(value);
if (from === 'button') setInputValue(inputValue + value);
}
const inputController = ({ value, type, from }) => {
boxDialer.onSoundType({ type: 'pick', bool: true });
switch (type) {
case 'add':
if (
value.match(/^[a-zA-Z0-9!@#\$%\^\&*\)\(+=._-]+$/g).join('').length
) {
if (from === 'input') return setInputValue(value);
if (from === 'button') setInputValue(inputValue + value);
}
break;
case 'delete':
if (from === 'button') {
setInputValue(inputValue
.split('')
.slice(0, inputValue.length - 1)
.join(''),);
}
if (from === 'input') {
setInputValue(value);
}
break;
default:
break;
}
};
break;
case 'delete':
if (from === 'button') {
setInputValue(
inputValue
.split('')
.slice(0, inputValue.length - 1)
.join(''),
);
}
if (from === 'input') {
setInputValue(value);
}
break;
default:
break;
}
};
const history = ({type}) => {
if (phoneModal && (modalState.bool ? false : true)) {
if ((type === 'up' && numberSelectHistory < call_history.length) || numberSelectHistory === 'zero') {
setNumberSelectHistory(numberSelectHistory !== 'zero' ? numberSelectHistory + 1 : 0 + 1,);
}
if (type === 'down' && numberSelectHistory > 0) {
setNumberSelectHistory(numberSelectHistory !== 'zero' ? numberSelectHistory - 1 : 0 - 1,);
}
}
};
const history = ({ type }) => {
if (phoneModal && (modalState.bool ? false : true)) {
if (
(type === 'up' && numberSelectHistory < call_history.length) ||
numberSelectHistory === 'zero'
) {
setNumberSelectHistory(
numberSelectHistory !== 'zero' ? numberSelectHistory + 1 : 0 + 1,
);
}
if (type === 'down' && numberSelectHistory > 0) {
setNumberSelectHistory(
numberSelectHistory !== 'zero' ? numberSelectHistory - 1 : 0 - 1,
);
}
}
};
useEffect(() => {
if (phoneModal && (modalState.bool ? false : true)) {
let selectedNumber;
if (numberSelectHistory == 0) {
setInputValue('');
}
selectedNumber = call_history.slice(numberSelectHistory * -1)[0] ? call_history.slice(numberSelectHistory * -1)[0] : false;
useEffect(() => {
if (phoneModal && (modalState.bool ? false : true)) {
let selectedNumber;
if (numberSelectHistory == 0) {
setInputValue('');
}
selectedNumber = call_history.slice(numberSelectHistory * -1)[0]
? call_history.slice(numberSelectHistory * -1)[0]
: false;
if (numberSelectHistory === 0) {
selectedNumber = '';
setNumberSelectHistory('zero');
}
if (numberSelectHistory === 'zero') {
selectedNumber = '';
setNumberSelectHistory('zero');
}
if (selectedNumber) {
setInputValue(selectedNumber.value);
}
}
}, [numberSelectHistory]);
if (numberSelectHistory === 0) {
selectedNumber = '';
setNumberSelectHistory('zero');
}
if (numberSelectHistory === 'zero') {
selectedNumber = '';
setNumberSelectHistory('zero');
}
if (selectedNumber) {
setInputValue(selectedNumber.value);
}
}
}, [numberSelectHistory]);
document.onkeydown = function (e) {
if (phoneModal && modalState.bool ? false : true) {
e = e || window.event;
let actualKeyCode = e.keyCode;
if (e.ctrlKey && actualKeyCode === 86) {
navigator.clipboard
.readText()
.then((text) => {
inputController({type: 'add', value: text, from: 'button'});
})
.catch((err) => {
console.log('Something went wrong', err);
});
}
return true;
}
};
const gameState = {
toggleCP: (e) => {
if (phoneModal && (modalState.bool ? false : true) && e.key === 'Enter') {
callButton();
} else if (phoneModal && (modalState.bool ? false : true) && e.key === 'Backspace') {
inputController({type: 'delete', from: 'button', value: e.value});
} else if (phoneModal && (modalState.bool ? false : true) && !isNaN(+e.key)) {
inputController({type: 'add', value: e.key, from: 'button'});
} else if (phoneModal && (modalState.bool ? false : true) && e.key === 'Backspace') {
} else if ((phoneModal && (modalState.bool ? false : true) && e.keyCode == 38) || e.keyCode == 40) history({type: e.keyCode === 38 ? 'up' : 'down'});
},
};
document.onkeydown = function (e) {
if (phoneModal && modalState.bool ? false : true) {
e = e || window.event;
let actualKeyCode = e.keyCode;
if (e.ctrlKey && actualKeyCode === 86) {
navigator.clipboard
.readText()
.then((text) => {
inputController({ type: 'add', value: text, from: 'button' });
})
.catch((err) => {
console.log('Something went wrong', err);
});
}
return true;
}
};
const gameState = {
toggleCP: (e) => {
if (phoneModal && (modalState.bool ? false : true) && e.key === 'Enter') {
callButton();
} else if (
phoneModal &&
(modalState.bool ? false : true) &&
e.key === 'Backspace'
) {
inputController({ type: 'delete', from: 'button', value: e.value });
} else if (
phoneModal &&
(modalState.bool ? false : true) &&
!isNaN(+e.key)
) {
inputController({ type: 'add', value: e.key, from: 'button' });
} else if (
phoneModal &&
(modalState.bool ? false : true) &&
e.key === 'Backspace'
) {
} else if (
(phoneModal && (modalState.bool ? false : true) && e.keyCode == 38) ||
e.keyCode == 40
)
history({ type: e.keyCode === 38 ? 'up' : 'down' });
},
};
const handleKeyUp = useCallback((event) => {
gameState.toggleCP(event);
}, [gameState.toggleCP],);
const handleKeyUp = useCallback(
(event) => {
gameState.toggleCP(event);
},
[gameState.toggleCP],
);
useEffect(() => {
document.addEventListener('keyup', handleKeyUp);
useEffect(() => {
document.addEventListener('keyup', handleKeyUp);
return () => {
document.removeEventListener('keyup', handleKeyUp);
};
}, [handleKeyUp]);
// `${Data.getHours()}:${Data.getMinutes()} ${Data.getDate()}.${Data.getMonth()+1}.${Data.getFullYear()}`
const callButton = () => {
// inset if ----------
return () => {
document.removeEventListener('keyup', handleKeyUp);
};
}, [handleKeyUp]);
// `${Data.getHours()}:${Data.getMinutes()} ${Data.getDate()}.${Data.getMonth()+1}.${Data.getFullYear()}`
const callButton = () => {
// inset if ----------
// -------------------
var currentTime = new Date();
if (dynamicValue === 'connected') {
if (Boolean(inputValue.toString().length) && call_history.slice(-1)[0]?.value != inputValue) {
let newCallsStringify = JSON.stringify([...call_history, {
value: inputValue,
time: `${currentTime.getHours()}:${currentTime.getMinutes()} ${currentTime.getDate()}.${currentTime.getMonth()}.${currentTime.getFullYear()}`,
},]);
localStorage.setItem('callhistory', newCallsStringify);
}
boxDialer.initialized(inputValue);
setInputValue('');
} else {
toast.error('Please wait', {
style: {
zIndex: '99999999999999999',
},
});
}
};
const selectFunc = (e) => {
setInputValue(e);
};
const setDefaultHistoryNumberHistory = () => {
setNumberSelectHistory('zero');
};
// -------------------
var currentTime = new Date();
if (dynamicValue === 'connected') {
if (
Boolean(inputValue.toString().length) &&
call_history.slice(-1)[0]?.value != inputValue
) {
let newCallsStringify = JSON.stringify([
...call_history,
{
value: inputValue,
time: `${currentTime.getHours()}:${currentTime.getMinutes()} ${currentTime.getDate()}.${currentTime.getMonth()}.${currentTime.getFullYear()}`,
},
]);
localStorage.setItem('callhistory', newCallsStringify);
}
boxDialer.initialized(inputValue);
setInputValue('');
} else {
toast.error('Please wait', {
style: {
zIndex: '99999999999999999',
},
});
}
};
const selectFunc = (e) => {
setInputValue(e);
};
const setDefaultHistoryNumberHistory = () => {
setNumberSelectHistory('zero');
};
document.querySelector('body').addEventListener('click', function (e) {
if (exNum) setExNum(false);
});
return (<ModalPhoneNumpadStyle
switchAnim={useColorConfigStore.state?.switchAnim}
position={position}
hiddenValue={!phoneModal}
variant={variant}
onClick={(e) => e.stopPropagation()}>
<SettingsIcon className={'settingIcon'} onClick={() => setSettingHidden(!settingHidden)}/>
<ModalPhoneNumpadStyle.InputArea>
<CallHistoryInputDropdown
call_history={call_history}
inputValue={inputValue}
selectFunc={selectFunc}
numberSelectHistory={numberSelectHistory}
setDefaultHistoryNumberHistory={setDefaultHistoryNumberHistory}
/>
{inputValue?.length ? (<Input.BackSpaceIcon
onClick={() => inputController({type: 'delete', from: 'button'})}
/>) : ('')}
</ModalPhoneNumpadStyle.InputArea>
<ModalPhoneNumpadStyle.ButtonArea>
{numbers?.map((mapItem) => (<NumberButton
switchAnim={useColorConfigStore.state?.switchAnim}
sizeContext={useColorConfigStore.state.sizePixel}
onMouseDown={() => boxDialer.dialTone(mapItem.ringHz[0], mapItem.ringHz[1])}
onMouseUp={() => boxDialer.stop()}
onMouseOut={() => boxDialer.stop()}
className='nocopy'
key={mapItem.id}
onClick={() => {
mapItem.type === 'number' && inputController({
value: mapItem.value, type: 'add', from: 'button',
});
}}>
{mapItem.nameNumber}
<NumberButton.Icon>{mapItem.icon}</NumberButton.Icon>
</NumberButton>))}
{!modalState.bool ? (<>
<NumberButton
style={{gridColumn: '1/4'}}
status={dynamicValue}
type={'call_button'}>
<NumberButton.CallButton exNum={exNum}>
<div className='left' onClick={() => callButton()}>
<CallIcon className='callIcon'/>
<p className='call_text'>{translator.translate('CALL')}</p>
</div>
<div className='right' onClick={() => setExNum(!exNum)}>
{/* <KeyboardControlKeyIcon className='icon' /> */}
<div className='icon'></div>
</div>
</NumberButton.CallButton>
<NumberButton.CallButtonModal switchAnim={useColorConfigStore.state?.switchAnim} visiblevalue={exNum}>
<NumberButton.CallButtonModalInset switchAnim={useColorConfigStore.state?.switchAnim}>
{extnums?.map(({number, title}, index) => (<p
key={index}
className='num_item'
onClick={() => {
boxDialer.extnum = number;
setExNum(false);
callButton();
}}>
{title}
</p>))}
</NumberButton.CallButtonModalInset>
</NumberButton.CallButtonModal>
{/* <ModalPhoneNumpadStyle.Window
document.querySelector('body').addEventListener('click', function (e) {
if (exNum) setExNum(false);
});
return (
<ModalPhoneNumpadStyle
switchAnim={useColorConfigStore.state?.switchAnim}
position={position}
hiddenValue={!phoneModal}
variant={variant}
onClick={(e) => e.stopPropagation()}>
<SettingsIcon
className={'settingIcon'}
onClick={() => setSettingHidden(!settingHidden)}
/>
<ModalPhoneNumpadStyle.InputArea>
<CallHistoryInputDropdown
call_history={call_history}
inputValue={inputValue}
selectFunc={selectFunc}
numberSelectHistory={numberSelectHistory}
setDefaultHistoryNumberHistory={setDefaultHistoryNumberHistory}
/>
{inputValue?.length ? (
<Input.BackSpaceIcon
onClick={() => inputController({ type: 'delete', from: 'button' })}
/>
) : (
''
)}
</ModalPhoneNumpadStyle.InputArea>
<ModalPhoneNumpadStyle.ButtonArea>
{numbers?.map((mapItem) => (
<NumberButton
switchAnim={useColorConfigStore.state?.switchAnim}
sizeContext={useColorConfigStore.state.sizePixel}
onMouseDown={() =>
boxDialer.dialTone(mapItem.ringHz[0], mapItem.ringHz[1])
}
onMouseUp={() => boxDialer.stop()}
onMouseOut={() => boxDialer.stop()}
className='nocopy'
key={mapItem.id}
onClick={() => {
mapItem.type === 'number' &&
inputController({
value: mapItem.value,
type: 'add',
from: 'button',
});
}}>
{mapItem.nameNumber}
<NumberButton.Icon>{mapItem.icon}</NumberButton.Icon>
</NumberButton>
))}
{!modalState.bool ? (
<>
<NumberButton
style={{ gridColumn: '1/4' }}
status={dynamicValue}
type={'call_button'}>
<NumberButton.CallButton exNum={exNum}>
<div className='left' onClick={() => callButton()}>
<CallIcon className='callIcon' />
<p className='call_text'>{translator.translate('CALL')}</p>
</div>
<div className='right' onClick={() => setExNum(!exNum)}>
{/* <KeyboardControlKeyIcon className='icon' /> */}
<div className='icon'></div>
</div>
</NumberButton.CallButton>
<NumberButton.CallButtonModal
switchAnim={useColorConfigStore.state?.switchAnim}
visiblevalue={exNum}>
<NumberButton.CallButtonModalInset
switchAnim={useColorConfigStore.state?.switchAnim}>
{extnums?.map(({ number, title }, index) => (
<p
key={index}
className='num_item'
onClick={() => {
boxDialer.extnum = number;
setExNum(false);
callButton();
}}>
{title}
</p>
))}
</NumberButton.CallButtonModalInset>
</NumberButton.CallButtonModal>
{/* <ModalPhoneNumpadStyle.Window
visiblevalue={exNum}
onClick={() => setExNum(false)}
/> */}
</NumberButton>
</>) : (<>
<div style={{height: '33px'}}></div>
<div style={{height: '33px'}}></div>
</>)}
<DropDown selectFunc={onSetDnd} reasons={reasons} reason={reason}/>
</ModalPhoneNumpadStyle.ButtonArea>
</ModalPhoneNumpadStyle>);
</NumberButton>
</>
) : (
<>
<div style={{ height: '33px' }}></div>
<div style={{ height: '33px' }}></div>
</>
)}
<DropDown selectFunc={onSetDnd} reasons={reasons} reason={reason} />
</ModalPhoneNumpadStyle.ButtonArea>
</ModalPhoneNumpadStyle>
);
};
export default ModalPhoneNumpad;
......@@ -3,7 +3,7 @@
import styled from 'styled-components';
import KeyboardBackspaceIcon from '@mui/icons-material/KeyboardBackspace';
import { boxDialerWidjetPosition } from '../../lib/boxDialerWidjetPosition';
import {sizePixelPixelSizeFunc} from "../../lib/sizeContext"
import { sizePixelPixelSizeFunc } from '../../lib/sizeContext';
const ModalPhoneNumpadStyle = styled.div`
box-shadow: 0 0 20px #00000047;
......@@ -15,8 +15,9 @@ const ModalPhoneNumpadStyle = styled.div`
width: 230px;
position: fixed;
bottom: 120px;
transition: ${({switchAnim})=> typeof switchAnim !== 'undefined' ? switchAnim ? '0.2s' : '0s' : '0.2s' };
${({switchAnim})=> console.log('switchAnim: ', switchAnim)}
transition: ${({ switchAnim }) =>
typeof switchAnim !== 'undefined' ? (switchAnim ? '0.2s' : '0s') : '0.2s'};
${({ switchAnim }) => console.log('switchAnim: ', switchAnim)}
z-index: 9999;
${({ hiddenValue, position, variant }) =>
hiddenValue
......@@ -28,7 +29,7 @@ const ModalPhoneNumpadStyle = styled.div`
grid-template-rows: 40px 1fr;
grid-gap: 15px;
cursor: default;
.settingIcon{
.settingIcon {
position: absolute;
font-size: 11px;
cursor: pointer;
......@@ -103,7 +104,7 @@ const NumberButton = styled.div`
display: flex;
justify-content: center;
align-items: center;
${({sizeContext})=> sizePixelPixelSizeFunc(sizeContext, 22)}
${({ sizeContext }) => sizePixelPixelSizeFunc(sizeContext, 22)}
cursor: pointer;
height: 33px;
position: relative;
......@@ -113,8 +114,9 @@ const NumberButton = styled.div`
? 'orange'
: status === 'connected' && '#a0c13d'
: '#0000007d'};
transition: ${({switchAnim})=> typeof switchAnim !== 'undefined' ? switchAnim ? '0.3s' : '0s' : '0.3s' };
transition: ${({ switchAnim }) =>
typeof switchAnim !== 'undefined' ? (switchAnim ? '0.3s' : '0s') : '0.3s'};
.callIcon {
color: #0000007d;
}
......@@ -169,7 +171,6 @@ NumberButton.CallButton = styled.div`
display: flex;
align-items: center;
.icon {
margin: 0 auto;
border: 4px solid transparent;
width: 8px;
......@@ -210,8 +211,9 @@ NumberButton.CallButtonModal = styled.div`
padding: 3px 3px 15px 3px;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
transition: ${({switchAnim})=> typeof switchAnim !== 'undefined' ? switchAnim ? '0.1s' : '0s' : '0.1s' };
transition: ${({ switchAnim }) =>
typeof switchAnim !== 'undefined' ? (switchAnim ? '0.1s' : '0s') : '0.1s'};
clip-path: polygon(100% 0, 100% 93%, 57% 93%, 50% 100%, 43% 93%, 0 93%, 0 0);
${({ visiblevalue }) =>
visiblevalue
......@@ -236,7 +238,12 @@ NumberButton.CallButtonModalInset = styled.div`
.num_item {
text-wrap: nowrap;
color: #000;
transition: ${({switchAnim})=> typeof switchAnim !== 'undefined' ? switchAnim ? '0.2s' : '0s' : '0.2s' };
transition: ${({ switchAnim }) =>
typeof switchAnim !== 'undefined'
? switchAnim
? '0.2s'
: '0s'
: '0.2s'};
padding: 5px 10px;
font-size: 14px;
margin: 2px 0;
......
/** @format */
import {toast} from 'react-hot-toast';
import { toast } from 'react-hot-toast';
import outcomingringTone from '../sounds/ringtone.wav';
import waitRingTone from '../sounds/ringbacktone.wav';
import pickSound from '../sounds/dtmf.wav';
import {WebSocketInterface, UA} from 'jssip';
import { WebSocketInterface, UA } from 'jssip';
import tugpng from '../img/tug.png';
import packageJson from '../../package.json';
export class BoxDialer {
sTransferNumber;
oRingTone;
oRingbackTone;
oSipStack;
oSipSessionRegister;
oSipSessionCall;
oSipSessionCallSecond;
oSipSessionTransferCall;
videoRemote;
videoLocal;
remoteAudio;
bFullScreen = false;
oNotifICall;
bDisableVideo = false;
viewVideoLocal;
viewVideoRemote;
viewLocalScreencast; // <video> (webrtc) or <div> (webrtc4all)
oConfigCall;
callDirection;
oReadyStateTimer;
ringtone;
ringbacktone;
sipState;
sipBxState;
soundBool;
onSipStateChange = {};
callEvetsBoxDialer;
musicContext;
gainNode;
gainNode;
oscillator1;
oscillator2;
extnum;
timer = {
time: 0,
type: null,
};
innerTimer = {
time: 0,
type: null,
};
options;
socket;
ua;
testTimer;
testInnerTimer;
callSession;
sipDomain;
player;
strmTrack;
isRestarting;
globalHistoryData
constructor() {
this.played = false;
document.body.addEventListener('click', () => {
this.played = true;
});
this.isRestarting = false;
this.videoRemote = document.createElement('video');
this.videoLocal = document.createElement('video');
this.remoteAudio = document.createElement('audio');
this.remoteAudio.autoplay = true;
document.body.appendChild(this.videoRemote);
document.body.appendChild(this.videoLocal);
document.body.appendChild(this.remoteAudio);
this.ringtone = new Audio(outcomingringTone);
this.waitRingTone = new Audio(waitRingTone);
this.pickSound = new Audio(pickSound);
this.ringtone.loop = true;
this.waitRingTone.loop = true;
this.callEvetsBoxDialer = {
callHold: false,
callMute: null,
};
this.options = {
eventHandlers: this.uaEvents(),
mediaConstraints: {audio: true, video: false},
};
}
setGlobalHistoryData(data){
console.log('setGlobalHistoryData: ', data)
this.globalHistoryData = data
}
dialTone(freq1, freq2) {
// merger = context.createChannelMerger(2);
// setTimeout(() => {
// console.log('-= sTOPING BY TIMEOUT');
// this.stop();
// }, 1000);
// if (this.oscillator1 || this.oscillator2) return;
// console.log('Begin dialTone:', this.oscillator1, this.oscillator2);
// this.oscillator1 = this.musicContext.createOscillator();
// // this.oscillator1.type = null;
// this.oscillator1.frequency.value = freq1;
// this.gainNode = this.musicContext.createGain
// ? this.musicContext.createGain()
// : this.musicContext.createGainNode();
// this.oscillator1.connect(this.gainNode, 0, 0);
// this.gainNode.connect(this.musicContext.destination);
// this.gainNode.gain.value = 0.1;
// this.oscillator1.start
// ? this.oscillator1.start(0)
// : this.oscillator1.noteOn(0);
// // this.gainNode.connect(merger,0,1);
// this.oscillator2 = this.musicContext.createOscillator();
// // this.oscillator2.type = null;
// this.oscillator2.frequency.value = freq2;
// this.gainNode = this.musicContext.createGain
// ? this.musicContext.createGain()
// : this.musicContext.createGainNode();
// this.oscillator2.connect(this.gainNode);
// this.gainNode.connect(this.musicContext.destination);
// // this.gainNode.connect(merger,0,0);
// this.gainNode.gain.value = 0.1;
// this.oscillator2.start
// ? this.oscillator2.start(0)
// : this.oscillator2.noteOn(0);
}
start() {
// if (typeof this.oscillator1 != 'undefined') this.oscillator1.disconnect();
// if (typeof this.oscillator2 != 'undefined') this.oscillator2.disconnect();
// oscOn(
// parseFloat(document.getElementById('freq').value),
// parseFloat(document.getElementById('freq2').value),
// );
}
stop() {
// console.log('STOP', this.oscillator1, this.oscillator2);
// console.log('FUNC', this.oscillator1?.disconnect, this.oscillator1?.stop);
// this.oscillator1?.disconnect();
// this.oscillator2?.disconnect();
// this.oscillator1?.stop();
// this.oscillator2?.stop();
// this.oscillator1 = null;
// this.oscillator2 = null;
}
uaEvents() {
return {
progress: (e) => {
console.log('%c progress', 'font-size: 22px; color: green;', e);
// this.hangupButtonClick();
// this.closeBxCall();
// window.innerCallBegin(true);
this.onSipStateChange.innerCallerModal({
bool: true,
type: 'connectingOutgoing',
from: this?.callSession?._remote_identity?._uri?.user,
});
this.setGuiPhoneState({
funcName: 'modalState',
stateCode: 'connectingOutgoing',
funcParam: {
bool: false,
callType: '',
},
});
},
failed: (e) => {
console.log('%c failed', 'font-size: 22px; color: green;', e);
if (e?.cause) {
toast.error(e?.cause);
}
// console.log('call failed with cause: ' + e.data);
this.closeBxCall();
this.onSipStateChange.innerCallerModal({
bool: false,
type: null,
from: '',
});
this.stopInnerTimer();
if (e.cause == 'User Denied Media Access') {
console.log('User_Danied_Media_Access');
toast.error('Your micrafon is OFF', {
style: {
zIndex: '99999999999999999',
},
});
window.navigator.mediaDevices
.getUserMedia({audio: true})
.then(function (stream) {
console.log(
'User_Danied_Media_Access',
'You let me use your mic!',
);
})
.catch(function (err) {
console.log('User_Danied_Media_Access', 'No mic for you!');
});
}
},
ended: (e) => {
console.log('%c ended', 'font-size: 22px; color: green;');
this.closeBxCall();
this.onSipStateChange.innerCallerModal({
bool: false,
type: null,
from: '',
});
this.stopInnerTimer();
this.setGuiPhoneState({
funcName: 'modalState',
funcParam: {
bool: false,
callType: '',
},
});
this.removeViExternalCard();
},
confirmed: (e) => {
console.log('%c confirmed', 'font-size: 22px; color: green;', e);
// console.log(`%c BXLOG:`, datas, 'background-color: red;');
this.onSipStateChange.innerCallerModal({
bool: true,
type: 'connected',
from: this?.callSession?._remote_identity?._uri?.user,
});
this.startInnerTimer();
this.setGuiPhoneState({
funcName: 'modalState',
stateCode: 'connected',
funcParam: {
bool: true,
callType: 'connected',
callFromName: 'Test',
},
});
},
};
}
isUaRunning() {
return (
Boolean(typeof window.BX !== 'undefined') &&
Boolean(window.localStorage.getItem(BX.bitrix_sessid() + '_mycall')) &&
Boolean(window.localStorage.getItem('mycall'))
);
}
removeViExternalCard() {
// if (
// typeof BX !== 'undefined' &&
// window.localStorage.getItem(BX.bitrix_sessid() + '_mycall') &&
// window.localStorage.getItem('mycall')
// ) {
// BX?.localStorage?.remove('viExternalCard');
// } else if (typeof BX !== 'undefined') {
// BX?.localStorage?.remove('viExternalCard');
// }
}
startTimer() {
this.testTimer = setInterval(() => {
this.timer.time = this.timer.time + 1;
this.onSipStateChange.setDndTimer(this.timer.time);
}, 1000);
}
stopTimer() {
clearInterval(this.testTimer);
this.timer.time = 0;
this.onSipStateChange.setDndTimer(this.timer.time);
}
startInnerTimer() {
this.testInnerTimer = setInterval(() => {
this.innerTimer.time = this.innerTimer.time + 1;
this.onSipStateChange.innerTimer(this.innerTimer.time);
}, 1000);
}
stopInnerTimer() {
clearInterval(this.testInnerTimer);
this.innerTimer.time = 0;
this.onSipStateChange.innerTimer(this.innerTimer.time);
}
showNotification(cbk) {
let callerId = this.callSession._remote_identity._uri.user;
const greeting = new Notification(`Звонок от ${callerId}`, {
body: 'Answer Call',
icon: tugpng,
});
greeting.addEventListener('click', cbk);
}
onSoundType({type, bool}) {
this.ringtone.remove();
this.waitRingTone.remove();
this.pickSound.remove();
if (this.played) {
switch (type) {
case 'ring':
if (bool) {
this.ringtone.pause();
this.ringtone.remove();
this.ringtone.play();
} else {
this.ringtone.pause();
this.ringtone.remove();
}
break;
case 'wait':
if (bool) {
this.waitRingTone.pause();
this.waitRingTone.remove();
console.log(this.waitRingTone, 'sound waitRingTone');
this.waitRingTone.play();
} else {
this.waitRingTone.pause();
this.waitRingTone.remove();
}
break;
case 'pick':
if (bool) {
this.pickSound.remove();
this.pickSound.pause();
this.pickSound.play();
} else {
this.pickSound.pause();
this.pickSound.remove();
}
break;
default:
console.error('onSoundType: Such a sound does not exist');
break;
}
}
}
sipRegister = ({number, secret, wsurl, isIce}) => {
try {
if (window?.alovoice_setversion && packageJson?.version) {
window.alovoice_setversion(packageJson?.version);
}
if (this.options) {
if (typeof BX !== 'undefined')
BX?.localStorage?.remove('viExternalCard');
this.socket = new WebSocketInterface(`wss://${wsurl}/ws`);
this.callSession = false;
this.sipDomain = wsurl;
console.log('ua_configure ', {
sockets: [this.socket],
uri: `sip:${number}@${wsurl}`,
password: secret,
stun_server: 'stun:stun.l.google.com:19302',
});
this.ua = new UA({
sockets: [this.socket],
uri: `sip:${number}@${wsurl}`,
password: secret,
stun_server: 'stun:stun.l.google.com:19302',
register_expires: 60,
});
if (typeof BX !== 'undefined') {
console.log(
'setting_my_call =============================-----------',
);
window.localStorage.setItem(
BX.bitrix_sessid() + '_mycall',
this.ua.configuration.instance_id,
);
window.localStorage.setItem(
'mycall',
this.ua.configuration.instance_id,
);
}
this.ua.on('connected', (e) => {
console.log(
'%c sip_register [connected]: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.ua.on('disconnected', (e) => {
this.onSipStateChange.dynamicValue('pending');
console.log(
'%c sip_register [disconnected]: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.ua.on('registered', (e) => {
this.onSipStateChange.dynamicValue('connected');
console.log(
'%c sip_register [registered]: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.ua.on('unregistered', (e) => {
console.log(
'%c sip_register [unregistered]: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.ua.on('registrationFailed', (e) => {
console.log(
'%c sip_register [registrationFailed]: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.ua.on('connecting', (e) => {
console.log('%c connecting: ', 'font-size: 22px; color: yellow;', e);
});
this.ua.on('registrationExpiring', (e) => {
console.log(
'%c registrationExpiring: ',
'font-size: 22px; color: yellow;',
e,
);
this.ua.register();
});
this.ua.on('newMessage', (e) => {
console.log('%c newMessage: ', 'font-size: 22px; color: yellow;', e);
});
this.ua.on('sipEvent', (e) => {
console.log('%c sipEvent: ', 'font-size: 22px; color: yellow;', e);
});
this.ua.on('newOptions', (e) => {
console.log('%c newOptions: ', 'font-size: 22px; color: yellow;', e);
});
this.ua.on('newRTCSession', (data) => {
console.log(
'%c newRTCSession: ',
'font-size: 22px; color: yellow;',
data,
);
this.callSession = data.session;
if (this.callSession && this.callSession.connection) {
this.callSession.connection.onaddstream = (e) => {
this.strmTrack = e.stream.getAudioTracks();
if (this.strmTrack[0]) {
this.remoteAudio.srcObject = new MediaStream([
this.strmTrack[0],
]);
this.remoteAudio.play();
}
};
}
this.setGuiPhoneState({
funcName: 'modalState',
funcParam: {
bool: true,
callType: 'incoming',
},
});
this.onSipStateChange.innerCallerModal({
bool: true,
type: 'connectingIncoming',
from: this?.callSession?._remote_identity?._uri?.user,
});
if (this.callSession.direction === 'incoming') {
let second
console.log('auto_answer is work: ', this.globalHistoryData?.autoAnswer)
if (this.globalHistoryData?.autoAnswer) {
switch (this.globalHistoryData?.autoAnswerSecond) {
case 1:
second = 1000
break
case 50:
second = 5000
break
case 100:
second = 10000
break
default:
second = 0
}
console.log('auto_answer second: ', second)
setTimeout(() => {
console.log('auto_answer run boxDialer.answerButtonClick()')
this.answerButtonClick()
}, second)
}
this.showNotification(() => {
this.answerButtonClick();
});
this.onSoundType({type: 'ring', bool: true});
this.setGuiPhoneState({
funcName: 'modalState',
stateCode: 'connectingIncoming',
funcParam: {
bool: true,
callType: 'incoming',
},
});
// window.innerCallBegin();
this.callSession.on('progress', (e) => {
console.log(
'%c progress: ',
'font-size: 22px; color: yellow;',
e,
);
this.setGuiPhoneState({
stateCode: 'incoming',
});
});
// incoming call here
this.callSession.on('accepted', () => {
console.log(
'%c newRTCSession accepted: ',
'font-size: 22px; color: yellow;',
e,
);
// the call has answered
this.onSoundType({type: 'ring', bool: false});
this.setGuiPhoneState({
funcName: 'modalState',
funcParam: {
bool: true,
callType: 'connected',
},
});
this.onSipStateChange.innerCallerModal({
bool: false,
type: '',
from: '',
});
});
this.callSession.on('confirmed', () => {
console.log(
'%c newRTCSession confirmed: ',
'font-size: 22px; color: yellow;',
);
// this handler will be called for incoming calls too
console.log(
'%c incoming confirmed',
'font-size: 22px; color: yellow;',
);
this.onSipStateChange.innerCallerModal({
bool: true,
type: 'connected',
from: this?.callSession?._remote_identity?._uri?.user,
});
this.startInnerTimer();
this.setGuiPhoneState({
funcName: 'modalState',
funcParam: {
bool: true,
callType: 'connected',
},
});
});
this.callSession.on('ended', () => {
console.log(
'%c newRTCSession ended: ',
'font-size: 22px; color: yellow;',
);
// the call has ended
console.log('%c incoming end', 'font-size: 22px; color: yellow;');
this.onSipStateChange.innerCallerModal({
bool: false,
type: null,
from: '',
});
this.stopInnerTimer();
this.setGuiPhoneState({
funcName: 'modalState',
funcParam: {
bool: false,
callType: '',
},
});
this.closeBxCall();
this.hangupButtonClick();
this.removeViExternalCard();
});
this.callSession.on('failed', () => {
// unable to establish the call
console.log(
'%c incoming faile ',
'font-size: 22px; color: yellow;',
);
this.onSipStateChange.innerCallerModal({
bool: false,
type: null,
});
this.stopInnerTimer();
this.onSoundType({type: 'ring', bool: false});
this.closeBxCall();
this.hangupButtonClick();
this.setGuiPhoneState({
funcName: 'modalState',
funcParam: {
bool: false,
callType: '',
},
});
});
this.callSession.on('connecting', (e) => {
console.log(
'%c connecting: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on('sending', (e) => {
console.log('%c sending: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('newDTMF', (e) => {
console.log('%c newDTMF: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('newInfo', (e) => {
console.log('%c newInfo: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('hold', (e) => {
console.log(
'%c ___________hold: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on('unhold', (e) => {
console.log(
'%c ___________unhold: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on('muted', (e) => {
console.log('%c muted: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('unmuted', (e) => {
console.log('%c unmuted: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('reinvite', (e) => {
console.log(
'%c reinvite: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on('update', (e) => {
console.log('%c update: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('refer', (e) => {
console.log('%c refer: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('replaces', (e) => {
console.log(
'%c replaces: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on('sdp', (e) => {
console.log('%c sdp: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('icecandidate', (e) => {
console.log(
'%c icecandidate: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on('getusermediafailed', (e) => {
console.log(
'%c getusermediafailed: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on('peerconnection: createofferfailed', (e) => {
console.log(
'%c peerconnection: createofferfailed: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on(
'peerconnection: setlocaldescriptionfailed',
(e) => {
console.log(
'%c peerconnection: setlocaldescriptionfailed: ',
'font-size: 22px; color: yellow;',
e,
);
},
);
this.callSession.on(
'peerconnection: setremotedescriptionfailed',
(e) => {
console.log(
'%c peerconnection: setremotedescriptionfailed: ',
'font-size: 22px; color: yellow;',
e,
);
},
);
}
});
this.ua.start();
}
} catch (err) {
console.log(`jsSip_error: `, err);
}
};
getBxUiState(sipState) {
// if (sipState && !!sipState.length) sipState = this.sipState;
let uiStates = {
incoming: '1',
transferIncoming: '2',
outgoing: '3',
connectingIncoming: '4',
connectingOutgoing: '5',
connected: '6',
transferring: '7',
transferFailed: '8',
transferConnected: '9',
idle: '10',
error: '11',
moneyError: '12',
sipPhoneError: '13',
redial: '14',
externalCard: '15',
};
console.log('getBxUiState_inset: ', sipState, uiStates[sipState]);
this.sipBxState = uiStates[sipState];
return sipState && uiStates[sipState] ? uiStates[sipState] : '';
}
callBxMethods({bxMethodName, bxFuncParams, callback}) {
if (window.BX24 && window.BX24.placement) {
window?.BX24.placement.call(bxMethodName, bxFuncParams, callback);
} else if (window.alovoicePhone && window.alovoicePhone.callMethods) {
window.alovoicePhone.callMethods[bxMethodName](bxFuncParams, callback);
}
if (bxFuncParams.uiState == '5') {
this.removeViExternalCard();
}
}
closeBxCall() {
if (window.BX24 && window.BX24.placement) {
window?.BX24.placement.call('CallCardClose', {}, () => {
});
} else if (
window.alovoicePhone &&
window.alovoicePhone.callMethods &&
window.alovoicePhone.bodClose
) {
window?.alovoicePhone?.bodClose();
}
}
setGuiPhoneState({stateCode, funcName, funcParam}) {
if (window?.alovoice_wsphone && !!stateCode?.length) {
console.log(
'this_getBxUiState_stateCode',
stateCode,
this.getBxUiState(stateCode),
);
this.callBxMethods({
bxMethodName: 'CallCardSetUiState',
bxFuncParams: {uiState: this.getBxUiState(stateCode)},
callback: (e) => {
console.log(e, `CallCardSetUiState method done ${e}`);
},
});
} else if (
!window?.alovoice_wsphone &&
!stateCode?.length &&
!!funcName &&
this.onSipStateChange[funcName] !== 'undefined'
) {
this.onSipStateChange[funcName](funcParam);
}
}
bxLog(...datas) {
console.log(`%c BXLOG:`, datas, 'background-color: red;');
}
onSessionEvent({type, event}) {
}
selectUser() {
BX.Runtime.loadExtension('ui.entity-selector').then((exports) => {
const {Dialog, TagSelector} = exports;
const dialog = new BX.UI.EntitySelector.Dialog({
// targetNode: button,
enableSearch: true,
multiple: false,
context: 'MY_MODULE_CONTEXT',
entities: [
{
id: 'user', // пользователи
options: {selectFields: ['ufPhoneInner']},
},
{
id: 'department', // структура компании: выбор только пользователей
},
],
events: {
'_Item:onSelect': (event) => {
const {item} = event.getData();
const dialog = event.getTarget();
const selectedItems = dialog.getSelectedItems();
if (item.customData.get('ufPhoneInner')) {
this.transferButtonClick(item.customData.get('ufPhoneInner'));
}
},
get 'Item:onSelect'() {
return this['_Item:onSelect'];
},
set 'Item:onSelect'(value) {
this['_Item:onSelect'] = value;
},
},
});
dialog.show();
});
}
// call_connected;
setSipStateChangeCallback(callback, funcName) {
this.onSipStateChange[funcName] = callback.bind(this);
}
sipHangUp() {
console.log('sipHangUp');
}
sipUnRegister() {
console.log('sipUnRegister');
}
sipTransfer() {
console.log('sipTransfer');
}
initialized(phoneNumber) {
this.sipBxState = null;
this.callDirection = 'out';
let phoneNumberString = phoneNumber.toString();
if (phoneNumberString.length) {
this.onSipStateChange.phoneModal(false);
this.options.extraHeaders = [`X-ALOVOICE-EXTNUM: ${this.extnum}`];
this.callSession = this.ua.call(
'sip:' + phoneNumberString + '@' + this.sipDomain,
this.options,
);
// this.callSession.connection.addEventListener('addstream', (event) => {
// console.log('--== ss OUT STREAM: ');
// this.remoteAudio.srcObject = event.stream;
// this.remoteAudio.play();
// });
} else {
toast.error('Do not correct number', {
style: {
zIndex: '99999999999999999',
},
});
}
// this.onSipStateChange.phoneModal(false);
}
skipButtonClick() {
this.onSoundType({type: 'ring', bool: false});
this.hangupButtonClick();
}
answerButtonClick() {
this.onSoundType({type: 'ring', bool: false});
this.callSession?.answer(this.options);
this.callSession.connection.addEventListener('addstream', (event) => {
this.remoteAudio.srcObject = event.stream;
this.remoteAudio.play();
});
}
sipSendDTMF(code) {
this.callSession.sendDTMF(code);
}
addCommentButtonClick() {
console.log('addCommentButtonClick');
}
muteButtonClick() {
let {audio} = this.callSession.isMuted();
if (audio) {
this.callSession.unmute();
console.log('muteButtonClick_unmute');
this.onSipStateChange['setCallEvents']({callMute: false});
} else {
this.callSession.mute();
console.log('muteButtonClick_mute');
this.onSipStateChange['setCallEvents']({callMute: true});
}
}
holdButtonClick() {
let {local} = this.callSession.isOnHold();
console.log('local: ', local);
if (local) {
this.callSession.unhold();
this.onSipStateChange['setCallEvents']({callHold: false});
} else {
this.callSession.hold();
this.onSipStateChange['setCallEvents']({callHold: true});
}
}
closeButtonClick() {
this.hangupButtonClick();
}
hangupButtonClick() {
this.onSoundType({type: 'ring', bool: false});
this.onSipStateChange.innerCallerModal({
bool: false,
type: null,
from: '',
});
console.log(
'hangupButtonClick========-----------',
this.callSession._status,
);
if (this.callSession && this.callSession._status != '8')
this.callSession.terminate();
}
transferButtonClick(number) {
this.callSession.refer(number, this.options);
}
cancelTransferButtonClick() {
console.log('cancelTransferButtonClick');
}
completeTransferButtonClick() {
console.log('completeTransferButtonClick');
}
nextButtonClick() {
console.log('nextButtonClick');
}
entityChanged() {
console.log('entityChanged');
}
qualityMeterClick() {
console.log('qualityMeterClick');
}
dialpadButtonClick(c) {
console.log('dialpadButtonClick');
this.sipSendDTMF(c);
}
notifyAdminButtonClick() {
console.log('notifyAdminButtonClick');
}
stateLog(state) {
let stColor = state && state.slice(0, 4) == 'call' ? 'blue' : 'green';
if (state && state.slice(0, 8) == 'register') {
stColor = 'yellow';
}
let css = 'color:' + stColor + '; font-size: 20px;';
console.log(' ---onSessionEvent EVENT: %c %s', css, state);
}
sTransferNumber;
oRingTone;
oRingbackTone;
oSipStack;
oSipSessionRegister;
oSipSessionCall;
oSipSessionCallSecond;
oSipSessionTransferCall;
videoRemote;
videoLocal;
remoteAudio;
bFullScreen = false;
oNotifICall;
bDisableVideo = false;
viewVideoLocal;
viewVideoRemote;
viewLocalScreencast; // <video> (webrtc) or <div> (webrtc4all)
oConfigCall;
callDirection;
oReadyStateTimer;
ringtone;
ringbacktone;
sipState;
sipBxState;
soundBool;
onSipStateChange = {};
callEvetsBoxDialer;
musicContext;
gainNode;
gainNode;
oscillator1;
oscillator2;
extnum;
timer = {
time: 0,
type: null,
};
innerTimer = {
time: 0,
type: null,
};
options;
socket;
ua;
testTimer;
testInnerTimer;
callSession;
sipDomain;
player;
strmTrack;
isRestarting;
globalHistoryData;
constructor() {
this.played = false;
document.body.addEventListener('click', () => {
this.played = true;
});
this.isRestarting = false;
this.videoRemote = document.createElement('video');
this.videoLocal = document.createElement('video');
this.remoteAudio = document.createElement('audio');
this.remoteAudio.autoplay = true;
document.body.appendChild(this.videoRemote);
document.body.appendChild(this.videoLocal);
document.body.appendChild(this.remoteAudio);
this.ringtone = new Audio(outcomingringTone);
this.waitRingTone = new Audio(waitRingTone);
this.pickSound = new Audio(pickSound);
this.ringtone.loop = true;
this.waitRingTone.loop = true;
this.callEvetsBoxDialer = {
callHold: false,
callMute: null,
};
this.options = {
eventHandlers: this.uaEvents(),
mediaConstraints: { audio: true, video: false },
};
}
setGlobalHistoryData(data) {
console.log('setGlobalHistoryData: ', data);
this.globalHistoryData = data;
}
dialTone(freq1, freq2) {
// merger = context.createChannelMerger(2);
// setTimeout(() => {
// console.log('-= sTOPING BY TIMEOUT');
// this.stop();
// }, 1000);
// if (this.oscillator1 || this.oscillator2) return;
// console.log('Begin dialTone:', this.oscillator1, this.oscillator2);
// this.oscillator1 = this.musicContext.createOscillator();
// // this.oscillator1.type = null;
// this.oscillator1.frequency.value = freq1;
// this.gainNode = this.musicContext.createGain
// ? this.musicContext.createGain()
// : this.musicContext.createGainNode();
// this.oscillator1.connect(this.gainNode, 0, 0);
// this.gainNode.connect(this.musicContext.destination);
// this.gainNode.gain.value = 0.1;
// this.oscillator1.start
// ? this.oscillator1.start(0)
// : this.oscillator1.noteOn(0);
// // this.gainNode.connect(merger,0,1);
// this.oscillator2 = this.musicContext.createOscillator();
// // this.oscillator2.type = null;
// this.oscillator2.frequency.value = freq2;
// this.gainNode = this.musicContext.createGain
// ? this.musicContext.createGain()
// : this.musicContext.createGainNode();
// this.oscillator2.connect(this.gainNode);
// this.gainNode.connect(this.musicContext.destination);
// // this.gainNode.connect(merger,0,0);
// this.gainNode.gain.value = 0.1;
// this.oscillator2.start
// ? this.oscillator2.start(0)
// : this.oscillator2.noteOn(0);
}
start() {
// if (typeof this.oscillator1 != 'undefined') this.oscillator1.disconnect();
// if (typeof this.oscillator2 != 'undefined') this.oscillator2.disconnect();
// oscOn(
// parseFloat(document.getElementById('freq').value),
// parseFloat(document.getElementById('freq2').value),
// );
}
stop() {
// console.log('STOP', this.oscillator1, this.oscillator2);
// console.log('FUNC', this.oscillator1?.disconnect, this.oscillator1?.stop);
// this.oscillator1?.disconnect();
// this.oscillator2?.disconnect();
// this.oscillator1?.stop();
// this.oscillator2?.stop();
// this.oscillator1 = null;
// this.oscillator2 = null;
}
uaEvents() {
return {
progress: (e) => {
console.log('%c progress', 'font-size: 22px; color: green;', e);
// this.hangupButtonClick();
// this.closeBxCall();
// window.innerCallBegin(true);
this.onSipStateChange.innerCallerModal({
bool: true,
type: 'connectingOutgoing',
from: this?.callSession?._remote_identity?._uri?.user,
});
this.setGuiPhoneState({
funcName: 'modalState',
stateCode: 'connectingOutgoing',
funcParam: {
bool: false,
callType: '',
},
});
},
failed: (e) => {
console.log('%c failed', 'font-size: 22px; color: green;', e);
if (e?.cause) {
toast.error(e?.cause);
}
// console.log('call failed with cause: ' + e.data);
this.closeBxCall();
this.onSipStateChange.innerCallerModal({
bool: false,
type: null,
from: '',
});
this.stopInnerTimer();
if (e.cause == 'User Denied Media Access') {
console.log('User_Danied_Media_Access');
toast.error('Your micrafon is OFF', {
style: {
zIndex: '99999999999999999',
},
});
window.navigator.mediaDevices
.getUserMedia({ audio: true })
.then(function (stream) {
console.log(
'User_Danied_Media_Access',
'You let me use your mic!',
);
})
.catch(function (err) {
console.log('User_Danied_Media_Access', 'No mic for you!');
});
}
},
ended: (e) => {
console.log('%c ended', 'font-size: 22px; color: green;');
this.closeBxCall();
this.onSipStateChange.innerCallerModal({
bool: false,
type: null,
from: '',
});
this.stopInnerTimer();
this.setGuiPhoneState({
funcName: 'modalState',
funcParam: {
bool: false,
callType: '',
},
});
this.removeViExternalCard();
},
confirmed: (e) => {
console.log('%c confirmed', 'font-size: 22px; color: green;', e);
// console.log(`%c BXLOG:`, datas, 'background-color: red;');
this.onSipStateChange.innerCallerModal({
bool: true,
type: 'connected',
from: this?.callSession?._remote_identity?._uri?.user,
});
this.startInnerTimer();
this.setGuiPhoneState({
funcName: 'modalState',
stateCode: 'connected',
funcParam: {
bool: true,
callType: 'connected',
callFromName: 'Test',
},
});
},
};
}
isUaRunning() {
return (
Boolean(typeof window.BX !== 'undefined') &&
Boolean(window.localStorage.getItem(BX.bitrix_sessid() + '_mycall')) &&
Boolean(window.localStorage.getItem('mycall'))
);
}
removeViExternalCard() {
// if (
// typeof BX !== 'undefined' &&
// window.localStorage.getItem(BX.bitrix_sessid() + '_mycall') &&
// window.localStorage.getItem('mycall')
// ) {
// BX?.localStorage?.remove('viExternalCard');
// } else if (typeof BX !== 'undefined') {
// BX?.localStorage?.remove('viExternalCard');
// }
}
startTimer() {
this.testTimer = setInterval(() => {
this.timer.time = this.timer.time + 1;
this.onSipStateChange.setDndTimer(this.timer.time);
}, 1000);
}
stopTimer() {
clearInterval(this.testTimer);
this.timer.time = 0;
this.onSipStateChange.setDndTimer(this.timer.time);
}
startInnerTimer() {
this.testInnerTimer = setInterval(() => {
this.innerTimer.time = this.innerTimer.time + 1;
this.onSipStateChange.innerTimer(this.innerTimer.time);
}, 1000);
}
stopInnerTimer() {
clearInterval(this.testInnerTimer);
this.innerTimer.time = 0;
this.onSipStateChange.innerTimer(this.innerTimer.time);
}
showNotification(cbk) {
let callerId = this.callSession._remote_identity._uri.user;
const greeting = new Notification(`Звонок от ${callerId}`, {
body: 'Answer Call',
icon: tugpng,
});
greeting.addEventListener('click', cbk);
}
onSoundType({ type, bool }) {
this.ringtone.remove();
this.waitRingTone.remove();
this.pickSound.remove();
if (this.played) {
switch (type) {
case 'ring':
if (bool) {
this.ringtone.pause();
this.ringtone.remove();
this.ringtone.play();
} else {
this.ringtone.pause();
this.ringtone.remove();
}
break;
case 'wait':
if (bool) {
this.waitRingTone.pause();
this.waitRingTone.remove();
console.log(this.waitRingTone, 'sound waitRingTone');
this.waitRingTone.play();
} else {
this.waitRingTone.pause();
this.waitRingTone.remove();
}
break;
case 'pick':
if (bool) {
this.pickSound.remove();
this.pickSound.pause();
this.pickSound.play();
} else {
this.pickSound.pause();
this.pickSound.remove();
}
break;
default:
console.error('onSoundType: Such a sound does not exist');
break;
}
}
}
sipRegister = ({ number, secret, wsurl, isIce }) => {
try {
if (window?.alovoice_setversion && packageJson?.version) {
window.alovoice_setversion(packageJson?.version);
}
if (this.options) {
if (typeof BX !== 'undefined')
BX?.localStorage?.remove('viExternalCard');
this.socket = new WebSocketInterface(`wss://${wsurl}/ws`);
this.callSession = false;
this.sipDomain = wsurl;
console.log('ua_configure ', {
sockets: [this.socket],
uri: `sip:${number}@${wsurl}`,
password: secret,
stun_server: 'stun:stun.l.google.com:19302',
});
this.ua = new UA({
sockets: [this.socket],
uri: `sip:${number}@${wsurl}`,
password: secret,
stun_server: 'stun:stun.l.google.com:19302',
register_expires: 60,
});
if (typeof BX !== 'undefined') {
console.log(
'setting_my_call =============================-----------',
);
window.localStorage.setItem(
BX.bitrix_sessid() + '_mycall',
this.ua.configuration.instance_id,
);
window.localStorage.setItem(
'mycall',
this.ua.configuration.instance_id,
);
}
this.ua.on('connected', (e) => {
console.log(
'%c sip_register [connected]: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.ua.on('disconnected', (e) => {
this.onSipStateChange.dynamicValue('pending');
console.log(
'%c sip_register [disconnected]: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.ua.on('registered', (e) => {
this.onSipStateChange.dynamicValue('connected');
console.log(
'%c sip_register [registered]: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.ua.on('unregistered', (e) => {
console.log(
'%c sip_register [unregistered]: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.ua.on('registrationFailed', (e) => {
console.log(
'%c sip_register [registrationFailed]: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.ua.on('connecting', (e) => {
console.log('%c connecting: ', 'font-size: 22px; color: yellow;', e);
});
this.ua.on('registrationExpiring', (e) => {
console.log(
'%c registrationExpiring: ',
'font-size: 22px; color: yellow;',
e,
);
this.ua.register();
});
this.ua.on('newMessage', (e) => {
console.log('%c newMessage: ', 'font-size: 22px; color: yellow;', e);
});
this.ua.on('sipEvent', (e) => {
console.log('%c sipEvent: ', 'font-size: 22px; color: yellow;', e);
});
this.ua.on('newOptions', (e) => {
console.log('%c newOptions: ', 'font-size: 22px; color: yellow;', e);
});
this.ua.on('newRTCSession', (data) => {
console.log(
'%c newRTCSession: ',
'font-size: 22px; color: yellow;',
data,
);
this.callSession = data.session;
if (this.callSession && this.callSession.connection) {
this.callSession.connection.onaddstream = (e) => {
this.strmTrack = e.stream.getAudioTracks();
if (this.strmTrack[0]) {
this.remoteAudio.srcObject = new MediaStream([
this.strmTrack[0],
]);
this.remoteAudio.play();
}
};
}
this.setGuiPhoneState({
funcName: 'modalState',
funcParam: {
bool: true,
callType: 'incoming',
},
});
this.onSipStateChange.innerCallerModal({
bool: true,
type: 'connectingIncoming',
from: this?.callSession?._remote_identity?._uri?.user,
});
if (this.callSession.direction === 'incoming') {
let second;
console.log(
'auto_answer is work: ',
this.globalHistoryData?.autoAnswer,
);
if (this.globalHistoryData?.autoAnswer) {
switch (this.globalHistoryData?.autoAnswerSecond) {
case 1:
second = 1000;
break;
case 50:
second = 5000;
break;
case 100:
second = 10000;
break;
default:
second = 0;
}
console.log('auto_answer second: ', second);
setTimeout(() => {
console.log('auto_answer run boxDialer.answerButtonClick()');
this.answerButtonClick();
}, second);
}
this.showNotification(() => {
this.answerButtonClick();
});
this.onSoundType({ type: 'ring', bool: true });
this.setGuiPhoneState({
funcName: 'modalState',
stateCode: 'connectingIncoming',
funcParam: {
bool: true,
callType: 'incoming',
},
});
// window.innerCallBegin();
this.callSession.on('progress', (e) => {
console.log(
'%c progress: ',
'font-size: 22px; color: yellow;',
e,
);
this.setGuiPhoneState({
stateCode: 'incoming',
});
});
// incoming call here
this.callSession.on('accepted', () => {
console.log(
'%c newRTCSession accepted: ',
'font-size: 22px; color: yellow;',
e,
);
// the call has answered
this.onSoundType({ type: 'ring', bool: false });
this.setGuiPhoneState({
funcName: 'modalState',
funcParam: {
bool: true,
callType: 'connected',
},
});
this.onSipStateChange.innerCallerModal({
bool: false,
type: '',
from: '',
});
});
this.callSession.on('confirmed', () => {
console.log(
'%c newRTCSession confirmed: ',
'font-size: 22px; color: yellow;',
);
// this handler will be called for incoming calls too
console.log(
'%c incoming confirmed',
'font-size: 22px; color: yellow;',
);
this.onSipStateChange.innerCallerModal({
bool: true,
type: 'connected',
from: this?.callSession?._remote_identity?._uri?.user,
});
this.startInnerTimer();
this.setGuiPhoneState({
funcName: 'modalState',
funcParam: {
bool: true,
callType: 'connected',
},
});
});
this.callSession.on('ended', () => {
console.log(
'%c newRTCSession ended: ',
'font-size: 22px; color: yellow;',
);
// the call has ended
console.log('%c incoming end', 'font-size: 22px; color: yellow;');
this.onSipStateChange.innerCallerModal({
bool: false,
type: null,
from: '',
});
this.stopInnerTimer();
this.setGuiPhoneState({
funcName: 'modalState',
funcParam: {
bool: false,
callType: '',
},
});
this.closeBxCall();
this.hangupButtonClick();
this.removeViExternalCard();
});
this.callSession.on('failed', () => {
// unable to establish the call
console.log(
'%c incoming faile ',
'font-size: 22px; color: yellow;',
);
this.onSipStateChange.innerCallerModal({
bool: false,
type: null,
});
this.stopInnerTimer();
this.onSoundType({ type: 'ring', bool: false });
this.closeBxCall();
this.hangupButtonClick();
this.setGuiPhoneState({
funcName: 'modalState',
funcParam: {
bool: false,
callType: '',
},
});
});
this.callSession.on('connecting', (e) => {
console.log(
'%c connecting: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on('sending', (e) => {
console.log('%c sending: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('newDTMF', (e) => {
console.log('%c newDTMF: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('newInfo', (e) => {
console.log('%c newInfo: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('hold', (e) => {
console.log(
'%c ___________hold: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on('unhold', (e) => {
console.log(
'%c ___________unhold: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on('muted', (e) => {
console.log('%c muted: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('unmuted', (e) => {
console.log('%c unmuted: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('reinvite', (e) => {
console.log(
'%c reinvite: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on('update', (e) => {
console.log('%c update: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('refer', (e) => {
console.log('%c refer: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('replaces', (e) => {
console.log(
'%c replaces: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on('sdp', (e) => {
console.log('%c sdp: ', 'font-size: 22px; color: yellow;', e);
});
this.callSession.on('icecandidate', (e) => {
console.log(
'%c icecandidate: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on('getusermediafailed', (e) => {
console.log(
'%c getusermediafailed: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on('peerconnection: createofferfailed', (e) => {
console.log(
'%c peerconnection: createofferfailed: ',
'font-size: 22px; color: yellow;',
e,
);
});
this.callSession.on(
'peerconnection: setlocaldescriptionfailed',
(e) => {
console.log(
'%c peerconnection: setlocaldescriptionfailed: ',
'font-size: 22px; color: yellow;',
e,
);
},
);
this.callSession.on(
'peerconnection: setremotedescriptionfailed',
(e) => {
console.log(
'%c peerconnection: setremotedescriptionfailed: ',
'font-size: 22px; color: yellow;',
e,
);
},
);
}
});
this.ua.start();
}
} catch (err) {
console.log(`jsSip_error: `, err);
}
};
getBxUiState(sipState) {
// if (sipState && !!sipState.length) sipState = this.sipState;
let uiStates = {
incoming: '1',
transferIncoming: '2',
outgoing: '3',
connectingIncoming: '4',
connectingOutgoing: '5',
connected: '6',
transferring: '7',
transferFailed: '8',
transferConnected: '9',
idle: '10',
error: '11',
moneyError: '12',
sipPhoneError: '13',
redial: '14',
externalCard: '15',
};
console.log('getBxUiState_inset: ', sipState, uiStates[sipState]);
this.sipBxState = uiStates[sipState];
return sipState && uiStates[sipState] ? uiStates[sipState] : '';
}
callBxMethods({ bxMethodName, bxFuncParams, callback }) {
if (window.BX24 && window.BX24.placement) {
window?.BX24.placement.call(bxMethodName, bxFuncParams, callback);
} else if (window.alovoicePhone && window.alovoicePhone.callMethods) {
window.alovoicePhone.callMethods[bxMethodName](bxFuncParams, callback);
}
if (bxFuncParams.uiState == '5') {
this.removeViExternalCard();
}
}
closeBxCall() {
if (window.BX24 && window.BX24.placement) {
window?.BX24.placement.call('CallCardClose', {}, () => {});
} else if (
window.alovoicePhone &&
window.alovoicePhone.callMethods &&
window.alovoicePhone.bodClose
) {
window?.alovoicePhone?.bodClose();
}
}
setGuiPhoneState({ stateCode, funcName, funcParam }) {
console.log('boxdialer_setGuiPhoneState_states: ', { stateCode, funcName, funcParam })
if (window?.alovoice_wsphone && !!stateCode?.length) {
console.log(
'this_getBxUiState_stateCode',
stateCode,
this.getBxUiState(stateCode),
);
this.callBxMethods({
bxMethodName: 'CallCardSetUiState',
bxFuncParams: { uiState: this.getBxUiState(stateCode) },
callback: (e) => {
console.log(e, `CallCardSetUiState method done ${e}`);
},
});
} else if (
!window?.alovoice_wsphone &&
!stateCode?.length &&
!!funcName &&
this.onSipStateChange[funcName] !== 'undefined'
) {
this.onSipStateChange[funcName](funcParam);
}
}
bxLog(...datas) {
console.log(`%c BXLOG:`, datas, 'background-color: red;');
}
onSessionEvent({ type, event }) {}
selectUser() {
BX.Runtime.loadExtension('ui.entity-selector').then((exports) => {
const { Dialog, TagSelector } = exports;
const dialog = new BX.UI.EntitySelector.Dialog({
// targetNode: button,
enableSearch: true,
multiple: false,
context: 'MY_MODULE_CONTEXT',
entities: [
{
id: 'user', // пользователи
options: { selectFields: ['ufPhoneInner'] },
},
{
id: 'department', // структура компании: выбор только пользователей
},
],
events: {
'_Item:onSelect': (event) => {
const { item } = event.getData();
const dialog = event.getTarget();
const selectedItems = dialog.getSelectedItems();
if (item.customData.get('ufPhoneInner')) {
this.transferButtonClick(item.customData.get('ufPhoneInner'));
}
},
get 'Item:onSelect'() {
return this['_Item:onSelect'];
},
set 'Item:onSelect'(value) {
this['_Item:onSelect'] = value;
},
},
});
dialog.show();
});
}
// call_connected;
setSipStateChangeCallback(callback, funcName) {
this.onSipStateChange[funcName] = callback.bind(this);
}
sipHangUp() {
console.log('sipHangUp');
}
sipUnRegister() {
console.log('sipUnRegister');
}
sipTransfer() {
console.log('sipTransfer');
}
initialized(phoneNumber) {
this.sipBxState = null;
this.callDirection = 'out';
let phoneNumberString = phoneNumber.toString();
if (phoneNumberString.length) {
this.onSipStateChange.phoneModal(false);
this.options.extraHeaders = [`X-ALOVOICE-EXTNUM: ${this.extnum}`];
this.callSession = this.ua.call(
'sip:' + phoneNumberString + '@' + this.sipDomain,
this.options,
);
// this.callSession.connection.addEventListener('addstream', (event) => {
// console.log('--== ss OUT STREAM: ');
// this.remoteAudio.srcObject = event.stream;
// this.remoteAudio.play();
// });
} else {
toast.error('Do not correct number', {
style: {
zIndex: '99999999999999999',
},
});
}
// this.onSipStateChange.phoneModal(false);
}
skipButtonClick() {
this.onSoundType({ type: 'ring', bool: false });
this.hangupButtonClick();
}
sipSendDTMF(code) {
this.callSession.sendDTMF(code);
}
addCommentButtonClick() {
console.log('addCommentButtonClick');
}
muteButtonClick() {
let { audio } = this.callSession.isMuted();
if (audio) {
this.callSession.unmute();
console.log('muteButtonClick_unmute');
this.onSipStateChange['setCallEvents']({ callMute: false });
} else {
this.callSession.mute();
console.log('muteButtonClick_mute');
this.onSipStateChange['setCallEvents']({ callMute: true });
}
}
holdButtonClick() {
let { local } = this.callSession.isOnHold();
console.log('local: ', local);
if (local) {
this.callSession.unhold();
this.onSipStateChange['setCallEvents']({ callHold: false });
} else {
this.callSession.hold();
this.onSipStateChange['setCallEvents']({ callHold: true });
}
}
closeButtonClick() {
this.hangupButtonClick();
}
hangupButtonClick() {
this.onSoundType({ type: 'ring', bool: false });
this.onSipStateChange.innerCallerModal({
bool: false,
type: null,
from: '',
});
console.log(
'hangupButtonClick========-----------',
this.callSession._status,
);
if (this.callSession && this.callSession._status != '8')
this.callSession.terminate();
}
transferButtonClick(number) {
this.callSession.refer(number, this.options);
}
cancelTransferButtonClick() {
console.log('cancelTransferButtonClick');
}
completeTransferButtonClick() {
console.log('completeTransferButtonClick');
}
nextButtonClick() {
console.log('nextButtonClick');
}
entityChanged() {
console.log('entityChanged');
}
qualityMeterClick() {
console.log('qualityMeterClick');
}
dialpadButtonClick(c) {
console.log('dialpadButtonClick');
this.sipSendDTMF(c);
}
notifyAdminButtonClick() {
console.log('notifyAdminButtonClick');
}
stateLog(state) {
let stColor = state && state.slice(0, 4) == 'call' ? 'blue' : 'green';
if (state && state.slice(0, 8) == 'register') {
stColor = 'yellow';
}
let css = 'color:' + stColor + '; font-size: 20px;';
console.log(' ---onSessionEvent EVENT: %c %s', css, state);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment