From 3d492bf450a245aafbfb5b3cff320c1d45832b37 Mon Sep 17 00:00:00 2001 From: nickago Date: Tue, 11 Aug 2015 10:28:30 -0700 Subject: Completely rehauled scrolling system, finished base implementation --- web/react/components/create_post.jsx | 2 +- web/react/components/post_list.jsx | 123 ++++++++++----------------------- web/react/components/post_right.jsx | 1 + web/react/components/sidebar_right.jsx | 7 +- web/react/utils/utils.jsx | 3 +- 5 files changed, 42 insertions(+), 94 deletions(-) (limited to 'web/react') diff --git a/web/react/components/create_post.jsx b/web/react/components/create_post.jsx index 9ca1d5388..d6b98cbbc 100644 --- a/web/react/components/create_post.jsx +++ b/web/react/components/create_post.jsx @@ -88,7 +88,7 @@ module.exports = React.createClass({ ); } - $('.post-list-holder-by-time').perfectScrollbar('update'); + // Scrolling Code Was Here }, componentDidUpdate: function() { this.resizePostHolder(); diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx index 0abb3107e..cfbdad571 100644 --- a/web/react/components/post_list.jsx +++ b/web/react/components/post_list.jsx @@ -28,15 +28,13 @@ function getStateFromStores() { module.exports = React.createClass({ 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, - scrolledToNew: false, // Signifies we've already scrolled to the "new message" bar - // one time, don't want to do it again even if the bar - // doesn't go away + holdPosition: false, // The default state is to scroll to the bottom on change + // This behavior should NOT be taken advantage of, always set this to the desired state + + scrollHeightFromBottom: 0, // This represents the distance from the container's scrollHeight + // and current scrollTop + // Based on equation scrollTop + scrollHeightFromBottom = scrollHeight componentDidMount: function() { // Add CSS required to have the theme colors @@ -66,58 +64,10 @@ module.exports = React.createClass({ UserStore.addStatusesChangeListener(this._onTimeChange); SocketStore.addChangeListener(this._onSocketChange); - // Initialize perfect scrollbar - $(".post-list-holder-by-time").perfectScrollbar(); - - 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; - }); + // Timeout exists for the DOM to fully render before making changes + setTimeout(this.scrollWindow, 1) + // Highlight stylingx $('body').on('click.userpopover', function(e){ if ($(e.target).attr('data-toggle') !== 'popover' && $(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'); } }); - + }, + componentWillUpdate: function() { + var container = $('.post-list-holder-by-time'); + if (this.holdPosition) { + this.scrollHeightFromBottom = container[0].scrollHeight - container.scrollTop(); + } }, componentDidUpdate: function() { - this.resize(); - var post_holder = $(".post-list-holder-by-time")[0]; - this.scrollPosition = $(post_holder).scrollTop() + $(post_holder).innerHeight(); - this.oldScrollHeight = post_holder.scrollHeight; + this.scrollWindow() $('.post-list__content div .post').removeClass('post--last'); $('.post-list__content div:last-child .post').addClass('post--last'); }, @@ -166,34 +118,25 @@ module.exports = React.createClass({ SocketStore.removeChangeListener(this._onSocketChange); $('body').off('click.userpopover'); }, - resize: function() { - var post_holder = $(".post-list-holder-by-time")[0]; - this.preventScrollTrigger = true; - if (this.gotMorePosts) { - this.gotMorePosts = false; - $(post_holder).scrollTop($(post_holder).scrollTop() + (post_holder.scrollHeight-this.oldScrollHeight) ); - } else if ($("#new_message")[0] && !this.scrolledToNew) { - $(post_holder).scrollTop($(post_holder).scrollTop() + $("#new_message").offset().top - 63); - this.scrolledToNew = true; + scrollWindow: function() { + var container = $('.post-list-holder-by-time'); + + // If there's a new message, this jumps the window to that + // If there's no new message, we check if there is a scroll position to retrieve from the previous state + // If we don't, then we just jump to the bottom + if ($('#new_message').length) { + container.scrollTop(container.scrollTop() + $('#new_message').offset().top - container.offset().top - $('.new-separator').height()); + } else if (this.holdPosition) { + container.scrollTop(container[0].scrollHeight - this.scrollHeightFromBottom); + this.holdPosition = false; } else { - $(post_holder).scrollTop(post_holder.scrollHeight); + container.scrollTop(container[0].scrollHeight - container.innerHeight()); } - $(post_holder).perfectScrollbar('update'); }, _onChange: function() { var newState = getStateFromStores(); 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); } }, @@ -209,6 +152,8 @@ module.exports = React.createClass({ post_list.order.unshift(post.id); } + this.holdPosition = false; + if (this.state.channel.id === msg.channel_id) { this.setState({ post_list: post_list }); }; @@ -225,6 +170,8 @@ module.exports = React.createClass({ post_list.posts[post.id] = post; this.setState({ post_list: post_list }); + this.holdPosition = true; + PostStore.storePosts(msg.channel_id, post_list); } else { AsyncClient.getPosts(true, msg.channel_id); @@ -241,6 +188,8 @@ module.exports = React.createClass({ var index = post_list.order.indexOf(msg.props.post_id); if (index > -1) post_list.order.splice(index, 1); + this.holdPosition = true; + this.setState({ post_list: 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..."); var self = this; - var currentPos = $(".post-list").scrollTop; + this.holdPosition = true; Client.getPosts( channel_id, @@ -282,6 +231,7 @@ module.exports = React.createClass({ Constants.POST_CHUNK_SIZE, function(data) { $(self.refs.loadmore.getDOMNode()).text("Load more messages"); + console.log("here") if (!data) return; @@ -298,7 +248,6 @@ module.exports = React.createClass({ }); Client.getProfiles(); - $(".post-list").scrollTop(currentPos); }, function(err) { $(self.refs.loadmore.getDOMNode()).text("Load more messages"); diff --git a/web/react/components/post_right.jsx b/web/react/components/post_right.jsx index ad8b54012..e7a6fcf2a 100644 --- a/web/react/components/post_right.jsx +++ b/web/react/components/post_right.jsx @@ -119,6 +119,7 @@ RootPost = React.createClass({ CommentPost = React.createClass({ render: function() { + console.log("YOU NEED TO REMOVE THE POST RIGHT ENTRY") var post = this.props.post; var commentClass = "post"; diff --git a/web/react/components/sidebar_right.jsx b/web/react/components/sidebar_right.jsx index 8334b345b..a39bceeb8 100644 --- a/web/react/components/sidebar_right.jsx +++ b/web/react/components/sidebar_right.jsx @@ -39,8 +39,7 @@ module.exports = React.createClass({ } }, resize: function() { - $(".post-list-holder-by-time").scrollTop(100000); - $(".post-list-holder-by-time").perfectScrollbar('update'); + // Scrolling Code Was Here }, getInitialState: function() { return getStateFromStores(); @@ -49,7 +48,7 @@ module.exports = React.createClass({ if (! (this.state.search_visible || this.state.post_right_visible)) { $('.inner__wrap').removeClass('move--left').removeClass('move--right'); $('.sidebar--right').removeClass('move--left'); - this.resize(); + // Scrolling Code Was Here return (
); @@ -59,7 +58,7 @@ module.exports = React.createClass({ $('.sidebar--left').removeClass('move--right'); $('.sidebar--right').addClass('move--left'); $('.sidebar--right').prepend(''); - this.resize(); + // Scrolling Code Was Here setTimeout(function(){ $('.sidebar__overlay').fadeOut("200", function(){ $(this).remove(); diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx index 2214b6239..5e4e8e3a2 100644 --- a/web/react/utils/utils.jsx +++ b/web/react/utils/utils.jsx @@ -313,8 +313,7 @@ var getYoutubeEmbed = function(link) { var metadata = data.items[0].snippet; $('.video-uploader.'+youtubeId).html(metadata.channelTitle); $('.video-title.'+youtubeId).find('a').html(metadata.title); - $(".post-list-holder-by-time").scrollTop($(".post-list-holder-by-time")[0].scrollHeight); - $(".post-list-holder-by-time").perfectScrollbar('update'); + // Scrolling Code Was Here }; if(config.GoogleDeveloperKey) { -- cgit v1.2.3-1-g7c22