Fix trimming of chats in overlayed view mode

This commit is contained in:
JC Brand 2021-10-14 17:07:28 +02:00
parent 5a7f16b6f9
commit 3cfdf4c946
7 changed files with 23 additions and 32 deletions

View File

@ -2,6 +2,7 @@
## 9.0.0 (Unreleased) ## 9.0.0 (Unreleased)
- Fix trimming of chats in overlayed view mode
- #2647: Singleton mode doesn't work - #2647: Singleton mode doesn't work
- Emit a `change` event when a configuration setting changes - Emit a `change` event when a configuration setting changes

View File

@ -13,6 +13,15 @@ class ChatBoxViews {
return this.views[key]; return this.views[key];
} }
xget (id) {
return this.keys()
.filter(k => (k !== id))
.reduce((acc, k) => {
acc[k] = this.views[k]
return acc;
}, {});
}
getAll () { getAll () {
return Object.values(this.views); return Object.values(this.views);
} }

View File

@ -69,9 +69,7 @@ converse.plugins.add('converse-controlbox', {
_converse.ControlBox = ControlBox; _converse.ControlBox = ControlBox;
_converse.ControlBoxToggle = ControlBoxToggle; _converse.ControlBoxToggle = ControlBoxToggle;
/******************** Event Handlers ********************/
api.listen.on('chatBoxesFetched', onChatBoxesFetched); api.listen.on('chatBoxesFetched', onChatBoxesFetched);
api.listen.on('cleanup', () => delete _converse.controlboxtoggle);
api.listen.on('clearSession', clearSession); api.listen.on('clearSession', clearSession);
api.listen.on('will-reconnect', disconnect); api.listen.on('will-reconnect', disconnect);

View File

@ -3,10 +3,10 @@
* @copyright 2020, the Converse.js contributors * @copyright 2020, the Converse.js contributors
* @license Mozilla Public License (MPLv2) * @license Mozilla Public License (MPLv2)
*/ */
import './view.js';
import './components/minimized-chat.js'; import './components/minimized-chat.js';
import 'plugins/chatview/index.js'; import 'plugins/chatview/index.js';
import debounce from 'lodash-es/debounce'; import debounce from 'lodash-es/debounce';
import MinimizedChats from './view.js';
import MinimizedChatsToggle from './toggle.js'; import MinimizedChatsToggle from './toggle.js';
import { _converse, api, converse } from '@converse/headless/core'; import { _converse, api, converse } from '@converse/headless/core';
import { import {
@ -104,30 +104,19 @@ converse.plugins.add('converse-minimize', {
initialize () { initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by Converse.js's plugin machinery.
*/
api.settings.extend({'no_trimming': false}); api.settings.extend({'no_trimming': false});
api.promises.add('minimizedChatsInitialized'); api.promises.add('minimizedChatsInitialized');
_converse.MinimizedChatsToggle = MinimizedChatsToggle; _converse.MinimizedChatsToggle = MinimizedChatsToggle;
_converse.MinimizedChats = MinimizedChats; _converse.minimize = { trimChats, minimize, maximize };
_converse.minimize = {};
_converse.minimize.trimChats = trimChats;
_converse.minimize.minimize = minimize;
_converse.minimize.maximize = maximize;
function onChatInitialized (model) { function onChatInitialized (model) {
model.on( 'change:minimized', () => onMinimizedChanged(model)); model.on( 'change:minimized', () => onMinimizedChanged(model));
} }
/************************ BEGIN Event Handlers ************************/
api.listen.on('chatBoxViewInitialized', view => _converse.minimize.trimChats(view)); api.listen.on('chatBoxViewInitialized', view => _converse.minimize.trimChats(view));
api.listen.on('chatRoomViewInitialized', view => _converse.minimize.trimChats(view)); api.listen.on('chatRoomViewInitialized', view => _converse.minimize.trimChats(view));
api.listen.on('chatBoxMaximized', view => _converse.minimize.trimChats(view));
api.listen.on('controlBoxOpened', view => _converse.minimize.trimChats(view)); api.listen.on('controlBoxOpened', view => _converse.minimize.trimChats(view));
api.listen.on('chatBoxInitialized', onChatInitialized); api.listen.on('chatBoxInitialized', onChatInitialized);
api.listen.on('chatRoomInitialized', onChatInitialized); api.listen.on('chatRoomInitialized', onChatInitialized);

View File

@ -164,7 +164,7 @@ describe("A Chatbox", function () {
await u.waitUntil(() => _converse.chatboxviews.keys().length === 1); await u.waitUntil(() => _converse.chatboxviews.keys().length === 1);
const minimized_chats = await u.waitUntil(() => document.querySelector("converse-minimized-chats")); const minimized_chats = await u.waitUntil(() => document.querySelector("converse-minimized-chats"));
minimized_chats.querySelector("a.restore-chat").click(); minimized_chats.querySelector("a.restore-chat").click();
expect(_converse.minimize.trimChats.calls.count()).toBe(17); expect(_converse.minimize.trimChats.calls.count()).toBe(16);
})); }));
}); });

