Commit 38d1e4e3 authored by JC Brand's avatar JC Brand

Bugfix. Sometimes when trimming chats, minimized chats go off screen

parent 2849adf8
......@@ -273,14 +273,14 @@
it("can be saved to, and retrieved from, browserStorage",
mock.initConverse(
null, ['rosterGroupsFetched', 'chatBoxesFetched',], {},
null, ['rosterGroupsFetched'], {},
async function (done, _converse) {
spyOn(_converse.ChatBoxViews.prototype, 'trimChats');
await test_utils.waitForRoster(_converse, 'current');
test_utils.openControlBox();
spyOn(_converse.api, "trigger");
spyOn(_converse.chatboxviews, 'trimChats');
test_utils.openControlBox();
test_utils.openChatBoxes(_converse, 6);
......@@ -386,11 +386,11 @@
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
spyOn(_converse.ChatBoxViews.prototype, 'trimChats');
await test_utils.waitForRoster(_converse, 'current');
test_utils.openControlBox();
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
spyOn(_converse.api, "trigger");
spyOn(_converse.chatboxviews, 'trimChats');
_converse.chatboxes.browserStorage._clear();
test_utils.closeControlBox();
......
......@@ -555,11 +555,14 @@ converse.plugins.add('converse-chatview', {
},
insertIntoDOM () {
/* This method gets overridden in src/converse-controlbox.js
* as well as src/converse-muc.js (if those plugins are
* enabled).
*/
_converse.chatboxviews.insertRowColumn(this.el);
/**
* Triggered once the _converse.ChatBoxView has been inserted into the DOM
* @event _converse#chatBoxInsertedIntoDOM
* @type { _converse.ChatBoxView | _converse.HeadlinesBoxView }
* @example _converse.api.listen.on('chatBoxInsertedIntoDOM', view => { ... });
*/
_converse.api.trigger('chatBoxInsertedIntoDOM', this);
return this;
},
......
......@@ -344,6 +344,11 @@ converse.plugins.add('converse-controlbox', {
onControlBoxToggleHidden () {
this.model.set('closed', false);
this.el.classList.remove('hidden');
/**
* Triggered once the controlbox has been opened
* @event _converse#controlBoxOpened
* @type {_converse.ControlBox}
*/
_converse.api.trigger('controlBoxOpened', this);
},
......
......@@ -88,12 +88,6 @@ converse.plugins.add('converse-minimize', {
}
},
afterShown () {
const { _converse } = this.__super__;
this.__super__.afterShown.apply(this, arguments);
_converse.chatboxviews.trimChats(this);
},
isNewMessageHidden () {
return this.model.get('minimized') ||
this.__super__.isNewMessageHidden.apply(this, arguments);
......@@ -301,23 +295,37 @@ converse.plugins.add('converse-minimize', {
);
},
trimChats: _.debounce(async function (newchat) {
/* This method is called when a newly created chat box will
* be shown.
*
* It checks whether there is enough space on the page to show
* another chat box. Otherwise it minimizes the oldest chat box
* to create space.
*/
if (!_converse.connection.connected || _converse.view_mode !== 'overlayed') {
getMinimizedWidth () {
const minimized_el = _.get(_converse.minimized_chats, 'el');
return _.includes(this.model.pluck('minimized'), true) ?
u.getOuterWidth(minimized_el, true) : 0;
},
getBoxesWidth (newchat) {
const new_id = newchat ? newchat.model.get('id') : null;
const newchat_width = newchat ? u.getOuterWidth(newchat.el, true) : 0;
return Object.values(this.xget(new_id))
.reduce((memo, view) => memo + this.getChatBoxWidth(view), newchat_width);
},
/**
* This method is called when a newly created chat box will be shown.
* It checks whether there is enough space on the page to show
* another chat box. Otherwise it minimizes the oldest chat box
* to create space.
* @private
* @method _converse.ChatBoxViews#trimChats
* @param { [ChatBoxView|ChatRoomView|ControlBoxView|HeadlinesBoxView] } newchat
*/
async trimChats (newchat) {
if (_converse.no_trimming || !_converse.connection.connected || _converse.view_mode !== 'overlayed') {
return;
}
const shown_chats = this.getShownChats();
const body_width = u.getOuterWidth(document.querySelector('body'), true);
if (_converse.no_trimming || shown_chats.length <= 1) {
if (shown_chats.length <= 1) {
return;
}
const body_width = u.getOuterWidth(document.querySelector('body'), true);
if (this.getChatBoxWidth(shown_chats[0]) === body_width) {
// If the chats shown are the same width as the body,
// then we're in responsive mode and the chats are
......@@ -325,19 +333,10 @@ converse.plugins.add('converse-minimize', {
return;
}
await _converse.api.waitUntil('minimizedChatsInitialized');
const minimized_el = _.get(_converse.minimized_chats, 'el'),
new_id = newchat ? newchat.model.get('id') : null;
const minimized_el = _.get(_converse.minimized_chats, 'el');
if (minimized_el) {
const minimized_width = _.includes(this.model.pluck('minimized'), true) ?
u.getOuterWidth(minimized_el, true) : 0;
const boxes_width = _.reduce(
this.xget(new_id),
(memo, view) => memo + this.getChatBoxWidth(view),
newchat ? u.getOuterWidth(newchat.el, true) : 0
);
if ((minimized_width + boxes_width) > body_width) {
while ((this.getMinimizedWidth() + this.getBoxesWidth(newchat)) > body_width) {
const new_id = newchat ? newchat.model.get('id') : null;
const oldest_chat = this.getOldestMaximizedChat([new_id]);
if (oldest_chat) {
// We hide the chat immediately, because waiting
......@@ -349,10 +348,12 @@ converse.plugins.add('converse-minimize', {
view.hide();
}
oldest_chat.minimize();
} else {
break;
}
}
}
}, 100),
},
getOldestMaximizedChat (exclude_ids) {
// Get oldest view (if its id is not excluded)
......@@ -452,7 +453,6 @@ converse.plugins.add('converse-minimize', {
this.el.classList.add('hidden');
} else if (this.keys().length > 0 && !u.isVisible(this.el)) {
this.el.classList.remove('hidden');
_converse.chatboxviews.trimChats();
}
return this.el;
},
......@@ -570,10 +570,11 @@ converse.plugins.add('converse-minimize', {
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
const trimChats = () => _converse.chatboxviews.trimChats();
_converse.api.listen.on('controlBoxOpened', trimChats);
_converse.api.listen.on('registeredGlobalEventHandlers', () => window.addEventListener("resize", trimChats));
_converse.api.listen.on('unregisteredGlobalEventHandlers', () => window.removeEventListener("resize", trimChats));
const debouncedTrimChats = _.debounce(() => _converse.chatboxviews.trimChats(), 250);
_converse.api.listen.on('chatBoxInsertedIntoDOM', view => _converse.chatboxviews.trimChats(view));
_converse.api.listen.on('controlBoxOpened', view => _converse.chatboxviews.trimChats(view));
_converse.api.listen.on('registeredGlobalEventHandlers', () => window.addEventListener("resize", debouncedTrimChats));
_converse.api.listen.on('unregisteredGlobalEventHandlers', () => window.removeEventListener("resize", debouncedTrimChats));
/************************ END Event Handlers ************************/
}
});
......@@ -199,12 +199,13 @@ u.stringToNode = function (s) {
};
u.getOuterWidth = function (el, include_margin=false) {
var width = el.offsetWidth;
let width = el.offsetWidth;
if (!include_margin) {
return width;
}
var style = window.getComputedStyle(el);
width += parseInt(style.marginLeft, 10) + parseInt(style.marginRight, 10);
const style = window.getComputedStyle(el);
width += parseInt(style.marginLeft ? style.marginLeft : 0, 10) +
parseInt(style.marginRight ? style.marginRight : 0, 10);
return width;
};
......
......@@ -108,10 +108,10 @@
};
utils.openChatBoxes = function (converse, amount) {
var i = 0, jid, views = [];
for (i; i<amount; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
views[i] = converse.roster.get(jid).trigger("open");
const views = [];
for (let i=0; i<amount; i++) {
const jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
views.push(converse.roster.get(jid).trigger("open"));
}
return views;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment