Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | import React from 'react'
import { Dropdown, DropdownToggle } from 'reactstrap'
import DropdownMenu from './HeaderNotification/DropdownMenu'
import Icon from './Common/Icon'
import Crowi from 'client/util/Crowi'
import { Notification } from 'client/types/crowi'
interface Props {
crowi: Crowi
me: string
}
interface State {
count: number
loaded: boolean
notifications: Notification[]
open: boolean
}
export default class HeaderNotification extends React.Component<Props, State> {
constructor(props: Props) {
super(props)
this.state = {
count: 0,
loaded: false,
notifications: [],
open: false,
}
}
componentDidMount() {
this.initializeSocket()
this.fetchList()
this.fetchStatus()
}
initializeSocket() {
this.props.crowi.getWebSocket().on('notification updated', (data: { user: string }) => {
if (this.props.me === data.user) {
this.fetchList()
this.fetchStatus()
}
})
}
async fetchStatus() {
try {
const { count = null } = await this.props.crowi.apiGet('/notification.status')
if (count !== null && count !== this.state.count) {
this.setState({ count })
}
} catch (err) {
// TODO: error handling
}
}
async updateStatus() {
try {
await this.props.crowi.apiPost('/notification.read')
this.setState({ count: 0 })
} catch (err) {
// TODO: error handling
}
}
async fetchList() {
const limit = 6
try {
const { notifications } = await this.props.crowi.apiGet('/notification.list', { limit })
this.setState({ loaded: true, notifications })
} catch (err) {
// TODO: error handling
}
}
toggle() {
const { open, count } = this.state
if (!open && count > 0) {
this.updateStatus()
}
this.setState({ open: !open })
}
async handleNotificationOnClick(notification: Notification) {
try {
await this.props.crowi.apiPost('/notification.open', { id: notification._id })
// jump to target page
window.location.href = notification.target.path
} catch (err) {
// TODO: error handling
}
}
render() {
const { count, open, loaded, notifications } = this.state
const badge = count > 0 ? <span className="badge badge-pill badge-danger notification-badge">{count}</span> : ''
return (
<Dropdown className="notification-wrapper" isOpen={open} toggle={this.toggle.bind(this)}>
<DropdownToggle tag="a" className="nav-link">
<Icon name="bell" /> {badge}
</DropdownToggle>
<DropdownMenu loaded={loaded} notifications={notifications} notificationClickHandler={this.handleNotificationOnClick.bind(this)} />
</Dropdown>
)
}
}
|