2013-10-16 13:48:00 -04:00
|
|
|
/*global app, client, URL, me*/
|
2013-08-29 23:38:28 -04:00
|
|
|
"use strict";
|
|
|
|
|
2013-09-03 22:18:31 -04:00
|
|
|
var HumanModel = require('human-model');
|
2013-10-16 13:48:00 -04:00
|
|
|
var getUserMedia = require('getusermedia');
|
2013-08-20 13:45:06 -04:00
|
|
|
var Contacts = require('./contacts');
|
2013-10-15 15:15:25 -04:00
|
|
|
var Calls = require('./calls');
|
2013-08-29 23:38:28 -04:00
|
|
|
var Contact = require('./contact');
|
2013-09-16 19:12:00 -04:00
|
|
|
var MUCs = require('./mucs');
|
|
|
|
var MUC = require('./muc');
|
2013-10-16 13:48:40 -04:00
|
|
|
var ContactRequests = require('./contactRequests');
|
2015-03-20 15:36:40 -04:00
|
|
|
var avatarHandler = require('../helpers/avatarHandler');
|
|
|
|
var crypto = require('crypto');
|
2013-06-03 18:51:30 -04:00
|
|
|
|
2013-09-05 19:53:23 -04:00
|
|
|
module.exports = HumanModel.define({
|
2013-10-15 17:48:39 -04:00
|
|
|
initialize: function (opts) {
|
2015-03-16 08:43:20 -04:00
|
|
|
this.setAvatar(opts ? opts.avatarID : null);
|
2013-10-15 17:48:39 -04:00
|
|
|
|
|
|
|
this.bind('change:jid', this.load, this);
|
2013-09-14 05:12:57 -04:00
|
|
|
this.bind('change:hasFocus', function () {
|
|
|
|
this.setActiveContact(this._activeContact);
|
|
|
|
}, this);
|
2013-10-15 19:21:22 -04:00
|
|
|
this.calls.bind('add remove reset', this.updateActiveCalls, this);
|
2013-10-15 17:48:39 -04:00
|
|
|
this.bind('change:avatarID', this.save, this);
|
|
|
|
this.bind('change:status', this.save, this);
|
|
|
|
this.bind('change:rosterVer', this.save, this);
|
2015-01-25 14:21:57 -05:00
|
|
|
this.bind('change:soundEnabled', this.save, this);
|
2013-09-27 12:47:54 -04:00
|
|
|
this.contacts.bind('change:unreadCount', this.updateUnreadCount, this);
|
2013-09-26 23:19:46 -04:00
|
|
|
app.state.bind('change:active', this.updateIdlePresence, this);
|
2014-01-23 19:34:21 -05:00
|
|
|
app.state.bind('change:deviceIDReady', this.registerDevice, this);
|
2013-09-11 17:58:39 -04:00
|
|
|
},
|
2013-10-15 17:48:39 -04:00
|
|
|
props: {
|
2013-09-10 03:57:01 -04:00
|
|
|
jid: ['object', true],
|
2013-12-20 06:39:06 -05:00
|
|
|
status: 'string',
|
|
|
|
avatarID: 'string',
|
|
|
|
rosterVer: 'string',
|
|
|
|
nick: 'string'
|
2013-10-15 17:48:39 -04:00
|
|
|
},
|
|
|
|
session: {
|
2014-01-05 07:19:46 -05:00
|
|
|
avatar: 'string',
|
|
|
|
connected: ['bool', false, false],
|
|
|
|
shouldAskForAlertsPermission: ['bool', false, false],
|
|
|
|
hasFocus: ['bool', false, false],
|
|
|
|
_activeContact: 'string',
|
2015-01-25 14:21:57 -05:00
|
|
|
stream: 'object',
|
|
|
|
soundEnabled: ['bool', false, true],
|
2013-06-03 18:51:30 -04:00
|
|
|
},
|
2013-08-20 13:45:06 -04:00
|
|
|
collections: {
|
2013-09-16 19:12:00 -04:00
|
|
|
contacts: Contacts,
|
2013-10-16 13:48:40 -04:00
|
|
|
contactRequests: ContactRequests,
|
2013-10-15 15:15:25 -04:00
|
|
|
mucs: MUCs,
|
|
|
|
calls: Calls
|
2013-08-20 13:45:06 -04:00
|
|
|
},
|
2013-10-16 13:48:00 -04:00
|
|
|
derived: {
|
2013-12-20 06:39:06 -05:00
|
|
|
displayName: {
|
|
|
|
deps: ['nick', 'jid'],
|
|
|
|
fn: function () {
|
|
|
|
return this.nick || this.jid.bare;
|
|
|
|
}
|
|
|
|
},
|
2013-10-16 13:48:00 -04:00
|
|
|
streamUrl: {
|
|
|
|
deps: ['stream'],
|
|
|
|
fn: function () {
|
|
|
|
if (!this.stream) return '';
|
|
|
|
return URL.createObjectURL(this.stream);
|
|
|
|
}
|
2015-02-09 10:20:28 -05:00
|
|
|
},
|
|
|
|
organization: {
|
|
|
|
deps: ['orga'],
|
|
|
|
fn: function () {
|
2015-04-07 10:12:28 -04:00
|
|
|
return app.serverConfig().name || 'Kaiwa';
|
2015-02-09 10:20:28 -05:00
|
|
|
}
|
|
|
|
},
|
2015-01-25 14:21:57 -05:00
|
|
|
soundEnabledClass: {
|
|
|
|
deps: ['soundEnabled'],
|
|
|
|
fn: function () {
|
|
|
|
return this.soundEnabled ? "primary" : "secondary";
|
|
|
|
}
|
|
|
|
},
|
2015-03-19 11:41:32 -04:00
|
|
|
isAdmin: {
|
|
|
|
deps: ['jid'],
|
|
|
|
fn: function () {
|
|
|
|
return this.jid.local === SERVER_CONFIG.admin ? 'meIsAdmin' : '';
|
|
|
|
}
|
|
|
|
}
|
2013-10-16 13:48:00 -04:00
|
|
|
},
|
2013-09-11 23:59:50 -04:00
|
|
|
setActiveContact: function (jid) {
|
|
|
|
var prev = this.getContact(this._activeContact);
|
|
|
|
if (prev) {
|
|
|
|
prev.activeContact = false;
|
|
|
|
}
|
|
|
|
var curr = this.getContact(jid);
|
|
|
|
if (curr) {
|
|
|
|
curr.activeContact = true;
|
|
|
|
curr.unreadCount = 0;
|
2014-01-05 07:19:46 -05:00
|
|
|
this._activeContact = curr.id;
|
2013-09-11 23:59:50 -04:00
|
|
|
}
|
|
|
|
},
|
2015-02-26 16:59:05 -05:00
|
|
|
getName: function () {
|
|
|
|
return this.displayName;
|
|
|
|
},
|
|
|
|
getNickname: function () {
|
|
|
|
return this.displayName != this.nick ? this.nick : '';
|
|
|
|
},
|
|
|
|
getAvatar: function () {
|
|
|
|
return this.avatar;
|
|
|
|
},
|
2014-01-01 23:39:06 -05:00
|
|
|
setAvatar: function (id, type, source) {
|
2015-03-20 15:36:40 -04:00
|
|
|
if (!this.avatar) this.avatar = avatarHandler.getGravatar('').uri;
|
|
|
|
|
2013-09-18 19:24:40 -04:00
|
|
|
var self = this;
|
2015-03-20 15:36:40 -04:00
|
|
|
avatarHandler.fetch('', id, type, source, function (avatar) {
|
2013-09-19 19:57:37 -04:00
|
|
|
self.avatarID = avatar.id;
|
|
|
|
self.avatar = avatar.uri;
|
2013-09-18 19:24:40 -04:00
|
|
|
});
|
|
|
|
},
|
2015-03-20 15:36:40 -04:00
|
|
|
publishAvatar: function (data) {
|
|
|
|
if (!data) data = this.avatar;
|
|
|
|
if (!data || data.indexOf('https://') != -1) return;
|
|
|
|
|
|
|
|
var resampler = new Resample(data, 80, 80, function (data) {
|
|
|
|
var b64Data = data.split(',')[1];
|
|
|
|
var id = crypto.createHash('sha1').update(atob(b64Data)).digest('hex');
|
|
|
|
app.storage.avatars.add({id: id, uri: data});
|
|
|
|
client.publishAvatar(id, b64Data, function (err, res) {
|
|
|
|
if (err) return;
|
|
|
|
client.useAvatars([{
|
|
|
|
id: id,
|
|
|
|
width: 80,
|
|
|
|
height: 80,
|
|
|
|
type: 'image/png',
|
|
|
|
bytes: b64Data.length
|
|
|
|
}]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
},
|
2015-03-19 11:41:32 -04:00
|
|
|
hasLdapUsers: function () {
|
|
|
|
return app.ldapUsers.length > 0 ? 'hasLdapUsers' : '';
|
|
|
|
},
|
2015-01-25 14:21:57 -05:00
|
|
|
setSoundNotification: function(enable) {
|
|
|
|
this.soundEnabled = enable;
|
|
|
|
},
|
2013-08-20 13:45:06 -04:00
|
|
|
getContact: function (jid, alt) {
|
2015-02-26 16:59:05 -05:00
|
|
|
if (typeof jid === 'string') {
|
|
|
|
if (SERVER_CONFIG.domain && jid.indexOf('@') == -1) jid += '@' + SERVER_CONFIG.domain;
|
|
|
|
jid = new client.JID(jid);
|
|
|
|
}
|
2013-09-11 23:59:50 -04:00
|
|
|
if (typeof alt === 'string') alt = new client.JID(alt);
|
|
|
|
|
2013-08-20 13:45:06 -04:00
|
|
|
if (this.isMe(jid)) {
|
|
|
|
jid = alt || jid;
|
|
|
|
}
|
2014-01-05 07:19:46 -05:00
|
|
|
|
|
|
|
if (!jid) return;
|
|
|
|
|
2013-10-15 22:16:09 -04:00
|
|
|
return this.contacts.get(jid.bare) ||
|
|
|
|
this.mucs.get(jid.bare) ||
|
|
|
|
this.calls.findWhere('jid', jid);
|
2013-08-20 13:45:06 -04:00
|
|
|
},
|
2013-08-29 23:38:28 -04:00
|
|
|
setContact: function (data, create) {
|
|
|
|
var contact = this.getContact(data.jid);
|
2013-09-10 03:57:01 -04:00
|
|
|
data.jid = data.jid.bare;
|
|
|
|
|
2013-08-29 23:38:28 -04:00
|
|
|
if (contact) {
|
|
|
|
contact.set(data);
|
|
|
|
contact.save();
|
|
|
|
} else if (create) {
|
|
|
|
contact = new Contact(data);
|
2013-09-11 17:58:39 -04:00
|
|
|
contact.inRoster = true;
|
|
|
|
contact.owner = this.jid.bare;
|
2013-08-29 23:38:28 -04:00
|
|
|
contact.save();
|
|
|
|
this.contacts.add(contact);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
removeContact: function (jid) {
|
2015-04-04 09:56:22 -04:00
|
|
|
var self = this;
|
|
|
|
client.removeRosterItem(jid, function(err, res) {
|
|
|
|
var contact = self.getContact(jid);
|
|
|
|
self.contacts.remove(contact.jid);
|
|
|
|
app.storage.roster.remove(contact.storageId);
|
|
|
|
});
|
2013-08-29 23:38:28 -04:00
|
|
|
},
|
2013-10-15 17:48:39 -04:00
|
|
|
load: function () {
|
2013-09-11 17:58:39 -04:00
|
|
|
if (!this.jid.bare) return;
|
|
|
|
|
|
|
|
var self = this;
|
|
|
|
|
2013-10-15 17:48:39 -04:00
|
|
|
app.storage.profiles.get(this.jid.bare, function (err, profile) {
|
|
|
|
if (!err) {
|
2015-02-09 10:20:28 -05:00
|
|
|
self.nick = self.jid.local;
|
2013-10-15 17:48:39 -04:00
|
|
|
self.status = profile.status;
|
|
|
|
self.avatarID = profile.avatarID;
|
2015-01-25 14:21:57 -05:00
|
|
|
self.soundEnabled = profile.soundEnabled;
|
2013-10-15 17:48:39 -04:00
|
|
|
}
|
|
|
|
self.save();
|
|
|
|
app.storage.roster.getAll(self.jid.bare, function (err, contacts) {
|
|
|
|
if (err) return;
|
|
|
|
|
|
|
|
contacts.forEach(function (contact) {
|
|
|
|
contact = new Contact(contact);
|
|
|
|
contact.owner = self.jid.bare;
|
|
|
|
contact.inRoster = true;
|
2015-02-09 08:56:02 -05:00
|
|
|
if (contact.jid.indexOf("@" + SERVER_CONFIG.domain) > -1)
|
|
|
|
contact.persistent = true;
|
2013-10-15 17:48:39 -04:00
|
|
|
contact.save();
|
|
|
|
self.contacts.add(contact);
|
|
|
|
});
|
|
|
|
});
|
2013-09-11 17:58:39 -04:00
|
|
|
});
|
2015-02-09 08:56:02 -05:00
|
|
|
|
|
|
|
this.mucs.once('loaded', function () {
|
|
|
|
self.contacts.trigger('loaded');
|
|
|
|
});
|
2013-09-11 17:58:39 -04:00
|
|
|
},
|
2013-08-20 13:45:06 -04:00
|
|
|
isMe: function (jid) {
|
2014-01-05 07:19:46 -05:00
|
|
|
return jid && (jid.bare === this.jid.bare);
|
2013-09-26 23:19:46 -04:00
|
|
|
},
|
2015-02-22 17:43:49 -05:00
|
|
|
updateJid: function(newJid) {
|
|
|
|
if (this.jid.domain && this.isMe(newJid)) {
|
|
|
|
this.jid.full = newJid.full;
|
|
|
|
this.jid.resource = newJid.resource;
|
|
|
|
this.jid.unescapedFull = newJid.unescapedFull;
|
|
|
|
this.jid.prepped = newJid.prepped;
|
|
|
|
} else {
|
|
|
|
this.jid = newJid;
|
2015-03-16 10:07:39 -04:00
|
|
|
this.nick = this.jid.local;
|
2015-02-22 17:43:49 -05:00
|
|
|
}
|
|
|
|
},
|
2013-09-26 23:19:46 -04:00
|
|
|
updateIdlePresence: function () {
|
|
|
|
var update = {
|
|
|
|
status: this.status,
|
|
|
|
show: this.show,
|
|
|
|
caps: app.api.disco.caps
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!app.state.active) {
|
|
|
|
update.idle = {since: app.state.idleSince};
|
|
|
|
}
|
|
|
|
|
|
|
|
app.api.sendPresence(update);
|
2013-09-27 12:47:54 -04:00
|
|
|
},
|
|
|
|
updateUnreadCount: function () {
|
|
|
|
var unreadCounts = this.contacts.pluck('unreadCount');
|
|
|
|
var count = unreadCounts.reduce(function (a, b) { return a + b; });
|
|
|
|
if (count === 0) {
|
|
|
|
count = '';
|
|
|
|
}
|
|
|
|
app.state.badge = '' + count;
|
2013-10-15 19:21:22 -04:00
|
|
|
},
|
|
|
|
updateActiveCalls: function () {
|
|
|
|
app.state.hasActiveCall = !!this.calls.length;
|
2013-10-15 19:22:53 -04:00
|
|
|
},
|
2013-10-15 17:48:39 -04:00
|
|
|
save: function () {
|
|
|
|
var data = {
|
|
|
|
jid: this.jid.bare,
|
|
|
|
avatarID: this.avatarID,
|
|
|
|
status: this.status,
|
2015-01-25 14:21:57 -05:00
|
|
|
rosterVer: this.rosterVer,
|
|
|
|
soundEnabled: this.soundEnabled
|
2013-10-15 17:48:39 -04:00
|
|
|
};
|
|
|
|
app.storage.profiles.set(data);
|
2013-10-16 13:48:00 -04:00
|
|
|
},
|
|
|
|
cameraOn: function () {
|
2013-10-16 13:49:49 -04:00
|
|
|
var self = this;
|
2013-10-16 13:48:00 -04:00
|
|
|
getUserMedia(function (err, stream) {
|
|
|
|
if (err) {
|
|
|
|
console.error(err);
|
|
|
|
} else {
|
2013-10-16 13:49:49 -04:00
|
|
|
self.stream = stream;
|
2013-10-16 13:48:00 -04:00
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
cameraOff: function () {
|
|
|
|
if (this.stream) {
|
|
|
|
this.stream.stop();
|
|
|
|
this.stream = null;
|
|
|
|
}
|
2014-01-23 19:34:21 -05:00
|
|
|
},
|
|
|
|
registerDevice: function () {
|
|
|
|
var deviceID = app.state.deviceID;
|
2014-01-27 17:43:28 -05:00
|
|
|
if (!!deviceID && deviceID !== undefined && deviceID !== 'undefined') {
|
2014-01-27 17:28:27 -05:00
|
|
|
client.otalkRegister(deviceID).then(function () {
|
|
|
|
client.registerPush('push@push.otalk.im/prod');
|
|
|
|
}).catch(function (err) {
|
|
|
|
console.log('Could not enable push notifications');
|
|
|
|
});
|
|
|
|
}
|
2013-06-03 18:51:30 -04:00
|
|
|
}
|
|
|
|
});
|