mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 17:33:14 +01:00
Break up HeaderNotifications into stateless components and pass props down to MenuItems
React-bootstrap Dropdowns expect that passed down props will reach their MenuItems in order for event callbacks to be triggered (ie. auto closing the dropdown on select).
This commit is contained in:
parent
388e10471b
commit
f775222768
@ -1,10 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
||||
import MenuItem from 'react-bootstrap/lib/MenuItem';
|
||||
import Nav from 'react-bootstrap/lib/Nav';
|
||||
import NavDropdown from 'react-bootstrap/lib/NavDropdown';
|
||||
|
||||
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
||||
@ -18,11 +15,89 @@ import { currentUserShape } from './prop_types';
|
||||
import { getLangText } from '../utils/lang';
|
||||
|
||||
|
||||
let HeaderNotifications = React.createClass({
|
||||
const { array, bool, object } = React.PropTypes;
|
||||
|
||||
const NotificationList = ({ isPiece, notifications, ...props }) => {
|
||||
if (notifications.length) {
|
||||
return (
|
||||
<div>
|
||||
<div className="notification-header">
|
||||
{`${(isPiece ? 'Artworks' : 'Editions')} (${notifications.length})`}
|
||||
</div>
|
||||
{notifications.map((notification) => {
|
||||
const pieceOrEdition = isPiece ? notification.piece : notification.edition;
|
||||
const href = isPiece ? `/pieces/${pieceOrEdition.id}`
|
||||
: `/editions/${pieceOrEdition.bitcoin_id}`;
|
||||
|
||||
if (pieceOrEdition && notification.notification) {
|
||||
return (
|
||||
<LinkContainer {...props} key={href} to={href}>
|
||||
<MenuItem>
|
||||
<NotificationListItem
|
||||
notifications={notification.notification}
|
||||
pieceOrEdition={pieceOrEdition} />
|
||||
</MenuItem>
|
||||
</LinkContainer>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
NotificationList.propTypes = {
|
||||
notifications: array.isRequired,
|
||||
isPiece: bool
|
||||
};
|
||||
|
||||
const NotificationListItem = ({ notifications, pieceOrEdition }) => (
|
||||
<div className="row notification-wrapper">
|
||||
<div className="col-xs-4 clear-paddings thumbnail-wrapper">
|
||||
<img role="presentation" src={pieceOrEdition.thumbnail.url_safe} />
|
||||
</div>
|
||||
<div className="col-xs-8 notification-list-item-header">
|
||||
<h1>{pieceOrEdition.title}</h1>
|
||||
<div className="sub-header">by {pieceOrEdition.artist_name}</div>
|
||||
<NotificationAction notifications={notifications} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
NotificationListItem.propTypes = {
|
||||
notifications: array.isRequired,
|
||||
pieceOrEdition: object.isRequired
|
||||
};
|
||||
|
||||
const NotificationAction = ({ notifications }) => {
|
||||
const additionalNotifications = notifications.length > 1 ? (
|
||||
<div>
|
||||
+ {notifications.length - 1} {getLangText('more...')}
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<div className="notification-action">
|
||||
{notifications[0].action_str}
|
||||
{additionalNotifications}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
NotificationAction.propTypes = {
|
||||
notifications: array.isRequired,
|
||||
};
|
||||
|
||||
|
||||
const HeaderNotifications = React.createClass({
|
||||
propTypes: {
|
||||
// Injected through HOCs
|
||||
currentUser: currentUserShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||
isLoggedIn: React.PropTypes.bool.isRequired // eslint-disable-line react/sort-prop-types
|
||||
currentUser: currentUserShape.isRequired,
|
||||
isLoggedIn: bool.isRequired
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
@ -56,35 +131,6 @@ let HeaderNotifications = React.createClass({
|
||||
NotificationActions.fetchEditionListNotifications();
|
||||
},
|
||||
|
||||
renderNotifications({ notifications, isPiece }) {
|
||||
if (notifications.length) {
|
||||
return (
|
||||
<div>
|
||||
<div className="notification-header">
|
||||
{`${(isPiece ? 'Artworks' : 'Editions')} (${notifications.length})`}
|
||||
</div>
|
||||
{notifications.map((notification) => {
|
||||
const pieceOrEdition = isPiece ? notification.piece : notification.edition;
|
||||
const href = isPiece ? `/pieces/${pieceOrEdition.id}`
|
||||
: `/editions/${pieceOrEdition.bitcoin_id}`;
|
||||
|
||||
return (
|
||||
<LinkContainer key={href} to={href}>
|
||||
<MenuItem>
|
||||
<NotificationListItem
|
||||
notification={notification.notification}
|
||||
pieceOrEdition={pieceOrEdition} />
|
||||
</MenuItem>
|
||||
</LinkContainer>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
const { editionListNotifications, pieceListNotifications } = this.state;
|
||||
if (pieceListNotifications.length || editionListNotifications.length) {
|
||||
@ -108,14 +154,8 @@ let HeaderNotifications = React.createClass({
|
||||
<span className="notification-amount">({numNotifications})</span>
|
||||
</span>
|
||||
}>
|
||||
{this.renderNotifications({
|
||||
notifications: pieceListNotifications,
|
||||
isPiece: true
|
||||
})}
|
||||
{this.renderNotifications({
|
||||
notifications: editionListNotifications,
|
||||
isPiece: false
|
||||
})}
|
||||
<NotificationList isPiece notifications={pieceListNotifications} />
|
||||
<NotificationList notifications={editionListNotifications} />
|
||||
</NavDropdown>
|
||||
);
|
||||
}
|
||||
@ -123,49 +163,4 @@ let HeaderNotifications = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
let NotificationListItem = React.createClass({
|
||||
propTypes: {
|
||||
notification: React.PropTypes.array,
|
||||
pieceOrEdition: React.PropTypes.object,
|
||||
},
|
||||
|
||||
getNotificationText() {
|
||||
let numNotifications = null;
|
||||
if (this.props.notification.length > 1) {
|
||||
numNotifications = (
|
||||
<div>
|
||||
+ {this.props.notification.length - 1} {getLangText('more...')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="notification-action">
|
||||
{this.props.notification[0].action_str}
|
||||
{numNotifications}
|
||||
</div>);
|
||||
},
|
||||
|
||||
render() {
|
||||
const { pieceOrEdition } = this.props;
|
||||
|
||||
if (pieceOrEdition) {
|
||||
return (
|
||||
<div className="row notification-wrapper">
|
||||
<div className="col-xs-4 clear-paddings">
|
||||
<div className="thumbnail-wrapper">
|
||||
<img role="presentation" src={pieceOrEdition.thumbnail.url_safe} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-xs-8 notification-list-item-header">
|
||||
<h1>{pieceOrEdition.title}</h1>
|
||||
<div className="sub-header">by {pieceOrEdition.artist_name}</div>
|
||||
{this.getNotificationText()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
export default withContext(HeaderNotifications, 'currentUser', 'isLoggedIn');
|
||||
|
Loading…
Reference in New Issue
Block a user