Browse Source

WIP: show unread messages for occupant

JC Brand 9 months ago
parent
commit
974990e4ce

+ 5 - 0
src/headless/index.js

@@ -8,6 +8,7 @@ import u from './utils/index.js';
 import converse from './shared/api/public.js';
 import log from './log.js';
 
+
 // START: Removable components
 // ---------------------------
 // The following components may be removed if they're not needed.
@@ -22,12 +23,16 @@ import './plugins/disco/index.js'; // XEP-0030 Service discovery
 import './plugins/adhoc/index.js'; // XEP-0050 Ad Hoc Commands
 import './plugins/headlines/index.js'; // Support for headline messages
 
+import ModelWithMessages from './shared/model-with-messages.js';
+export { ModelWithMessages };
+
 // XEP-0313 Message Archive Management
 export { MAMPlaceholderMessage } from './plugins/mam/index.js';
 
 // XEP-0045 Multi-user chat
 export { MUCMessage, MUCMessages, MUC, MUCOccupant, MUCOccupants } from './plugins/muc/index.js';
 
+
 import './plugins/ping/index.js'; // XEP-0199 XMPP Ping
 import './plugins/pubsub.js'; // XEP-0060 Pubsub
 

+ 2 - 1
src/headless/types/index.d.ts

@@ -2,6 +2,7 @@ export { EmojiPicker } from "./plugins/emoji/index.js";
 export { MAMPlaceholderMessage } from "./plugins/mam/index.js";
 export { XMPPStatus } from "./plugins/status/index.js";
 export default converse;
+import ModelWithMessages from './shared/model-with-messages.js';
 import { api } from './shared/index.js';
 import converse from './shared/api/public.js';
 import { _converse } from './shared/index.js';
@@ -12,7 +13,7 @@ export const constants: typeof shared_constants & typeof muc_constants;
 import { parsers } from './shared/index.js';
 import { constants as shared_constants } from './shared/index.js';
 import * as muc_constants from './plugins/muc/constants.js';
-export { api, converse, _converse, i18n, log, u, parsers };
+export { ModelWithMessages, api, converse, _converse, i18n, log, u, parsers };
 export { Bookmark, Bookmarks } from "./plugins/bookmarks/index.js";
 export { ChatBox, Message, Messages } from "./plugins/chat/index.js";
 export { MUCMessage, MUCMessages, MUC, MUCOccupant, MUCOccupants } from "./plugins/muc/index.js";

+ 2 - 0
src/headless/types/plugins/muc/occupant.d.ts

@@ -210,6 +210,8 @@ declare class MUCOccupant extends MUCOccupant_base {
         hats: any[];
         show: string;
         states: any[];
+        hidden: boolean;
+        num_unread: number;
     };
     save(key: any, val: any, options: any): any;
     getMessagesCollection(): MUCMessages;

+ 5 - 0
src/plugins/muc-views/styles/muc-occupants.scss

@@ -110,6 +110,11 @@
                                 color: var(--link-hover-color);
                             }
 
