about summary refs log tree commit diff
path: root/app/javascript/glitch/components/notification
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript/glitch/components/notification')
-rw-r--r--app/javascript/glitch/components/notification/container.js28
-rw-r--r--app/javascript/glitch/components/notification/follow_notification.js78
-rw-r--r--app/javascript/glitch/components/notification/index.js84
3 files changed, 190 insertions, 0 deletions
diff --git a/app/javascript/glitch/components/notification/container.js b/app/javascript/glitch/components/notification/container.js
new file mode 100644
index 000000000..60303537d
--- /dev/null
+++ b/app/javascript/glitch/components/notification/container.js
@@ -0,0 +1,28 @@
+//  Package imports  //
+import { connect } from 'react-redux';
+
+//  Mastodon imports  //
+import { makeGetNotification } from '../../../mastodon/selectors';
+
+//  Our imports  //
+import Notification from '.';
+import { deleteNotification } from '../../../mastodon/actions/notifications';
+
+const makeMapStateToProps = () => {
+  const getNotification = makeGetNotification();
+
+  const mapStateToProps = (state, props) => ({
+    notification: getNotification(state, props.notification, props.accountId),
+    settings: state.get('local_settings'),
+  });
+
+  return mapStateToProps;
+};
+
+const mapDispatchToProps = (dispatch) => ({
+  onDeleteNotification (id) {
+    dispatch(deleteNotification(id));
+  },
+});
+
+export default connect(makeMapStateToProps, mapDispatchToProps)(Notification);
diff --git a/app/javascript/glitch/components/notification/follow_notification.js b/app/javascript/glitch/components/notification/follow_notification.js
new file mode 100644
index 000000000..7cabd91f6
--- /dev/null
+++ b/app/javascript/glitch/components/notification/follow_notification.js
@@ -0,0 +1,78 @@
+//  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
new file mode 100644
index 000000000..0cdc03cbe
--- /dev/null
+++ b/app/javascript/glitch/components/notification/index.js
@@ -0,0 +1,84 @@
+//  Package imports  //
+import React from 'react';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import PropTypes from 'prop-types';
+
+//  Mastodon imports  //
+
+//  Our imports  //
+import StatusContainer from '../status/container';
+import FollowNotification from './follow_notification';
+
+export default class Notification extends ImmutablePureComponent {
+
+  static propTypes = {
+    notification: ImmutablePropTypes.map.isRequired,
+    settings: ImmutablePropTypes.map.isRequired,
+    onDeleteNotification: PropTypes.func.isRequired,
+  };
+
+  renderFollow (notification) {
+    return (
+      <FollowNotification
+        notificationId={notification.get('id')}
+        account={notification.get('account')}
+        onDeleteNotification={this.props.onDeleteNotification}
+      />
+    );
+  }
+
+  renderMention (notification) {
+    return (
+      <StatusContainer
+        id={notification.get('status')}
+        notificationId={notification.get('id')}
+        withDismiss
+      />
+    );
+  }
+
+  renderFavourite (notification) {
+    return (
+      <StatusContainer
+        id={notification.get('status')}
+        account={notification.get('account')}
+        prepend='favourite'
+        muted
+        notificationId={notification.get('id')}
+        withDismiss
+      />
+    );
+  }
+
+  renderReblog (notification) {
+    return (
+      <StatusContainer
+        id={notification.get('status')}
+        account={notification.get('account')}
+        prepend='reblog'
+        muted
+        notificationId={notification.get('id')}
+        withDismiss
+      />
+    );
+  }
+
+  render () {
+    const { notification } = this.props;
+
+    switch(notification.get('type')) {
+    case 'follow':
+      return this.renderFollow(notification);
+    case 'mention':
+      return this.renderMention(notification);
+    case 'favourite':
+      return this.renderFavourite(notification);
+    case 'reblog':
+      return this.renderReblog(notification);
+    }
+
+    return null;
+  }
+
+}