浏览代码

Updates #1999 - Demarcate first unread message

Dele Olajide 5 年之前
父节点
当前提交
cae5e9c875
共有 7 个文件被更改,包括 57 次插入12 次删除
  1. 1 0
      CHANGES.md
  2. 14 7
      package-lock.json
  3. 19 4
      spec/chatbox.js
  4. 1 1
      src/converse-message-view.js
  5. 18 0
      src/headless/converse-chat.js
  6. 1 0
      src/headless/converse-muc.js
  7. 3 0
      src/templates/message.html

+ 1 - 0
CHANGES.md

@@ -21,6 +21,7 @@ Soon we'll deprecate the latter, so prepare now.
 - #1896: Don't send receipts for messages fetched from the archive
 - #1937: Editing a message removes the mentions highlight
 - #1963: Mentions are visually incorrect when used in message replies
+- #1999: Demarcate first unread message
 - #2002: fix rendering of `muc_roomid_policy_hint`
 - #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`

+ 14 - 7
package-lock.json

@@ -2244,7 +2244,8 @@
 			"dependencies": {
 				"filesize": {
 					"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": {
 					"version": "8.1.0",
@@ -2278,7 +2279,8 @@
 				},
 				"jed": {
 					"version": "1.1.1",
-					"resolved": false
+					"resolved": "https://registry.npmjs.org/jed/-/jed-1.1.1.tgz",
+					"integrity": "sha1-elSbvZ/+FYWwzQoZHiAwVb7ldLQ="
 				},
 				"jsonfile": {
 					"version": "5.0.0",
@@ -2299,18 +2301,21 @@
 				},
 				"localforage": {
 					"version": "1.7.3",
-					"resolved": false,
+					"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.7.3.tgz",
+					"integrity": "sha512-1TulyYfc4udS7ECSBT2vwJksWbkwwTX8BzeUIiq8Y07Riy7bDAAnxDaPU/tWyOVmQAcWJIEIFP9lPfBGqVoPgQ==",
 					"requires": {
 						"lie": "3.1.1"
 					}
 				},
 				"lodash": {
 					"version": "4.17.15",
-					"resolved": false
+					"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+					"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
 				},
 				"pluggable.js": {
 					"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": {
 						"lodash": "^4.17.11"
 					}
@@ -2324,11 +2329,13 @@
 				},
 				"strophe.js": {
 					"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": {
 					"version": "12.1.5",
-					"resolved": false,
+					"resolved": "https://registry.npmjs.org/twemoji/-/twemoji-12.1.5.tgz",
+					"integrity": "sha512-B0PBVy5xomwb1M/WZxf/IqPZfnoIYy1skXnlHjMwLwTNfZ9ljh8VgWQktAPcJXu8080WoEh6YwQGPVhDVqvrVQ==",
 					"requires": {
 						"fs-extra": "^8.0.1",
 						"jsonfile": "^5.0.0",

+ 19 - 4
spec/chatbox.js

@@ -1296,6 +1296,8 @@ describe("Chatboxes", function () {
             await _converse.handleMessageStanza(msg);
             await u.waitUntil(() => view.model.messages.length);
             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();
         }));
 
@@ -1329,9 +1331,12 @@ describe("Chatboxes", function () {
             await mock.openChatBoxFor(_converse, sender_jid);
             const chatbox = _converse.chatboxes.get(sender_jid);
             _converse.windowState = 'hidden';
-            _converse.handleMessageStanza(msgFactory());
+            const msg = msgFactory();
+            _converse.handleMessageStanza(msg);
             await u.waitUntil(() => chatbox.messages.length);
             expect(chatbox.get('num_unread')).toBe(1);
+            const msgid = chatbox.messages.last().get('id');
+            expect(chatbox.get('first_unread_id')).toBe(msgid);
             done();
         }));
 
@@ -1347,9 +1352,12 @@ describe("Chatboxes", function () {
             const chatbox = _converse.chatboxes.get(sender_jid);
             chatbox.save('scrolled', true);
             _converse.windowState = 'hidden';
-            _converse.handleMessageStanza(msgFactory());
+            const msg = msgFactory();
+            _converse.handleMessageStanza(msg);
             await u.waitUntil(() => chatbox.messages.length);
             expect(chatbox.get('num_unread')).toBe(1);
+            const msgid = chatbox.messages.last().get('id');
+            expect(chatbox.get('first_unread_id')).toBe(msgid);
             done();
         }));
 
@@ -1364,9 +1372,12 @@ describe("Chatboxes", function () {
             await mock.openChatBoxFor(_converse, sender_jid);
             const chatbox = _converse.chatboxes.get(sender_jid);
             _converse.windowState = 'hidden';
-            _converse.handleMessageStanza(msgFactory());
+            const msg = msgFactory();
+            _converse.handleMessageStanza(msg);
             await u.waitUntil(() => chatbox.messages.length);
             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');
             expect(chatbox.get('num_unread')).toBe(0);
             done();
@@ -1384,11 +1395,15 @@ describe("Chatboxes", function () {
             const chatbox = _converse.chatboxes.get(sender_jid);
             chatbox.save('scrolled', true);
             _converse.windowState = 'hidden';
-            _converse.handleMessageStanza(msgFactory());
+            const msg = msgFactory();
+            _converse.handleMessageStanza(msg);
             await u.waitUntil(() => chatbox.messages.length);
             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');
             expect(chatbox.get('num_unread')).toBe(1);
+            expect(chatbox.get('first_unread_id')).toBe(msgid);
             done();
         }));
     });

+ 1 - 1
src/converse-message-view.js

@@ -145,7 +145,7 @@ converse.plugins.add('converse-message-view', {
                     return this.renderFileUploadProgresBar();
                 }
                 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) {
                     await this.debouncedRender();
                 }

+ 18 - 0
src/headless/converse-chat.js

@@ -1110,11 +1110,29 @@ converse.plugins.add('converse-chat', {
                     return;
                 }
                 if (utils.isNewMessage(message) && this.isHidden()) {
+                    this.setFirstUnreadMsgId(message);
                     this.save({'num_unread': this.get('num_unread') + 1});
                     _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 () {
                 u.safeSave(this, {'num_unread': 0});
             },

+ 1 - 0
src/headless/converse-muc.js

@@ -2387,6 +2387,7 @@ converse.plugins.add('converse-muc', {
                 const body = message.get('message');
                 if (!body) { return; }
                 if (u.isNewMessage(message) && this.isHidden()) {
+                    this.setFirstUnreadMsgId(message);
                     const settings = {'num_unread_general': this.get('num_unread_general') + 1};
                     if (this.isUserMentioned(message)) {
                         settings.num_unread = this.get('num_unread') + 1;

+ 3 - 0
src/templates/message.html

@@ -4,6 +4,9 @@
     <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' : ''}}}">
+        {[ 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">
             {[ 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>