Completely rehauled scrolling system, finished base implementation
Этот коммит содержится в:
@@ -88,7 +88,7 @@ module.exports = React.createClass({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.post-list-holder-by-time').perfectScrollbar('update');
|
// Scrolling Code Was Here
|
||||||
},
|
},
|
||||||
componentDidUpdate: function() {
|
componentDidUpdate: function() {
|
||||||
this.resizePostHolder();
|
this.resizePostHolder();
|
||||||
|
|||||||
@@ -28,15 +28,13 @@ function getStateFromStores() {
|
|||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: "PostList",
|
displayName: "PostList",
|
||||||
scrollPosition: 0,
|
|
||||||
preventScrollTrigger: false, // Can't think of an intuitive name, but when true,
|
|
||||||
// scrollPosition is affected by the 'on scroll' event below
|
|
||||||
gotMorePosts: false,
|
|
||||||
oldScrollHeight: 0,
|
|
||||||
oldZoom: 0,
|
oldZoom: 0,
|
||||||
scrolledToNew: false, // Signifies we've already scrolled to the "new message" bar
|
holdPosition: false, // The default state is to scroll to the bottom on change
|
||||||
// one time, don't want to do it again even if the bar
|
// This behavior should NOT be taken advantage of, always set this to the desired state
|
||||||
// doesn't go away
|
|
||||||
|
scrollHeightFromBottom: 0, // This represents the distance from the container's scrollHeight
|
||||||
|
// and current scrollTop
|
||||||
|
// Based on equation scrollTop + scrollHeightFromBottom = scrollHeight
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
|
||||||
// Add CSS required to have the theme colors
|
// Add CSS required to have the theme colors
|
||||||
@@ -66,58 +64,10 @@ module.exports = React.createClass({
|
|||||||
UserStore.addStatusesChangeListener(this._onTimeChange);
|
UserStore.addStatusesChangeListener(this._onTimeChange);
|
||||||
SocketStore.addChangeListener(this._onSocketChange);
|
SocketStore.addChangeListener(this._onSocketChange);
|
||||||
|
|
||||||
// Initialize perfect scrollbar
|
// Timeout exists for the DOM to fully render before making changes
|
||||||
$(".post-list-holder-by-time").perfectScrollbar();
|
setTimeout(this.scrollWindow, 1)
|
||||||
|
|
||||||
this.resize();
|
|
||||||
|
|
||||||
// Set initial values of these component properties, will be updated on every re-render
|
|
||||||
// scrollPosition - scroll point of bottom of current viewport
|
|
||||||
// oldScrollHeight - bottom scroll point possible of viewport
|
|
||||||
// oldZoom - represents "browser zoom"
|
|
||||||
var post_holder = $(".post-list-holder-by-time")[0];
|
|
||||||
this.scrollPosition = $(post_holder).scrollTop() + $(post_holder).innerHeight();
|
|
||||||
this.oldScrollHeight = post_holder.scrollHeight;
|
|
||||||
this.oldZoom = (window.outerWidth - 8) / window.innerWidth;
|
|
||||||
|
|
||||||
/*************** End of 'run on mount' code, Start of event listeners *****************/
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
$(window).resize(function(){
|
|
||||||
$(post_holder).perfectScrollbar('update');
|
|
||||||
|
|
||||||
// this only kind of works, detecting zoom in browsers is a nightmare
|
|
||||||
var newZoom = (window.outerWidth - 8) / window.innerWidth;
|
|
||||||
|
|
||||||
// We resize if :
|
|
||||||
// 1. We are scrolled below the max scroll
|
|
||||||
// 2. Edge case similar to offscreen resizing
|
|
||||||
// 3. We changed zoom sizes
|
|
||||||
if (self.scrollPosition >= post_holder.scrollHeight ||
|
|
||||||
(self.oldScrollHeight !== post_holder.scrollHeight && self.scrollPosition >= self.oldScrollHeight) ||
|
|
||||||
self.oldZoom !== newZoom) {
|
|
||||||
self.resize();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.oldZoom = newZoom;
|
|
||||||
|
|
||||||
// Sets the size of the viewport, doesn't affect the overflowed component
|
|
||||||
if ($('#create_post').length > 0) {
|
|
||||||
var height = $(window).height() - $('#create_post').height() - $('#error_bar').outerHeight() - 50;
|
|
||||||
$(".post-list-holder-by-time").css("height", height + "px");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// scrollPosistion records and holds every position that the user has been at
|
|
||||||
// unless preventScrollTrigger is enabled, then it skips one reading
|
|
||||||
// Consider storing this in localStorage instead
|
|
||||||
$(post_holder).scroll(function(e){
|
|
||||||
if (!self.preventScrollTrigger) {
|
|
||||||
self.scrollPosition = $(post_holder).scrollTop() + $(post_holder).innerHeight();
|
|
||||||
}
|
|
||||||
self.preventScrollTrigger = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// Highlight stylingx
|
||||||
$('body').on('click.userpopover', function(e){
|
$('body').on('click.userpopover', function(e){
|
||||||
if ($(e.target).attr('data-toggle') !== 'popover'
|
if ($(e.target).attr('data-toggle') !== 'popover'
|
||||||
&& $(e.target).parents('.popover.in').length === 0) {
|
&& $(e.target).parents('.popover.in').length === 0) {
|
||||||
@@ -149,13 +99,15 @@ module.exports = React.createClass({
|
|||||||
$(this).parent('div').next('.date-separator, .new-separator').removeClass('hovered--comment');
|
$(this).parent('div').next('.date-separator, .new-separator').removeClass('hovered--comment');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
componentWillUpdate: function() {
|
||||||
|
var container = $('.post-list-holder-by-time');
|
||||||
|
if (this.holdPosition) {
|
||||||
|
this.scrollHeightFromBottom = container[0].scrollHeight - container.scrollTop();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
componentDidUpdate: function() {
|
componentDidUpdate: function() {
|
||||||
this.resize();
|
this.scrollWindow()
|
||||||
var post_holder = $(".post-list-holder-by-time")[0];
|
|
||||||
this.scrollPosition = $(post_holder).scrollTop() + $(post_holder).innerHeight();
|
|
||||||
this.oldScrollHeight = post_holder.scrollHeight;
|
|
||||||
$('.post-list__content div .post').removeClass('post--last');
|
$('.post-list__content div .post').removeClass('post--last');
|
||||||
$('.post-list__content div:last-child .post').addClass('post--last');
|
$('.post-list__content div:last-child .post').addClass('post--last');
|
||||||
},
|
},
|
||||||
@@ -166,34 +118,25 @@ module.exports = React.createClass({
|
|||||||
SocketStore.removeChangeListener(this._onSocketChange);
|
SocketStore.removeChangeListener(this._onSocketChange);
|
||||||
$('body').off('click.userpopover');
|
$('body').off('click.userpopover');
|
||||||
},
|
},
|
||||||
resize: function() {
|
scrollWindow: function() {
|
||||||
var post_holder = $(".post-list-holder-by-time")[0];
|
var container = $('.post-list-holder-by-time');
|
||||||
this.preventScrollTrigger = true;
|
|
||||||
if (this.gotMorePosts) {
|
// If there's a new message, this jumps the window to that
|
||||||
this.gotMorePosts = false;
|
// If there's no new message, we check if there is a scroll position to retrieve from the previous state
|
||||||
$(post_holder).scrollTop($(post_holder).scrollTop() + (post_holder.scrollHeight-this.oldScrollHeight) );
|
// If we don't, then we just jump to the bottom
|
||||||
} else if ($("#new_message")[0] && !this.scrolledToNew) {
|
if ($('#new_message').length) {
|
||||||
$(post_holder).scrollTop($(post_holder).scrollTop() + $("#new_message").offset().top - 63);
|
container.scrollTop(container.scrollTop() + $('#new_message').offset().top - container.offset().top - $('.new-separator').height());
|
||||||
this.scrolledToNew = true;
|
} else if (this.holdPosition) {
|
||||||
|
container.scrollTop(container[0].scrollHeight - this.scrollHeightFromBottom);
|
||||||
|
this.holdPosition = false;
|
||||||
} else {
|
} else {
|
||||||
$(post_holder).scrollTop(post_holder.scrollHeight);
|
container.scrollTop(container[0].scrollHeight - container.innerHeight());
|
||||||
}
|
}
|
||||||
$(post_holder).perfectScrollbar('update');
|
|
||||||
},
|
},
|
||||||
_onChange: function() {
|
_onChange: function() {
|
||||||
var newState = getStateFromStores();
|
var newState = getStateFromStores();
|
||||||
|
|
||||||
if (!utils.areStatesEqual(newState, this.state)) {
|
if (!utils.areStatesEqual(newState, this.state)) {
|
||||||
if (this.state.post_list &&
|
|
||||||
this.state.post_list.order &&
|
|
||||||
this.state.channel.id === newState.channel.id &&
|
|
||||||
this.state.post_list.order.length !== newState.post_list.order.length &&
|
|
||||||
newState.post_list.order.length > Constants.POST_CHUNK_SIZE) {
|
|
||||||
this.gotMorePosts = true;
|
|
||||||
}
|
|
||||||
if (this.state.channel.id !== newState.channel.id) {
|
|
||||||
this.scrolledToNew = false;
|
|
||||||
}
|
|
||||||
this.setState(newState);
|
this.setState(newState);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -209,6 +152,8 @@ module.exports = React.createClass({
|
|||||||
post_list.order.unshift(post.id);
|
post_list.order.unshift(post.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.holdPosition = false;
|
||||||
|
|
||||||
if (this.state.channel.id === msg.channel_id) {
|
if (this.state.channel.id === msg.channel_id) {
|
||||||
this.setState({ post_list: post_list });
|
this.setState({ post_list: post_list });
|
||||||
};
|
};
|
||||||
@@ -225,6 +170,8 @@ module.exports = React.createClass({
|
|||||||
post_list.posts[post.id] = post;
|
post_list.posts[post.id] = post;
|
||||||
this.setState({ post_list: post_list });
|
this.setState({ post_list: post_list });
|
||||||
|
|
||||||
|
this.holdPosition = true;
|
||||||
|
|
||||||
PostStore.storePosts(msg.channel_id, post_list);
|
PostStore.storePosts(msg.channel_id, post_list);
|
||||||
} else {
|
} else {
|
||||||
AsyncClient.getPosts(true, msg.channel_id);
|
AsyncClient.getPosts(true, msg.channel_id);
|
||||||
@@ -241,6 +188,8 @@ module.exports = React.createClass({
|
|||||||
var index = post_list.order.indexOf(msg.props.post_id);
|
var index = post_list.order.indexOf(msg.props.post_id);
|
||||||
if (index > -1) post_list.order.splice(index, 1);
|
if (index > -1) post_list.order.splice(index, 1);
|
||||||
|
|
||||||
|
this.holdPosition = true;
|
||||||
|
|
||||||
this.setState({ post_list: post_list });
|
this.setState({ post_list: post_list });
|
||||||
|
|
||||||
PostStore.storePosts(msg.channel_id, post_list);
|
PostStore.storePosts(msg.channel_id, post_list);
|
||||||
@@ -274,7 +223,7 @@ module.exports = React.createClass({
|
|||||||
$(this.refs.loadmore.getDOMNode()).text("Retrieving more messages...");
|
$(this.refs.loadmore.getDOMNode()).text("Retrieving more messages...");
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var currentPos = $(".post-list").scrollTop;
|
this.holdPosition = true;
|
||||||
|
|
||||||
Client.getPosts(
|
Client.getPosts(
|
||||||
channel_id,
|
channel_id,
|
||||||
@@ -282,6 +231,7 @@ module.exports = React.createClass({
|
|||||||
Constants.POST_CHUNK_SIZE,
|
Constants.POST_CHUNK_SIZE,
|
||||||
function(data) {
|
function(data) {
|
||||||
$(self.refs.loadmore.getDOMNode()).text("Load more messages");
|
$(self.refs.loadmore.getDOMNode()).text("Load more messages");
|
||||||
|
console.log("here")
|
||||||
|
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
|
||||||
@@ -298,7 +248,6 @@ module.exports = React.createClass({
|
|||||||
});
|
});
|
||||||
|
|
||||||
Client.getProfiles();
|
Client.getProfiles();
|
||||||
$(".post-list").scrollTop(currentPos);
|
|
||||||
},
|
},
|
||||||
function(err) {
|
function(err) {
|
||||||
$(self.refs.loadmore.getDOMNode()).text("Load more messages");
|
$(self.refs.loadmore.getDOMNode()).text("Load more messages");
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ RootPost = React.createClass({
|
|||||||
|
|
||||||
CommentPost = React.createClass({
|
CommentPost = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
|
console.log("YOU NEED TO REMOVE THE POST RIGHT ENTRY")
|
||||||
var post = this.props.post;
|
var post = this.props.post;
|
||||||
|
|
||||||
var commentClass = "post";
|
var commentClass = "post";
|
||||||
|
|||||||
@@ -39,8 +39,7 @@ module.exports = React.createClass({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
resize: function() {
|
resize: function() {
|
||||||
$(".post-list-holder-by-time").scrollTop(100000);
|
// Scrolling Code Was Here
|
||||||
$(".post-list-holder-by-time").perfectScrollbar('update');
|
|
||||||
},
|
},
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return getStateFromStores();
|
return getStateFromStores();
|
||||||
@@ -49,7 +48,7 @@ module.exports = React.createClass({
|
|||||||
if (! (this.state.search_visible || this.state.post_right_visible)) {
|
if (! (this.state.search_visible || this.state.post_right_visible)) {
|
||||||
$('.inner__wrap').removeClass('move--left').removeClass('move--right');
|
$('.inner__wrap').removeClass('move--left').removeClass('move--right');
|
||||||
$('.sidebar--right').removeClass('move--left');
|
$('.sidebar--right').removeClass('move--left');
|
||||||
this.resize();
|
// Scrolling Code Was Here
|
||||||
return (
|
return (
|
||||||
<div></div>
|
<div></div>
|
||||||
);
|
);
|
||||||
@@ -59,7 +58,7 @@ module.exports = React.createClass({
|
|||||||
$('.sidebar--left').removeClass('move--right');
|
$('.sidebar--left').removeClass('move--right');
|
||||||
$('.sidebar--right').addClass('move--left');
|
$('.sidebar--right').addClass('move--left');
|
||||||
$('.sidebar--right').prepend('<div class="sidebar__overlay"></div>');
|
$('.sidebar--right').prepend('<div class="sidebar__overlay"></div>');
|
||||||
this.resize();
|
// Scrolling Code Was Here
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
$('.sidebar__overlay').fadeOut("200", function(){
|
$('.sidebar__overlay').fadeOut("200", function(){
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
|
|||||||
@@ -313,8 +313,7 @@ var getYoutubeEmbed = function(link) {
|
|||||||
var metadata = data.items[0].snippet;
|
var metadata = data.items[0].snippet;
|
||||||
$('.video-uploader.'+youtubeId).html(metadata.channelTitle);
|
$('.video-uploader.'+youtubeId).html(metadata.channelTitle);
|
||||||
$('.video-title.'+youtubeId).find('a').html(metadata.title);
|
$('.video-title.'+youtubeId).find('a').html(metadata.title);
|
||||||
$(".post-list-holder-by-time").scrollTop($(".post-list-holder-by-time")[0].scrollHeight);
|
// Scrolling Code Was Here
|
||||||
$(".post-list-holder-by-time").perfectScrollbar('update');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if(config.GoogleDeveloperKey) {
|
if(config.GoogleDeveloperKey) {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user