Bläddra i källkod

Re-render chats when the viewport changes

So that custom height/width can be applied or removed.
We want to remove the custom dimensions on smaller viewports.
JC Brand 1 månad sedan
förälder
incheckning
33106fd5b1

+ 14 - 0
src/plugins/controlbox/controlbox.js

@@ -1,5 +1,6 @@
 import { _converse, api, constants, u } from '@converse/headless';
 import { CustomElement } from 'shared/components/element.js';
+import { MOBILE_CUTOFF } from 'shared/constants.js';
 import tplControlbox from './templates/controlbox.js';
 import './navbar.js';
 
@@ -20,6 +21,8 @@ class ControlBoxView extends CustomElement {
         if (this.model.get('connected') && this.model.get('closed') === undefined) {
             this.model.set('closed', !api.settings.get('show_controlbox_by_default'));
         }
+        this.viewportMediaQuery = window.matchMedia(`(max-width: ${MOBILE_CUTOFF}px)`);
+        this.renderOnViewportChange = () => this.requestUpdate();
         /**
          * Triggered when the _converse.ControlBoxView has been initialized and therefore
          * exists. The controlbox contains the login and register forms when the user is
@@ -31,6 +34,17 @@ class ControlBoxView extends CustomElement {
         api.trigger('controlBoxInitialized', this);
     }
 
+    connectedCallback() {
+        super.connectedCallback();
+        this.viewportMediaQuery.addEventListener('change', this.renderOnViewportChange);
+    }
+
+    disconnectedCallback() {
+        super.disconnectedCallback();
+        _converse.state.chatboxviews.remove('controlbox', this);
+        this.viewportMediaQuery.removeEventListener('change', this.renderOnViewportChange);
+    }
+
     setModel() {
         this.model = _converse.state.chatboxes.get('controlbox');
         this.listenTo(_converse.state.connfeedback, 'change:connection_status', () => this.requestUpdate());

+ 6 - 5
src/plugins/muc-views/chatarea.js

@@ -1,6 +1,7 @@
-import { api, converse, u } from '@converse/headless';
+import { api, converse } from '@converse/headless';
 import { __ } from 'i18n';
 import { CustomElement } from 'shared/components/element.js';
+import { MOBILE_CUTOFF } from 'shared/constants.js';
 import tplMUCChatarea from './templates/muc-chatarea.js';
 
 export default class MUCChatArea extends CustomElement {
@@ -17,7 +18,7 @@ export default class MUCChatArea extends CustomElement {
         this.jid = null;
         this.type = null;
         this.split = null;
-        this.mediaQueryList = window.matchMedia('(max-width: 576px)');
+        this.viewportMediaQuery = window.matchMedia(`(max-width: ${MOBILE_CUTOFF}px)`);
     }
 
     async initialize() {
@@ -38,19 +39,19 @@ export default class MUCChatArea extends CustomElement {
      */
     #hideSidebarIfSmallViewport(event) {
         if (this.model?.get('hidden_occupants')) return;
-        const is_small = event ? event.matches : this.mediaQueryList.matches;
+        const is_small = event ? event.matches : this.viewportMediaQuery.matches;
         if (is_small) this.model?.save('hidden_occupants', true);
     }
 
     connectedCallback() {
         super.connectedCallback();
         this.hideSidebarIfSmallViewport = this.#hideSidebarIfSmallViewport.bind(this);
-        this.mediaQueryList.addEventListener('change', this.hideSidebarIfSmallViewport);
+        this.viewportMediaQuery.addEventListener('change', this.hideSidebarIfSmallViewport);
     }
 
     disconnectedCallback() {
         super.disconnectedCallback();
-        this.mediaQueryList?.removeEventListener('change', this.hideSidebarIfSmallViewport);
+        this.viewportMediaQuery?.removeEventListener('change', this.hideSidebarIfSmallViewport);
     }
 
     shouldShowSidebar() {

+ 2 - 0
src/plugins/roomslist/styles/roomsgroups.scss

@@ -27,6 +27,8 @@
                     line-height: 1.5em;
                     height: 2.5em;
                     span {
+                        overflow-x: hidden;
+                        text-overflow: ellipsis;
                         padding-top: 0.25em;
                     }
                 }

