diff options
author | kibigo! <marrus-sh@users.noreply.github.com> | 2017-07-14 11:13:02 -0700 |
---|---|---|
committer | kibigo! <marrus-sh@users.noreply.github.com> | 2017-07-16 17:13:16 -0700 |
commit | d0aad1ac854eaa53f9b7d38cc8dd90e289790629 (patch) | |
tree | 492c5fbc81bfb6dee10017814afb14d5ef549f27 /app/javascript/glitch/components/notification | |
parent | 21b04af524888fea134cc7dfa04e1203ede0427a (diff) |
Documentation and cleanup
Diffstat (limited to 'app/javascript/glitch/components/notification')
4 files changed, 220 insertions, 82 deletions
diff --git a/app/javascript/glitch/components/notification/container.js b/app/javascript/glitch/components/notification/container.js index 60303537d..bed086172 100644 --- a/app/javascript/glitch/components/notification/container.js +++ b/app/javascript/glitch/components/notification/container.js @@ -1,3 +1,21 @@ +/* + +`<NotificationContainer>` +========================= + +This container connects `<Notification>`s to the Redux store. + +*/ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +/* + +Imports: +-------- + +*/ + // Package imports // import { connect } from 'react-redux'; @@ -8,6 +26,20 @@ import { makeGetNotification } from '../../../mastodon/selectors'; import Notification from '.'; import { deleteNotification } from '../../../mastodon/actions/notifications'; +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +/* + +State mapping: +-------------- + +The `mapStateToProps()` function maps various state properties to the +props of our component. We wrap this in `makeMapStateToProps()` so that +we only have to call `makeGetNotification()` once instead of every +time. + +*/ + const makeMapStateToProps = () => { const getNotification = makeGetNotification(); @@ -19,7 +51,20 @@ const makeMapStateToProps = () => { return mapStateToProps; }; -const mapDispatchToProps = (dispatch) => ({ +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +/* + +Dispatch mapping: +----------------- + +The `mapDispatchToProps()` function maps dispatches to our store to the +various props of our component. We only need to provide a dispatch for +deleting notifications. + +*/ + +const mapDispatchToProps = dispatch => ({ onDeleteNotification (id) { dispatch(deleteNotification(id)); }, diff --git a/app/javascript/glitch/components/notification/follow.js b/app/javascript/glitch/components/notification/follow.js new file mode 100644 index 000000000..26396478b --- /dev/null +++ b/app/javascript/glitch/components/notification/follow.js @@ -0,0 +1,171 @@ +/* + +`<NotificationFollow>` +====================== + +This component renders a follow notification. + +__Props:__ + + - __`id` (`PropTypes.number.isRequired`) :__ + This is the id of the notification. + + - __`onDeleteNotification` (`PropTypes.func.isRequired`) :__ + The function to call when a notification should be + dismissed/deleted. + + - __`account` (`PropTypes.object.isRequired`) :__ + The account associated with the follow notification, ie the account + which followed the user. + + - __`intl` (`PropTypes.object.isRequired`) :__ + Our internationalization object, inserted by `@injectIntl`. + +*/ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +/* + +Imports: +-------- + +*/ + +// Package imports // +import React from 'react'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import PropTypes from 'prop-types'; +import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; +import escapeTextContentForBrowser from 'escape-html'; +import ImmutablePureComponent from 'react-immutable-pure-component'; + +// Mastodon imports // +import emojify from '../../../mastodon/emoji'; +import Permalink from '../../../mastodon/components/permalink'; +import AccountContainer from '../../../mastodon/containers/account_container'; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +/* + +Inital setup: +------------- + +The `messages` constant is used to define any messages that we need +from inside props. + +*/ + +const messages = defineMessages({ + deleteNotification : + { id: 'status.dismiss_notification', defaultMessage: 'Dismiss notification' }, +}); + +/* + +Implementation: +--------------- + +*/ + +@injectIntl +export default class NotificationFollow extends ImmutablePureComponent { + + static propTypes = { + id : PropTypes.number.isRequired, + onDeleteNotification : PropTypes.func.isRequired, + account : ImmutablePropTypes.map.isRequired, + intl : PropTypes.object.isRequired, + }; + +/* + +### `handleNotificationDeleteClick()` + +This function just calls our `onDeleteNotification()` prop with the +notification's `id`. + +*/ + + handleNotificationDeleteClick = () => { + this.props.onDeleteNotification(this.props.id); + } + +/* + +### `render()` + +This actually renders the component. + +*/ + + render () { + const { account, intl } = this.props; + +/* + +`dismiss` creates the notification dismissal button. Its title is given +by `dismissTitle`. + +*/ + + const dismissTitle = intl.formatMessage(messages.deleteNotification); + const dismiss = ( + <button + aria-label={dismissTitle} + title={dismissTitle} + onClick={this.handleNotificationDeleteClick} + className='status__prepend-dismiss-button' + > + <i className='fa fa-eraser' /> + </button> + ); + +/* + +`link` is a container for the account's `displayName`, which links to +the account timeline using a `<Permalink>`. + +*/ + + const displayName = account.get('display_name') || account.get('username'); + const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) }; + const link = ( + <Permalink + className='notification__display-name' + href={account.get('url')} + title={account.get('acct')} + to={`/accounts/${account.get('id')}`} + dangerouslySetInnerHTML={displayNameHTML} + /> + ); + +/* + +We can now render our component. + +*/ + + return ( + <div className='notification notification-follow'> + <div className='notification__message'> + <div className='notification__favourite-icon-wrapper'> + <i className='fa fa-fw fa-user-plus' /> + </div> + + <FormattedMessage + id='notification.follow' + defaultMessage='{name} followed you' + values={{ name: link }} + /> + + {dismiss} + </div> + + <AccountContainer id={account.get('id')} withNote={false} /> + </div> + ); + } + +} diff --git a/app/javascript/glitch/components/notification/follow_notification.js b/app/javascript/glitch/components/notification/follow_notification.js deleted file mode 100644 index 7cabd91f6..000000000 --- a/app/javascript/glitch/components/notification/follow_notification.js +++ /dev/null @@ -1,78 +0,0 @@ -// Package imports // -import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import PropTypes from 'prop-types'; -import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; -import escapeTextContentForBrowser from 'escape-html'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - -// Mastodon imports // -import emojify from '../../../mastodon/emoji'; -import Permalink from '../../../mastodon/components/permalink'; -import AccountContainer from '../../../mastodon/containers/account_container'; - -const messages = defineMessages({ - deleteNotification: { id: 'status.dismiss_notification', defaultMessage: 'Dismiss notification' }, -}); - - -@injectIntl -export default class FollowNotification extends ImmutablePureComponent { - - static contextTypes = { - router: PropTypes.object, - }; - - static propTypes = { - notificationId: PropTypes.number.isRequired, - onDeleteNotification: PropTypes.func.isRequired, - account: ImmutablePropTypes.map.isRequired, - intl: PropTypes.object.isRequired, - }; - - // Avoid checking props that are functions (and whose equality will always - // evaluate to false. See react-immutable-pure-component for usage. - updateOnProps = [ - 'account', - ] - - handleNotificationDeleteClick = () => { - this.props.onDeleteNotification(this.props.notificationId); - } - - render () { - const { account, intl } = this.props; - - const dismissTitle = intl.formatMessage(messages.deleteNotification); - const dismiss = ( - <button - aria-label={dismissTitle} - title={dismissTitle} - onClick={this.handleNotificationDeleteClick} - className='status__prepend-dismiss-button' - > - <i className='fa fa-eraser' /> - </button> - ); - - const displayName = account.get('display_name').length > 0 ? account.get('display_name') : account.get('username'); - const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) }; - const link = <Permalink className='notification__display-name' href={account.get('url')} title={account.get('acct')} to={`/accounts/${account.get('id')}`} dangerouslySetInnerHTML={displayNameHTML} />; - return ( - <div className='notification notification-follow'> - <div className='notification__message'> - <div className='notification__favourite-icon-wrapper'> - <i className='fa fa-fw fa-user-plus' /> - </div> - - <FormattedMessage id='notification.follow' defaultMessage='{name} followed you' values={{ name: link }} /> - - {dismiss} - </div> - - <AccountContainer id={account.get('id')} withNote={false} /> - </div> - ); - } - -} diff --git a/app/javascript/glitch/components/notification/index.js b/app/javascript/glitch/components/notification/index.js index 0cdc03cbe..556d5aea8 100644 --- a/app/javascript/glitch/components/notification/index.js +++ b/app/javascript/glitch/components/notification/index.js @@ -8,7 +8,7 @@ import PropTypes from 'prop-types'; // Our imports // import StatusContainer from '../status/container'; -import FollowNotification from './follow_notification'; +import NotificationFollow from './follow'; export default class Notification extends ImmutablePureComponent { @@ -20,8 +20,8 @@ export default class Notification extends ImmutablePureComponent { renderFollow (notification) { return ( - <FollowNotification - notificationId={notification.get('id')} + <NotificationFollow + id={notification.get('id')} account={notification.get('account')} onDeleteNotification={this.props.onDeleteNotification} /> |