How to send confirmation messages between clients - PeerJS - meteor

I am using PeerJS to make audio calls between clients and it works. I am showing a Dialog to the user who is receiving a call with two buttons (Answer, and Decline). As shown below:
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
peer.on('call', function(call) {
// sweetAlert("BINGO")
bootbox.dialog({
className: "modal-danger nonumpad",
closeButton: false,
animate: true,
title: 'Call Recieved',
message: "Accept or Decline",
onEscape: null,
buttons: {
pickup: {
label: "<i class=\"fa fa-phone\"></i> Answer",
className: "btn-warning btn-lg pull-left",
callback: function(){
return false
}
},
hangup: {
label: "<i class=\"fa fa-phone\"></i> Decline",
className: "btn-warning btn-lg pull-left",
callback: function(){
return false;
}
}
}
});
});
My question here is, how can I send the action to the other user (who is making the call)?
The reason is because I want to show timer once the receiver press on "Answer" or show dialog to inform the caller that the receiver has pressed decline

From the PeerJS documentation:
Data connections
Connect
var conn = peer.connect('another-peers-id');
conn.on('open', function(){
conn.send('hi!');
});
Receive
peer.on('connection', function(conn) {
conn.on('data', function(data){
// Will print 'hi!'
console.log(data);
});
});
You can get the id of the peer making the call via call.peer and then open a data connection to send a message ('accept', 'decline', etc) to the caller

Related

I want to save device battery status details to firebase when every time user sign in and sign out in app IONIC 3

I can get battery status using Battery
getBatteryStatus() {
// watch change in battery status
this.subscription = this.oBatteryStatus.onChange().subscribe(
(status: BatteryStatusResponse) => {
this.currentBatteryLevel = status.level;
this.currentBatteryIsPlugged = status.isPlugged;
this.oUser_log_model.user_id = this.loggedInUserId;
this.oUser_log_model.user_device_battery_status = this.currentBatteryLevel;
this.oUser_log_model.user_device_battery_is_plugged = this.currentBatteryIsPlugged;
this.oAngularFireDatabase.database.ref('User_Log').set(this.oUser_log_model).then(() => {
let toast3 = this.oToastController.create({
message: 'Successfully Saved..',
duration: 3000,
position: 'top',
cssClass: 'dark-trans',
closeButtonText: 'OK',
showCloseButton: true
});
toast3.present();
})
});
}
if i call this function on button click event it is working fine. but i want call this function every time user login to app and logout from app .I have tried to call this getBatteryStatus() function in initializeApp() function.but it is not saving battery status to firebase.
initializeApp() {
this.platform.ready().then(() => {
// I HAVE TRIED TO CALL GET BATTERY STATUS FUNCTION FROM HERE
// watch network for a disconnect
let disconnectSubscription = this.oNetwork.onDisconnect().subscribe(() => {
let toast = this.oToastController.create({
message: 'You are offline ..',
duration: 3000,
position: 'top',
cssClass: 'dark-trans',
closeButtonText: 'OK',
showCloseButton: true
});
toast.present();
});
// watch network for a connection
let connectSubscription = this.oNetwork.onConnect().subscribe(() => {
let toast = this.oToastController.create({
message: 'Get back to online .. ',
duration: 3000,
position: 'top',
cssClass: 'dark-trans',
closeButtonText: 'OK',
showCloseButton: true
});
toast.present();
// We just got a connection but we need to wait briefly
// before we determine the connection type. Might need to wait.
// prior to doing any api requests as well.
setTimeout(() => {
if (this.oNetwork.type === 'wifi') {
let toast = this.oToastController.create({
message: 'Connected to the wifi',
duration: 3000,
position: 'top',
cssClass: 'dark-trans',
closeButtonText: 'OK',
showCloseButton: true
});
toast.present();
}
}, 3000);
});
// this.statusBar.styleDefault();
this.statusBar.styleLightContent();
this.splashScreen.hide();
});
}

How to send data between caller and receiver in PeerJS?

