Fix list view scrolling

Resize handlers are ugly. But not as ugly as scroll handlers. :p
Normalized some whitespace along the way.
This commit is contained in:
lilia 2015-01-29 20:59:08 -10:00
parent ec01d33b50
commit db5e7fd6b6
9 changed files with 75 additions and 54 deletions

View file

@ -32,7 +32,7 @@
<div class='discussion-container'></div> <div class='discussion-container'></div>
<div class="bottom-bar"> <div class="bottom-bar" id='footer'>
<form class='send'> <form class='send'>
<div class='attachments'> <div class='attachments'>
<div class='paperclip'></div> <div class='paperclip'></div>

View file

@ -42,6 +42,7 @@
if (this.model.id) { if (this.model.id) {
this.model.fetchMessages({reset: true}); this.model.fetchMessages({reset: true});
} }
window.addEventListener('resize', this.view.resize.bind(this.view));
}, },
events: { events: {

View file

@ -45,6 +45,7 @@
this.conversations.get(message.conversationId).fetchMessages(); this.conversations.get(message.conversationId).fetchMessages();
}.bind(this)); }.bind(this));
}.bind(this)); }.bind(this));
window.addEventListener('resize', this.inbox.resize.bind(this.inbox));
}, },
events: { events: {
'keyup': 'keyup', 'keyup': 'keyup',

View file

@ -16,33 +16,45 @@
var Whisper = Whisper || {}; var Whisper = Whisper || {};
(function () { (function () {
'use strict'; 'use strict';
/* /*
* Generic list view that watches a given collection, wraps its members in * Generic list view that watches a given collection, wraps its members in
* a given child view and adds the child view elements to its own element. * a given child view and adds the child view elements to its own element.
*/ */
Whisper.ListView = Backbone.View.extend({ Whisper.ListView = Backbone.View.extend({
tagName: 'ul', tagName: 'ul',
itemView: Backbone.View, itemView: Backbone.View,
initialize: function() { initialize: function() {
this.listenTo(this.collection, 'change', this.render); // auto update this.listenTo(this.collection, 'change', this.render); // auto update
this.listenTo(this.collection, 'add', this.addOne); this.listenTo(this.collection, 'add', this.addOne);
this.listenTo(this.collection, 'reset', this.addAll); this.listenTo(this.collection, 'reset', this.addAll);
this.listenTo(this.collection, 'all', this.render); this.listenTo(this.collection, 'all', this.render);
}, },
addOne: function(model) { addOne: function(model) {
if (this.itemView) { if (this.itemView) {
var view = new this.itemView({model: model}); var view = new this.itemView({model: model});
this.$el.append(view.render().el); this.$el.append(view.render().el);
this.$el.trigger('add'); this.$el.trigger('add');
} }
}, },
addAll: function() { addAll: function() {
this.$el.html(''); this.$el.html('');
this.collection.each(this.addOne, this); this.collection.each(this.addOne, this);
} this.resize();
}); },
resize: function() {
var height = window.innerHeight - $('#header').height() - $('#footer').height();
if (this.$el.height() > height) {
this.$el.css('height', height + 'px');
this.$el.css('overflow-y', 'scroll');
} else {
this.$el.css('height', 'auto');
this.$el.css('overflow-y', 'auto');
}
}
});
})(); })();

View file

@ -16,23 +16,23 @@
var Whisper = Whisper || {}; var Whisper = Whisper || {};
(function () { (function () {
'use strict'; 'use strict';
Whisper.MessageListView = Whisper.ListView.extend({ Whisper.MessageListView = Whisper.ListView.extend({
tagName: 'ul', tagName: 'ul',
className: 'message-list', className: 'message-list',
itemView: Whisper.MessageView, itemView: Whisper.MessageView,
events: { events: {
'add': 'scrollToBottom', 'add': 'scrollToBottom',
'update *': 'scrollToBottom' 'update *': 'scrollToBottom'
}, },
scrollToBottom: function() { scrollToBottom: function() {
// TODO: Avoid scrolling if user has manually scrolled up? // TODO: Avoid scrolling if user has manually scrolled up?
this.$el.scrollTop(this.el.scrollHeight); this.$el.scrollTop(this.el.scrollHeight);
}, },
addAll: function() { addAll: function() {
Whisper.ListView.prototype.addAll.apply(this, arguments); // super() Whisper.ListView.prototype.addAll.apply(this, arguments); // super()
this.scrollToBottom(); this.scrollToBottom();
}, }
}); });
})(); })();

View file

@ -66,10 +66,11 @@ button {
.message-list { .message-list {
margin: 36px + 16px 0; max-height: 100%;
padding: 0; margin: 0;
padding: 1em 0;
list-style: none; list-style: none;
font-weight: 300; overflow-y: scroll;
li { li {
margin: 0 8px 16px; margin: 0 8px 16px;

View file

@ -1,6 +1,5 @@
* { * {
box-sizing: border-box; box-sizing: border-box;
max-height: 100%;
} }
body { body {

View file

@ -2,6 +2,10 @@
margin-top: 36px; margin-top: 36px;
} }
#contacts {
overflow-y: scroll;
}
.loading .gutter { .loading .gutter {
// TODO: spinner // TODO: spinner
} }

View file

@ -3,8 +3,7 @@
font-family: 'Roboto'; font-family: 'Roboto';
src: url("/fonts/Roboto-Regular.ttf") format("truetype"); } src: url("/fonts/Roboto-Regular.ttf") format("truetype"); }
* { * {
box-sizing: border-box; box-sizing: border-box; }
max-height: 100%; }
body { body {
height: 100%; height: 100%;
@ -26,6 +25,9 @@ body {
.gutter { .gutter {
margin-top: 36px; } margin-top: 36px; }
#contacts {
overflow-y: scroll; }
.contact .checkbox { .contact .checkbox {
display: none; } display: none; }
@ -194,10 +196,11 @@ button {
content: "✓"; } content: "✓"; }
.message-list { .message-list {
margin: 52px 0; max-height: 100%;
padding: 0; margin: 0;
padding: 1em 0;
list-style: none; list-style: none;
font-weight: 300; } overflow-y: scroll; }
.message-list li { .message-list li {
margin: 0 8px 16px; } margin: 0 8px 16px; }
.message-list li::after { .message-list li::after {