234 lines
8.7 KiB
JavaScript
234 lines
8.7 KiB
JavaScript
/*======================================================
|
|
************ Messages ************
|
|
======================================================*/
|
|
var Messages = function (container, params) {
|
|
var defaults = {
|
|
autoLayout: true,
|
|
newMessagesFirst: false,
|
|
scrollMessages: true,
|
|
scrollMessagesOnlyOnEdge: false,
|
|
messageTemplate:
|
|
'{{#if day}}' +
|
|
'<div class="messages-date">{{day}} {{#if time}}, <span>{{time}}</span>{{/if}}</div>' +
|
|
'{{/if}}' +
|
|
'<div class="message message-{{type}} {{#if hasImage}}message-pic{{/if}} {{#if avatar}}message-with-avatar{{/if}} {{#if position}}message-appear-from-{{position}}{{/if}}">' +
|
|
'{{#if name}}<div class="message-name">{{name}}</div>{{/if}}' +
|
|
'<div class="message-text">{{text}}{{#if date}}<div class="message-date">{{date}}</div>{{/if}}</div>' +
|
|
'{{#if avatar}}<div class="message-avatar" style="background-image:url({{avatar}})"></div>{{/if}}' +
|
|
'{{#if label}}<div class="message-label">{{label}}</div>{{/if}}' +
|
|
'</div>'
|
|
};
|
|
params = params || {};
|
|
for (var def in defaults) {
|
|
if (typeof params[def] === 'undefined' || params[def] === null) {
|
|
params[def] = defaults[def];
|
|
}
|
|
}
|
|
|
|
// Instance
|
|
var m = this;
|
|
|
|
// Params
|
|
m.params = params;
|
|
|
|
// Container
|
|
m.container = $(container);
|
|
if (m.container.length === 0) return;
|
|
|
|
// Autolayout
|
|
if (m.params.autoLayout) m.container.addClass('messages-auto-layout');
|
|
|
|
// New messages first
|
|
if (m.params.newMessagesFirst) m.container.addClass('messages-new-first');
|
|
|
|
// Is In Page
|
|
m.pageContainer = m.container.parents('.page').eq(0);
|
|
m.pageContent = m.pageContainer.find('.page-content');
|
|
|
|
// Compiled template
|
|
m.template = Template7.compile(m.params.messageTemplate);
|
|
|
|
// Auto Layout
|
|
m.layout = function () {
|
|
if (!m.container.hasClass('messages-auto-layout')) m.container.addClass('messages-auto-layout');
|
|
m.container.find('.message').each(function () {
|
|
var message = $(this);
|
|
if (message.find('.message-text img').length > 0) {
|
|
var childNodes = message.find('.message-text')[0].childNodes;
|
|
var onlyPic = true;
|
|
for (var i = 0 ; i < childNodes.length; i++) {
|
|
if (childNodes[i].nodeType === 1 && childNodes[i].nodeName.toLowerCase() !== 'img') onlyPic = false;
|
|
if (childNodes[i].nodeType === 3 && childNodes[i].textContent.trim() !== '') onlyPic = false;
|
|
}
|
|
if (onlyPic) message.addClass('message-pic');
|
|
else message.removeClass('message-pic');
|
|
}
|
|
if (message.find('.message-avatar').length > 0) message.addClass('message-with-avatar');
|
|
});
|
|
m.container.find('.message').each(function () {
|
|
var message = $(this);
|
|
var isSent = message.hasClass('message-sent');
|
|
var next = message.next('.message-' + (isSent ? 'sent' : 'received'));
|
|
var prev = message.prev('.message-' + (isSent ? 'sent' : 'received'));
|
|
if (next.length === 0) {
|
|
message.addClass('message-last message-with-tail');
|
|
}
|
|
else message.removeClass('message-last message-with-tail');
|
|
|
|
if (prev.length === 0) {
|
|
message.addClass('message-first');
|
|
}
|
|
else message.removeClass('message-first');
|
|
|
|
if (prev.length > 0 && prev.find('.message-name').length > 0 && message.find('.message-name').length > 0) {
|
|
if (prev.find('.message-name').text() !== message.find('.message-name').text()) {
|
|
prev.addClass('message-last message-with-tail');
|
|
message.addClass('message-first');
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
// Add Message
|
|
m.appendMessage = function (props, animate) {
|
|
return m.addMessage(props, 'append', animate);
|
|
};
|
|
m.prependMessage = function (props, animate) {
|
|
return m.addMessage(props, 'prepend', animate);
|
|
};
|
|
m.addMessage = function (props, method, animate) {
|
|
return m.addMessages([props], method, animate);
|
|
};
|
|
m.addMessages = function (newMessages, method, animate) {
|
|
if (typeof animate === 'undefined') {
|
|
animate = true;
|
|
}
|
|
if (typeof method === 'undefined') {
|
|
method = m.params.newMessagesFirst ? 'prepend' : 'append';
|
|
}
|
|
var newMessagesHTML = '', i;
|
|
for (i = 0; i < newMessages.length; i++) {
|
|
var props = newMessages[i] || {};
|
|
props.type = props.type || 'sent';
|
|
if (!props.text) continue;
|
|
props.hasImage = props.text.indexOf('<img') >= 0;
|
|
if (props.onlyImage === false) props.hasImage = false;
|
|
if (animate) props.position = method === 'append' ? 'bottom' : 'top';
|
|
|
|
newMessagesHTML += m.template(props);
|
|
}
|
|
var scrollHeightBefore = m.pageContent[0].scrollHeight,
|
|
heightBefore = m.pageContent[0].offsetHeight,
|
|
scrollBefore = m.pageContent[0].scrollTop;
|
|
m.container[method](newMessagesHTML);
|
|
if (m.params.autoLayout) m.layout();
|
|
if (method === 'prepend') {
|
|
m.pageContent[0].scrollTop = scrollBefore + (m.pageContent[0].scrollHeight - scrollHeightBefore);
|
|
}
|
|
if (m.params.scrollMessages && (method === 'append' && !m.params.newMessagesFirst) || (method === 'prepend' && m.params.newMessagesFirst)) {
|
|
if (m.params.scrollMessagesOnlyOnEdge) {
|
|
var onEdge = false;
|
|
if (m.params.newMessagesFirst) {
|
|
if (scrollBefore === 0) onEdge = true;
|
|
}
|
|
else {
|
|
if (scrollBefore - (scrollHeightBefore - heightBefore) >= -10) onEdge = true;
|
|
}
|
|
if (onEdge) m.scrollMessages(animate ? undefined : 0);
|
|
}
|
|
else m.scrollMessages(animate ? undefined : 0);
|
|
}
|
|
var messages = m.container.find('.message');
|
|
if (newMessages.length === 1) {
|
|
return method === 'append' ? messages[messages.length - 1] : messages[0];
|
|
}
|
|
else {
|
|
var messagesToReturn = [];
|
|
if (method === 'append') {
|
|
for (i = messages.length - newMessages.length; i < messages.length; i++) {
|
|
messagesToReturn.push(messages[i]);
|
|
}
|
|
}
|
|
else {
|
|
for (i = 0; i < newMessages.length; i++) {
|
|
messagesToReturn.push(messages[i]);
|
|
}
|
|
}
|
|
return messagesToReturn;
|
|
}
|
|
|
|
};
|
|
m.removeMessage = function (message) {
|
|
message = $(message);
|
|
if (message.length === 0) {
|
|
return false;
|
|
}
|
|
else {
|
|
message.remove();
|
|
if (m.params.autoLayout) m.layout();
|
|
return true;
|
|
}
|
|
};
|
|
m.removeMessages = function (messages) {
|
|
m.removeMessage(messages);
|
|
};
|
|
m.clean = function () {
|
|
m.container.html('');
|
|
};
|
|
|
|
// Scroll
|
|
m.scrollMessages = function (duration, scrollTop) {
|
|
if (typeof duration === 'undefined') duration = 400;
|
|
var currentScroll = m.pageContent[0].scrollTop;
|
|
var newScroll;
|
|
if (typeof scrollTop !== 'undefined') newScroll = scrollTop;
|
|
else {
|
|
newScroll = m.params.newMessagesFirst ? 0 : m.pageContent[0].scrollHeight - m.pageContent[0].offsetHeight;
|
|
if (newScroll === currentScroll) return;
|
|
}
|
|
m.pageContent.scrollTop(newScroll, duration);
|
|
};
|
|
|
|
// Init Destroy
|
|
m.init = function () {
|
|
if (m.params.messages) {
|
|
m.addMessages(m.params.messages, undefined, false);
|
|
}
|
|
else {
|
|
if (m.params.autoLayout) m.layout();
|
|
m.scrollMessages(0);
|
|
}
|
|
|
|
};
|
|
m.destroy = function () {
|
|
m = null;
|
|
};
|
|
|
|
// Init
|
|
m.init();
|
|
|
|
m.container[0].f7Messages = m;
|
|
return m;
|
|
};
|
|
app.messages = function (container, params) {
|
|
return new Messages (container, params);
|
|
};
|
|
app.initPageMessages = function (pageContainer) {
|
|
pageContainer = $(pageContainer);
|
|
var messages = pageContainer.find('.messages');
|
|
if (messages.length === 0) return;
|
|
if (!messages.hasClass('messages-init')) {
|
|
return;
|
|
}
|
|
var m = app.messages(messages, messages.dataset());
|
|
|
|
// Destroy on page remove
|
|
function pageBeforeRemove() {
|
|
m.destroy();
|
|
pageContainer.off('pageBeforeRemove', pageBeforeRemove);
|
|
}
|
|
if (pageContainer.hasClass('page')) {
|
|
pageContainer.on('pageBeforeRemove', pageBeforeRemove);
|
|
}
|
|
};
|