From 872f001fbbebe93ae7fc4b92a6d17a378e0d50d5 Mon Sep 17 00:00:00 2001 From: hmhealey Date: Tue, 15 Dec 2015 14:56:40 -0500 Subject: Added floating post timestamp --- web/react/components/posts_view.jsx | 92 +++++++++++++++++++++++---- web/sass-files/sass/partials/_post.scss | 32 +++++++++- web/sass-files/sass/partials/_responsive.scss | 5 +- 3 files changed, 111 insertions(+), 18 deletions(-) diff --git a/web/react/components/posts_view.jsx b/web/react/components/posts_view.jsx index e116fdeea..83e580307 100644 --- a/web/react/components/posts_view.jsx +++ b/web/react/components/posts_view.jsx @@ -26,7 +26,11 @@ export default class PostsView extends React.Component { this.wasAtBottom = true; this.scrollHeight = 0; - this.state = {displayNameType: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'false')}; + this.state = { + displayNameType: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'false'), + isScrolling: true, // TODO change this once we start detecting scrolling + topPostId: null + }; } static get SCROLL_TYPE_FREE() { return 1; @@ -69,6 +73,37 @@ export default class PostsView extends React.Component { this.props.postViewScrolled(this.isAtBottom()); this.prevScrollHeight = this.refs.postlist.scrollHeight; this.prevOffsetTop = this.jumpToPostNode.offsetTop; + + this.updateFloatingTimestamp(); + } + updateFloatingTimestamp() { + if (this.props.postList) { + // iterate through posts starting at the bottom since users are more likely to be viewing newer posts + for (let i = 0; i < this.props.postList.order.length; i++) { + const id = this.props.postList.order[i]; + const element = ReactDOM.findDOMNode(this.refs[id]); + + if (!element || element.offsetTop + element.clientHeight <= this.refs.postlist.scrollTop) { + // this post is off the top of the screen so the last one is at the top of the screen + let topPostId; + + if (i > 0) { + topPostId = this.props.postList.order[i - 1]; + } else { + // the first post we look at should always be on the screen, but handle that case anyway + topPostId = id; + } + + if (topPostId !== this.state.topPostId) { + this.setState({ + topPostId + }); + } + + break; + } + } + } } loadMorePostsTop() { this.props.loadMorePostsTopClicked(); @@ -322,6 +357,12 @@ export default class PostsView extends React.Component { if (nextState.displayNameType !== this.state.displayNameType) { return true; } + if (this.state.topPostId !== nextState.topPostId) { + return true; + } + if (this.state.isScrolling !== nextState.isScrolling) { + return true; + } return false; } @@ -377,20 +418,43 @@ export default class PostsView extends React.Component { } } + let floatingTimestamp = null; + if (this.state.topPostId) { + const topPost = this.props.postList.posts[this.state.topPostId]; + const dateString = Utils.getDateForUnixTicks(topPost.create_at).toDateString(); + + let timestampClass = 'post-list__timestamp'; + if (this.state.isScrolling) { + timestampClass += ' scrolling'; + } + + floatingTimestamp = ( +
+ {dateString} +
+ ); + } + return ( -
-
-
- {moreMessagesTop} - {postElements} - {moreMessagesBottom} +
+ {floatingTimestamp} +
+
+
+ {moreMessagesTop} + {postElements} + {moreMessagesBottom} +
diff --git a/web/sass-files/sass/partials/_post.scss b/web/sass-files/sass/partials/_post.scss index fbebb4e98..4e5968254 100644 --- a/web/sass-files/sass/partials/_post.scss +++ b/web/sass-files/sass/partials/_post.scss @@ -211,6 +211,10 @@ body.ios { overflow-y: hidden; height: 100%; + .inactive { + display: none; + } + .post-list-holder-by-time { background: #fff; overflow-y: scroll; @@ -222,9 +226,6 @@ body.ios { &::-webkit-scrollbar { width: 0px !important; } - &.inactive { - display: none; - } &.active { display: inline; } @@ -247,6 +248,31 @@ body.ios { } } +.post-list__timestamp { + position: absolute; + top: 8px; + left: 50%; + z-index: 50; + width: 120px; + text-align: center; + background: $primary-color; + color: #fff; + @include border-radius(3px); + font-size: 12px; + line-height: 25px; + margin-left: -60px; + -webkit-font-smoothing: initial; + @include single-transition(all, 0.3s, ease, 1.0s); + @include translateY(-45px); + @include opacity(0); + + &.scrolling { + @include single-transition(all, 0.3s, ease); + @include translateY(0); + @include opacity(0.8); + } +} + .post-create__container { form { width: 100%; diff --git a/web/sass-files/sass/partials/_responsive.scss b/web/sass-files/sass/partials/_responsive.scss index 2aa130fa9..c493c6aeb 100644 --- a/web/sass-files/sass/partials/_responsive.scss +++ b/web/sass-files/sass/partials/_responsive.scss @@ -241,6 +241,9 @@ } } } + .post-list__timestamp { + display: block; + } .signup-team__container { padding: 30px 0; margin-bottom: 30px; @@ -795,4 +798,4 @@ font-size: 2em; } } -} \ No newline at end of file +} -- cgit v1.2.3-1-g7c22