parent
ccd817cce1
commit
ac36adddfe
@ -1353,7 +1353,7 @@ describe("Chatboxes", function () {
|
|||||||
done();
|
done();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("is incremeted when message is received, chatbox is scrolled down and the window is not focused",
|
it("is incremented when message is received, chatbox is scrolled down and the window is not focused",
|
||||||
mock.initConverse(['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
mock.initConverse(['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||||
async function (done, _converse) {
|
async function (done, _converse) {
|
||||||
|
|
||||||
@ -1375,7 +1375,7 @@ describe("Chatboxes", function () {
|
|||||||
done();
|
done();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("is incremeted when message is received, chatbox is scrolled up and the window is not focused",
|
it("is incremented when message is received, chatbox is scrolled up and the window is not focused",
|
||||||
mock.initConverse(
|
mock.initConverse(
|
||||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||||
async function (done, _converse) {
|
async function (done, _converse) {
|
||||||
|
@ -6,6 +6,30 @@ const u = converse.env.utils;
|
|||||||
|
|
||||||
describe("A Chat Message", function () {
|
describe("A Chat Message", function () {
|
||||||
|
|
||||||
|
it("will be demarcated if it's the first newly received message",
|
||||||
|
mock.initConverse(['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||||
|
async function (done, _converse) {
|
||||||
|
|
||||||
|
await mock.waitForRoster(_converse, 'current', 1);
|
||||||
|
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
||||||
|
await mock.openChatBoxFor(_converse, contact_jid);
|
||||||
|
const view = _converse.api.chatviews.get(contact_jid);
|
||||||
|
await _converse.handleMessageStanza(mock.createChatMessage(_converse, contact_jid, 'This message will be read'));
|
||||||
|
|
||||||
|
_converse.windowState = 'hidden';
|
||||||
|
await _converse.handleMessageStanza(mock.createChatMessage(_converse, contact_jid, 'This message will be new'));
|
||||||
|
|
||||||
|
await u.waitUntil(() => view.model.messages.length);
|
||||||
|
expect(view.model.get('num_unread')).toBe(1);
|
||||||
|
expect(view.model.get('first_unread_id')).toBe(view.model.messages.last().get('id'));
|
||||||
|
|
||||||
|
await u.waitUntil(() => view.el.querySelectorAll('converse-chat-message').length === 2);
|
||||||
|
const last_msg_el = view.el.querySelector('converse-chat-message:last-child');
|
||||||
|
expect(last_msg_el.firstElementChild?.textContent).toBe('New messages');
|
||||||
|
done();
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
it("is rejected if it's an unencapsulated forwarded message",
|
it("is rejected if it's an unencapsulated forwarded message",
|
||||||
mock.initConverse(
|
mock.initConverse(
|
||||||
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||||
|
@ -4,7 +4,7 @@ let _converse, initConverse;
|
|||||||
|
|
||||||
const converseLoaded = new Promise(resolve => window.addEventListener('converse-loaded', resolve));
|
const converseLoaded = new Promise(resolve => window.addEventListener('converse-loaded', resolve));
|
||||||
|
|
||||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = 7000;
|
||||||
|
|
||||||
mock.initConverse = function (promise_names=[], settings=null, func) {
|
mock.initConverse = function (promise_names=[], settings=null, func) {
|
||||||
if (typeof promise_names === "function") {
|
if (typeof promise_names === "function") {
|
||||||
|
@ -74,7 +74,8 @@ describe("A sent presence stanza", function () {
|
|||||||
spyOn(_converse.connection, 'send').and.callThrough();
|
spyOn(_converse.connection, 'send').and.callThrough();
|
||||||
|
|
||||||
const cbview = _converse.chatboxviews.get('controlbox');
|
const cbview = _converse.chatboxviews.get('controlbox');
|
||||||
cbview.el.querySelector('.change-status').click()
|
const change_status_el = await u.waitUntil(() => cbview.el.querySelector('.change-status'));
|
||||||
|
change_status_el.click()
|
||||||
const modal = _converse.xmppstatusview.status_modal;
|
const modal = _converse.xmppstatusview.status_modal;
|
||||||
await u.waitUntil(() => u.isVisible(modal.el), 1000);
|
await u.waitUntil(() => u.isVisible(modal.el), 1000);
|
||||||
const msg = 'My custom status';
|
const msg = 'My custom status';
|
||||||
|
@ -20,6 +20,7 @@ const tpl_message = (o) => html`
|
|||||||
?has_mentions=${o.has_mentions}
|
?has_mentions=${o.has_mentions}
|
||||||
?is_delayed=${o.is_delayed}
|
?is_delayed=${o.is_delayed}
|
||||||
?is_encrypted=${o.is_encrypted}
|
?is_encrypted=${o.is_encrypted}
|
||||||
|
?is_first_unread=${o.is_first_unread}
|
||||||
?is_me_message=${o.is_me_message}
|
?is_me_message=${o.is_me_message}
|
||||||
?is_only_emojis=${o.is_only_emojis}
|
?is_only_emojis=${o.is_only_emojis}
|
||||||
?is_retracted=${o.is_retracted}
|
?is_retracted=${o.is_retracted}
|
||||||
@ -67,6 +68,18 @@ function getDayIndicator (model) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getHats (model) {
|
||||||
|
if (model.get('type') === 'groupchat') {
|
||||||
|
if (api.settings.get('muc_hats_from_vcard')) {
|
||||||
|
const role = model.vcard ? model.vcard.get('role') : null;
|
||||||
|
return role ? role.split(',') : [];
|
||||||
|
} else {
|
||||||
|
return model.occupant?.get('hats') || [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class MessageHistory extends CustomElement {
|
class MessageHistory extends CustomElement {
|
||||||
|
|
||||||
@ -91,30 +104,18 @@ class MessageHistory extends CustomElement {
|
|||||||
}
|
}
|
||||||
const day = getDayIndicator(model);
|
const day = getDayIndicator(model);
|
||||||
const templates = day ? [day] : [];
|
const templates = day ? [day] : [];
|
||||||
const is_retracted = model.get('retracted') || model.get('moderated') === 'retracted';
|
|
||||||
const is_groupchat = model.get('type') === 'groupchat';
|
const is_groupchat = model.get('type') === 'groupchat';
|
||||||
|
|
||||||
let hats = [];
|
|
||||||
if (is_groupchat) {
|
|
||||||
if (api.settings.get('muc_hats_from_vcard')) {
|
|
||||||
const role = model.vcard ? model.vcard.get('role') : null;
|
|
||||||
hats = role ? role.split(',') : [];
|
|
||||||
} else {
|
|
||||||
hats = model.occupant?.get('hats') || [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const chatbox = this.chatview.model;
|
const chatbox = this.chatview.model;
|
||||||
const has_mentions = is_groupchat && model.get('sender') === 'them' && chatbox.isUserMentioned(model);
|
|
||||||
const message = tpl_message(
|
const message = tpl_message(
|
||||||
Object.assign(model.toJSON(), {
|
Object.assign(model.toJSON(), {
|
||||||
'chatview': this.chatview,
|
'chatview': this.chatview,
|
||||||
|
'has_mentions': is_groupchat && model.get('sender') === 'them' && chatbox.isUserMentioned(model),
|
||||||
|
'hats': getHats(model),
|
||||||
|
'is_first_unread': chatbox.get('first_unread_id') === model.get('id'),
|
||||||
'is_me_message': model.isMeCommand(),
|
'is_me_message': model.isMeCommand(),
|
||||||
|
'is_retracted': model.get('retracted') || model.get('moderated') === 'retracted',
|
||||||
'occupant': model.occupant,
|
'occupant': model.occupant,
|
||||||
'username': model.getDisplayName(),
|
'username': model.getDisplayName(),
|
||||||
has_mentions,
|
|
||||||
hats,
|
|
||||||
is_retracted,
|
|
||||||
model,
|
model,
|
||||||
}));
|
}));
|
||||||
return [...templates, message];
|
return [...templates, message];
|
||||||
|
@ -17,7 +17,8 @@ const i18n_edit_message = __('Edit this message');
|
|||||||
const i18n_edited = __('This message has been edited');
|
const i18n_edited = __('This message has been edited');
|
||||||
const i18n_show = __('Show more');
|
const i18n_show = __('Show more');
|
||||||
const i18n_show_less = __('Show less');
|
const i18n_show_less = __('Show less');
|
||||||
const i18n_uploading = __('Uploading file:')
|
const i18n_uploading = __('Uploading file:');
|
||||||
|
const i18n_new_messages = __('New messages');
|
||||||
|
|
||||||
|
|
||||||
class Message extends CustomElement {
|
class Message extends CustomElement {
|
||||||
@ -30,19 +31,19 @@ class Message extends CustomElement {
|
|||||||
editable: { type: Boolean },
|
editable: { type: Boolean },
|
||||||
error: { type: String },
|
error: { type: String },
|
||||||
error_text: { type: String },
|
error_text: { type: String },
|
||||||
first_unread: { type: Boolean },
|
|
||||||
from: { type: String },
|
from: { type: String },
|
||||||
has_mentions: { type: Boolean },
|
has_mentions: { type: Boolean },
|
||||||
hats: { type: Array },
|
hats: { type: Array },
|
||||||
|
edited: { type: String },
|
||||||
is_delayed: { type: Boolean },
|
is_delayed: { type: Boolean },
|
||||||
is_encrypted: { type: Boolean },
|
is_encrypted: { type: Boolean },
|
||||||
|
is_first_unread: { type: Boolean },
|
||||||
is_me_message: { type: Boolean },
|
is_me_message: { type: Boolean },
|
||||||
is_only_emojis: { type: Boolean },
|
is_only_emojis: { type: Boolean },
|
||||||
is_retracted: { type: Boolean },
|
is_retracted: { type: Boolean },
|
||||||
is_spoiler: { type: Boolean },
|
is_spoiler: { type: Boolean },
|
||||||
is_spoiler_visible: { type: Boolean },
|
is_spoiler_visible: { type: Boolean },
|
||||||
message_type: { type: String },
|
message_type: { type: String },
|
||||||
edited: { type: String },
|
|
||||||
model: { type: Object },
|
model: { type: Object },
|
||||||
moderated_by: { type: String },
|
moderated_by: { type: String },
|
||||||
moderation_reason: { type: String },
|
moderation_reason: { type: String },
|
||||||
@ -125,6 +126,7 @@ class Message extends CustomElement {
|
|||||||
renderChatMessage () {
|
renderChatMessage () {
|
||||||
const is_groupchat_message = (this.message_type === 'groupchat');
|
const is_groupchat_message = (this.message_type === 'groupchat');
|
||||||
return html`
|
return html`
|
||||||
|
${ this.is_first_unread ? html`<div class="message date-separator"><hr class="separator"><span class="separator-text">${ i18n_new_messages }</span></div>` : '' }
|
||||||
<div class="message chat-msg ${this.message_type} ${this.getExtraMessageClasses()}
|
<div class="message chat-msg ${this.message_type} ${this.getExtraMessageClasses()}
|
||||||
${ this.is_me_message ? 'chat-msg--action' : '' }
|
${ this.is_me_message ? 'chat-msg--action' : '' }
|
||||||
${this.isFollowup() ? 'chat-msg--followup' : ''}"
|
${this.isFollowup() ? 'chat-msg--followup' : ''}"
|
||||||
@ -132,7 +134,6 @@ class Message extends CustomElement {
|
|||||||
|
|
||||||
${ renderAvatar(this) }
|
${ renderAvatar(this) }
|
||||||
<div class="chat-msg__content chat-msg__content--${this.sender} ${this.is_me_message ? 'chat-msg__content--action' : ''}">
|
<div class="chat-msg__content chat-msg__content--${this.sender} ${this.is_me_message ? 'chat-msg__content--action' : ''}">
|
||||||
${this.first_unread ? html`<div class="message date-separator"><hr class="separator"><span class="separator-text">{{{this.__('unread messages')}}}</span></div>` : '' }
|
|
||||||
<span class="chat-msg__heading">
|
<span class="chat-msg__heading">
|
||||||
${ (this.is_me_message) ? html`
|
${ (this.is_me_message) ? html`
|
||||||
<time timestamp="${this.time}" class="chat-msg__time">${this.pretty_time}</time>
|
<time timestamp="${this.time}" class="chat-msg__time">${this.pretty_time}</time>
|
||||||
|
@ -1145,29 +1145,17 @@ converse.plugins.add('converse-chat', {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (utils.isNewMessage(message) && this.isHidden()) {
|
if (utils.isNewMessage(message) && this.isHidden()) {
|
||||||
this.setFirstUnreadMsgId(message);
|
const settings = {
|
||||||
this.save({'num_unread': this.get('num_unread') + 1});
|
'num_unread': this.get('num_unread') + 1
|
||||||
|
};
|
||||||
|
if (this.get('num_unread') === 0) {
|
||||||
|
settings['first_unread_id'] = message.get('id');
|
||||||
|
}
|
||||||
|
this.save(settings);
|
||||||
_converse.incrementMsgCounter();
|
_converse.incrementMsgCounter();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the msgid of the first unread realtime message in a ChatBox.
|
|
||||||
* @param {_converse.Message} message
|
|
||||||
*/
|
|
||||||
setFirstUnreadMsgId (message) {
|
|
||||||
if (this.get('num_unread') == 0) {
|
|
||||||
const first_unread_id = this.get('first_unread_id');
|
|
||||||
|
|
||||||
if (first_unread_id) {
|
|
||||||
const msg = this.messages.get(first_unread_id);
|
|
||||||
if (msg) msg.save("first_unread", false);
|
|
||||||
}
|
|
||||||
message.save("first_unread", true);
|
|
||||||
this.save({'first_unread_id': message.get('id')});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
clearUnreadMsgCounter () {
|
clearUnreadMsgCounter () {
|
||||||
u.safeSave(this, {'num_unread': 0});
|
u.safeSave(this, {'num_unread': 0});
|
||||||
},
|
},
|
||||||
|
@ -2408,8 +2408,12 @@ converse.plugins.add('converse-muc', {
|
|||||||
const body = message.get('message');
|
const body = message.get('message');
|
||||||
if (!body) { return; }
|
if (!body) { return; }
|
||||||
if (u.isNewMessage(message) && this.isHidden()) {
|
if (u.isNewMessage(message) && this.isHidden()) {
|
||||||
this.setFirstUnreadMsgId(message);
|
const settings = {
|
||||||
const settings = {'num_unread_general': this.get('num_unread_general') + 1};
|
'num_unread_general': this.get('num_unread_general') + 1
|
||||||
|
};
|
||||||
|
if (this.get('num_unread') === 0) {
|
||||||
|
settings['first_unread_id'] = message.get('id');
|
||||||
|
}
|
||||||
if (this.isUserMentioned(message)) {
|
if (this.isUserMentioned(message)) {
|
||||||
settings.num_unread = this.get('num_unread') + 1;
|
settings.num_unread = this.get('num_unread') + 1;
|
||||||
_converse.incrementMsgCounter();
|
_converse.incrementMsgCounter();
|
||||||
|
Loading…
Reference in New Issue
Block a user