TT#20504 Call: As a Customer, I want to initiate an audio/video call

- Call: Implement ringing state
- Call: Implement pending state
- Call: Implement call cancellation

Change-Id: Ia38f5a7867c1eba6677b71893549a7b21fdd9ef2
changes/60/15160/2
Hans-Peter Herzog 8 years ago committed by Robert Axelsen
parent 4d27a8fd36
commit d3a43fa47a

@ -100,3 +100,67 @@ $border-radius : 50%;
.rtc-button-margin {
margin: 0 50px 0 0;
}
.call-button {
border-radius: 50%;
background-color: #16b603;
color: white;
border-width: 0;
}
.call-button * {
font-size: 22px;
}
.call-button .icon-large {
font-size: 22px;
position: absolute;
bottom: 0px;
left: 2px;
}
.call-button .icon-small {
font-size: 11px;
position: absolute;
top: 2px;
right: 3px;
}
.call-button-cancel {
background-color: red;
}
.call-button-accept {
background-color: forestgreen;
}
.call-icon-cancel {
position: absolute;
transform: rotate(135deg);
font-size: 22px;
top: 2px;
left: 4px;
}
.call-button-cancel.x-btn.x-btn-pressed,
.call-button-cancel-focus,
.call-button-cancel-over {
background-color: darkred;
}
.call-button-accept.x-btn.x-btn-pressed,
.call-button-accept-focus,
.call-button-accept-over {
background-color: darkgreen;
}
#call-local-preview {
width: 100%;
}
.x-panel-body-default {
label.call-number-label {
font-size: 16px;
font-weight: bold;
}
}

