loading states for notifications
This commit is contained in:
parent
10359a1f53
commit
f35cea5ba6
10 changed files with 58 additions and 17 deletions
|
@ -4,16 +4,23 @@ import GlobalUI from './index'
|
||||||
|
|
||||||
const Notifications = {
|
const Notifications = {
|
||||||
notifications: [],
|
notifications: [],
|
||||||
|
notificationsLoading: false,
|
||||||
unreadNotificationsCount: 0,
|
unreadNotificationsCount: 0,
|
||||||
init: serverData => {
|
init: serverData => {
|
||||||
Notifications.unreadNotificationsCount = serverData.unreadNotificationsCount
|
Notifications.unreadNotificationsCount = serverData.unreadNotificationsCount
|
||||||
},
|
},
|
||||||
fetchNotifications: render => {
|
fetchNotifications: render => {
|
||||||
|
Notifications.notificationsLoading = true
|
||||||
|
render()
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '/notifications.json',
|
url: '/notifications.json',
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
Notifications.notifications = data
|
Notifications.notifications = data
|
||||||
|
Notifications.notificationsLoading = false
|
||||||
render()
|
render()
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
GlobalUI.notifyUser('There was an error fetching notifications')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
@ -53,7 +53,6 @@ const ReactApp = {
|
||||||
switch (pathname.split('/')[1]) {
|
switch (pathname.split('/')[1]) {
|
||||||
case '':
|
case '':
|
||||||
if (Active.Mapper && Active.Mapper.id) {
|
if (Active.Mapper && Active.Mapper.id) {
|
||||||
$('#yield').hide()
|
|
||||||
ExploreMaps.updateFromPath(pathname)
|
ExploreMaps.updateFromPath(pathname)
|
||||||
self.mapId = null
|
self.mapId = null
|
||||||
Active.Map = null
|
Active.Map = null
|
||||||
|
@ -61,7 +60,6 @@ const ReactApp = {
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'explore':
|
case 'explore':
|
||||||
$('#yield').hide()
|
|
||||||
ExploreMaps.updateFromPath(pathname)
|
ExploreMaps.updateFromPath(pathname)
|
||||||
self.mapId = null
|
self.mapId = null
|
||||||
self.topicId = null
|
self.topicId = null
|
||||||
|
@ -69,21 +67,18 @@ const ReactApp = {
|
||||||
Active.Topic = null
|
Active.Topic = null
|
||||||
break
|
break
|
||||||
case 'topics':
|
case 'topics':
|
||||||
$('#yield').hide()
|
|
||||||
Active.Map = null
|
Active.Map = null
|
||||||
self.mapId = null
|
self.mapId = null
|
||||||
self.topicId = pathname.split('/')[2]
|
self.topicId = pathname.split('/')[2]
|
||||||
break
|
break
|
||||||
case 'maps':
|
case 'maps':
|
||||||
if (!pathname.includes('request_access')) {
|
if (!pathname.includes('request_access')) {
|
||||||
$('#yield').hide()
|
|
||||||
Active.Topic = null
|
Active.Topic = null
|
||||||
self.topicId = null
|
self.topicId = null
|
||||||
self.mapId = pathname.split('/')[2]
|
self.mapId = pathname.split('/')[2]
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
$('#yield').show()
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
self.render()
|
self.render()
|
||||||
|
@ -108,6 +103,7 @@ const ReactApp = {
|
||||||
openInviteLightbox: () => self.openLightbox('invite'),
|
openInviteLightbox: () => self.openLightbox('invite'),
|
||||||
serverData: self.serverData,
|
serverData: self.serverData,
|
||||||
notifications: Notifications.notifications,
|
notifications: Notifications.notifications,
|
||||||
|
notificationsLoading: Notifications.notificationsLoading,
|
||||||
fetchNotifications: apply(Notifications.fetchNotifications, ReactApp.render),
|
fetchNotifications: apply(Notifications.fetchNotifications, ReactApp.render),
|
||||||
fetchNotification: apply(Notifications.fetchNotification, ReactApp.render),
|
fetchNotification: apply(Notifications.fetchNotification, ReactApp.render),
|
||||||
markAsRead: apply(Notifications.markAsRead, ReactApp.render),
|
markAsRead: apply(Notifications.markAsRead, ReactApp.render),
|
||||||
|
|
|
@ -9,6 +9,7 @@ import Loading from './Loading'
|
||||||
class NotificationBox extends Component {
|
class NotificationBox extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
notifications: PropTypes.array,
|
notifications: PropTypes.array,
|
||||||
|
loading: PropTypes.bool.isRequired,
|
||||||
fetchNotifications: PropTypes.func.isRequired,
|
fetchNotifications: PropTypes.func.isRequired,
|
||||||
toggleNotificationsBox: PropTypes.func.isRequired,
|
toggleNotificationsBox: PropTypes.func.isRequired,
|
||||||
markAsRead: PropTypes.func.isRequired,
|
markAsRead: PropTypes.func.isRequired,
|
||||||
|
@ -60,11 +61,11 @@ class NotificationBox extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render = () => {
|
render = () => {
|
||||||
const { notifications } = this.props
|
const { loading } = this.props
|
||||||
return <div className='notificationsBox'>
|
return <div className='notificationsBox'>
|
||||||
<div className='notificationsBoxTriangle' />
|
<div className='notificationsBoxTriangle' />
|
||||||
<ul className='notifications'>
|
<ul className='notifications'>
|
||||||
{notifications ? this.showNotifications() : this.showLoading()}
|
{loading ? this.showLoading() : this.showNotifications()}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ class UpperRightUI extends Component {
|
||||||
render () {
|
render () {
|
||||||
const { currentUser, signInPage, unreadNotificationsCount,
|
const { currentUser, signInPage, unreadNotificationsCount,
|
||||||
notifications, fetchNotifications, openInviteLightbox,
|
notifications, fetchNotifications, openInviteLightbox,
|
||||||
markAsRead, markAsUnread } = this.props
|
markAsRead, markAsUnread, notificationsLoading } = this.props
|
||||||
const { accountBoxOpen, notificationsBoxOpen } = this.state
|
const { accountBoxOpen, notificationsBoxOpen } = this.state
|
||||||
return <div className="upperRightUI">
|
return <div className="upperRightUI">
|
||||||
{currentUser && <a href="/maps/new" target="_blank" className="addMap upperRightEl upperRightIcon">
|
{currentUser && <a href="/maps/new" target="_blank" className="addMap upperRightEl upperRightIcon">
|
||||||
|
@ -63,6 +63,7 @@ class UpperRightUI extends Component {
|
||||||
unreadNotificationsCount={unreadNotificationsCount}
|
unreadNotificationsCount={unreadNotificationsCount}
|
||||||
toggleNotificationsBox={this.toggleNotificationsBox}/>
|
toggleNotificationsBox={this.toggleNotificationsBox}/>
|
||||||
{notificationsBoxOpen && <NotificationBox
|
{notificationsBoxOpen && <NotificationBox
|
||||||
|
loading={notificationsLoading}
|
||||||
notifications={notifications}
|
notifications={notifications}
|
||||||
fetchNotifications={fetchNotifications}
|
fetchNotifications={fetchNotifications}
|
||||||
markAsRead={markAsRead}
|
markAsRead={markAsRead}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
|
||||||
|
// these come from mailboxer.rb in the api repo
|
||||||
export const MAP_ACCESS_REQUEST = 'ACCESS_REQUEST'
|
export const MAP_ACCESS_REQUEST = 'ACCESS_REQUEST'
|
||||||
export const MAP_ACCESS_APPROVED = 'ACCESS_APPROVED'
|
export const MAP_ACCESS_APPROVED = 'ACCESS_APPROVED'
|
||||||
export const MAP_INVITE_TO_EDIT = 'INVITE_TO_EDIT'
|
export const MAP_INVITE_TO_EDIT = 'INVITE_TO_EDIT'
|
||||||
|
|
|
@ -43,7 +43,7 @@ class App extends Component {
|
||||||
mobile, mobileTitle, mobileTitleWidth, mobileTitleClick, location,
|
mobile, mobileTitle, mobileTitleWidth, mobileTitleClick, location,
|
||||||
map, userRequested, requestAnswered, requestApproved, serverData,
|
map, userRequested, requestAnswered, requestApproved, serverData,
|
||||||
onRequestAccess, notifications, fetchNotifications,
|
onRequestAccess, notifications, fetchNotifications,
|
||||||
markAsRead, markAsUnread } = this.props
|
markAsRead, markAsUnread, notificationsLoading } = this.props
|
||||||
const { pathname } = location || {}
|
const { pathname } = location || {}
|
||||||
// this fixes a bug that happens otherwise when you logout
|
// this fixes a bug that happens otherwise when you logout
|
||||||
const currentUser = this.props.currentUser && this.props.currentUser.id ? this.props.currentUser : null
|
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}
|
{!mobile && <UpperRightUI currentUser={currentUser}
|
||||||
unreadNotificationsCount={unreadNotificationsCount}
|
unreadNotificationsCount={unreadNotificationsCount}
|
||||||
notifications={notifications}
|
notifications={notifications}
|
||||||
|
notificationsLoading={notificationsLoading}
|
||||||
fetchNotifications={fetchNotifications}
|
fetchNotifications={fetchNotifications}
|
||||||
markAsRead={markAsRead}
|
markAsRead={markAsRead}
|
||||||
markAsUnread={markAsUnread}
|
markAsUnread={markAsUnread}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { throttle } from 'lodash'
|
||||||
import Header from './Header'
|
import Header from './Header'
|
||||||
import MapperCard from './MapperCard'
|
import MapperCard from './MapperCard'
|
||||||
import MapCard from './MapCard'
|
import MapCard from './MapCard'
|
||||||
|
import LoadingPage from '../helpers/LoadingPage'
|
||||||
|
|
||||||
class Maps extends Component {
|
class Maps extends Component {
|
||||||
static propTypes = {
|
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 { mobile, maps, mapsWidth, currentUser, juntoState, pending, section, user, onStar, onRequest, onMapFollow } = this.props
|
||||||
const style = { width: mapsWidth + 'px' }
|
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 (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { Link } from 'react-router'
|
||||||
|
|
||||||
import { MAP_ACCESS_REQUEST } from '../../constants'
|
import { MAP_ACCESS_REQUEST } from '../../constants'
|
||||||
import NotificationsHeader from './NotificationsHeader'
|
import NotificationsHeader from './NotificationsHeader'
|
||||||
|
import LoadingPage from '../helpers/LoadingPage'
|
||||||
import Loading from '../../components/Loading'
|
import Loading from '../../components/Loading'
|
||||||
import NotificationBody from '../../components/NotificationBody'
|
import NotificationBody from '../../components/NotificationBody'
|
||||||
|
|
||||||
|
@ -25,11 +26,7 @@ class NotificationPage extends Component {
|
||||||
if (!notification) {
|
if (!notification) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div id="yield">
|
<LoadingPage />
|
||||||
<div className="centerContent withPadding back">
|
|
||||||
<Loading />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<NotificationsHeader />
|
<NotificationsHeader />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Link } from 'react-router'
|
import { Link } from 'react-router'
|
||||||
|
|
||||||
|
import LoadingPage from '../helpers/LoadingPage'
|
||||||
import Notification from '../../components/Notification'
|
import Notification from '../../components/Notification'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -10,7 +11,6 @@ import {
|
||||||
} from '../../constants'
|
} from '../../constants'
|
||||||
import NotificationsHeader from './NotificationsHeader'
|
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]
|
const BLACKLIST = [MAP_ACCESS_REQUEST, MAP_ACCESS_APPROVED, MAP_INVITE_TO_EDIT]
|
||||||
|
|
||||||
/* TODO!!
|
/* TODO!!
|
||||||
|
@ -25,8 +25,16 @@ class Notifications extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render = () => {
|
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)))
|
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 (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div id="yield">
|
<div id="yield">
|
||||||
|
|
17
src/routes/helpers/LoadingPage.js
Normal file
17
src/routes/helpers/LoadingPage.js
Normal 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
|
Loading…
Reference in a new issue