+                            .msgs-indicator {
+                                margin-left: -0.5em;
+                                margin-right: 0.5em;
+                            }
+
                             .occupant-nick-badge {
                                 display: flex;
                                 justify-content: space-between;

+ 4 - 0
src/plugins/muc-views/templates/occupant.js

@@ -8,6 +8,7 @@ import { html } from "lit";
 import { until } from 'lit/directives/until.js';
 import { showOccupantModal } from '../utils.js';
 import { getAuthorStyle } from 'utils/color.js';
+import { getUnreadMsgsDisplay } from 'shared/chat/utils.js';
 
 const i18n_occupant_hint = /** @param {MUCOccupant} o */(o) => {
     return __('Click to mention %1$s in your message.', o.get('nick'));
@@ -158,6 +159,8 @@ export default (o, chat) => {
         [classes, color] = ['fa fa-circle', 'subdued-color'];
     }
 
+   const num_unread = getUnreadMsgsDisplay(o);
+
     return html`
         <li class="occupant" id="${o.id}">
             <div class="row g-0">
@@ -175,6 +178,7 @@ export default (o, chat) => {
                            style="margin-top: -0.1em"
                            size="0.82em"
                            class="${classes} chat-status chat-status--avatar"></converse-icon>
+                        ${ num_unread ? html`<span class="msgs-indicator">${ num_unread }</span>` : '' }
                     </a>
                 </div>
                 <div class="col occupant-nick-badge">

+ 1 - 1
src/plugins/muc-views/tests/muc-private-messages.js

@@ -2,7 +2,7 @@
 const { stx, u } = converse.env;
 
 describe('When receiving a MUC private message', function () {
-    fit(
+    it(
         "doesn't appear in the main MUC chatarea",
         mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) {
             const muc_jid = 'coven@chat.shakespeare.lit';

+ 0 - 10
src/plugins/rosterview/styles/roster.scss

@@ -116,16 +116,6 @@
                         }
                     }
 
-                    .msgs-indicator {
-                        color: var(--text-color-invert);
-                        background-color: var(--chat-color);
-                        opacity: 1;
-                        border-radius: 10%;
-                        padding: 0.2em 0.4em;
-                        font-size: var(--font-size-small);
-                        margin-right: 0;
-                    }
-
                     .contact-name {
                         padding: 0;
                         margin: 0;

+ 10 - 1
src/shared/chat/utils.js

@@ -1,16 +1,25 @@
 /**
  * @typedef {import('@converse/headless').Message} Message
+ * @typedef {import('@converse/skeletor').Model} Model
  * @typedef {import('../../plugins/muc-views/muc.js').default} MUCView
  */
 import debounce from 'lodash-es/debounce';
-import tplNewDay from './templates/new-day.js';
 import { api, converse } from '@converse/headless';
 import { html } from 'lit';
 import { until } from 'lit/directives/until.js';
+import tplNewDay from './templates/new-day.js';
 
 const { dayjs, u } = converse.env;
 const { convertASCII2Emoji, getShortnameReferences, getCodePointReferences } = u;
 
+/**
+ * @param {Model} model
+ */
+export function getUnreadMsgsDisplay (model) {
+    const num_unread = model.get('num_unread') || 0;
+    return num_unread < 100 ? num_unread : '99+';
+}
+
 export async function getHeadingDropdownItem (promise_or_data) {
     const data = await promise_or_data;
     return data

+ 10 - 0
src/shared/styles/messages.scss

@@ -3,6 +3,16 @@
         color: var(--subdued-color);
     }
 
+    .msgs-indicator {
+        color: var(--text-color-invert);
+        background-color: var(--chat-color);
+        opacity: 1;
+        border-radius: 10%;
+        padding: 0.2em 0.4em;
+        font-size: var(--font-size-small);
+        margin-right: 0;
+    }
+
     .message {
         .show-msg-author-modal {
             align-self: flex-start; // Don't expand height to that of largest sibling

+ 5 - 0
src/types/shared/chat/utils.d.ts

@@ -1,3 +1,7 @@
+/**
+ * @param {Model} model
+ */
+export function getUnreadMsgsDisplay(model: Model): any;
 export function getHeadingDropdownItem(promise_or_data: any): Promise<import("lit").TemplateResult<1> | "">;
 export function getHeadingStandaloneButton(promise_or_data: any): Promise<import("lit").TemplateResult<1>>;
 /**
@@ -64,5 +68,6 @@ export type EmojiMarkupOptions = {
     add_title_wrapper?: boolean;
 };
 export type Message = import("@converse/headless").Message;
+export type Model = import("@converse/skeletor").Model;
 export type MUCView = import("../../plugins/muc-views/muc.js").default;
 //# sourceMappingURL=utils.d.ts.map