Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/NotificationsReader/NotificationsReader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
1 change: 0 additions & 1 deletion src/config/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,6 @@ export const DATE_TO_USER_FIELD_MAP = {

// Notifications
export const REFRESH_NOTIFICATIONS_INTERVAL = 1000 * 60 * 1 // 1 minute interval
export const REFRESH_UNREAD_UPDATE_INTERVAL = 1000 * 10 * 1 // 10 second interval
export const NOTIFICATIONS_DROPDOWN_PER_SOURCE = 5
export const NOTIFICATIONS_NEW_PER_SOURCE = 10

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/
import React from 'react'
import PT from 'prop-types'
import _ from 'lodash'

import Sticky from '../../../../components/Sticky'

Expand All @@ -16,52 +17,53 @@ import {
filterNotificationsByProjectId,
filterTopicAndPostChangedNotifications,
} from '../../../../routes/notifications/helpers/notifications'
import { REFRESH_UNREAD_UPDATE_INTERVAL, SCROLL_TO_MARGIN } from '../../../../config/constants'
import { SCROLL_TO_MARGIN } from '../../../../config/constants'

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() {
Expand All @@ -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 ? (
<Sticky top={SCROLL_TO_MARGIN} innerZ={999}>
<Sticky top={SCROLL_TO_MARGIN} innerZ={10}>
<div styleName="prompt">
<button
className={`tc-btn tc-btn-primary tc-btn-md ${styles.button}`}
onClick={refreshFeeds}
onClick={this.refreshFeeds}
>
<Refresh styleName="icon" />
Reload page to view updates
Expand Down