Commit a6c3b462 authored by JC Brand's avatar JC Brand

Move the drag-resize code into a separate component.

parent 332a0d92
...@@ -48,6 +48,7 @@ require.config({ ...@@ -48,6 +48,7 @@ require.config({
"converse-chatview": "src/converse-chatview", "converse-chatview": "src/converse-chatview",
"converse-controlbox": "src/converse-controlbox", "converse-controlbox": "src/converse-controlbox",
"converse-core": "src/converse-core", "converse-core": "src/converse-core",
"converse-dragresize": "src/converse-dragresize",
"converse-headline": "src/converse-headline", "converse-headline": "src/converse-headline",
"converse-mam": "src/converse-mam", "converse-mam": "src/converse-mam",
"converse-minimize": "src/converse-minimize", "converse-minimize": "src/converse-minimize",
...@@ -242,6 +243,7 @@ if (typeof define !== 'undefined') { ...@@ -242,6 +243,7 @@ if (typeof define !== 'undefined') {
"converse-ping", // XEP-0199 XMPP Ping "converse-ping", // XEP-0199 XMPP Ping
"converse-notification",// HTML5 Notifications "converse-notification",// HTML5 Notifications
"converse-minimize", // Allows chat boxes to be minimized "converse-minimize", // Allows chat boxes to be minimized
"converse-dragresize", // Allows chat boxes to be resized by dragging them
"converse-headline", // Support for headline messages "converse-headline", // Support for headline messages
/* END: Removable components */ /* END: Removable components */
......
...@@ -68,14 +68,10 @@ ...@@ -68,14 +68,10 @@
'click .toggle-smiley': 'toggleEmoticonMenu', 'click .toggle-smiley': 'toggleEmoticonMenu',
'click .toggle-smiley ul li': 'insertEmoticon', 'click .toggle-smiley ul li': 'insertEmoticon',
'click .toggle-clear': 'clearMessages', 'click .toggle-clear': 'clearMessages',
'click .toggle-call': 'toggleCall', 'click .toggle-call': 'toggleCall'
'mousedown .dragresize-top': 'onStartVerticalResize',
'mousedown .dragresize-left': 'onStartHorizontalResize',
'mousedown .dragresize-topleft': 'onStartDiagonalResize'
}, },
initialize: function () { initialize: function () {
$(window).on('resize', _.debounce(this.setDimensions.bind(this), 100));
this.model.messages.on('add', this.onMessageAdded, this); this.model.messages.on('add', this.onMessageAdded, this);
this.model.on('show', this.show, this); this.model.on('show', this.show, this);
this.model.on('destroy', this.hide, this); this.model.on('destroy', this.hide, this);
...@@ -103,7 +99,6 @@ ...@@ -103,7 +99,6 @@
) )
) )
); );
this.setWidth();
this.$content = this.$el.find('.chat-content'); this.$content = this.$el.find('.chat-content');
this.renderToolbar().renderAvatar(); this.renderToolbar().renderAvatar();
converse.emit('chatBoxOpened', this); converse.emit('chatBoxOpened', this);
...@@ -111,14 +106,6 @@ ...@@ -111,14 +106,6 @@
return this.showStatusMessage(); return this.showStatusMessage();
}, },
setWidth: function () {
// 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')) {
this.$el.css('width', this.model.get('width'));
}
},
afterMessagesFetched: function () { afterMessagesFetched: function () {
// Provides a hook for plugins, such as converse-mam. // Provides a hook for plugins, such as converse-mam.
return; return;
...@@ -140,56 +127,6 @@ ...@@ -140,56 +127,6 @@
return this; return this;
}, },
adjustToViewport: function () {
/* Event handler called when viewport gets resized. We remove
* custom width/height from chat boxes.
*/
var viewport_width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var viewport_height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
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);
}
},
initDragResize: function () {
/* Determine and store the default box size.
* We need this information for the drag-resizing feature.
*/
var $flyout = this.$el.find('.box-flyout');
if (typeof this.model.get('height') === 'undefined') {
var height = $flyout.height();
var width = $flyout.width();
this.model.set('height', height);
this.model.set('default_height', height);
this.model.set('width', width);
this.model.set('default_width', width);
}
var min_width = $flyout.css('min-width');
var min_height = $flyout.css('min-height');
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;
if (converse.connection.connected) {
this.height = this.model.get('height');
this.width = this.model.get('width');
}
return this;
},
setDimensions: function () {
// 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'));
},
clearStatusNotification: function () { clearStatusNotification: function () {
this.$content.find('div.chat-event').remove(); this.$content.find('div.chat-event').remove();
}, },
...@@ -569,72 +506,6 @@ ...@@ -569,72 +506,6 @@
} }
}, },
onStartVerticalResize: function (ev) {
if (!converse.allow_dragresize) { return true; }
// Record element attributes for mouseMove().
this.height = this.$el.children('.box-flyout').height();
converse.resizing = {
'chatbox': this,
'direction': 'top'
};
this.prev_pageY = ev.pageY;
},
onStartHorizontalResize: function (ev) {
if (!converse.allow_dragresize) { return true; }
this.width = this.$el.children('.box-flyout').width();
converse.resizing = {
'chatbox': this,
'direction': 'left'
};
this.prev_pageX = ev.pageX;
},
onStartDiagonalResize: function (ev) {
this.onStartHorizontalResize(ev);
this.onStartVerticalResize(ev);
converse.resizing.direction = 'topleft';
},
setChatBoxHeight: function (height) {
if (height) {
height = converse.applyDragResistance(height, this.model.get('default_height'))+'px';
} else {
height = "";
}
this.$el.children('.box-flyout')[0].style.height = height;
},
setChatBoxWidth: function (width) {
if (width) {
width = converse.applyDragResistance(width, this.model.get('default_width'))+'px';
} else {
width = "";
}
this.$el[0].style.width = width;
this.$el.children('.box-flyout')[0].style.width = width;
},
resizeChatBox: function (ev) {
var diff;
if (converse.resizing.direction.indexOf('top') === 0) {
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);
}
}
if (converse.resizing.direction.indexOf('left') !== -1) {
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);
}
}
},
clearMessages: function (ev) { clearMessages: function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); } if (ev && ev.preventDefault) { ev.preventDefault(); }
var result = confirm(__("Are you sure you want to clear the messages from this chat box?")); var result = confirm(__("Are you sure you want to clear the messages from this chat box?"));
...@@ -792,20 +663,22 @@ ...@@ -792,20 +663,22 @@
} }
}, },
_show: function (focus) {
/* Inner show method that gets debounced */
if (this.$el.is(':visible') && this.$el.css('opacity') === "1") {
if (focus) { this.focus(); }
return;
}
this.$el.fadeIn(this.afterShown.bind(this));
},
show: function (focus) { show: function (focus) {
if (typeof this.debouncedShow === 'undefined') { if (typeof this.debouncedShow === 'undefined') {
/* We wrap the method in a debouncer and set it on the /* We wrap the method in a debouncer and set it on the
* instance, so that we have it debounced per instance. * instance, so that we have it debounced per instance.
* Debouncing it on the class-level is too broad. * Debouncing it on the class-level is too broad.
*/ */
this.debouncedShow = _.debounce(function (focus) { this.debouncedShow = _.debounce(this._show, 250, true);
if (this.$el.is(':visible') && this.$el.css('opacity') === "1") {
if (focus) { this.focus(); }
return;
}
this.initDragResize().setDimensions();
this.$el.fadeIn(this.afterShown.bind(this));
}, 250, true);
} }
this.debouncedShow.apply(this, arguments); this.debouncedShow.apply(this, arguments);
return this; return this;
......
...@@ -137,11 +137,10 @@ ...@@ -137,11 +137,10 @@
ChatBox: { ChatBox: {
initialize: function () { initialize: function () {
if (this.get('id') === 'controlbox') { if (this.get('id') === 'controlbox') {
this.set( this.set({
_.extend( 'time_opened': moment(0).valueOf(),
this.getDefaultSettings(), 'num_unread': 0
{ 'time_opened': moment(0).valueOf() } });
));
} else { } else {
this._super.initialize.apply(this, arguments); this._super.initialize.apply(this, arguments);
} }
...@@ -196,14 +195,10 @@ ...@@ -196,14 +195,10 @@
events: { events: {
'click a.close-chatbox-button': 'close', 'click a.close-chatbox-button': 'close',
'click ul#controlbox-tabs li a': 'switchTab', 'click ul#controlbox-tabs li a': 'switchTab',
'mousedown .dragresize-top': 'onStartVerticalResize',
'mousedown .dragresize-left': 'onStartHorizontalResize',
'mousedown .dragresize-topleft': 'onStartDiagonalResize'
}, },
initialize: function () { initialize: function () {
this.$el.insertAfter(converse.controlboxtoggle.$el); this.$el.insertAfter(converse.controlboxtoggle.$el);
$(window).on('resize', _.debounce(this.setDimensions.bind(this), 100));
this.model.on('change:connected', this.onConnected, this); this.model.on('change:connected', this.onConnected, this);
this.model.on('destroy', this.hide, this); this.model.on('destroy', this.hide, this);
this.model.on('hide', this.hide, this); this.model.on('hide', this.hide, this);
...@@ -277,7 +272,6 @@ ...@@ -277,7 +272,6 @@
this.loginpanel.delegateEvents().initialize(cfg); this.loginpanel.delegateEvents().initialize(cfg);
} }
this.loginpanel.render(); this.loginpanel.render();
this.initDragResize().setDimensions();
if ($feedback.length && $feedback.text() !== __('Connecting')) { if ($feedback.length && $feedback.text() !== __('Connecting')) {
this.$('.conn-feedback').replaceWith($feedback); this.$('.conn-feedback').replaceWith($feedback);
} }
...@@ -293,7 +287,6 @@ ...@@ -293,7 +287,6 @@
'model': converse.xmppstatus 'model': converse.xmppstatus
}); });
converse.xmppstatusview.render(); converse.xmppstatusview.render();
this.initDragResize().setDimensions();
}, },
close: function (ev) { close: function (ev) {
......
...@@ -244,7 +244,6 @@ ...@@ -244,7 +244,6 @@
// ---------------------------- // ----------------------------
this.default_settings = { this.default_settings = {
allow_contact_requests: true, allow_contact_requests: true,
allow_dragresize: true,
animate: true, animate: true,
authentication: 'login', // Available values are "login", "prebind", "anonymous". authentication: 'login', // Available values are "login", "prebind", "anonymous".
auto_away: 0, // Seconds after which user status is set to 'away' auto_away: 0, // Seconds after which user status is set to 'away'
...@@ -500,24 +499,6 @@ ...@@ -500,24 +499,6 @@
} }
}; };
this.applyDragResistance = function (value, default_value) {
/* This method applies some resistance around the
* default_value. If value is close enough to
* default_value, then default_value is returned instead.
*/
if (typeof value === 'undefined') {
return undefined;
} else if (typeof default_value === 'undefined') {
return value;
}
var resistance = 10;
if ((value !== default_value) &&
(Math.abs(value- default_value) < resistance)) {
return default_value;
}
return value;
};
this.updateMsgCounter = function () { this.updateMsgCounter = function () {
if (this.msg_counter > 0) { if (this.msg_counter > 0) {
if (document.title.search(/^Messages \(\d+\) /) === -1) { if (document.title.search(/^Messages \(\d+\) /) === -1) {
...@@ -579,33 +560,6 @@ ...@@ -579,33 +560,6 @@
}; };
this.registerGlobalEventHandlers = function () { this.registerGlobalEventHandlers = function () {
$(document).on('mousemove', function (ev) {
if (!this.resizing || !this.allow_dragresize) { return true; }
ev.preventDefault();
this.resizing.chatbox.resizeChatBox(ev);
}.bind(this));
$(document).on('mouseup', function (ev) {
if (!this.resizing || !this.allow_dragresize) { return true; }
ev.preventDefault();
var height = this.applyDragResistance(
this.resizing.chatbox.height,
this.resizing.chatbox.model.get('default_height')
);
var width = this.applyDragResistance(
this.resizing.chatbox.width,
this.resizing.chatbox.model.get('default_width')
);
if (this.connection.connected) {
this.resizing.chatbox.model.save({'height': height});
this.resizing.chatbox.model.save({'width': width});
} else {
this.resizing.chatbox.model.set({'height': height});
this.resizing.chatbox.model.set({'width': width});
}
this.resizing = null;
}.bind(this));
$(window).on("blur focus", function (ev) { $(window).on("blur focus", function (ev) {
if ((converse.windowState !== ev.type) && (ev.type === 'focus')) { if ((converse.windowState !== ev.type) && (ev.type === 'focus')) {
converse.clearMsgCounter(); converse.clearMsgCounter();
...@@ -1204,25 +1158,16 @@ ...@@ -1204,25 +1158,16 @@
this.messages = new converse.Messages(); this.messages = new converse.Messages();
this.messages.browserStorage = new Backbone.BrowserStorage[converse.storage]( this.messages.browserStorage = new Backbone.BrowserStorage[converse.storage](
b64_sha1('converse.messages'+this.get('jid')+converse.bare_jid)); b64_sha1('converse.messages'+this.get('jid')+converse.bare_jid));
this.save(_.extend(this.getDefaultSettings(), { this.save({
// The chat_state will be set to ACTIVE once the chat box is opened // The chat_state will be set to ACTIVE once the chat box is opened
// and we listen for change:chat_state, so shouldn't set it to ACTIVE here. // and we listen for change:chat_state, so shouldn't set it to ACTIVE here.
'chat_state': undefined,
'box_id' : b64_sha1(this.get('jid')), 'box_id' : b64_sha1(this.get('jid')),
'chat_state': undefined,
'num_unread': this.get('num_unread') || 0,
'time_opened': this.get('time_opened') || moment().valueOf(), 'time_opened': this.get('time_opened') || moment().valueOf(),
'url': '', 'url': '',
'user_id' : Strophe.getNodeFromJid(this.get('jid')) 'user_id' : Strophe.getNodeFromJid(this.get('jid'))
})); });
},
getDefaultSettings: function () {
var height = this.get('height'),
width = this.get('width');
return {
'height': converse.applyDragResistance(height, this.get('default_height')),
'width': converse.applyDragResistance(width, this.get('default_width')),
'num_unread': this.get('num_unread') || 0
};
}, },
createMessage: function ($message, $delay) { createMessage: function ($message, $delay) {
......
This diff is collapsed.
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
"converse-core", "converse-core",
"converse-api", "converse-api",
"converse-chatview", // Could be made a soft dependency "converse-chatview", // Could be made a soft dependency
"converse-muc", // Could be made a soft dependency
"strophe.rsm" "strophe.rsm"
], factory); ], factory);
}(this, function (converse, converse_api) { }(this, function (converse, converse_api) {
...@@ -115,8 +116,19 @@ ...@@ -115,8 +116,19 @@
}); });
} }
}, },
},
ChatRoomView: {
render: function () {
var result = this._super.render.apply(this, arguments);
if (!this.disable_mam) {
this.$content.on('scroll', _.debounce(this.onScroll.bind(this), 100));
}
return result;
},
} }
}, },
......
...@@ -51,13 +51,12 @@ ...@@ -51,13 +51,12 @@
}, },
registerGlobalEventHandlers: function () { registerGlobalEventHandlers: function () {
this._super.registerGlobalEventHandlers.apply(this, arguments);
$(window).on("resize", _.debounce(function (ev) { $(window).on("resize", _.debounce(function (ev) {
if (converse.connection.connected) { if (converse.connection.connected) {
converse.chatboxviews.trimChats(); converse.chatboxviews.trimChats();
} }
}, 200)); }, 200));
return this._super.registerGlobalEventHandlers.apply(this, arguments);
}, },
wrappedChatBox: function (chatbox) { wrappedChatBox: function (chatbox) {
......
...@@ -176,13 +176,9 @@ ...@@ -176,13 +176,9 @@
'click .toggle-call': 'toggleCall', 'click .toggle-call': 'toggleCall',
'click .toggle-occupants a': 'toggleOccupants', 'click .toggle-occupants a': 'toggleOccupants',
'keypress textarea.chat-textarea': 'keyPressed', 'keypress textarea.chat-textarea': 'keyPressed',
'mousedown .dragresize-top': 'onStartVerticalResize',
'mousedown .dragresize-left': 'onStartHorizontalResize',
'mousedown .dragresize-topleft': 'onStartDiagonalResize'
}, },
initialize: function () { initialize: function () {
$(window).on('resize', _.debounce(this.setDimensions.bind(this), 100));
this.model.messages.on('add', this.onMessageAdded, this); this.model.messages.on('add', this.onMessageAdded, this);
this.occupantsview = new converse.ChatRoomOccupantsView({ this.occupantsview = new converse.ChatRoomOccupantsView({
model: new converse.ChatRoomOccupants({nick: this.model.get('nick')}) model: new converse.ChatRoomOccupants({nick: this.model.get('nick')})
...@@ -203,8 +199,6 @@ ...@@ -203,8 +199,6 @@
this.$el.attr('id', this.model.get('box_id')) this.$el.attr('id', this.model.get('box_id'))
.html(converse.templates.chatroom(this.model.toJSON())); .html(converse.templates.chatroom(this.model.toJSON()));
this.renderChatArea(); this.renderChatArea();
this.$content.on('scroll', _.debounce(this.onScroll.bind(this), 100));
this.setWidth();
window.setTimeout(converse.refreshWebkit, 50); window.setTimeout(converse.refreshWebkit, 50);
return this; return this;
}, },
......
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