I am building audio calling app and I am struggling to send data between the call receiver to the caller. Here is my code (In the call receiver):
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
peer.on('call', function(call) {
console.log("call.peer: " + call.peer)
conn = peer.connect(call.peer)
bootbox.dialog({
className: "modal-danger nonumpad",
closeButton: false,
animate: true,
title: 'Call Recieved',
message: "Accept or Decline",
onEscape: null,
buttons: {
pickup: {
label: "<i class=\"fa fa-phone\"></i> Answer",
className: "btn-warning btn-lg pull-left",
callback: function(){
conn.send('ACCEPT') // send Accept to the caller
return false
}
},
hangup: {
label: "<i class=\"fa fa-phone\"></i> Decline",
className: "btn-warning btn-lg pull-left",
callback: function(){
conn.send('DECLINED') // Send Decline to the caller
return false;
}
}
}
});
});
With the above code, when I make the call, dialog appears and when I press one of the options, data should be sent to the caller.
Here is the caller code, who receives the above sent data:
peer.on('open', function () {
Meteor.users.update(Meteor.userId(), { $set: { 'profile.peerId': peer.id } })
console.log(Meteor.user().profile.peerId);
peer.on('connection', function(conn) {
conn.on('data', function(data){
console.log(data);
});
});
});
Nothing is printed to the console.
What am I doing wrong here?
The connection event isn't important. You want to listen to the call event like this
peer.on('call', function (incomingCall) {
Hopefully that will work better for you.
I wouldn't update the user record with the peerId, Meteor don't recommend using it, as the authentication system also writes to it. I have used dburles:presence successfully, and in fact passed the presence id to peerjs to use (rather than letting peerjs allocate one)

Adding participants in a group chat

I am trying to add participants in a group chat but I am not getting any error but nothing is happening here is my code:
Meteor.methods({
addMember: function(groupId,email){
Groups.update({_id:groupId},
{$addToSet: {participants:{"emails":email}}}
);
}
});
My event:
Template.editGroup.events({
'click .add': function() {
var id = this._id;
swal({
title: "An input!",
text: "Add an email address:",
type: "input",
showCancelButton: true,
closeOnConfirm: false,
animation: "slide-from-top",
inputPlaceholder: "Add email address"
},
function(email) {
if (email === false) return false;
if (email === "") {
swal.showInputError("You need to add email address!");
return false
}
Meteor.call("addMember",id,email)
})
}
})
The id is the first parameter of a meteor collection update.
See in: https://docs.meteor.com/api/collections.html#Mongo-Collection-update
try it
Meteor.methods({
addMember: function(groupId,email){
Groups.update(groupId,
{$addToSet: {participants:{"emails":email}}}
);
}
});
You should be using dot notation to update the emails field inside participants.
https://docs.mongodb.com/v3.2/core/document/#document-dot-notation
Just replace {$addToSet: {participants:{"emails":email}}} with
{$addToSet: {"participants.emails":email}}

NoUiSlider getting initial value from collection field and update on change - Meteor

EDIT: The question is no longer valid as I stopped using the NoUiSlider package. See my answer below to see what I've done for this.
I'm trying to have a live progress bar for each task and when I enter the page, I want the slider to have the start value from the collection field.
Currently it doesn't even show up. Once I change "start: progressNow" to "start:0", it only works on the client side and doesn't save/change anything on the DB.
Inside methods:
addTask: function (projectId, text, description, due, progress) {
check(projectId, String);
check(text, String);
if (!this.userId) {
throw new Meteor.Error(403, 'not-authorized');
}
Tasks.insert({
text: text,
createdAt: new Date(),
owner: this.userId,
username: Meteor.user().username || Meteor.user().profile.name,
projectId: projectId,
taskDescription: description,
due: due,
progress: 0
});
},
Event and rendered:
Template.task.events({
"change .slider": function () {
var progressVal = this.noUiSlider.value;
Tasks.update({
progress: progressVal
})
},
});
Template.task.rendered = function () {
var progressNow = return Tasks.findOne({_id: this._id}).progress;
this.$('.slider').noUiSlider({
start: progressNow,
connect: "lower",
step: 0,
format: wNumb({
decimals: 0,
}),
range: {
'smin': 0,
'max': 100
}
});
this.$('.slider').Link('lower').to(this.$('.range'));
};
Instead of using NoUiSlider package, I just made it with HTML5.
When a task is created, progress is automatically 0 (which is basically one line in task creation method.
Tasks.insert({
//other fields
progress: 0,
});
Simple HTML - {{progress}} is simply the progress field value.
<form>
<input type="range" value="{{progress}}" class="progress" name="progress" min="0" max="100">
</form>
<span class="spn-btn">{{progress}}</span>
Inside methods:
updateProgress: function(taskId, progress) {
Tasks.update(taskId,{
$set: { progress:progress}
});
}
Inside template events:
'change input[type="range"]': function (e,t) {
var progress = e.target.value;
Meteor.call("updateProgress", this._id, progress);
console.log('success!');
}
Cheers.

IonicPopup.show() - shake on empty values instead of "nothing"

I took sample code for the IonicPopup and I've modified the wifi password entry to be a username and password entry. It works as expected, but if you click the Login button without entering a username or password, all that happens is e.preventDefault().
Is there a way I can add an animation to the popup, perhaps a "shake" animation, if either field is left blank?
$scope.promptLogin = function() {
$scope.data = {};
// An elaborate, custom popup
var myPopup = $ionicPopup.show({
template: '<input type="text" placeholder="Username" ng-model="data.user"><br><input type="password" placeholder="Password" ng-model="data.pass">',
title: 'Enter Credentials',
subTitle: '',
scope: $scope,
buttons: [
{ text: 'Cancel' },
{
text: '<b>Login</b>',
type: 'button-positive',
onTap: function(e) {
if (!$scope.data.user || !$scope.data.pass) {
//don't allow the user to close unless he enters a user and pass
e.preventDefault();
} else {
//console.log($scope.data.user + " - " + $scope.data.pass);
}
}
}
]
});
};

Resources