Updates #1999 - Demarcate first unread message
This commit is contained in:
parent
6157189efe
commit
cae5e9c875
|
@ -21,6 +21,7 @@ Soon we'll deprecate the latter, so prepare now.
|
||||||
- #1896: Don't send receipts for messages fetched from the archive
|
- #1896: Don't send receipts for messages fetched from the archive
|
||||||
- #1937: Editing a message removes the mentions highlight
|
- #1937: Editing a message removes the mentions highlight
|
||||||
- #1963: Mentions are visually incorrect when used in message replies
|
- #1963: Mentions are visually incorrect when used in message replies
|
||||||
|
- #1999: Demarcate first unread message
|
||||||
- #2002: fix rendering of `muc_roomid_policy_hint`
|
- #2002: fix rendering of `muc_roomid_policy_hint`
|
||||||
- #2006: fix rendering of emojis in case `use_system_emojis == false`
|
- #2006: fix rendering of emojis in case `use_system_emojis == false`
|
||||||
- Allow ignoring of bootstrap modules at build using environment variable. For xample: `export BOOTSTRAP_IGNORE_MODULES="Modal,Dropdown" && make dist`
|
- Allow ignoring of bootstrap modules at build using environment variable. For xample: `export BOOTSTRAP_IGNORE_MODULES="Modal,Dropdown" && make dist`
|
||||||
|
|
21
package-lock.json
generated
21
package-lock.json
generated
|
@ -2244,7 +2244,8 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"filesize": {
|
"filesize": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": false
|
"resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg=="
|
||||||
},
|
},
|
||||||
"fs-extra": {
|
"fs-extra": {
|
||||||
"version": "8.1.0",
|
"version": "8.1.0",
|
||||||
|
@ -2278,7 +2279,8 @@
|
||||||
},
|
},
|
||||||
"jed": {
|
"jed": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": false
|
"resolved": "https://registry.npmjs.org/jed/-/jed-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-elSbvZ/+FYWwzQoZHiAwVb7ldLQ="
|
||||||
},
|
},
|
||||||
"jsonfile": {
|
"jsonfile": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
|
@ -2299,18 +2301,21 @@
|
||||||
},
|
},
|
||||||
"localforage": {
|
"localforage": {
|
||||||
"version": "1.7.3",
|
"version": "1.7.3",
|
||||||
"resolved": false,
|
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.7.3.tgz",
|
||||||
|
"integrity": "sha512-1TulyYfc4udS7ECSBT2vwJksWbkwwTX8BzeUIiq8Y07Riy7bDAAnxDaPU/tWyOVmQAcWJIEIFP9lPfBGqVoPgQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"lie": "3.1.1"
|
"lie": "3.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "4.17.15",
|
"version": "4.17.15",
|
||||||
"resolved": false
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||||
|
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||||
},
|
},
|
||||||
"pluggable.js": {
|
"pluggable.js": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": false,
|
"resolved": "https://registry.npmjs.org/pluggable.js/-/pluggable.js-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-SBt6v6Tbp20Jf8hU0cpcc/+HBHGMY8/Q+yA6Ih0tBQE8tfdZ6U4PRG0iNvUUjLx/hVyOP53n0UfGBymlfaaXCg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"lodash": "^4.17.11"
|
"lodash": "^4.17.11"
|
||||||
}
|
}
|
||||||
|
@ -2324,11 +2329,13 @@
|
||||||
},
|
},
|
||||||
"strophe.js": {
|
"strophe.js": {
|
||||||
"version": "1.3.4",
|
"version": "1.3.4",
|
||||||
"resolved": false
|
"resolved": "https://registry.npmjs.org/strophe.js/-/strophe.js-1.3.4.tgz",
|
||||||
|
"integrity": "sha512-jSLDG8jolhAwGOSgiJ7DTMSYK3wVoEJHKtpVRyEacQZ6CWA6z2WRPJpcFMjsIweq5aP9/XIvKUQqHBu/ZhvESA=="
|
||||||
},
|
},
|
||||||
"twemoji": {
|
"twemoji": {
|
||||||
"version": "12.1.5",
|
"version": "12.1.5",
|
||||||
"resolved": false,
|
"resolved": "https://registry.npmjs.org/twemoji/-/twemoji-12.1.5.tgz",
|
||||||
|
"integrity": "sha512-B0PBVy5xomwb1M/WZxf/IqPZfnoIYy1skXnlHjMwLwTNfZ9ljh8VgWQktAPcJXu8080WoEh6YwQGPVhDVqvrVQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"fs-extra": "^8.0.1",
|
"fs-extra": "^8.0.1",
|
||||||
"jsonfile": "^5.0.0",
|
"jsonfile": "^5.0.0",
|
||||||
|
|
|
@ -1296,6 +1296,8 @@ describe("Chatboxes", function () {
|
||||||
await _converse.handleMessageStanza(msg);
|
await _converse.handleMessageStanza(msg);
|
||||||
await u.waitUntil(() => view.model.messages.length);
|
await u.waitUntil(() => view.model.messages.length);
|
||||||
expect(view.model.get('num_unread')).toBe(1);
|
expect(view.model.get('num_unread')).toBe(1);
|
||||||
|
const msgid = view.model.messages.last().get('id');
|
||||||
|
expect(view.model.get('first_unread_id')).toBe(msgid);
|
||||||
done();
|
done();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -1329,9 +1331,12 @@ describe("Chatboxes", function () {
|
||||||
await mock.openChatBoxFor(_converse, sender_jid);
|
await mock.openChatBoxFor(_converse, sender_jid);
|
||||||
const chatbox = _converse.chatboxes.get(sender_jid);
|
const chatbox = _converse.chatboxes.get(sender_jid);
|
||||||
_converse.windowState = 'hidden';
|
_converse.windowState = 'hidden';
|
||||||
_converse.handleMessageStanza(msgFactory());
|
const msg = msgFactory();
|
||||||
|
_converse.handleMessageStanza(msg);
|
||||||
await u.waitUntil(() => chatbox.messages.length);
|
await u.waitUntil(() => chatbox.messages.length);
|
||||||
expect(chatbox.get('num_unread')).toBe(1);
|
expect(chatbox.get('num_unread')).toBe(1);
|
||||||
|
const msgid = chatbox.messages.last().get('id');
|
||||||
|
expect(chatbox.get('first_unread_id')).toBe(msgid);
|
||||||
done();
|
done();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -1347,9 +1352,12 @@ describe("Chatboxes", function () {
|
||||||
const chatbox = _converse.chatboxes.get(sender_jid);
|
const chatbox = _converse.chatboxes.get(sender_jid);
|
||||||
chatbox.save('scrolled', true);
|
chatbox.save('scrolled', true);
|
||||||
_converse.windowState = 'hidden';
|
_converse.windowState = 'hidden';
|
||||||
_converse.handleMessageStanza(msgFactory());
|
const msg = msgFactory();
|
||||||
|
_converse.handleMessageStanza(msg);
|
||||||
await u.waitUntil(() => chatbox.messages.length);
|
await u.waitUntil(() => chatbox.messages.length);
|
||||||
expect(chatbox.get('num_unread')).toBe(1);
|
expect(chatbox.get('num_unread')).toBe(1);
|
||||||
|
const msgid = chatbox.messages.last().get('id');
|
||||||
|
expect(chatbox.get('first_unread_id')).toBe(msgid);
|
||||||
done();
|
done();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -1364,9 +1372,12 @@ describe("Chatboxes", function () {
|
||||||
await mock.openChatBoxFor(_converse, sender_jid);
|
await mock.openChatBoxFor(_converse, sender_jid);
|
||||||
const chatbox = _converse.chatboxes.get(sender_jid);
|
const chatbox = _converse.chatboxes.get(sender_jid);
|
||||||
_converse.windowState = 'hidden';
|
_converse.windowState = 'hidden';
|
||||||
_converse.handleMessageStanza(msgFactory());
|
const msg = msgFactory();
|
||||||
|
_converse.handleMessageStanza(msg);
|
||||||
await u.waitUntil(() => chatbox.messages.length);
|
await u.waitUntil(() => chatbox.messages.length);
|
||||||
expect(chatbox.get('num_unread')).toBe(1);
|
expect(chatbox.get('num_unread')).toBe(1);
|
||||||
|
const msgid = chatbox.messages.last().get('id');
|
||||||
|
expect(chatbox.get('first_unread_id')).toBe(msgid);
|
||||||
_converse.saveWindowState(null, 'focus');
|
_converse.saveWindowState(null, 'focus');
|
||||||
expect(chatbox.get('num_unread')).toBe(0);
|
expect(chatbox.get('num_unread')).toBe(0);
|
||||||
done();
|
done();
|
||||||
|
@ -1384,11 +1395,15 @@ describe("Chatboxes", function () {
|
||||||
const chatbox = _converse.chatboxes.get(sender_jid);
|
const chatbox = _converse.chatboxes.get(sender_jid);
|
||||||
chatbox.save('scrolled', true);
|
chatbox.save('scrolled', true);
|
||||||
_converse.windowState = 'hidden';
|
_converse.windowState = 'hidden';
|
||||||
_converse.handleMessageStanza(msgFactory());
|
const msg = msgFactory();
|
||||||
|
_converse.handleMessageStanza(msg);
|
||||||
await u.waitUntil(() => chatbox.messages.length);
|
await u.waitUntil(() => chatbox.messages.length);
|
||||||
expect(chatbox.get('num_unread')).toBe(1);
|
expect(chatbox.get('num_unread')).toBe(1);
|
||||||
|
const msgid = chatbox.messages.last().get('id');
|
||||||
|
expect(chatbox.get('first_unread_id')).toBe(msgid);
|
||||||
_converse.saveWindowState(null, 'focus');
|
_converse.saveWindowState(null, 'focus');
|
||||||
expect(chatbox.get('num_unread')).toBe(1);
|
expect(chatbox.get('num_unread')).toBe(1);
|
||||||
|
expect(chatbox.get('first_unread_id')).toBe(msgid);
|
||||||
done();
|
done();
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
|
@ -145,7 +145,7 @@ converse.plugins.add('converse-message-view', {
|
||||||
return this.renderFileUploadProgresBar();
|
return this.renderFileUploadProgresBar();
|
||||||
}
|
}
|
||||||
const isValidChange = prop => Object.prototype.hasOwnProperty.call(this.model.changed, prop);
|
const isValidChange = prop => Object.prototype.hasOwnProperty.call(this.model.changed, prop);
|
||||||
const props = ['moderated', 'retracted', 'correcting', 'message', 'type', 'upload', 'received', 'editable'];
|
const props = ['moderated', 'retracted', 'correcting', 'message', 'type', 'upload', 'received', 'editable', 'first_unread'];
|
||||||
if (props.filter(isValidChange).length) {
|
if (props.filter(isValidChange).length) {
|
||||||
await this.debouncedRender();
|
await this.debouncedRender();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1110,11 +1110,29 @@ converse.plugins.add('converse-chat', {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (utils.isNewMessage(message) && this.isHidden()) {
|
if (utils.isNewMessage(message) && this.isHidden()) {
|
||||||
|
this.setFirstUnreadMsgId(message);
|
||||||
this.save({'num_unread': this.get('num_unread') + 1});
|
this.save({'num_unread': this.get('num_unread') + 1});
|
||||||
_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});
|
||||||
},
|
},
|
||||||
|
|
|
@ -2387,6 +2387,7 @@ 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 = {'num_unread_general': this.get('num_unread_general') + 1};
|
const settings = {'num_unread_general': this.get('num_unread_general') + 1};
|
||||||
if (this.isUserMentioned(message)) {
|
if (this.isUserMentioned(message)) {
|
||||||
settings.num_unread = this.get('num_unread') + 1;
|
settings.num_unread = this.get('num_unread') + 1;
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
<canvas class="avatar chat-msg__avatar" height="36" width="36"></canvas>
|
<canvas class="avatar chat-msg__avatar" height="36" width="36"></canvas>
|
||||||
{[ } ]}
|
{[ } ]}
|
||||||
<div class="chat-msg__content chat-msg__content--{{{o.sender}}} {{{o.is_me_message ? 'chat-msg__content--action' : ''}}}">
|
<div class="chat-msg__content chat-msg__content--{{{o.sender}}} {{{o.is_me_message ? 'chat-msg__content--action' : ''}}}">
|
||||||
|
{[ if (o.first_unread) { ]}
|
||||||
|
<div class="message date-separator"><hr class="separator"><span class="separator-text">{{{o.__('unread messages')}}}</span></div>
|
||||||
|
{[ } ]}
|
||||||
<span class="chat-msg__heading">
|
<span class="chat-msg__heading">
|
||||||
{[ if (o.is_me_message) { ]}<time timestamp="{{{o.isodate}}}" class="chat-msg__time">{{{o.pretty_time}}}</time>{[ } ]}
|
{[ if (o.is_me_message) { ]}<time timestamp="{{{o.isodate}}}" class="chat-msg__time">{{{o.pretty_time}}}</time>{[ } ]}
|
||||||
<span class="chat-msg__author">{[ if (o.is_me_message) { ]}**{[ }; ]}{{{o.username}}}</span>
|
<span class="chat-msg__author">{[ if (o.is_me_message) { ]}**{[ }; ]}{{{o.username}}}</span>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user