mirror of
https://github.com/moparisthebest/kaiwa
synced 2024-11-25 18:52:20 -05:00
Make MUCs look nicer
This commit is contained in:
parent
4f63da4d20
commit
2ca32ca3bd
@ -23,9 +23,9 @@ module.exports = HumanModel.define({
|
|||||||
},
|
},
|
||||||
derived: {
|
derived: {
|
||||||
mine: {
|
mine: {
|
||||||
deps: ['from'],
|
deps: ['from', '_mucMine'],
|
||||||
fn: function () {
|
fn: function () {
|
||||||
return me.isMe(this.from);
|
return this._mucMine || me.isMe(this.from);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sender: {
|
sender: {
|
||||||
@ -81,16 +81,12 @@ module.exports = HumanModel.define({
|
|||||||
nick: {
|
nick: {
|
||||||
deps: ['mine', 'type'],
|
deps: ['mine', 'type'],
|
||||||
fn: function () {
|
fn: function () {
|
||||||
if (this.mine) {
|
|
||||||
if (this.type === 'groupchat') {
|
|
||||||
return me.mucs.get(this.to.bare).nick;
|
|
||||||
} else {
|
|
||||||
return 'me';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.type === 'groupchat') {
|
if (this.type === 'groupchat') {
|
||||||
return this.from.resource;
|
return this.from.resource;
|
||||||
}
|
}
|
||||||
|
if (this.mine) {
|
||||||
|
return 'me';
|
||||||
|
}
|
||||||
return me.getContact(this.from.bare).displayName;
|
return me.getContact(this.from.bare).displayName;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -104,13 +100,21 @@ module.exports = HumanModel.define({
|
|||||||
deps: ['edited', 'pending', 'body'],
|
deps: ['edited', 'pending', 'body'],
|
||||||
cache: false,
|
cache: false,
|
||||||
fn: function () {
|
fn: function () {
|
||||||
|
if (this.type === 'groupchat') {
|
||||||
|
return templates.includes.mucBareMessage({message: this});
|
||||||
|
} else {
|
||||||
return templates.includes.bareMessage({message: this});
|
return templates.includes.bareMessage({message: this});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
templateHtml: {
|
templateHtml: {
|
||||||
fn: function () {
|
fn: function () {
|
||||||
|
if (this.type === 'groupchat') {
|
||||||
|
return templates.includes.mucWrappedMessage({message: this});
|
||||||
|
} else {
|
||||||
return templates.includes.wrappedMessage({message: this});
|
return templates.includes.wrappedMessage({message: this});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
classList: {
|
classList: {
|
||||||
cache: false,
|
cache: false,
|
||||||
@ -128,6 +132,7 @@ module.exports = HumanModel.define({
|
|||||||
},
|
},
|
||||||
session: {
|
session: {
|
||||||
_created: 'date',
|
_created: 'date',
|
||||||
|
_mucMine: 'bool',
|
||||||
receiptReceived: ['bool', true, false],
|
receiptReceived: ['bool', true, false],
|
||||||
edited: ['bool', true, false],
|
edited: ['bool', true, false],
|
||||||
delay: 'object'
|
delay: 'object'
|
||||||
@ -160,6 +165,10 @@ module.exports = HumanModel.define({
|
|||||||
app.storage.archive.add(data);
|
app.storage.archive.add(data);
|
||||||
},
|
},
|
||||||
shouldGroupWith: function (previous) {
|
shouldGroupWith: function (previous) {
|
||||||
|
if (this.type === 'groupchat') {
|
||||||
|
return previous && previous.from.full === this.from.full;
|
||||||
|
} else {
|
||||||
return previous && previous.from.bare === this.from.bare;
|
return previous && previous.from.bare === this.from.bare;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
@ -61,17 +61,24 @@ module.exports = HumanModel.define({
|
|||||||
addMessage: function (message, notify) {
|
addMessage: function (message, notify) {
|
||||||
message.owner = me.jid.bare;
|
message.owner = me.jid.bare;
|
||||||
|
|
||||||
if (notify && (!this.activeContact || (this.activeContact && !app.hasFocus))) {
|
if (notify && (!this.activeContact || (this.activeContact && !app.state.focused)) && message.from.resource !== this.nick) {
|
||||||
this.unreadCount++;
|
this.unreadCount++;
|
||||||
app.notifications.create(this.displayName, {
|
app.notifications.create(this.displayName, {
|
||||||
body: message.body,
|
body: message.body,
|
||||||
icon: this.avatar,
|
icon: this.avatar,
|
||||||
tag: this.id,
|
tag: this.id,
|
||||||
onclick: _.bind(app.navigate, app, '/chat/' + this.jid)
|
onclick: _.bind(app.navigate, app, '/groupchat/' + this.jid)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message.acked = true;
|
||||||
|
|
||||||
this.messages.add(message);
|
this.messages.add(message);
|
||||||
|
if (message.from.resource === this.nick) {
|
||||||
|
message = this.messages.get(message.id); // Grab the existing message object that was updated
|
||||||
|
message._mucMine = true;
|
||||||
|
this.lastSentMessage = message;
|
||||||
|
}
|
||||||
|
|
||||||
var newInteraction = new Date(message.created);
|
var newInteraction = new Date(message.created);
|
||||||
if (!this.lastInteraction || this.lastInteraction < newInteraction) {
|
if (!this.lastInteraction || this.lastInteraction < newInteraction) {
|
||||||
|
@ -1,16 +1,27 @@
|
|||||||
/*global $, app, me, client*/
|
/*global $, app, me, client*/
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var _ = require('underscore');
|
||||||
var BasePage = require('./base');
|
var BasePage = require('./base');
|
||||||
var templates = require('../templates');
|
var templates = require('../templates');
|
||||||
var Message = require('../views/mucMessage');
|
var Message = require('../views/mucMessage');
|
||||||
var MessageModel = require('../models/message');
|
var MessageModel = require('../models/message');
|
||||||
|
var chatHelpers = require('../helpers/chatHelpers');
|
||||||
|
|
||||||
|
|
||||||
module.exports = BasePage.extend({
|
module.exports = BasePage.extend(chatHelpers).extend({
|
||||||
template: templates.pages.groupchat,
|
template: templates.pages.groupchat,
|
||||||
initialize: function (spec) {
|
initialize: function (spec) {
|
||||||
this.editMode = false;
|
this.editMode = false;
|
||||||
|
|
||||||
|
this.listenTo(this, 'pageloaded', this.handlePageLoaded);
|
||||||
|
this.listenTo(this, 'pageunloaded', this.handlePageUnloaded);
|
||||||
|
|
||||||
|
this.listenTo(this.model.messages, 'change:body', this.refreshModel);
|
||||||
|
this.listenTo(this.model.messages, 'change:edited', this.refreshModel);
|
||||||
|
this.listenTo(this.model.messages, 'change:pending', this.refreshModel);
|
||||||
|
this.listenTo(this.model.messages, 'change:mine', this.refreshModel);
|
||||||
|
|
||||||
this.render();
|
this.render();
|
||||||
},
|
},
|
||||||
events: {
|
events: {
|
||||||
@ -42,14 +53,51 @@ module.exports = BasePage.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
|
if (this.rendered) return this;
|
||||||
|
this.rendered = true;
|
||||||
|
|
||||||
this.renderAndBind();
|
this.renderAndBind();
|
||||||
this.typingTimer = null;
|
this.typingTimer = null;
|
||||||
this.$chatInput = this.$('.chatBox textarea');
|
this.$chatInput = this.$('.chatBox textarea');
|
||||||
|
this.$chatBox = this.$('.chatBox');
|
||||||
this.$messageList = this.$('.messages');
|
this.$messageList = this.$('.messages');
|
||||||
this.renderCollection(this.model.messages, Message, this.$('.messages'));
|
this.$scrollContainer = this.$messageList;
|
||||||
|
|
||||||
|
this.listenTo(this.model.messages, 'add', this.handleChatAdded);
|
||||||
|
|
||||||
|
this.renderCollection();
|
||||||
|
|
||||||
|
$(window).on('resize', _.bind(this.handleWindowResize, this));
|
||||||
|
|
||||||
|
this.initializeScroll();
|
||||||
|
|
||||||
this.registerBindings();
|
this.registerBindings();
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
renderCollection: function () {
|
||||||
|
var self = this;
|
||||||
|
var previous;
|
||||||
|
var bottom = this.isBottom() || this.$messageList.is(':empty');
|
||||||
|
this.model.messages.each(function (model, i) {
|
||||||
|
self.appendModel(model);
|
||||||
|
});
|
||||||
|
this.scrollIfPinned();
|
||||||
|
},
|
||||||
|
handleChatAdded: function (model) {
|
||||||
|
this.appendModel(model, true);
|
||||||
|
},
|
||||||
|
handlePageLoaded: function () {
|
||||||
|
this.scrollPageLoad();
|
||||||
|
this.handleWindowResize();
|
||||||
|
},
|
||||||
|
handlePageUnloaded: function () {
|
||||||
|
this.scrollPageUnload();
|
||||||
|
},
|
||||||
|
handleWindowResize: function () {
|
||||||
|
this.scrollIfPinned();
|
||||||
|
this.resizeInput();
|
||||||
|
},
|
||||||
handleKeyDown: function (e) {
|
handleKeyDown: function (e) {
|
||||||
clearTimeout(this.typingTimer);
|
clearTimeout(this.typingTimer);
|
||||||
if (e.which === 13 && !e.shiftKey) {
|
if (e.which === 13 && !e.shiftKey) {
|
||||||
@ -140,7 +188,7 @@ module.exports = BasePage.extend({
|
|||||||
|
|
||||||
var id = client.sendMessage(message);
|
var id = client.sendMessage(message);
|
||||||
message.id = id;
|
message.id = id;
|
||||||
message.from = me.jid;
|
message.from = client.JID(this.model.jid.bare + '/' + this.model.nick);
|
||||||
|
|
||||||
if (this.editMode) {
|
if (this.editMode) {
|
||||||
this.model.lastSentMessage.correct(message);
|
this.model.lastSentMessage.correct(message);
|
||||||
@ -161,5 +209,27 @@ module.exports = BasePage.extend({
|
|||||||
},
|
},
|
||||||
handleLeave: function () {
|
handleLeave: function () {
|
||||||
this.model.leave();
|
this.model.leave();
|
||||||
|
},
|
||||||
|
appendModel: function (model, preload) {
|
||||||
|
var self = this;
|
||||||
|
var isGrouped = model.shouldGroupWith(this.lastModel);
|
||||||
|
var newEl, first, last;
|
||||||
|
|
||||||
|
if (isGrouped) {
|
||||||
|
newEl = $(model.partialTemplateHtml);
|
||||||
|
last = this.$messageList.find('li').last();
|
||||||
|
last.find('.messageWrapper').append(newEl);
|
||||||
|
last.addClass('chatGroup');
|
||||||
|
} else {
|
||||||
|
newEl = $(model.templateHtml);
|
||||||
|
this.$messageList.append(newEl);
|
||||||
|
}
|
||||||
|
this.lastModel = model;
|
||||||
|
|
||||||
|
this.scrollIfPinned();
|
||||||
|
},
|
||||||
|
refreshModel: function (model) {
|
||||||
|
var existing = this.$('#chat' + model.cid);
|
||||||
|
existing.replaceWith(model.partialTemplateHtml);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -101,6 +101,21 @@ exports.includes.messageGroup = function anonymous(locals) {
|
|||||||
return buf.join("");
|
return buf.join("");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// mucBareMessage.jade compiled template
|
||||||
|
exports.includes.mucBareMessage = function anonymous(locals) {
|
||||||
|
var buf = [];
|
||||||
|
with (locals || {}) {
|
||||||
|
buf.push("<div" + jade.attrs({
|
||||||
|
id: "chat" + message.cid,
|
||||||
|
"class": "message" + " " + message.classList
|
||||||
|
}, {
|
||||||
|
"class": true,
|
||||||
|
id: true
|
||||||
|
}) + '><span class="timestamp">' + jade.escape(null == (jade.interp = message.formattedTime) ? "" : jade.interp) + '</span><p class="body">' + ((jade.interp = message.processedBody) == null ? "" : jade.interp) + "</p></div>");
|
||||||
|
}
|
||||||
|
return buf.join("");
|
||||||
|
};
|
||||||
|
|
||||||
// mucListItem.jade compiled template
|
// mucListItem.jade compiled template
|
||||||
exports.includes.mucListItem = function anonymous(locals) {
|
exports.includes.mucListItem = function anonymous(locals) {
|
||||||
var buf = [];
|
var buf = [];
|
||||||
@ -115,11 +130,17 @@ exports.includes.mucListItem = function anonymous(locals) {
|
|||||||
return buf.join("");
|
return buf.join("");
|
||||||
};
|
};
|
||||||
|
|
||||||
// mucMessage.jade compiled template
|
// mucWrappedMessage.jade compiled template
|
||||||
exports.includes.mucMessage = function anonymous(locals) {
|
exports.includes.mucWrappedMessage = function anonymous(locals) {
|
||||||
var buf = [];
|
var buf = [];
|
||||||
with (locals || {}) {
|
with (locals || {}) {
|
||||||
buf.push('<li><div class="message"><span class="timestamp">' + jade.escape(null == (jade.interp = message.created) ? "" : jade.interp) + '</span><p class="body">' + jade.escape(null == (jade.interp = message.body) ? "" : jade.interp) + '</p><span class="sender">' + jade.escape(null == (jade.interp = message.nick) ? "" : jade.interp) + "</span></div></li>");
|
buf.push('<li><div class="sender"><div class="name">' + jade.escape(null == (jade.interp = message.from.resource) ? "" : jade.interp) + '</div><a href="#" class="messageAvatar"><!--img(src=message.sender.avatar, alt=message.sender.displayName, data-placement="below")--></a></div><div class="messageWrapper"><div' + jade.attrs({
|
||||||
|
id: "chat" + message.cid,
|
||||||
|
"class": "message" + " " + message.classList
|
||||||
|
}, {
|
||||||
|
"class": true,
|
||||||
|
id: true
|
||||||
|
}) + '><span class="timestamp">' + jade.escape(null == (jade.interp = message.formattedTime) ? "" : jade.interp) + '</span><p class="body">' + ((jade.interp = message.processedBody) == null ? "" : jade.interp) + "</p></div></div></li>");
|
||||||
}
|
}
|
||||||
return buf.join("");
|
return buf.join("");
|
||||||
};
|
};
|
||||||
@ -128,7 +149,7 @@ exports.includes.mucMessage = function anonymous(locals) {
|
|||||||
exports.includes.wrappedMessage = function anonymous(locals) {
|
exports.includes.wrappedMessage = function anonymous(locals) {
|
||||||
var buf = [];
|
var buf = [];
|
||||||
with (locals || {}) {
|
with (locals || {}) {
|
||||||
buf.push('<li><a href="#" class="messageAvatar"><img' + jade.attrs({
|
buf.push('<li><div class="sender"><a href="#" class="messageAvatar"><img' + jade.attrs({
|
||||||
src: message.sender.avatar,
|
src: message.sender.avatar,
|
||||||
alt: message.sender.displayName,
|
alt: message.sender.displayName,
|
||||||
"data-placement": "below"
|
"data-placement": "below"
|
||||||
@ -136,7 +157,7 @@ exports.includes.wrappedMessage = function anonymous(locals) {
|
|||||||
src: true,
|
src: true,
|
||||||
alt: true,
|
alt: true,
|
||||||
"data-placement": true
|
"data-placement": true
|
||||||
}) + '/><span class="name">' + jade.escape(null == (jade.interp = message.sender.displayName + ": ") ? "" : jade.interp) + '</span></a><div class="messageWrapper"><div' + jade.attrs({
|
}) + '/></a></div><div class="messageWrapper"><div' + jade.attrs({
|
||||||
id: "chat" + message.cid,
|
id: "chat" + message.cid,
|
||||||
"class": "message" + " " + message.classList
|
"class": "message" + " " + message.classList
|
||||||
}, {
|
}, {
|
||||||
|
3
clientapp/templates/includes/mucBareMessage.jade
Normal file
3
clientapp/templates/includes/mucBareMessage.jade
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.message(id='chat'+message.cid, class=message.classList)
|
||||||
|
span.timestamp=message.formattedTime
|
||||||
|
p.body !{message.processedBody}
|
@ -1,5 +0,0 @@
|
|||||||
li
|
|
||||||
.message
|
|
||||||
span.timestamp=message.created
|
|
||||||
p.body=message.body
|
|
||||||
span.sender=message.nick
|
|
7
clientapp/templates/includes/mucWrappedMessage.jade
Normal file
7
clientapp/templates/includes/mucWrappedMessage.jade
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
li
|
||||||
|
.sender
|
||||||
|
.name=message.from.resource
|
||||||
|
a.messageAvatar(href='#')
|
||||||
|
//img(src=message.sender.avatar, alt=message.sender.displayName, data-placement="below")
|
||||||
|
.messageWrapper
|
||||||
|
include mucBareMessage
|
@ -1,6 +1,6 @@
|
|||||||
li
|
li
|
||||||
|
.sender
|
||||||
a.messageAvatar(href='#')
|
a.messageAvatar(href='#')
|
||||||
img(src=message.sender.avatar, alt=message.sender.displayName, data-placement="below")
|
img(src=message.sender.avatar, alt=message.sender.displayName, data-placement="below")
|
||||||
span.name=message.sender.displayName + ": "
|
|
||||||
.messageWrapper
|
.messageWrapper
|
||||||
include bareMessage
|
include bareMessage
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
"templatizer": "0.1.2",
|
"templatizer": "0.1.2",
|
||||||
"underscore": "1.5.1",
|
"underscore": "1.5.1",
|
||||||
"raf-component": "1.1.1",
|
"raf-component": "1.1.1",
|
||||||
"stanza.io": "2.8.1",
|
"stanza.io": "2.9.0",
|
||||||
"notify.js": "0.0.3",
|
"notify.js": "0.0.3",
|
||||||
"wildemitter": "0.0.5",
|
"wildemitter": "0.0.5",
|
||||||
"attachmediastream": "1.0.1",
|
"attachmediastream": "1.0.1",
|
||||||
|
@ -990,6 +990,7 @@ button.secondary:hover:not(:disabled) {
|
|||||||
position: relative;
|
position: relative;
|
||||||
bottom: 75px;
|
bottom: 75px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
display: table;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@ -1006,15 +1007,13 @@ button.secondary:hover:not(:disabled) {
|
|||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
|
display: table-row;
|
||||||
}
|
}
|
||||||
.messages li:last-of-type {
|
.messages li:last-of-type {
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
.messages li .messageAvatar {
|
.messages li .messageAvatar {
|
||||||
position: absolute;
|
display: inline-block;
|
||||||
top: 50%;
|
|
||||||
left: 10px;
|
|
||||||
margin-top: -15px;
|
|
||||||
}
|
}
|
||||||
.messages li .messageAvatar img {
|
.messages li .messageAvatar img {
|
||||||
width: 30px;
|
width: 30px;
|
||||||
@ -1031,10 +1030,25 @@ button.secondary:hover:not(:disabled) {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
}
|
}
|
||||||
|
.messages .sender {
|
||||||
|
display: table-cell;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #565656;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: right;
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
border-top: 1px solid #e1e1e1;
|
||||||
|
}
|
||||||
|
.messages .sender .name {
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
.messages .messageWrapper {
|
.messages .messageWrapper {
|
||||||
padding-left: 50px;
|
padding-left: 50px;
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
padding: 10px;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
}
|
}
|
||||||
.messages .message {
|
.messages .message {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
@ -108,6 +108,7 @@
|
|||||||
position: relative
|
position: relative
|
||||||
bottom: 75px
|
bottom: 75px
|
||||||
width: 100%
|
width: 100%
|
||||||
|
display: table
|
||||||
borderbox()
|
borderbox()
|
||||||
|
|
||||||
li
|
li
|
||||||
@ -120,15 +121,13 @@
|
|||||||
display: table
|
display: table
|
||||||
borderbox()
|
borderbox()
|
||||||
border-bottom: 1px solid $gray-lighter
|
border-bottom: 1px solid $gray-lighter
|
||||||
|
display: table-row
|
||||||
|
|
||||||
&:last-of-type
|
&:last-of-type
|
||||||
border: none
|
border: none
|
||||||
|
|
||||||
.messageAvatar
|
.messageAvatar
|
||||||
position: absolute
|
display: inline-block
|
||||||
top: 50%
|
|
||||||
left: 10px
|
|
||||||
margin-top: -15px
|
|
||||||
|
|
||||||
img
|
img
|
||||||
avatar()
|
avatar()
|
||||||
@ -138,10 +137,25 @@
|
|||||||
position: absolute
|
position: absolute
|
||||||
width: 1px
|
width: 1px
|
||||||
|
|
||||||
|
.sender
|
||||||
|
display: table-cell
|
||||||
|
font-size: 12px
|
||||||
|
font-weight: bold
|
||||||
|
color: $gray
|
||||||
|
padding: 10px
|
||||||
|
text-align: right
|
||||||
|
background-color: #f7f7f7
|
||||||
|
border-top: 1px solid #e1e1e1
|
||||||
|
|
||||||
|
.name
|
||||||
|
padding-left: 10px
|
||||||
|
|
||||||
.messageWrapper
|
.messageWrapper
|
||||||
padding-left: 50px
|
padding-left: 50px
|
||||||
display: table-cell
|
display: table-cell
|
||||||
vertical-align: middle
|
vertical-align: middle
|
||||||
|
padding: 10px
|
||||||
|
border-top: 1px solid #eee
|
||||||
|
|
||||||
.message
|
.message
|
||||||
font-size: $font-size-small
|
font-size: $font-size-small
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
CACHE MANIFEST
|
CACHE MANIFEST
|
||||||
# 0.0.1 1384923017253
|
# 0.0.1 1386980007554
|
||||||
|
|
||||||
CACHE:
|
CACHE:
|
||||||
/app.js
|
/app.js
|
||||||
|
Loading…
Reference in New Issue
Block a user