kaiwa/clientapp/models/message.js

263 lines
8.6 KiB
JavaScript
Raw Normal View History

/*global app, me*/
2013-08-29 23:38:28 -04:00
"use strict";
2014-01-02 03:52:26 -05:00
var _ = require('underscore');
var uuid = require('node-uuid');
var HumanModel = require('human-model');
2013-09-25 23:38:00 -04:00
var templates = require('../templates');
2013-09-26 15:34:31 -04:00
var htmlify = require('../helpers/htmlify');
2013-08-20 13:45:06 -04:00
2013-12-18 16:31:22 -05:00
var ID_CACHE = {};
2013-08-20 13:45:06 -04:00
2013-12-18 16:31:22 -05:00
var Message = module.exports = HumanModel.define({
2013-08-29 23:38:28 -04:00
initialize: function (attrs) {
this._created = new Date(Date.now() + app.timeInterval);
2013-08-20 13:45:06 -04:00
},
type: 'message',
props: {
mid: 'string',
owner: 'string',
to: 'object',
from: 'object',
body: 'string',
type: ['string', false, 'normal'],
acked: ['bool', false, false],
requestReceipt: ['bool', false, false],
receipt: ['bool', false, false],
archivedId: 'string',
oobURIs: 'array'
2013-08-20 13:45:06 -04:00
},
derived: {
mine: {
2013-12-13 19:16:40 -05:00
deps: ['from', '_mucMine'],
2013-08-20 13:45:06 -04:00
fn: function () {
2013-12-13 19:16:40 -05:00
return this._mucMine || me.isMe(this.from);
2013-08-20 13:45:06 -04:00
}
},
2013-09-25 23:38:00 -04:00
sender: {
deps: ['from', 'mine'],
fn: function () {
if (this.mine) {
return me;
} else {
return me.getContact(this.from);
}
}
},
2013-08-20 13:45:06 -04:00
delayed: {
deps: ['delay'],
fn: function () {
return !!this.delay;
}
},
created: {
deps: ['delay', '_created', '_edited'],
2013-08-20 13:45:06 -04:00
fn: function () {
if (this.delay && this.delay.stamp) {
return this.delay.stamp;
}
return this._created;
}
},
timestamp: {
deps: ['created', '_edited'],
fn: function () {
if (this._edited && !isNaN(this._edited.valueOf())) {
return this._edited;
}
return this.created;
}
},
2013-08-20 13:45:06 -04:00
formattedTime: {
deps: ['created'],
fn: function () {
2013-08-29 23:38:28 -04:00
if (this.created) {
2013-12-17 01:07:09 -05:00
var month = this.created.getMonth() + 1;
2013-08-30 01:37:24 -04:00
var day = this.created.getDate();
var hour = this.created.getHours();
var minutes = this.created.getMinutes();
var m = (hour >= 12) ? 'p' : 'a';
var strDay = (day < 10) ? '0' + day : day;
var strHour = (hour < 10) ? '0' + hour : hour;
var strMin = (minutes < 10) ? '0' + minutes: minutes;
return '' + month + '/' + strDay + ' ' + strHour + ':' + strMin + m;
2013-08-29 23:38:28 -04:00
}
return undefined;
2013-08-20 13:45:06 -04:00
}
},
pending: {
deps: ['acked'],
fn: function () {
return !this.acked;
}
2013-09-24 16:24:35 -04:00
},
nick: {
deps: ['mine', 'type'],
fn: function () {
if (this.type === 'groupchat') {
return this.from.resource;
}
2013-12-13 19:16:40 -05:00
if (this.mine) {
return 'me';
}
2013-09-24 16:24:35 -04:00
return me.getContact(this.from.bare).displayName;
}
2013-09-25 23:38:00 -04:00
},
2013-09-26 15:34:31 -04:00
processedBody: {
deps: ['body', 'meAction', 'mentions'],
2013-09-26 15:34:31 -04:00
fn: function () {
2013-12-16 17:28:13 -05:00
var body = this.body;
if (body) {
if (this.meAction) {
body = body.substr(4);
}
body = htmlify.toHTML(body);
for (var i = 0; i < this.mentions.length; i++) {
var existing = htmlify.toHTML(this.mentions[i]);
var parts = body.split(existing);
body = parts.join('<span class="mention">' + existing + '</span>');
}
return body;
2013-12-16 17:28:13 -05:00
}
this.body = '';
2013-09-26 15:34:31 -04:00
}
},
2013-09-25 23:38:00 -04:00
partialTemplateHtml: {
2014-01-02 03:52:26 -05:00
deps: ['edited', 'pending', 'body', 'urls'],
2013-09-25 23:38:00 -04:00
cache: false,
fn: function () {
2015-04-07 07:12:20 -04:00
return this.bareMessageTemplate(false);
2013-09-25 23:38:00 -04:00
}
},
templateHtml: {
2014-01-02 03:52:26 -05:00
deps: ['edited', 'pending', 'body', 'urls'],
cache: false,
2013-09-25 23:38:00 -04:00
fn: function () {
2013-12-13 19:16:40 -05:00
if (this.type === 'groupchat') {
2015-04-07 07:12:20 -04:00
return templates.includes.mucWrappedMessage({message: this, messageDate: Date.create(this.timestamp), firstEl: true});
2013-12-13 19:16:40 -05:00
} else {
2015-04-07 07:12:20 -04:00
return templates.includes.wrappedMessage({message: this, messageDate: Date.create(this.timestamp), firstEl: true});
2013-12-13 19:16:40 -05:00
}
2013-09-25 23:38:00 -04:00
}
},
classList: {
cache: false,
fn: function () {
var res = [];
if (this.mine) res.push('mine');
if (this.pending) res.push('pending');
if (this.delayed) res.push('delayed');
if (this.edited) res.push('edited');
2014-01-05 05:30:26 -05:00
if (this.requestReceipt) res.push('pendingReceipt');
if (this.receiptReceived) res.push('delivered');
2013-12-16 17:28:13 -05:00
if (this.meAction) res.push('meAction');
2013-09-25 23:38:00 -04:00
return res.join(' ');
}
2013-12-16 17:28:13 -05:00
},
meAction: {
deps: ['body'],
fn: function () {
return this.body && this.body.indexOf('/me') === 0;
2013-12-16 17:28:13 -05:00
}
2014-01-02 03:52:26 -05:00
},
urls: {
deps: ['body', 'oobURIs'],
fn: function () {
var self = this;
var result = [];
var urls = htmlify.collectLinks(this.body);
var oobURIs = _.pluck(this.oobURIs || [], 'url');
var uniqueURIs = _.unique(result.concat(urls).concat(oobURIs));
_.each(uniqueURIs, function (url) {
var oidx = oobURIs.indexOf(url);
if (oidx >= 0) {
result.push({
href: url,
desc: self.oobURIs[oidx].desc,
source: 'oob'
});
} else {
result.push({
href: url,
desc: url,
source: 'body'
});
}
});
return result;
}
2013-08-20 13:45:06 -04:00
}
},
session: {
_created: 'date',
_edited: 'date',
2013-12-13 19:16:40 -05:00
_mucMine: 'bool',
2013-08-20 13:45:06 -04:00
receiptReceived: ['bool', true, false],
edited: ['bool', true, false],
delay: 'object',
mentions: ['array', false, []]
2013-08-20 13:45:06 -04:00
},
correct: function (msg) {
if (this.from.full !== msg.from.full) return false;
2013-08-20 13:45:06 -04:00
delete msg.id;
2013-08-20 13:45:06 -04:00
this.set(msg);
2015-02-15 12:06:39 -05:00
this._edited = new Date(Date.now() + app.timeInterval);
2013-08-20 13:45:06 -04:00
this.edited = true;
this.save();
return true;
},
2015-04-07 07:12:20 -04:00
bareMessageTemplate: function (firstEl) {
if (this.type === 'groupchat') {
return templates.includes.mucBareMessage({message: this, messageDate: Date.create(this.timestamp), firstEl: firstEl});
} else {
return templates.includes.bareMessage({message: this, messageDate: Date.create(this.timestamp), firstEl: firstEl});
}
},
save: function () {
2013-12-18 16:31:22 -05:00
if (this.mid) {
var from = this.type == 'groupchat' ? this.from.full : this.from.bare;
Message.idStore(from, this.mid, this);
}
var data = {
archivedId: this.archivedId || uuid.v4(),
owner: this.owner,
to: this.to,
from: this.from,
created: this.created,
body: this.body,
type: this.type,
delay: this.delay,
edited: this.edited
};
app.storage.archive.add(data);
2013-09-25 23:38:00 -04:00
},
shouldGroupWith: function (previous) {
2013-12-13 19:16:40 -05:00
if (this.type === 'groupchat') {
return previous && previous.from.full === this.from.full && Math.round((this.created - previous.created) / 1000) <= 300 && previous.created.toLocaleDateString() === this.created.toLocaleDateString();
2013-12-13 19:16:40 -05:00
} else {
return previous && previous.from.bare === this.from.bare && Math.round((this.created - previous.created) / 1000) <= 300 && previous.created.toLocaleDateString() === this.created.toLocaleDateString();
2013-12-13 19:16:40 -05:00
}
2013-08-20 13:45:06 -04:00
}
});
2013-12-18 16:31:22 -05:00
Message.idLookup = function (jid, mid) {
var cache = ID_CACHE[jid] || (ID_CACHE[jid] = {});
return cache[mid];
};
Message.idStore = function (jid, mid, msg) {
var cache = ID_CACHE[jid] || (ID_CACHE[jid] = {});
cache[mid] = msg;
};