View File

@ -11,7 +11,8 @@ function getChatBoxWidth (view) {
if (u.isVisible(view)) { if (u.isVisible(view)) {
return u.getOuterWidth(view, true); return u.getOuterWidth(view, true);
} else { } else {
return u.getOuterWidth(_converse.controlboxtoggle.el, true); const toggle = document.querySelector('converse-controlbox-toggle');
return toggle ? u.getOuterWidth(toggle, true) : 0;
} }
} else if (!view.model.get('minimized') && u.isVisible(view)) { } else if (!view.model.get('minimized') && u.isVisible(view)) {
return u.getOuterWidth(view, true); return u.getOuterWidth(view, true);
@ -28,13 +29,13 @@ function getShownChats () {
} }
function getMinimizedWidth () { function getMinimizedWidth () {
const minimized_el = _converse.minimized_chats?.el; const minimized_el = document.querySelector('converse-minimized-chats');
return _converse.chatboxes.pluck('minimized').includes(true) ? u.getOuterWidth(minimized_el, true) : 0; return _converse.chatboxes.pluck('minimized').includes(true) ? u.getOuterWidth(minimized_el, true) : 0;
} }
function getBoxesWidth (newchat) { function getBoxesWidth (newchat) {
const new_id = newchat ? newchat.model.get('id') : null; const new_id = newchat ? newchat.model.get('id') : null;
const newchat_width = newchat ? u.getOuterWidth(newchat.el, true) : 0; const newchat_width = newchat ? u.getOuterWidth(newchat, true) : 0;
return Object.values(_converse.chatboxviews.xget(new_id)) return Object.values(_converse.chatboxviews.xget(new_id))
.reduce((memo, view) => memo + getChatBoxWidth(view), newchat_width); .reduce((memo, view) => memo + getChatBoxWidth(view), newchat_width);
} }
@ -48,8 +49,8 @@ function getBoxesWidth (newchat) {
* @method _converse.ChatBoxViews#trimChats * @method _converse.ChatBoxViews#trimChats
* @param { _converse.ChatBoxView|_converse.ChatRoomView|_converse.ControlBoxView|_converse.HeadlinesBoxView } [newchat] * @param { _converse.ChatBoxView|_converse.ChatRoomView|_converse.ControlBoxView|_converse.HeadlinesBoxView } [newchat]
*/ */
export async function trimChats (newchat) { export function trimChats (newchat) {
if (_converse.isTestEnv() || api.settings.get('no_trimming') || !api.connection.connected() || api.settings.get("view_mode") !== 'overlayed') { if (_converse.isTestEnv() || api.settings.get('no_trimming') || api.settings.get("view_mode") !== 'overlayed') {
return; return;
} }
const shown_chats = getShownChats(); const shown_chats = getShownChats();
@ -63,21 +64,14 @@ export async function trimChats (newchat) {
// fullscreen. In this case we don't trim. // fullscreen. In this case we don't trim.
return; return;
} }
await api.waitUntil('minimizedChatsInitialized'); const minimized_el = document.querySelector('converse-minimized-chats');
const minimized_el = _converse.minimized_chats?.el;
if (minimized_el) { if (minimized_el) {
while ((getMinimizedWidth() + getBoxesWidth(newchat)) > body_width) { while ((getMinimizedWidth() + getBoxesWidth(newchat)) > body_width) {
const new_id = newchat ? newchat.model.get('id') : null; const new_id = newchat ? newchat.model.get('id') : null;
const oldest_chat = getOldestMaximizedChat([new_id]); const oldest_chat = getOldestMaximizedChat([new_id]);
if (oldest_chat) { if (oldest_chat) {
// We hide the chat immediately, because waiting const model = _converse.chatboxes.get(oldest_chat.get('id'));
// for the event to fire (and letting the model?.save('hidden', true);
// ChatBoxView hide it then) causes race
// conditions.
const view = _converse.chatboxviews.get(oldest_chat.get('id'));
if (view) {
view.hide();
}
minimize(oldest_chat); minimize(oldest_chat);
} else { } else {
break; break;

View File

@ -5,7 +5,7 @@ const u = converse.env.utils;
describe("A MAM archived message", function () { describe("A MAM archived message", function () {
fit("will appear in the correct order", it("will appear in the correct order",
mock.initConverse([], {}, async function (_converse) { mock.initConverse([], {}, async function (_converse) {
const nick = 'romeo'; const nick = 'romeo';