+ 10 - 4
src/shared/chat/baseview.js

@@ -1,8 +1,6 @@
-/**
- * @typedef {import('@converse/skeletor').Model} Model
- */
 import { CustomElement } from '../components/element.js';
 import { _converse, api, constants } from '@converse/headless';
+import { MOBILE_CUTOFF } from 'shared/constants.js';
 import { onScrolledDown } from './utils.js';
 
 const { CHATROOMS_TYPE, INACTIVE } = constants;
@@ -17,12 +15,20 @@ export default class BaseChatView extends CustomElement {
     constructor() {
         super();
         this.jid = /** @type {string} */ null;
-        this.model = /** @type {Model} */ null;
+        this.model = /** @type {import('@converse/skeletor').Model} */ null;
+        this.viewportMediaQuery = window.matchMedia(`(max-width: ${MOBILE_CUTOFF}px)`);
+        this.renderOnViewportChange = () => this.requestUpdate();
+    }
+
+    connectedCallback() {
+        super.connectedCallback();
+        this.viewportMediaQuery.addEventListener('change', this.renderOnViewportChange);
     }
 
     disconnectedCallback() {
         super.disconnectedCallback();
         _converse.state.chatboxviews.remove(this.jid, this);
+        this.viewportMediaQuery.removeEventListener('change', this.renderOnViewportChange);
     }
 
     updated() {

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

@@ -8,13 +8,14 @@
 import { api, converse } from '@converse/headless';
 import { html } from 'lit';
 import { until } from 'lit/directives/until.js';
+import { MOBILE_CUTOFF } from 'shared/constants.js';
 import tplNewDay from './templates/new-day.js';
 
 const { dayjs, u } = converse.env;
 const { convertASCII2Emoji, getShortnameReferences, getCodePointReferences } = u;
 
 export function isMobileViewport() {
-    return window.innerWidth <= 768;
+    return window.innerWidth <= MOBILE_CUTOFF;
 }
 
 /**

+ 5 - 0
src/shared/constants.js

@@ -49,3 +49,8 @@ export const PRETTY_CHAT_STATUS = {
     chat:         __('Chatty'),
     online:       __('Online')
 };
+
+
+// The width in pixels below which we're considered on a mobile device and
+// above a desktop device.
+export const MOBILE_CUTOFF = 576;

+ 3 - 0
src/types/plugins/controlbox/controlbox.d.ts

@@ -8,6 +8,9 @@ export default ControlBoxView;
  */
 declare class ControlBoxView extends CustomElement {
     initialize(): void;
+    viewportMediaQuery: MediaQueryList;
+    renderOnViewportChange: () => void;
+    connectedCallback(): void;
     setModel(): void;
     model: any;
     render(): import("lit-html").TemplateResult<1> | "";

+ 1 - 1
src/types/plugins/muc-views/chatarea.d.ts

@@ -13,7 +13,7 @@ export default class MUCChatArea extends CustomElement {
     jid: any;
     type: any;
     split: any;
-    mediaQueryList: MediaQueryList;
+    viewportMediaQuery: MediaQueryList;
     initialize(): Promise<void>;
     model: any;
     render(): import("lit-html").TemplateResult<1> | "";

+ 3 - 1
src/types/shared/chat/baseview.d.ts

@@ -6,6 +6,9 @@ export default class BaseChatView extends CustomElement {
     };
     jid: any;
     model: any;
+    viewportMediaQuery: MediaQueryList;
+    renderOnViewportChange: () => void;
+    connectedCallback(): void;
     updated(): void;
     /**
      * @param {MouseEvent} ev
@@ -25,6 +28,5 @@ export default class BaseChatView extends CustomElement {
     scrollDown(ev?: Event): void;
     onWindowStateChanged(): void;
 }
-export type Model = import("@converse/skeletor").Model;
 import { CustomElement } from '../components/element.js';
 //# sourceMappingURL=baseview.d.ts.map

+ 1 - 0
src/types/shared/constants.d.ts

@@ -8,6 +8,7 @@ export namespace PRETTY_CHAT_STATUS {
     let chat: any;
     let online: any;
 }
+export const MOBILE_CUTOFF: 576;
 export type PrettyChatStatus = {
     offline: string;
     unavailable: string;