Skip to content

Commit

Permalink
Bug 1102841 - Implement Cancel and Block a call for incoming direct c…
Browse files Browse the repository at this point in the history
…alls. r=abr, a=lmandel
  • Loading branch information
mikedeboer committed Nov 24, 2014
1 parent 10012fe commit 2b5c0bf
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 10 deletions.
13 changes: 13 additions & 0 deletions browser/components/loop/MozLoopAPI.jsm
Expand Up @@ -656,6 +656,19 @@ function injectLoopAPI(targetWindow) {
MozLoopService.startDirectCall(contact, callType);
}
},

/**
* @see MozLoopInternal#blockDirectCaller
*/
blockDirectCaller: {
enumerable: true,
writable: true,
value: function(callerId, callback) {
MozLoopService.blockDirectCaller(callerId, err => {
callback(cloneValueInto(err, targetWindow));
});
}
},
};

function onStatusChanged(aSubject, aTopic, aData) {
Expand Down
51 changes: 51 additions & 0 deletions browser/components/loop/MozLoopService.jsm
Expand Up @@ -855,6 +855,50 @@ let MozLoopServiceInternal = {
return true;
},

/**
* Block a caller so it will show up in the contacts list as a blocked contact.
* If the contact is not yet part of the users' contacts list, it will be added
* as a blocked contact directly.
*
* @param {String} callerId Email address or phone number that may identify
* the caller as an existing contact
* @param {Function} callback Function that will be invoked once the operation
* has completed. When an error occurs, it will be
* passed as its first argument
*/
blockDirectCaller: function(callerId, callback) {
let field = callerId.contains("@") ? "email" : "tel";
Task.spawn(function* () {
// See if we can find the caller in our database.
let contacts = yield LoopContacts.promise("search", {
q: callerId,
field: field
});

let contact;
if (contacts.length) {
for (contact of contacts) {
yield LoopContacts.promise("block", contact._guid);
}
} else {
// If the contact doesn't exist yet, add it as a blocked contact.
contact = {
id: MozLoopService.generateUUID(),
name: [callerId],
category: ["local"],
blocked: true
};
// Add the phone OR email field to the contact.
contact[field] = [{
pref: true,
value: callerId
}];

yield LoopContacts.promise("add", contact);
}
}).then(callback, callback);
},

/**
* Open call progress websocket and terminate with a reason of busy
* the server.
Expand Down Expand Up @@ -1682,4 +1726,11 @@ this.MozLoopService = {
startDirectCall: function(contact, callType) {
MozLoopServiceInternal.startDirectCall(contact, callType);
},

/**
* @see MozLoopInternal#blockDirectCaller
*/
blockDirectCaller: function(callerId, callback) {
return MozLoopServiceInternal.blockDirectCaller(callerId, callback);
},
};
26 changes: 21 additions & 5 deletions browser/components/loop/content/js/conversation.js
Expand Up @@ -17,6 +17,9 @@ loop.conversation = (function(mozL10n) {
var OutgoingConversationView = loop.conversationViews.OutgoingConversationView;
var CallIdentifierView = loop.conversationViews.CallIdentifierView;

// Matches strings of the form "<nonspaces>@<nonspaces>" or "+<digits>"
var EMAIL_OR_PHONE_RE = /^(:?\S+@\S+|\+\d+)$/;

var IncomingCallView = React.createClass({displayName: 'IncomingCallView',
mixins: [sharedMixins.DropdownMenuMixin],

Expand Down Expand Up @@ -498,14 +501,27 @@ loop.conversation = (function(mozL10n) {
declineAndBlock: function() {
navigator.mozLoop.stopAlerting();
var token = this.props.conversation.get("callToken");
this.props.client.deleteCallUrl(token,
this.props.conversation.get("sessionType"),
function(error) {
var callerId = this.props.conversation.get("callerId");

// If this is a direct call, we'll need to block the caller directly.
if (callerId && EMAIL_OR_PHONE_RE.test(callerId)) {
navigator.mozLoop.blockDirectCaller(callerId, function(err) {
// XXX The conversation window will be closed when this cb is triggered
// figure out if there is a better way to report the error to the user
// (bug 1048909).
console.log(error);
// (bug 1103150).
console.log(err.fileName + ":" + err.lineNumber + ": " + err.message);
});
} else {
this.props.client.deleteCallUrl(token,
this.props.conversation.get("sessionType"),
function(error) {
// XXX The conversation window will be closed when this cb is triggered
// figure out if there is a better way to report the error to the user
// (bug 1048909).
console.log(error);
});
}

this._declineCall();
},

Expand Down
26 changes: 21 additions & 5 deletions browser/components/loop/content/js/conversation.jsx
Expand Up @@ -17,6 +17,9 @@ loop.conversation = (function(mozL10n) {
var OutgoingConversationView = loop.conversationViews.OutgoingConversationView;
var CallIdentifierView = loop.conversationViews.CallIdentifierView;

// Matches strings of the form "<nonspaces>@<nonspaces>" or "+<digits>"
var EMAIL_OR_PHONE_RE = /^(:?\S+@\S+|\+\d+)$/;

var IncomingCallView = React.createClass({
mixins: [sharedMixins.DropdownMenuMixin],

Expand Down Expand Up @@ -498,14 +501,27 @@ loop.conversation = (function(mozL10n) {
declineAndBlock: function() {
navigator.mozLoop.stopAlerting();
var token = this.props.conversation.get("callToken");
this.props.client.deleteCallUrl(token,
this.props.conversation.get("sessionType"),
function(error) {
var callerId = this.props.conversation.get("callerId");

// If this is a direct call, we'll need to block the caller directly.
if (callerId && EMAIL_OR_PHONE_RE.test(callerId)) {
navigator.mozLoop.blockDirectCaller(callerId, function(err) {
// XXX The conversation window will be closed when this cb is triggered
// figure out if there is a better way to report the error to the user
// (bug 1048909).
console.log(error);
// (bug 1103150).
console.log(err.fileName + ":" + err.lineNumber + ": " + err.message);
});
} else {
this.props.client.deleteCallUrl(token,
this.props.conversation.get("sessionType"),
function(error) {
// XXX The conversation window will be closed when this cb is triggered
// figure out if there is a better way to report the error to the user
// (bug 1048909).
console.log(error);
});
}

this._declineCall();
},

Expand Down
Expand Up @@ -72,6 +72,8 @@ loop.store = (function() {
// Call Connection information
// The call id from the loop-server
callId: undefined,
// The caller id of the contacting side
callerId: undefined,
// The connection progress url to connect the websocket
progressURL: undefined,
// The websocket token that allows connection to the progress url
Expand Down

0 comments on commit 2b5c0bf

Please sign in to comment.