|
@@ -118,7 +118,7 @@
|
|
}
|
|
}
|
|
_converse.api.listen.on('windowStateChanged', onWindowStateChanged);
|
|
_converse.api.listen.on('windowStateChanged', onWindowStateChanged);
|
|
|
|
|
|
- _converse.EmojiPicker = Backbone.Model.extend({
|
|
|
|
|
|
+ _converse.EmojiPicker = Backbone.Model.extend({
|
|
defaults: {
|
|
defaults: {
|
|
'current_category': 'people',
|
|
'current_category': 'people',
|
|
'current_skintone': '',
|
|
'current_skintone': '',
|
|
@@ -385,23 +385,24 @@
|
|
);
|
|
);
|
|
},
|
|
},
|
|
|
|
|
|
- insertDayIndicator (date, prepend) {
|
|
|
|
- /* Appends (or prepends if "prepend" is truthy) an indicator
|
|
|
|
|
|
+ insertDayIndicator (date, insert_method) {
|
|
|
|
+ /* Inserts an indicator
|
|
* into the chat area, showing the day as given by the
|
|
* into the chat area, showing the day as given by the
|
|
* passed in date.
|
|
* passed in date.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* Parameters:
|
|
* (String) date - An ISO8601 date string.
|
|
* (String) date - An ISO8601 date string.
|
|
|
|
+ * (Function) insert_method - The method to be used to
|
|
|
|
+ * insert the indicator
|
|
*/
|
|
*/
|
|
const day_date = moment(date).startOf('day');
|
|
const day_date = moment(date).startOf('day');
|
|
- const insert = prepend ? $(this.content).prepend: $(this.content).append;
|
|
|
|
- insert.call($(this.content), tpl_new_day({
|
|
|
|
|
|
+ insert_method(tpl_new_day({
|
|
isodate: day_date.format(),
|
|
isodate: day_date.format(),
|
|
datestring: day_date.format("dddd MMM Do YYYY")
|
|
datestring: day_date.format("dddd MMM Do YYYY")
|
|
}));
|
|
}));
|
|
},
|
|
},
|
|
|
|
|
|
- insertMessage (attrs, prepend) {
|
|
|
|
|
|
+ insertMessage (attrs, insert_method) {
|
|
/* Helper method which appends a message (or prepends if the
|
|
/* Helper method which appends a message (or prepends if the
|
|
* 2nd parameter is set to true) to the end of the chat box's
|
|
* 2nd parameter is set to true) to the end of the chat box's
|
|
* content area.
|
|
* content area.
|
|
@@ -409,15 +410,35 @@
|
|
* Parameters:
|
|
* Parameters:
|
|
* (Object) attrs: An object containing the message attributes.
|
|
* (Object) attrs: An object containing the message attributes.
|
|
*/
|
|
*/
|
|
- const insert = prepend ? $(this.content).prepend : $(this.content).append;
|
|
|
|
_.flow(($el) => {
|
|
_.flow(($el) => {
|
|
- insert.call($(this.content), $el);
|
|
|
|
|
|
+ insert_method($el[0]);
|
|
return $el;
|
|
return $el;
|
|
},
|
|
},
|
|
this.scrollDown.bind(this)
|
|
this.scrollDown.bind(this)
|
|
)(this.renderMessage(attrs));
|
|
)(this.renderMessage(attrs));
|
|
},
|
|
},
|
|
|
|
|
|
|
|
+ getLastMessageDate (cutoff) {
|
|
|
|
+ /* Return the ISO8601 format date of the latest message.
|
|
|
|
+ *
|
|
|
|
+ * Parameters:
|
|
|
|
+ * (Object) cutoff: Moment Date cutoff date. The last
|
|
|
|
+ * message received cutoff this date will be returned.
|
|
|
|
+ */
|
|
|
|
+ if (!cutoff) {
|
|
|
|
+ const last_msg = this.content.lastElementChild;
|
|
|
|
+ return last_msg ? last_msg.getAttribute('data-isodate') : null
|
|
|
|
+ }
|
|
|
|
+ const msg_dates = _.invokeMap(
|
|
|
|
+ this.content.querySelector('.message'),
|
|
|
|
+ Element.prototype.getAttribute,
|
|
|
|
+ 'data-isodate'
|
|
|
|
+ )
|
|
|
|
+ msg_dates.push(cutoff.format());
|
|
|
|
+ msg_dates.sort();
|
|
|
|
+ return msg_dates[msg_dates.indexOf(cutoff)-1];
|
|
|
|
+ },
|
|
|
|
+
|
|
showMessage (attrs) {
|
|
showMessage (attrs) {
|
|
/* Inserts a chat message into the content area of the chat box.
|
|
/* Inserts a chat message into the content area of the chat box.
|
|
* Will also insert a new day indicator if the message is on a
|
|
* Will also insert a new day indicator if the message is on a
|
|
@@ -430,62 +451,52 @@
|
|
* (Object) attrs: An object containing the message
|
|
* (Object) attrs: An object containing the message
|
|
* attributes.
|
|
* attributes.
|
|
*/
|
|
*/
|
|
- let current_msg_date = moment(attrs.time) || moment;
|
|
|
|
- const first_msg_el = this.content.firstElementChild,
|
|
|
|
- first_msg_date = first_msg_el ? first_msg_el.getAttribute('data-isodate') : null;
|
|
|
|
|
|
+ const current_msg_date = moment(attrs.time) || moment,
|
|
|
|
+ first_msg_el = this.content.firstElementChild,
|
|
|
|
+ first_msg_date = first_msg_el ? first_msg_el.getAttribute('data-isodate') : null,
|
|
|
|
+ append_element = _.bind(this.content.insertAdjacentElement, this.content, 'beforeend'),
|
|
|
|
+ append_html = _.bind(this.content.insertAdjacentHTML, this.content, 'beforeend');
|
|
|
|
|
|
if (!first_msg_date) {
|
|
if (!first_msg_date) {
|
|
// This is the first received message, so we insert a
|
|
// This is the first received message, so we insert a
|
|
// date indicator before it.
|
|
// date indicator before it.
|
|
- this.insertDayIndicator(current_msg_date);
|
|
|
|
- this.insertMessage(attrs);
|
|
|
|
|
|
+ this.insertDayIndicator(current_msg_date, append_html);
|
|
|
|
+ this.insertMessage(attrs, append_element);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- const last_msg_el = this.content.lastElementChild,
|
|
|
|
- last_msg_date = last_msg_el.getAttribute('data-isodate');
|
|
|
|
|
|
+ const last_msg_date = this.getLastMessageDate();
|
|
if (current_msg_date.isAfter(last_msg_date) ||
|
|
if (current_msg_date.isAfter(last_msg_date) ||
|
|
current_msg_date.isSame(last_msg_date)) {
|
|
current_msg_date.isSame(last_msg_date)) {
|
|
// The new message is after the last message
|
|
// The new message is after the last message
|
|
if (current_msg_date.isAfter(last_msg_date, 'day')) {
|
|
if (current_msg_date.isAfter(last_msg_date, 'day')) {
|
|
// Append a new day indicator
|
|
// Append a new day indicator
|
|
- this.insertDayIndicator(current_msg_date);
|
|
|
|
|
|
+ this.insertDayIndicator(current_msg_date, append_html);
|
|
}
|
|
}
|
|
- this.insertMessage(attrs);
|
|
|
|
|
|
+ this.insertMessage(attrs, append_element);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
+
|
|
if (current_msg_date.isBefore(first_msg_date) ||
|
|
if (current_msg_date.isBefore(first_msg_date) ||
|
|
current_msg_date.isSame(first_msg_date)) {
|
|
current_msg_date.isSame(first_msg_date)) {
|
|
// The message is before the first, but on the same day.
|
|
// The message is before the first, but on the same day.
|
|
// We need to prepend the message immediately before the
|
|
// We need to prepend the message immediately before the
|
|
// first message (so that it'll still be after the day
|
|
// first message (so that it'll still be after the day
|
|
// indicator).
|
|
// indicator).
|
|
- this.insertMessage(attrs, 'prepend');
|
|
|
|
|
|
+ const prepend_element = _.bind(this.content.insertAdjacentElement, this.content, 'afterbegin');
|
|
|
|
+ this.insertMessage(attrs, prepend_element);
|
|
if (current_msg_date.isBefore(first_msg_date, 'day')) {
|
|
if (current_msg_date.isBefore(first_msg_date, 'day')) {
|
|
// This message is also on a different day, so
|
|
// This message is also on a different day, so
|
|
// we prepend a day indicator.
|
|
// we prepend a day indicator.
|
|
- this.insertDayIndicator(current_msg_date, 'prepend');
|
|
|
|
|
|
+ this.insertDayIndicator(current_msg_date, append_html);
|
|
}
|
|
}
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- // Find the correct place to position the message
|
|
|
|
- current_msg_date = current_msg_date.format();
|
|
|
|
- const msg_dates = _.invokeMap(
|
|
|
|
- this.content.querySelector('.message'),
|
|
|
|
- Element.prototype.getAttribute,
|
|
|
|
- 'data-isodate'
|
|
|
|
- )
|
|
|
|
- msg_dates.push(current_msg_date);
|
|
|
|
- msg_dates.sort();
|
|
|
|
-
|
|
|
|
- const idx = msg_dates.indexOf(current_msg_date)-1;
|
|
|
|
- const latest_msg_el = this.content.querySelector(`.message[data-isodate="${msg_dates[idx]}"]`);
|
|
|
|
- _.flow(($el) => {
|
|
|
|
- $el.insertAfter(latest_msg_el);
|
|
|
|
- return $el;
|
|
|
|
- },
|
|
|
|
- this.scrollDown.bind(this)
|
|
|
|
- )(this.renderMessage(attrs));
|
|
|
|
|
|
+ const previous_msg_date = this.getLastMessageDate(current_msg_date);
|
|
|
|
+ const previous_msg_el = this.content.querySelector(
|
|
|
|
+ `.message[data-isodate="${previous_msg_date}"]`);
|
|
|
|
+ this.insertMessage(
|
|
|
|
+ attrs, _.bind(previous_msg_el.insertAdjacentElement, previous_msg_el, 'afterend'));
|
|
},
|
|
},
|
|
|
|
|
|
getExtraMessageTemplateAttributes () {
|
|
getExtraMessageTemplateAttributes () {
|