2016-04-01 14:46:19 +02:00
|
|
|
// Converse.js (A browser based XMPP chat client)
|
|
|
|
// http://conversejs.org
|
|
|
|
//
|
2017-02-13 15:37:17 +01:00
|
|
|
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
|
2016-04-01 14:46:19 +02:00
|
|
|
// Licensed under the Mozilla Public License (MPLv2)
|
|
|
|
//
|
|
|
|
/*global define, window */
|
|
|
|
|
|
|
|
(function (root, factory) {
|
2018-01-03 17:08:45 +01:00
|
|
|
define(["converse-core",
|
2016-12-02 18:41:05 +01:00
|
|
|
"tpl!dragresize",
|
2016-04-01 14:46:19 +02:00
|
|
|
"converse-chatview",
|
|
|
|
"converse-muc", // XXX: would like to remove this
|
|
|
|
"converse-controlbox"
|
|
|
|
], factory);
|
2018-01-03 17:08:45 +01:00
|
|
|
}(this, function (converse, tpl_dragresize) {
|
2016-04-01 14:46:19 +02:00
|
|
|
"use strict";
|
2017-07-10 21:14:48 +02:00
|
|
|
const { _ } = converse.env;
|
2016-04-01 14:46:19 +02:00
|
|
|
|
2017-06-13 18:53:41 +02:00
|
|
|
function renderDragResizeHandles (_converse, view) {
|
2017-07-10 17:46:22 +02:00
|
|
|
const flyout = view.el.querySelector('.box-flyout');
|
|
|
|
const div = document.createElement('div');
|
2017-06-13 18:53:41 +02:00
|
|
|
div.innerHTML = tpl_dragresize();
|
|
|
|
flyout.insertBefore(
|
|
|
|
div,
|
|
|
|
flyout.firstChild
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-20 11:42:20 +01:00
|
|
|
converse.plugins.add('converse-dragresize', {
|
2017-03-08 12:15:19 +01:00
|
|
|
/* Optional dependencies are other plugins which might be
|
|
|
|
* overridden or relied upon, and therefore need to be loaded before
|
|
|
|
* this plugin. They are called "optional" because they might not be
|
|
|
|
* available, in which case any overrides applicable to them will be
|
|
|
|
* ignored.
|
|
|
|
*
|
|
|
|
* It's possible however to make optional dependencies non-optional.
|
|
|
|
* If the setting "strict_plugin_dependencies" is set to true,
|
|
|
|
* an error will be raised if the plugin is not found.
|
|
|
|
*
|
|
|
|
* NB: These plugins need to have already been loaded via require.js.
|
|
|
|
*/
|
|
|
|
optional_dependencies: ["converse-headline"],
|
2016-04-01 14:46:19 +02:00
|
|
|
|
2017-11-02 15:30:24 +01:00
|
|
|
enabled (_converse) {
|
|
|
|
return _converse.view_mode == 'overlayed';
|
|
|
|
},
|
|
|
|
|
2016-04-01 14:46:19 +02:00
|
|
|
overrides: {
|
|
|
|
// Overrides mentioned here will be picked up by converse.js's
|
|
|
|
// plugin architecture they will replace existing methods on the
|
|
|
|
// relevant objects or classes.
|
|
|
|
//
|
|
|
|
// New functions which don't exist yet can also be added.
|
2016-05-28 10:55:03 +02:00
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
registerGlobalEventHandlers () {
|
|
|
|
const that = this;
|
2017-11-02 15:30:24 +01:00
|
|
|
|
2018-01-03 17:08:45 +01:00
|
|
|
document.addEventListener('mousemove', function (ev) {
|
2016-12-20 11:42:20 +01:00
|
|
|
if (!that.resizing || !that.allow_dragresize) { return true; }
|
2016-04-01 14:46:19 +02:00
|
|
|
ev.preventDefault();
|
2016-12-20 11:42:20 +01:00
|
|
|
that.resizing.chatbox.resizeChatBox(ev);
|
|
|
|
});
|
2016-04-01 14:46:19 +02:00
|
|
|
|
2018-01-03 17:08:45 +01:00
|
|
|
document.addEventListener('mouseup', function (ev) {
|
2016-12-20 11:42:20 +01:00
|
|
|
if (!that.resizing || !that.allow_dragresize) { return true; }
|
2016-04-01 14:46:19 +02:00
|
|
|
ev.preventDefault();
|
2017-07-10 17:46:22 +02:00
|
|
|
const height = that.applyDragResistance(
|
2016-12-20 11:42:20 +01:00
|
|
|
that.resizing.chatbox.height,
|
|
|
|
that.resizing.chatbox.model.get('default_height')
|
2016-04-01 14:46:19 +02:00
|
|
|
);
|
2017-07-10 17:46:22 +02:00
|
|
|
const width = that.applyDragResistance(
|
2016-12-20 11:42:20 +01:00
|
|
|
that.resizing.chatbox.width,
|
|
|
|
that.resizing.chatbox.model.get('default_width')
|
2016-04-01 14:46:19 +02:00
|
|
|
);
|
2016-12-20 11:42:20 +01:00
|
|
|
if (that.connection.connected) {
|
|
|
|
that.resizing.chatbox.model.save({'height': height});
|
|
|
|
that.resizing.chatbox.model.save({'width': width});
|
2016-04-01 14:46:19 +02:00
|
|
|
} else {
|
2016-12-20 11:42:20 +01:00
|
|
|
that.resizing.chatbox.model.set({'height': height});
|
|
|
|
that.resizing.chatbox.model.set({'width': width});
|
2016-04-01 14:46:19 +02:00
|
|
|
}
|
2016-12-20 11:42:20 +01:00
|
|
|
that.resizing = null;
|
|
|
|
});
|
2016-04-01 14:46:19 +02:00
|
|
|
|
2016-08-31 12:06:17 +02:00
|
|
|
return this.__super__.registerGlobalEventHandlers.apply(this, arguments);
|
2016-04-01 14:46:19 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
ChatBox: {
|
2017-07-10 17:46:22 +02:00
|
|
|
initialize () {
|
|
|
|
const { _converse } = this.__super__;
|
|
|
|
const result = this.__super__.initialize.apply(this, arguments),
|
2016-04-01 14:46:19 +02:00
|
|
|
height = this.get('height'), width = this.get('width'),
|
|
|
|
save = this.get('id') === 'controlbox' ? this.set.bind(this) : this.save.bind(this);
|
|
|
|
save({
|
2016-12-20 10:30:20 +01:00
|
|
|
'height': _converse.applyDragResistance(height, this.get('default_height')),
|
|
|
|
'width': _converse.applyDragResistance(width, this.get('default_width')),
|
2016-04-01 14:46:19 +02:00
|
|
|
});
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
ChatBoxView: {
|
|
|
|
events: {
|
|
|
|
'mousedown .dragresize-top': 'onStartVerticalResize',
|
|
|
|
'mousedown .dragresize-left': 'onStartHorizontalResize',
|
|
|
|
'mousedown .dragresize-topleft': 'onStartDiagonalResize'
|
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
initialize () {
|
2018-01-03 17:08:45 +01:00
|
|
|
window.addEventListener('resize', _.debounce(this.setDimensions.bind(this), 100));
|
2016-08-31 12:06:17 +02:00
|
|
|
this.__super__.initialize.apply(this, arguments);
|
2016-04-01 14:46:19 +02:00
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
render () {
|
|
|
|
const result = this.__super__.render.apply(this, arguments);
|
2017-06-13 18:53:41 +02:00
|
|
|
renderDragResizeHandles(this.__super__._converse, this);
|
2016-04-01 14:46:19 +02:00
|
|
|
this.setWidth();
|
|
|
|
return result;
|
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
setWidth () {
|
2016-04-01 14:46:19 +02:00
|
|
|
// If a custom width is applied (due to drag-resizing),
|
|
|
|
// then we need to set the width of the .chatbox element as well.
|
|
|
|
if (this.model.get('width')) {
|
2018-01-03 17:08:45 +01:00
|
|
|
this.el.style.width = this.model.get('width');
|
2016-04-01 14:46:19 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
_show () {
|
2016-04-01 14:46:19 +02:00
|
|
|
this.initDragResize().setDimensions();
|
2016-08-31 12:06:17 +02:00
|
|
|
this.__super__._show.apply(this, arguments);
|
2016-04-01 14:46:19 +02:00
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
initDragResize () {
|
2016-04-01 14:46:19 +02:00
|
|
|
/* Determine and store the default box size.
|
|
|
|
* We need this information for the drag-resizing feature.
|
|
|
|
*/
|
2018-01-03 17:08:45 +01:00
|
|
|
const { _converse } = this.__super__,
|
|
|
|
flyout = this.el.querySelector('.box-flyout'),
|
|
|
|
style = window.getComputedStyle(flyout);
|
|
|
|
|
2017-01-26 15:49:02 +01:00
|
|
|
if (_.isUndefined(this.model.get('height'))) {
|
2018-01-03 17:08:45 +01:00
|
|
|
const height = parseInt(style.height.replace(/px$/, ''), 10),
|
|
|
|
width = parseInt(style.width.replace(/px$/, ''), 10);
|
2016-04-01 14:46:19 +02:00
|
|
|
this.model.set('height', height);
|
|
|
|
this.model.set('default_height', height);
|
|
|
|
this.model.set('width', width);
|
|
|
|
this.model.set('default_width', width);
|
|
|
|
}
|
2018-01-03 17:08:45 +01:00
|
|
|
const min_width = style['min-width'];
|
|
|
|
const min_height = style['min-height'];
|
2016-04-01 14:46:19 +02:00
|
|
|
this.model.set('min_width', min_width.endsWith('px') ? Number(min_width.replace(/px$/, '')) :0);
|
|
|
|
this.model.set('min_height', min_height.endsWith('px') ? Number(min_height.replace(/px$/, '')) :0);
|
|
|
|
// Initialize last known mouse position
|
|
|
|
this.prev_pageY = 0;
|
|
|
|
this.prev_pageX = 0;
|
2016-12-20 10:30:20 +01:00
|
|
|
if (_converse.connection.connected) {
|
2016-04-01 14:46:19 +02:00
|
|
|
this.height = this.model.get('height');
|
|
|
|
this.width = this.model.get('width');
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
setDimensions () {
|
2016-04-01 14:46:19 +02:00
|
|
|
// Make sure the chat box has the right height and width.
|
|
|
|
this.adjustToViewport();
|
|
|
|
this.setChatBoxHeight(this.model.get('height'));
|
|
|
|
this.setChatBoxWidth(this.model.get('width'));
|
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
setChatBoxHeight (height) {
|
|
|
|
const { _converse } = this.__super__;
|
2016-04-01 14:46:19 +02:00
|
|
|
if (height) {
|
2016-12-20 10:30:20 +01:00
|
|
|
height = _converse.applyDragResistance(height, this.model.get('default_height'))+'px';
|
2016-04-01 14:46:19 +02:00
|
|
|
} else {
|
|
|
|
height = "";
|
|
|
|
}
|
2018-01-03 17:08:45 +01:00
|
|
|
this.el.querySelector('.box-flyout').style.height = height;
|
2016-04-01 14:46:19 +02:00
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
setChatBoxWidth (width) {
|
|
|
|
const { _converse } = this.__super__;
|
2016-04-01 14:46:19 +02:00
|
|
|
if (width) {
|
2016-12-20 10:30:20 +01:00
|
|
|
width = _converse.applyDragResistance(width, this.model.get('default_width'))+'px';
|
2016-04-01 14:46:19 +02:00
|
|
|
} else {
|
|
|
|
width = "";
|
|
|
|
}
|
2017-12-24 16:46:49 +01:00
|
|
|
this.el.style.width = width;
|
2018-01-03 17:08:45 +01:00
|
|
|
this.el.querySelector('.box-flyout').style.width = width;
|
2016-04-01 14:46:19 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
adjustToViewport () {
|
2016-04-01 14:46:19 +02:00
|
|
|
/* Event handler called when viewport gets resized. We remove
|
|
|
|
* custom width/height from chat boxes.
|
|
|
|
*/
|
2017-07-10 17:46:22 +02:00
|
|
|
const viewport_width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
|
|
|
|
const viewport_height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
|
2016-04-01 14:46:19 +02:00
|
|
|
if (viewport_width <= 480) {
|
|
|
|
this.model.set('height', undefined);
|
|
|
|
this.model.set('width', undefined);
|
|
|
|
} else if (viewport_width <= this.model.get('width')) {
|
|
|
|
this.model.set('width', undefined);
|
|
|
|
} else if (viewport_height <= this.model.get('height')) {
|
|
|
|
this.model.set('height', undefined);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
onStartVerticalResize (ev) {
|
|
|
|
const { _converse } = this.__super__;
|
2016-12-20 10:30:20 +01:00
|
|
|
if (!_converse.allow_dragresize) { return true; }
|
2016-04-01 14:46:19 +02:00
|
|
|
// Record element attributes for mouseMove().
|
2018-01-03 17:08:45 +01:00
|
|
|
const flyout = this.el.querySelector('.box-flyout'),
|
|
|
|
style = window.getComputedStyle(flyout);
|
|
|
|
this.height = parseInt(style.height.replace(/px$/, ''), 10);
|
2016-12-20 10:30:20 +01:00
|
|
|
_converse.resizing = {
|
2016-04-01 14:46:19 +02:00
|
|
|
'chatbox': this,
|
|
|
|
'direction': 'top'
|
|
|
|
};
|
|
|
|
this.prev_pageY = ev.pageY;
|
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
onStartHorizontalResize (ev) {
|
|
|
|
const { _converse } = this.__super__;
|
2016-12-20 10:30:20 +01:00
|
|
|
if (!_converse.allow_dragresize) { return true; }
|
2018-01-03 17:08:45 +01:00
|
|
|
const flyout = this.el.querySelector('.box-flyout'),
|
|
|
|
style = window.getComputedStyle(flyout);
|
|
|
|
this.width = parseInt(style.width.replace(/px$/, ''), 10);
|
2016-12-20 10:30:20 +01:00
|
|
|
_converse.resizing = {
|
2016-04-01 14:46:19 +02:00
|
|
|
'chatbox': this,
|
|
|
|
'direction': 'left'
|
|
|
|
};
|
|
|
|
this.prev_pageX = ev.pageX;
|
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
onStartDiagonalResize (ev) {
|
|
|
|
const { _converse } = this.__super__;
|
2016-04-01 14:46:19 +02:00
|
|
|
this.onStartHorizontalResize(ev);
|
|
|
|
this.onStartVerticalResize(ev);
|
2016-12-20 10:30:20 +01:00
|
|
|
_converse.resizing.direction = 'topleft';
|
2016-04-01 14:46:19 +02:00
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
resizeChatBox (ev) {
|
|
|
|
let diff;
|
|
|
|
const { _converse } = this.__super__;
|
2016-12-20 10:30:20 +01:00
|
|
|
if (_converse.resizing.direction.indexOf('top') === 0) {
|
2016-04-01 14:46:19 +02:00
|
|
|
diff = ev.pageY - this.prev_pageY;
|
|
|
|
if (diff) {
|
|
|
|
this.height = ((this.height-diff) > (this.model.get('min_height') || 0)) ? (this.height-diff) : this.model.get('min_height');
|
|
|
|
this.prev_pageY = ev.pageY;
|
|
|
|
this.setChatBoxHeight(this.height);
|
|
|
|
}
|
|
|
|
}
|
2016-12-20 10:30:20 +01:00
|
|
|
if (_.includes(_converse.resizing.direction, 'left')) {
|
2016-04-01 14:46:19 +02:00
|
|
|
diff = this.prev_pageX - ev.pageX;
|
|
|
|
if (diff) {
|
|
|
|
this.width = ((this.width+diff) > (this.model.get('min_width') || 0)) ? (this.width+diff) : this.model.get('min_width');
|
|
|
|
this.prev_pageX = ev.pageX;
|
|
|
|
this.setChatBoxWidth(this.width);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-12-19 08:46:48 +01:00
|
|
|
HeadlinesBoxView: {
|
|
|
|
events: {
|
|
|
|
'mousedown .dragresize-top': 'onStartVerticalResize',
|
|
|
|
'mousedown .dragresize-left': 'onStartHorizontalResize',
|
|
|
|
'mousedown .dragresize-topleft': 'onStartDiagonalResize'
|
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
initialize () {
|
2018-01-03 17:08:45 +01:00
|
|
|
window.addEventListener('resize', _.debounce(this.setDimensions.bind(this), 100));
|
2016-12-19 08:46:48 +01:00
|
|
|
return this.__super__.initialize.apply(this, arguments);
|
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
render () {
|
|
|
|
const result = this.__super__.render.apply(this, arguments);
|
2017-06-13 18:53:41 +02:00
|
|
|
renderDragResizeHandles(this.__super__._converse, this);
|
|
|
|
this.setWidth();
|
|
|
|
return result;
|
2016-12-19 08:46:48 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-04-01 14:46:19 +02:00
|
|
|
ControlBoxView: {
|
|
|
|
events: {
|
|
|
|
'mousedown .dragresize-top': 'onStartVerticalResize',
|
|
|
|
'mousedown .dragresize-left': 'onStartHorizontalResize',
|
|
|
|
'mousedown .dragresize-topleft': 'onStartDiagonalResize'
|
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
initialize () {
|
2018-01-03 17:08:45 +01:00
|
|
|
window.addEventListener('resize', _.debounce(this.setDimensions.bind(this), 100));
|
2016-08-31 12:06:17 +02:00
|
|
|
this.__super__.initialize.apply(this, arguments);
|
2016-04-01 14:46:19 +02:00
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
render () {
|
|
|
|
const result = this.__super__.render.apply(this, arguments);
|
2017-06-13 18:53:41 +02:00
|
|
|
renderDragResizeHandles(this.__super__._converse, this);
|
|
|
|
this.setWidth();
|
|
|
|
return result;
|
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
renderLoginPanel () {
|
|
|
|
const result = this.__super__.renderLoginPanel.apply(this, arguments);
|
2016-04-01 14:46:19 +02:00
|
|
|
this.initDragResize().setDimensions();
|
|
|
|
return result;
|
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
renderContactsPanel () {
|
|
|
|
const result = this.__super__.renderContactsPanel.apply(this, arguments);
|
2016-04-01 14:46:19 +02:00
|
|
|
this.initDragResize().setDimensions();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
ChatRoomView: {
|
|
|
|
events: {
|
|
|
|
'mousedown .dragresize-top': 'onStartVerticalResize',
|
|
|
|
'mousedown .dragresize-left': 'onStartHorizontalResize',
|
|
|
|
'mousedown .dragresize-topleft': 'onStartDiagonalResize'
|
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
initialize () {
|
2018-01-03 17:08:45 +01:00
|
|
|
window.addEventListener('resize', _.debounce(this.setDimensions.bind(this), 100));
|
2016-08-31 12:06:17 +02:00
|
|
|
this.__super__.initialize.apply(this, arguments);
|
2016-04-01 14:46:19 +02:00
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
render () {
|
|
|
|
const result = this.__super__.render.apply(this, arguments);
|
2017-06-13 18:53:41 +02:00
|
|
|
renderDragResizeHandles(this.__super__._converse, this);
|
2016-04-01 14:46:19 +02:00
|
|
|
this.setWidth();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
initialize () {
|
2016-04-01 14:46:19 +02:00
|
|
|
/* The initialize function gets called as soon as the plugin is
|
|
|
|
* loaded by converse.js's plugin machinery.
|
|
|
|
*/
|
2017-07-10 17:46:22 +02:00
|
|
|
const { _converse } = this;
|
2016-12-20 11:42:20 +01:00
|
|
|
|
2017-07-05 11:03:13 +02:00
|
|
|
_converse.api.settings.update({
|
2016-04-01 14:46:19 +02:00
|
|
|
allow_dragresize: true,
|
|
|
|
});
|
2016-12-20 11:42:20 +01:00
|
|
|
|
2016-12-20 10:30:20 +01:00
|
|
|
_converse.applyDragResistance = function (value, default_value) {
|
2016-04-01 14:46:19 +02:00
|
|
|
/* This method applies some resistance around the
|
|
|
|
* default_value. If value is close enough to
|
|
|
|
* default_value, then default_value is returned instead.
|
|
|
|
*/
|
2017-01-26 15:49:02 +01:00
|
|
|
if (_.isUndefined(value)) {
|
2016-04-01 14:46:19 +02:00
|
|
|
return undefined;
|
2017-01-26 15:49:02 +01:00
|
|
|
} else if (_.isUndefined(default_value)) {
|
2016-04-01 14:46:19 +02:00
|
|
|
return value;
|
|
|
|
}
|
2017-07-10 17:46:22 +02:00
|
|
|
const resistance = 10;
|
2016-04-01 14:46:19 +02:00
|
|
|
if ((value !== default_value) &&
|
|
|
|
(Math.abs(value- default_value) < resistance)) {
|
|
|
|
return default_value;
|
|
|
|
}
|
|
|
|
return value;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}));
|