From 3309545b882573dabc6528e72741fdaf4f028f51 Mon Sep 17 00:00:00 2001 From: Maksym Mykhailenko Date: Wed, 7 Nov 2018 15:29:11 +0800 Subject: [PATCH 1/2] fix dashboard auto refreshing --- .../NotificationsReader.jsx | 2 +- .../PostsRefreshPrompt/PostsRefreshPrompt.jsx | 84 +++++++++++-------- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/components/NotificationsReader/NotificationsReader.jsx b/src/components/NotificationsReader/NotificationsReader.jsx index 01397336f..ebeb580ea 100644 --- a/src/components/NotificationsReader/NotificationsReader.jsx +++ b/src/components/NotificationsReader/NotificationsReader.jsx @@ -11,7 +11,7 @@ import { markNotificationsReadByCriteria } from '../../routes/notifications/acti class NotificationsReader extends React.Component { componentWillMount() { - const { criteria } = this.props + const { criteria, markNotificationsReadByCriteria } = this.props markNotificationsReadByCriteria(criteria) } diff --git a/src/projects/detail/components/PostsRefreshPrompt/PostsRefreshPrompt.jsx b/src/projects/detail/components/PostsRefreshPrompt/PostsRefreshPrompt.jsx index 499f65519..5a63db32c 100644 --- a/src/projects/detail/components/PostsRefreshPrompt/PostsRefreshPrompt.jsx +++ b/src/projects/detail/components/PostsRefreshPrompt/PostsRefreshPrompt.jsx @@ -8,6 +8,7 @@ */ import React from 'react' import PT from 'prop-types' +import _ from 'lodash' import Sticky from '../../../../components/Sticky' @@ -22,46 +23,47 @@ import Refresh from '../../../../assets/icons/icon-refresh.svg' import styles from './PostsRefreshPrompt.scss' +/** + * Check if there are any new unread notifications related to topics or posts + * + * @param {Array} notifications current notifications + * @param {Array} nextNotifications updated notifications + * @param {Number} projectId project id + * + * @returns {Boolean} true if there are new unread notifications related to topics or posts + */ +const getIsNewTopicAndPostNotificationsArrived = (notifications, nextNotifications, projectId) => { + const newNotifications = _.differenceBy(nextNotifications, notifications, 'id') + + const notReadNotifications = filterReadNotifications(newNotifications) + const unreadTopicAndPostChangedNotifications = filterTopicAndPostChangedNotifications(filterNotificationsByProjectId(notReadNotifications, projectId)) + + return unreadTopicAndPostChangedNotifications.length > 0 +} + class PostsRefreshPrompt extends React.Component { constructor(props) { super(props) this.state = { - unreadUpdate: [], + hasToRefresh: false, scrolled: false, } this.onScroll = this.onScroll.bind(this) - this.checkForUnreadPosts = this.checkForUnreadPosts.bind(this) - - this.refreshUnreadUpdate = null - } - - componentWillMount() { - window.addEventListener('scroll', this.onScroll) + this.refreshFeeds = this.refreshFeeds.bind(this) } componentWillUnmount() { window.removeEventListener('scroll', this.onScroll) - // clearInterval(this.refreshUnreadUpdate) } componentDidMount() { this.setState({ - unreadUpdate: [], + hasToRefresh: false, scrolled: window.scrollY > 0, }) - - // this.refreshUnreadUpdate = setInterval(this.checkForUnreadPosts, REFRESH_UNREAD_UPDATE_INTERVAL) - } - - getUnreadTopicAndPostChangedNotifications() { - const { notifications, projectId } = this.props - - const notReadNotifications = filterReadNotifications(notifications.notifications) - const unreadTopicAndPostChangedNotifications = filterTopicAndPostChangedNotifications(filterNotificationsByProjectId(notReadNotifications, projectId)) - - return unreadTopicAndPostChangedNotifications + window.addEventListener('scroll', this.onScroll) } onScroll() { @@ -74,31 +76,45 @@ class PostsRefreshPrompt extends React.Component { } } - checkForUnreadPosts() { - const unreadUpdate = this.getUnreadTopicAndPostChangedNotifications() - const { refreshFeeds, preventShowing } = this.props - const { scrolled } = this.state + componentWillReceiveProps(nextProps) { + const { notifications: { notifications } } = this.props + const { notifications: { notifications: nextNotifications }, projectId, preventShowing } = nextProps + const { scrolled, hasToRefresh } = this.state + + const isNewTopicAndPostNotificationsArrived = getIsNewTopicAndPostNotificationsArrived(notifications, nextNotifications, projectId) + + // if there are new notification regarding topics or post, we have to refresh the feed + // we run this only once, so if we already have to refresh the feed, than do nothing + if (!hasToRefresh && isNewTopicAndPostNotificationsArrived) { + this.setState({ hasToRefresh: true }, () => { + // if not scrolled we refresh feed automatically without showing a button for manual refresh + if (!preventShowing && !scrolled) { + this.refreshFeeds() + } + }) + } + } - this.setState({ unreadUpdate: this.getUnreadTopicAndPostChangedNotifications() }) + refreshFeeds() { + const { refreshFeeds } = this.props - if (!preventShowing && !scrolled && unreadUpdate.length > 0) { - refreshFeeds() - } + refreshFeeds && refreshFeeds() + this.setState({ hasToRefresh: false }) } render() { - const { preventShowing, refreshFeeds } = this.props - const { unreadUpdate, scrolled } = this.state + const { preventShowing } = this.props + const { hasToRefresh } = this.state - const isShown = unreadUpdate.length > 0 && !preventShowing && scrolled + const isShown = hasToRefresh && !preventShowing return ( isShown ? ( - +