Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
B
BoxDialer
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kulya
BoxDialer
Commits
9b62f42b
Commit
9b62f42b
authored
Nov 10, 2023
by
Muhammadali
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update-
parent
4a51d89e
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
1020 additions
and
993 deletions
+1020
-993
package.json
package.json
+1
-1
boxDIaler.js
src/lib/boxDIaler.js
+1011
-964
index.jsx
src/root/index.jsx
+8
-28
No files found.
package.json
View file @
9b62f42b
{
"name"
:
"boxdialer"
,
"version"
:
"4.8.
59
"
,
"version"
:
"4.8.
60
"
,
"description"
:
""
,
"main"
:
"src/boxDialer.js"
,
"scripts"
:
{
...
...
src/lib/boxDIaler.js
View file @
9b62f42b
/** @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
},
};
}
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
'
)
{
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
40
:
second
=
3000
break
case
100
:
second
=
6000
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
);
}
}
src/root/index.jsx
View file @
9b62f42b
...
...
@@ -39,9 +39,11 @@ const Root = ({wsphonedata, onSetDnd, setWsphonedata, callMethod}) => {
}
},
[
secondLine
]);
useEffect
(()
=>
{
boxDialer
.
setGlobalHistoryData
(
useColorConfigStore
.
state
)
},
[
useColorConfigStore
.
state
])
useEffect
(()
=>
{
boxDialer
.
globalHistoryData
=
useColorConfigStore
.
state
if
(
wsphonedata
&&
wsphonedata
?.
number
)
{
boxDialer
.
setSipStateChangeCallback
(
setDynamicValue
,
'
dynamicValue
'
);
boxDialer
.
setSipStateChangeCallback
(
setModalState
,
'
modalState
'
);
...
...
@@ -90,33 +92,11 @@ const Root = ({wsphonedata, onSetDnd, setWsphonedata, callMethod}) => {
};
useEffect
(()
=>
{
console
.
log
(
'
auto_answer running:
'
,
modalState
.
callType
===
'
incoming
'
&&
modalState
.
bool
)
if
(
modalState
.
callType
===
'
incoming
'
&&
modalState
.
bool
){
let
second
if
(
useColorConfigStore
.
state
?.
autoAnswer
)
{
switch
(
useColorConfigStore
.
state
?.
autoAnswerSecond
)
{
case
1
:
second
=
1000
break
case
40
:
second
=
3000
break
case
100
:
second
=
6000
break
default
:
second
=
0
}
console
.
log
(
'
auto_answer second:
'
,
second
)
setTimeout
(()
=>
{
console
.
log
(
'
auto_answer run boxDialer.answerButtonClick()
'
)
boxDialer
.
answerButtonClick
()
},
second
)
}
}
},
[
modalState
.
callType
,
modalState
.
bool
,
useColorConfigStore
.
state
?.
autoAnswer
,
useColorConfigStore
.
state
?.
autoAnswerSecond
])
// useEffect(()=> {
// console.log('auto_answer running: ', modalState.callType === 'incoming' && modalState.bool)
//
// }, [modalState.callType, modalState.bool, useColorConfigStore.state?.autoAnswer, useColorConfigStore.state?.autoAnswerSecond])
//
const
selectWidjetType
=
(
type
)
=>
{
switch
(
type
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment