loading states for notifications

This commit is contained in:
Connor Turland 2018-03-07 18:38:53 -05:00
parent 10359a1f53
commit f35cea5ba6
10 changed files with 58 additions and 17 deletions

View file

@ -4,16 +4,23 @@ import GlobalUI from './index'
const Notifications = {
notifications: [],
notificationsLoading: false,
unreadNotificationsCount: 0,
init: serverData => {
Notifications.unreadNotificationsCount = serverData.unreadNotificationsCount
},
fetchNotifications: render => {
Notifications.notificationsLoading = true
render()
$.ajax({
url: '/notifications.json',
success: function(data) {
Notifications.notifications = data
Notifications.notificationsLoading = false
render()
},
error: function() {
GlobalUI.notifyUser('There was an error fetching notifications')
}
})
},

View file

@ -53,7 +53,6 @@ const ReactApp = {
switch (pathname.split('/')[1]) {
case '':
if (Active.Mapper && Active.Mapper.id) {
$('#yield').hide()
ExploreMaps.updateFromPath(pathname)
self.mapId = null
Active.Map = null
@ -61,7 +60,6 @@ const ReactApp = {
}
break
case 'explore':
$('#yield').hide()
ExploreMaps.updateFromPath(pathname)
self.mapId = null
self.topicId = null
@ -69,21 +67,18 @@ const ReactApp = {
Active.Topic = null
break
case 'topics':
$('#yield').hide()
Active.Map = null
self.mapId = null
self.topicId = pathname.split('/')[2]
break
case 'maps':
if (!pathname.includes('request_access')) {
$('#yield').hide()
Active.Topic = null
self.topicId = null
self.mapId = pathname.split('/')[2]
}
break
default:
$('#yield').show()
break
}
self.render()
@ -108,6 +103,7 @@ const ReactApp = {
openInviteLightbox: () => self.openLightbox('invite'),
serverData: self.serverData,
notifications: Notifications.notifications,
notificationsLoading: Notifications.notificationsLoading,
fetchNotifications: apply(Notifications.fetchNotifications, ReactApp.render),
fetchNotification: apply(Notifications.fetchNotification, ReactApp.render),
markAsRead: apply(Notifications.markAsRead, ReactApp.render),

View file

@ -9,6 +9,7 @@ import Loading from './Loading'
class NotificationBox extends Component {
static propTypes = {
notifications: PropTypes.array,
loading: PropTypes.bool.isRequired,
fetchNotifications: PropTypes.func.isRequired,
toggleNotificationsBox: PropTypes.func.isRequired,
markAsRead: PropTypes.func.isRequired,
@ -60,11 +61,11 @@ class NotificationBox extends Component {
}
render = () => {
const { notifications } = this.props
const { loading } = this.props
return <div className='notificationsBox'>
<div className='notificationsBoxTriangle' />
<ul className='notifications'>
{notifications ? this.showNotifications() : this.showLoading()}
{loading ? this.showLoading() : this.showNotifications()}
</ul>
</div>
}

View file

@ -50,7 +50,7 @@ class UpperRightUI extends Component {
render () {
const { currentUser, signInPage, unreadNotificationsCount,
notifications, fetchNotifications, openInviteLightbox,
markAsRead, markAsUnread } = this.props
markAsRead, markAsUnread, notificationsLoading } = this.props
const { accountBoxOpen, notificationsBoxOpen } = this.state
return <div className="upperRightUI">
{currentUser && <a href="/maps/new" target="_blank" className="addMap upperRightEl upperRightIcon">
@ -63,6 +63,7 @@ class UpperRightUI extends Component {
unreadNotificationsCount={unreadNotificationsCount}
toggleNotificationsBox={this.toggleNotificationsBox}/>
{notificationsBoxOpen && <NotificationBox
loading={notificationsLoading}
notifications={notifications}
fetchNotifications={fetchNotifications}
markAsRead={markAsRead}

View file

@ -1,3 +1,5 @@
// these come from mailboxer.rb in the api repo
export const MAP_ACCESS_REQUEST = 'ACCESS_REQUEST'
export const MAP_ACCESS_APPROVED = 'ACCESS_APPROVED'
export const MAP_INVITE_TO_EDIT = 'INVITE_TO_EDIT'

View file

@ -43,7 +43,7 @@ class App extends Component {
mobile, mobileTitle, mobileTitleWidth, mobileTitleClick, location,
map, userRequested, requestAnswered, requestApproved, serverData,
onRequestAccess, notifications, fetchNotifications,
markAsRead, markAsUnread } = this.props
markAsRead, markAsUnread, notificationsLoading } = this.props
const { pathname } = location || {}
// this fixes a bug that happens otherwise when you logout
const currentUser = this.props.currentUser && this.props.currentUser.id ? this.props.currentUser : null
@ -64,6 +64,7 @@ class App extends Component {
{!mobile && <UpperRightUI currentUser={currentUser}
unreadNotificationsCount={unreadNotificationsCount}
notifications={notifications}
notificationsLoading={notificationsLoading}
fetchNotifications={fetchNotifications}
markAsRead={markAsRead}
markAsUnread={markAsUnread}

View file

@ -4,6 +4,7 @@ import { throttle } from 'lodash'
import Header from './Header'
import MapperCard from './MapperCard'
import MapCard from './MapCard'
import LoadingPage from '../helpers/LoadingPage'
class Maps extends Component {
static propTypes = {
@ -45,7 +46,17 @@ class Maps extends Component {
const { mobile, maps, mapsWidth, currentUser, juntoState, pending, section, user, onStar, onRequest, onMapFollow } = this.props
const style = { width: mapsWidth + 'px' }
if (!maps) return null // do loading here instead
if (!maps) {
return (
<div>
<LoadingPage />
<Header signedIn={ !!currentUser }
section={ section }
user={ user }
/>
</div>
)
}
return (
<div>

View file

@ -3,6 +3,7 @@ import { Link } from 'react-router'
import { MAP_ACCESS_REQUEST } from '../../constants'
import NotificationsHeader from './NotificationsHeader'
import LoadingPage from '../helpers/LoadingPage'
import Loading from '../../components/Loading'
import NotificationBody from '../../components/NotificationBody'
@ -25,11 +26,7 @@ class NotificationPage extends Component {
if (!notification) {
return (
<div>
<div id="yield">
<div className="centerContent withPadding back">
<Loading />
</div>
</div>
<LoadingPage />
<NotificationsHeader />
</div>
)

View file

@ -1,6 +1,7 @@
import React, { Component } from 'react'
import { Link } from 'react-router'
import LoadingPage from '../helpers/LoadingPage'
import Notification from '../../components/Notification'
import {
@ -10,7 +11,6 @@ import {
} from '../../constants'
import NotificationsHeader from './NotificationsHeader'
// these come from mailboxer.rb in the api repo
const BLACKLIST = [MAP_ACCESS_REQUEST, MAP_ACCESS_APPROVED, MAP_INVITE_TO_EDIT]
/* TODO!!
@ -25,8 +25,16 @@ class Notifications extends Component {
}
render = () => {
const { markAsRead, markAsUnread } = this.props
const { notificationsLoading, markAsRead, markAsUnread } = this.props
const notifications = (this.props.notifications || []).filter(n => !(BLACKLIST.indexOf(n.type) > -1 && (!n.data.object || !n.data.map)))
if (notificationsLoading) {
return (
<div>
<LoadingPage />
<NotificationsHeader />
</div>
)
}
return (
<div>
<div id="yield">

View file

@ -0,0 +1,17 @@
import React, { Component } from 'react'
import Loading from '../../components/Loading'
class LoadingPage extends Component {
render = () => {
return (
<div id="yield">
<div className="centerContent withPadding back">
<Loading />
</div>
</div>
)
}
}
export default LoadingPage