@ -1,18 +1,51 @@
Ext.define('NgcpCsc.view.common.rtc.CallPanel', {
extend: 'Ext.form.Panel',
alias: 'widget.call-panel',
layout: 'center',
padding: '60 0 0 0',
bind: {
hidden: '{!callPanel}'
hidden: '{!callEnabled}'
},
items: [{
bind: {
hidden: '{!outgoingCallPending}'
},
xtype: 'label',
userCls: 'rtc-outgoing-label',
html: Ngcp.csc.locales.rtc.start_call[localStorage.getItem('languageSelected')] + Ngcp.csc.animations.loading_dots
layout : {
type : 'vbox',
align : 'center',
pack: 'center',
},
bind: {
hidden: '{!outgoingCall}'
},
items: [
{
bind: {
text: '{callActionLabel}'
},
xtype: 'label',
margin: '0 0 20 0'
},
{
bind: {
text: '{numberToCall}'
},
xtype: 'label',
margin: '0 0 20 0',
userCls: 'call-number-label',
},
{
xtype: 'button',
text: '',
userCls: 'call-button call-button-cancel call-button-hangup',
overCls: 'call-button-cancel-over',
focusCls: 'call-button-cancel-focus',
width: 40,
height: 40,
html: '<i class="x-fa fa-phone call-icon-cancel"></i>',
listeners: {
click: 'cancelOutgoingCall'
}
}
]},
{
bind: {
hidden: '{!incomingCallPending}'

@ -27,12 +27,26 @@ Ext.define('NgcpCsc.view.common.rtc.RtcController', {
},
initCall: function(mediaType) {
var $ct = this;
var $vm = this.getViewModel();
var callee = $vm.get('numberToCall');
var network = $vm.get('rtcEngineNetwork');
var localMediaStream = $vm.get('rtcEngineLocalMediaStream');
if (callee !== '' && callee !== null && callee !== void(0)) {
if(localMediaStream !== null) {
localMediaStream.stop();
$vm.set('rtcEngineLocalMediaStream', null);
}
this.createMedia(mediaType).then(function (localMediaStream) {
// Todo: attache stream to video element
// if(mediaType === 'video') {
// cdk.MediaElementHelper.attachStreamToDomNode(
// document.getElementById('call-local-preview'),
// localMediaStream
// );
// }
var call = network.call(callee, { localMediaStream: localMediaStream });
call.onPending(function () { $ct.outgoingPending(); })
.onAccepted(function () { $ct.outgoingAccepted(); })
@ -96,7 +110,7 @@ Ext.define('NgcpCsc.view.common.rtc.RtcController', {
vm.set('title', Ext.String.format(Ngcp.csc.locales.rtc.calling[localStorage.getItem('languageSelected')], number));
vm.set('thumbnail', record.get('thumbnail') || this.getViewModel().get('defaultThumbnail'));
vm.set('status', Ext.String.format(Ngcp.csc.locales.rtc.calling[localStorage.getItem('languageSelected')] + ' ...', number));
vm.set('callEnabled', false);
vm.set('callPanelEnabled', false);
vm.set('micEnabled', false);
vm.set('phoneComposerHidden', true);
vm.set('faxComposerHidden', true);
@ -146,9 +160,6 @@ Ext.define('NgcpCsc.view.common.rtc.RtcController', {
vm.set('callPanelHidden', true);
fieldToFocus = this.lookupReference('smsTextArea');
break;
case 'incomingCall':
me.showIncomingCallPendingState();
break;
}
panel.show().expand();
if (fieldToFocus) {
@ -221,7 +232,7 @@ Ext.define('NgcpCsc.view.common.rtc.RtcController', {
setTimeout(function() {
var seconds = minutes = hours = 0;
me.stopRingSound();
vm.set('callEnabled', true);
vm.set('callPanelEnabled', true);
vm.set('micEnabled', true);
me.startMedia(audioOn, videoOn);
@ -264,7 +275,7 @@ Ext.define('NgcpCsc.view.common.rtc.RtcController', {
},
toggleCall: function(btn) {
if (btn.pressed) { // this can be also checked against vm.get('callEnabled')
if (btn.pressed) { // this can be also checked against vm.get('callPanelEnabled')
this.emulateCall(true, false);
} else {
this.endCall();
@ -439,22 +450,22 @@ Ext.define('NgcpCsc.view.common.rtc.RtcController', {
var rtcNetwork = rtcClient.getNetworkByTag('sip');
$vm.set('rtcEngineNetwork', rtcNetwork);
rtcNetwork.onConnect(function() {
$vm.set('callEnabled', true);
$vm.set('callPanelEnabled', true);
}).onIncomingCall(function(call) {
call.onPending(function(){ $ct.incomingCallPending(); })
.onRemoteMedia(function(stream){ $ct.incomingRemoteMedia(stream); })
$ct.incomingCallPending();
call.onRemoteMedia(function(stream){ $ct.incomingRemoteMedia(stream); })
.onRemoteMediaEnded(function(){ $ct.incomingRemoteMediaEnded(); })
.onEnded(function(){ $ct.incomingRemoteMediaEnded() });
}).onDisconnect(function(){
$vm.set('callEnabled', false);
$vm.set('callPanelEnabled', false);
$vm.set('callDisabledReason', rtcNetwork.disconnectReason);
});
}).onDisconnect(function(){
$vm.set('callEnabled', false);
$vm.set('callPanelEnabled', false);
$vm.set('callDisabledReason', rtcClient.disconnectReason);
});
}).catch(function(err){
$vm.set('callEnabled', false);
$vm.set('callPanelEnabled', false);
$vm.set('callDisabledReason', err.message);
console.error(err);
});
@ -471,10 +482,12 @@ Ext.define('NgcpCsc.view.common.rtc.RtcController', {
outgoingRingingStart: function() {
console.log('outgoingCallRingingStart');
this.showOutgoingCallRingingState();
},
outgoingRingingStop: function() {
console.log('outgoingCallRingingStop');
this.stopRingSound();
},
outgoingRemoteMedia: function(stream) {
@ -491,6 +504,8 @@ Ext.define('NgcpCsc.view.common.rtc.RtcController', {
},
incomingCallPending: function() {
this.getView().show().expand();
this.showIncomingCallPendingState();
console.log('incomingCallPending');
},
@ -510,13 +525,38 @@ Ext.define('NgcpCsc.view.common.rtc.RtcController', {
callEnded: function() {
var $ct = this;
var $vm = $ct.getViewModel();
var localMediaStream = $vm.get('rtcEngineLocalMediaStream');
if(localMediaStream !== null) {
localMediaStream.stop();
$vm.set('rtcEngineLocalMediaStream', null);
},
cancelOutgoingCall: function() {
var call = this.getViewModel().get('rtcEngineCall');
var mediaStream = this.getViewModel().get('rtcEngineLocalMediaStream');
this.getViewModel().set('phoneComposerHidden', false);
this.getViewModel().set('callPending', false);
this.getViewModel().set('callRinging', false);
this.stopRingSound();
if(call !== null) {
call.end();
}
if(mediaStream !== null) {
mediaStream.stop();
}
},
showOutgoingCallPendingState: function() {
this.getViewModel().set('callPending', true);
this.getViewModel().set('callActionLabel', 'Try to call');
this.getViewModel().set('phoneComposerHidden', true);
},
showOutgoingCallRingingState: function() {
this.getViewModel().set('callRinging', true);
this.getViewModel().set('callPending', false);
this.getViewModel().set('callActionLabel', 'Ringing');
this.playRingSound();
},
// parameter state true causes the class for the background color change to
// be added, and parameter state false causes the class to be removed
setRtcpanelTitleColor: function (state) {
// parameter true to change color, and false to revert
var rtcpanel = Ext.getCmp('rtcpanel');
@ -536,20 +576,13 @@ Ext.define('NgcpCsc.view.common.rtc.RtcController', {
sound.currentTime = 0;
},
showOutgoingCallPendingState: function() {
var vm = this.getViewModel();
vm.set('callPanel', true);
vm.set('outgoingCallPending', true);
vm.set('phoneComposerHidden', true);
},
showIncomingCallPendingState: function (caller, type) {
showIncomingCallPendingState: function () {
// @hherzog: I added parameters for caller number and media type for
// now, but they can be replaced with cdk method calls in variable
// declaration below if you prefer
var vm = this.getViewModel();
var caller = caller || '+4312345';
var type = type || 'audio';
var caller = '+4312345';
var type = 'audio';
vm.set('callPanel', true);
vm.set('incomingCallPending', true);
vm.set('phoneComposerHidden', true);

@ -16,7 +16,7 @@ Ext.define('NgcpCsc.view.rtc.RtcModel', {
smsComposerHidden: true,
phoneKeyboardHidden: true,
incomingCallHidden: true,
callEnabled: false,
callPanelEnabled: false,
connected: false,
micEnabled: false,
videoEnabled: false,
@ -36,6 +36,9 @@ Ext.define('NgcpCsc.view.rtc.RtcModel', {
rtcEngineClient: null,
rtcEngineSession: null,
callPanel: true,
callActionLabel: '',
callPending: false,
callRinging: false,
outgoingCallPending: false,
incomingCallPending: false,
incomingType: '',
@ -54,7 +57,31 @@ Ext.define('NgcpCsc.view.rtc.RtcModel', {
return get('numberToCall').length < 1;
},
setuserCls:function(get){
return get('callEnabled') ? '' : 'fa-rotate-180';
return get('callPanelEnabled') ? '' : 'fa-rotate-180';
},
callEnabled: {
bind: {
callPending: '{callPending}',
callRinging: '{callRinging}',
incomingCallPending: '{incomingCallPending}'
},
get: function (data) {
return data.callPending || data.callRinging || data.incomingCallPending;
}
},
outgoingCall: {
bind: {
callPending: '{callPending}',
callRinging: '{callRinging}'
},
get: function (data) {
return data.callPending || data.callRinging;
}
},
callLocalPreview: {
get: function (data) {
return data.rtcEngineLocalMediaStream && data.rtcEngineLocalMediaStream.hasVideo();
}
}
}
});

@ -35,19 +35,29 @@ Ext.define('NgcpCsc.view.common.rtc.composer.Phone', {
xtype: 'container',
items: [{
xtype: 'button',
text: Ngcp.csc.locales.rtc.sendAudio[localStorage.getItem('languageSelected')],
iconCls: Ngcp.csc.icons.microphone,
text: '',
margin: '0 10 0 0',
listeners: {
click: 'sendAudio'
}
},
userCls: 'call-button call-button-accept',
overCls: 'call-button-accept-over',
focusCls: 'call-button-accept-focus',
width: 40,
height: 40,
html: '<i class="x-fa fa-phone icon-large"></i><i class="x-fa fa-microphone icon-small"></i>'
}, {
xtype: 'button',
text: Ngcp.csc.locales.rtc.sendVideo[localStorage.getItem('languageSelected')],
iconCls: Ngcp.csc.icons.video,
text: '',
listeners: {
click: 'sendVideo'
}
},
userCls: 'call-button call-button-accept',
overCls: 'call-button-accept-over',
focusCls: 'call-button-accept-focus',
width: 40,
height: 40,
html: '<i class="x-fa fa-phone icon-large"></i><i class="x-fa fa-video-camera icon-small"></i>'
}]
}]
}, {

Loading…
Cancel
Save