From a61ef801bb333bba3d5f2b0574dffdd171d6bba2 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Wed, 1 Jan 2014 12:34:38 -0800 Subject: [PATCH] Use Fritzy's StayDown lib. ^5 --- clientapp/helpers/chatHelpers.js | 108 ------------------------------- clientapp/pages/chat.js | 64 ++++++++++-------- clientapp/pages/groupchat.js | 34 ++++------ package.json | 5 +- public/css/otalk.css | 7 +- public/css/pages/chat.styl | 11 ++-- public/x-manifest.cache | 2 +- 7 files changed, 64 insertions(+), 167 deletions(-) delete mode 100644 clientapp/helpers/chatHelpers.js diff --git a/clientapp/helpers/chatHelpers.js b/clientapp/helpers/chatHelpers.js deleted file mode 100644 index 972712e..0000000 --- a/clientapp/helpers/chatHelpers.js +++ /dev/null @@ -1,108 +0,0 @@ -/*global app, $*/ -"use strict"; - -var _ = require('underscore'); - - -module.exports = { - initializeScroll: function () { - var self = this; - this.pinnedToBottom = true; - this.lastScrollTop = 0; - this.$scrollContainer.on('scroll', this.handleScroll.bind(this)); - }, - scrollPageLoad: function () { - if (typeof this.lastScrollPosition === 'number') { - this.scrollTo(this.lastScrollPosition); - } else { - this.scrollToBottom(); - } - }, - scrollPageUnload: function () { - this.savePosition(); - this.trimOldChats(); - }, - savePosition: function () { - this.lastScrollPosition = this.pinnedToBottom ? '' : this.$scrollContainer.scrollTop(); - }, - trimOldChats: function () { - var self = this; - var removedIds; - if (this.pinnedToBottom) { - _.delay(function () { - removedIds = [];//self.collection.trimOlderChats(); - removedIds.forEach(function (id) { - self.$('#chat' + id).remove(); - }); - }, 500); - } - }, - handleScroll: _.debounce(function (e) { - var scrollTop = this.$scrollContainer[0].scrollTop; - var direction = scrollTop >= this.lastScrollTop ? 'down' : 'up'; - if (direction === 'up' && !this.isBottom()) { - this.pinnedToBottom = false; - } else if (this.isBottom()) { - this.handleAtBottom(); - } - this.lastScrollTop = scrollTop; - }, 500), - scrollIfPinned: function (animate) { - if (this.pinnedToBottom) this.scrollToBottom(animate); - }, - handleAtBottom: function () { - if (this.isVisible()) { - this.pinnedToBottom = true; - } - }, - isBottom: function () { - var scrollTop = this.$scrollContainer[0].scrollTop; - var scrollHeight = this.$scrollContainer[0].scrollHeight; - var height = this.$scrollContainer.height(); - var fromBottom = scrollHeight - (scrollTop + height); - return fromBottom < 80; - }, - resizeInput: function () { - var height; - var scrollHeight; - var newHeight; - var newPadding; - var paddingDelta; - var maxHeight = 102; - - this.$chatInput.removeAttr('style'); - height = this.$chatInput.height() + 10, - scrollHeight = this.$chatInput.get(0).scrollHeight, - newHeight = scrollHeight + 2; - - if (newHeight > maxHeight) newHeight = maxHeight; - if (newHeight > height) { - this.$chatInput.css('height', newHeight); - newPadding = newHeight + 21; - paddingDelta = newPadding - parseInt(this.$messageList.css('paddingBottom'), 10); - if (!!paddingDelta) { - this.$messageList.css('paddingBottom', newPadding); - } - } - }, - scrollTo: function (height, animate) { - if (animate) { - this.$scrollContainer.animate({ - scrollTop: height - }, { - duration: 500, - queue: false - }); - } else { - this.$scrollContainer[0].scrollTop = height; - } - }, - scrollToBottom: function (animate) { - if (!this.isVisible()) return; - var height = this.$scrollContainer[0].scrollHeight; - this.scrollTo(height, animate); - }, - isVisible: function () { - return app.currentPage === this; - } -}; diff --git a/clientapp/pages/chat.js b/clientapp/pages/chat.js index a4176be..0d9fcf7 100644 --- a/clientapp/pages/chat.js +++ b/clientapp/pages/chat.js @@ -2,15 +2,15 @@ "use strict"; var _ = require('underscore'); +var StayDown = require('staydown'); var BasePage = require('./base'); var templates = require('../templates'); var Message = require('../views/message'); var MessageModel = require('../models/message'); -var chatHelpers = require('../helpers/chatHelpers'); var attachMediaStream = require('attachmediastream'); -module.exports = BasePage.extend(chatHelpers).extend({ +module.exports = BasePage.extend({ template: templates.pages.chat, initialize: function (spec) { this.editMode = false; @@ -61,6 +61,8 @@ module.exports = BasePage.extend(chatHelpers).extend({ }, render: function () { if (this.rendered) return this; + var self = this; + this.rendered = true; this.renderAndBind(); @@ -68,16 +70,14 @@ module.exports = BasePage.extend(chatHelpers).extend({ this.$chatInput = this.$('.chatBox textarea'); this.$chatBox = this.$('.chatBox'); this.$messageList = this.$('.messages'); - this.$scrollContainer = this.$messageList; + + this.staydown = new StayDown(this.$messageList[0], 500); + this.renderCollection(); this.listenTo(this.model.messages, 'add', this.handleChatAdded); this.listenToAndRun(this.model, 'change:jingleResources', this.handleJingleResourcesChanged); - this.renderCollection(); - - $(window).on('resize', _.bind(this.handleWindowResize, this)); - - this.initializeScroll(); + $(window).on('resize', _.bind(this.resizeInput, this)); this.registerBindings(me, { srcBindings: { @@ -88,11 +88,8 @@ module.exports = BasePage.extend(chatHelpers).extend({ return this; }, handlePageLoaded: function () { - this.scrollPageLoad(); - this.handleWindowResize(); - }, - handlePageUnloaded: function () { - this.scrollPageUnload(); + this.staydown.checkdown(); + this.resizeInput(); }, handleCallClick: function (e) { e.preventDefault(); @@ -101,17 +98,11 @@ module.exports = BasePage.extend(chatHelpers).extend({ }, renderCollection: function () { var self = this; - var previous; - var bottom = this.isBottom() || this.$messageList.is(':empty'); this.model.messages.each(function (model, i) { self.appendModel(model); }); - this.scrollIfPinned(); + this.staydown.checkdown(); }, - handleWindowResize: _.debounce(function () { - this.scrollIfPinned(); - this.resizeInput(); - }), handleKeyDown: function (e) { if (e.which === 13 && !e.shiftKey) { this.sendChat(); @@ -166,9 +157,9 @@ module.exports = BasePage.extend(chatHelpers).extend({ var message; var val = this.$chatInput.val(); - this.scrollToBottom(true); - if (val) { + this.staydown.intend_down = true; + message = { to: this.model.lockedResource || this.model.jid, type: 'chat', @@ -221,11 +212,9 @@ module.exports = BasePage.extend(chatHelpers).extend({ last.addClass('chatGroup'); } else { newEl = $(model.templateHtml); - this.$messageList.append(newEl); + this.staydown.append(newEl[0]); } this.lastModel = model; - - this.scrollIfPinned(); }, handleEndClick: function (e) { e.preventDefault(); @@ -236,5 +225,28 @@ module.exports = BasePage.extend(chatHelpers).extend({ }, handleMuteClick: function (e) { return false; - } + }, + resizeInput: _.throttle(function () { + var height; + var scrollHeight; + var newHeight; + var newPadding; + var paddingDelta; + var maxHeight = 102; + + this.$chatInput.removeAttr('style'); + height = this.$chatInput.height() + 10; + scrollHeight = this.$chatInput.get(0).scrollHeight; + newHeight = scrollHeight + 2; + + if (newHeight > maxHeight) newHeight = maxHeight; + if (newHeight > height) { + this.$chatInput.css('height', newHeight); + newPadding = newHeight + 21; + paddingDelta = newPadding - parseInt(this.$messageList.css('paddingBottom'), 10); + if (!!paddingDelta) { + this.$messageList.css('paddingBottom', newPadding); + } + } + }, 300) }); diff --git a/clientapp/pages/groupchat.js b/clientapp/pages/groupchat.js index fd57595..cd6a371 100644 --- a/clientapp/pages/groupchat.js +++ b/clientapp/pages/groupchat.js @@ -2,15 +2,15 @@ "use strict"; var _ = require('underscore'); +var StayDown = require('staydown'); var BasePage = require('./base'); var templates = require('../templates'); var MUCRosterItem = require('../views/mucRosterItem'); var Message = require('../views/mucMessage'); var MessageModel = require('../models/message'); -var chatHelpers = require('../helpers/chatHelpers'); -module.exports = BasePage.extend(chatHelpers).extend({ +module.exports = BasePage.extend({ template: templates.pages.groupchat, initialize: function (spec) { this.editMode = false; @@ -59,16 +59,15 @@ module.exports = BasePage.extend(chatHelpers).extend({ this.$chatInput = this.$('.chatBox textarea'); this.$chatBox = this.$('.chatBox'); this.$messageList = this.$('.messages'); - this.$scrollContainer = this.$messageList; - this.listenTo(this.model.messages, 'add', this.handleChatAdded); + this.staydown = new StayDown(this.$messageList[0], 500); this.renderMessages(); this.renderCollection(this.model.resources, MUCRosterItem, this.$('.groupRoster')); - $(window).on('resize', _.bind(this.handleWindowResize, this)); + this.listenTo(this.model.messages, 'add', this.handleChatAdded); - this.initializeScroll(); + $(window).on('resize', _.bind(this.resizeInput, this)); this.registerBindings(); @@ -76,25 +75,16 @@ module.exports = BasePage.extend(chatHelpers).extend({ }, renderMessages: function () { var self = this; - var previous; - var bottom = this.isBottom() || this.$messageList.is(':empty'); this.model.messages.each(function (model, i) { self.appendModel(model); }); - this.scrollIfPinned(); + this.staydown.checkdown(); }, handleChatAdded: function (model) { this.appendModel(model, true); }, handlePageLoaded: function () { - this.scrollPageLoad(); - this.handleWindowResize(); - }, - handlePageUnloaded: function () { - this.scrollPageUnload(); - }, - handleWindowResize: function () { - this.scrollIfPinned(); + this.staydown.checkdown(); this.resizeInput(); }, handleKeyDown: function (e) { @@ -139,7 +129,7 @@ module.exports = BasePage.extend(chatHelpers).extend({ this.pausedTyping(); } }, - resizeInput: function () { + resizeInput: _.throttle(function () { var height; var scrollHeight; var newHeight; @@ -161,7 +151,7 @@ module.exports = BasePage.extend(chatHelpers).extend({ this.$messageList.css('paddingBottom', newPadding); } } - }, + }, 300), pausedTyping: _.debounce(function () { if (this.typing && !this.paused) { this.paused = true; @@ -177,6 +167,8 @@ module.exports = BasePage.extend(chatHelpers).extend({ var val = this.$chatInput.val(); if (val) { + this.staydown.intend_down = true; + message = { to: this.model.jid, type: 'groupchat', @@ -223,11 +215,9 @@ module.exports = BasePage.extend(chatHelpers).extend({ last.addClass('chatGroup'); } else { newEl = $(model.templateHtml); - this.$messageList.append(newEl); + this.staydown.append(newEl[0]); } this.lastModel = model; - - this.scrollIfPinned(); }, refreshModel: function (model) { var existing = this.$('#chat' + model.cid); diff --git a/package.json b/package.json index a873c7d..33e0f38 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "url": "git@github.com:andyet/otalk.git" }, "dependencies": { - "bows": "", + "bows": "0.3.0", "async": "0.2.9", "backbone": "1.0.0", "express": "3.3.7", @@ -28,7 +28,8 @@ "attachmediastream": "1.0.1", "getusermedia": "0.2.1", "crypto-browserify": "1.0.3", - "browserify": "2.25.1" + "browserify": "2.25.1", + "staydown": "1.0.2" }, "devDependencies": { "precommit-hook": "0.3.6" diff --git a/public/css/otalk.css b/public/css/otalk.css index 4ab414b..b88be9d 100644 --- a/public/css/otalk.css +++ b/public/css/otalk.css @@ -1211,11 +1211,15 @@ button.secondary:hover:not(:disabled) { right: 0px; left: 201px; z-index: 200; + transition: none; + -webkit-transition: none; } .chatBox form { border-top: 1px solid #eee; background: #f7f7f7; padding: 11px; + transition: none; + -webkit-transition: none; } .chatBox .formwrap { -moz-box-sizing: border-box; @@ -1228,9 +1232,6 @@ button.secondary:hover:not(:disabled) { .chatBox textarea { height: 30px; padding: 6px 10px; -} -.chatBox textarea.typing:focus, -.chatBox textarea.editing:focus { transition: none; -webkit-transition: none; } diff --git a/public/css/pages/chat.styl b/public/css/pages/chat.styl index 1be1bd8..a1a603c 100644 --- a/public/css/pages/chat.styl +++ b/public/css/pages/chat.styl @@ -316,11 +316,15 @@ right: 0px left: 201px z-index: 200 + transition: none + -webkit-transition: none form border-top: 1px solid #eee background: lighten($gray-light, 93%) padding: 11px + transition: none + -webkit-transition: none .formwrap borderbox() @@ -331,11 +335,8 @@ textarea height: 30px padding: 6px 10px - - &.typing:focus, - &.editing:focus - transition: none - -webkit-transition: none + transition: none + -webkit-transition: none &.editing background-color: #fffcea diff --git a/public/x-manifest.cache b/public/x-manifest.cache index 6e51796..e57d457 100644 --- a/public/x-manifest.cache +++ b/public/x-manifest.cache @@ -1,5 +1,5 @@ CACHE MANIFEST -# 0.0.1 1388604898350 +# 0.0.1 1388608474826 CACHE: /app.js