about summary refs log tree commit diff
path: root/app/assets/javascripts/components/features/notifications
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2017-05-03 02:04:16 +0200
committerGitHub <noreply@github.com>2017-05-03 02:04:16 +0200
commitf5bf5ebb82e3af420dcd23d602b1be6cc86838e1 (patch)
tree92eef08642a038cf44ccbc6d16a884293e7a0814 /app/assets/javascripts/components/features/notifications
parent26bc5915727e0a0173c03cb49f5193dd612fb888 (diff)
Replace sprockets/browserify with Webpack (#2617)
* Replace browserify with webpack

* Add react-intl-translations-manager

* Do not minify in development, add offline-plugin for ServiceWorker background cache updates

* Adjust tests and dependencies

* Fix production deployments

* Fix tests

* More optimizations

* Improve travis cache for npm stuff

* Re-run travis

* Add back support for custom.scss as before

* Remove offline-plugin and babili

* Fix issue with Immutable.List().unshift(...values) not working as expected

* Make travis load schema instead of running all migrations in sequence

* Fix missing React import in WarningContainer. Optimize rendering performance by using ImmutablePureComponent instead of
React.PureComponent. ImmutablePureComponent uses Immutable.is() to compare props. Replace dynamic callback bindings in
<UI />

* Add react definitions to places that use JSX

* Add Procfile.dev for running rails, webpack and streaming API at the same time
Diffstat (limited to 'app/assets/javascripts/components/features/notifications')
-rw-r--r--app/assets/javascripts/components/features/notifications/components/clear_column_button.jsx26
-rw-r--r--app/assets/javascripts/components/features/notifications/components/column_settings.jsx70
-rw-r--r--app/assets/javascripts/components/features/notifications/components/notification.jsx88
-rw-r--r--app/assets/javascripts/components/features/notifications/components/setting_toggle.jsx20
-rw-r--r--app/assets/javascripts/components/features/notifications/containers/column_settings_container.jsx21
-rw-r--r--app/assets/javascripts/components/features/notifications/containers/notification_container.jsx15
-rw-r--r--app/assets/javascripts/components/features/notifications/index.jsx142
7 files changed, 0 insertions, 382 deletions
diff --git a/app/assets/javascripts/components/features/notifications/components/clear_column_button.jsx b/app/assets/javascripts/components/features/notifications/components/clear_column_button.jsx
deleted file mode 100644
index 206b05f91..000000000
--- a/app/assets/javascripts/components/features/notifications/components/clear_column_button.jsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import PropTypes from 'prop-types';
-import { defineMessages, injectIntl } from 'react-intl';
-
-const messages = defineMessages({
-  clear: { id: 'notifications.clear', defaultMessage: 'Clear notifications' }
-});
-
-class ClearColumnButton extends React.Component {
-
-  render () {
-    const { intl } = this.props;
-
-    return (
-      <div role='button' title={intl.formatMessage(messages.clear)} className='column-icon column-icon-clear' tabIndex='0' onClick={this.props.onClick}>
-        <i className='fa fa-eraser' />
-      </div>
-    );
-  }
-}
-
-ClearColumnButton.propTypes = {
-  onClick: PropTypes.func.isRequired,
-  intl: PropTypes.object.isRequired
-};
-
-export default injectIntl(ClearColumnButton);
diff --git a/app/assets/javascripts/components/features/notifications/components/column_settings.jsx b/app/assets/javascripts/components/features/notifications/components/column_settings.jsx
deleted file mode 100644
index 30063010c..000000000
--- a/app/assets/javascripts/components/features/notifications/components/column_settings.jsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import PropTypes from 'prop-types';
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-import ColumnCollapsable from '../../../components/column_collapsable';
-import SettingToggle from './setting_toggle';
-
-const messages = defineMessages({
-  settings: { id: 'notifications.settings', defaultMessage: 'Column settings' }
-});
-
-class ColumnSettings extends React.PureComponent {
-
-  render () {
-    const { settings, intl, onChange, onSave } = this.props;
-
-    const alertStr = <FormattedMessage id='notifications.column_settings.alert' defaultMessage='Desktop notifications' />;
-    const showStr  = <FormattedMessage id='notifications.column_settings.show' defaultMessage='Show in column' />;
-    const soundStr = <FormattedMessage id='notifications.column_settings.sound' defaultMessage='Play sound' />;
-
-    return (
-      <ColumnCollapsable icon='sliders' title={intl.formatMessage(messages.settings)} fullHeight={616} onCollapse={onSave}>
-        <div className='column-settings__outer'>
-          <span className='column-settings__section'><FormattedMessage id='notifications.column_settings.follow' defaultMessage='New followers:' /></span>
-
-          <div className='column-settings__row'>
-            <SettingToggle settings={settings} settingKey={['alerts', 'follow']} onChange={onChange} label={alertStr} />
-            <SettingToggle settings={settings} settingKey={['shows', 'follow']} onChange={onChange} label={showStr} />
-            <SettingToggle settings={settings} settingKey={['sounds', 'follow']} onChange={onChange} label={soundStr} />
-          </div>
-
-          <span className='column-settings__section'><FormattedMessage id='notifications.column_settings.favourite' defaultMessage='Favourites:' /></span>
-
-          <div className='column-settings__row'>
-            <SettingToggle settings={settings} settingKey={['alerts', 'favourite']} onChange={onChange} label={alertStr} />
-            <SettingToggle settings={settings} settingKey={['shows', 'favourite']} onChange={onChange} label={showStr} />
-            <SettingToggle settings={settings} settingKey={['sounds', 'favourite']} onChange={onChange} label={soundStr} />
-          </div>
-
-          <span className='column-settings__section'><FormattedMessage id='notifications.column_settings.mention' defaultMessage='Mentions:' /></span>
-
-          <div className='column-settings__row'>
-            <SettingToggle settings={settings} settingKey={['alerts', 'mention']} onChange={onChange} label={alertStr} />
-            <SettingToggle settings={settings} settingKey={['shows', 'mention']} onChange={onChange} label={showStr} />
-            <SettingToggle settings={settings} settingKey={['sounds', 'mention']} onChange={onChange} label={soundStr} />
-          </div>
-
-          <span className='column-settings__section'><FormattedMessage id='notifications.column_settings.reblog' defaultMessage='Boosts:' /></span>
-
-          <div className='column-settings__row'>
-            <SettingToggle settings={settings} settingKey={['alerts', 'reblog']} onChange={onChange} label={alertStr} />
-            <SettingToggle settings={settings} settingKey={['shows', 'reblog']} onChange={onChange} label={showStr} />
-            <SettingToggle settings={settings} settingKey={['sounds', 'reblog']} onChange={onChange} label={soundStr} />
-          </div>
-        </div>
-      </ColumnCollapsable>
-    );
-  }
-
-}
-
-ColumnSettings.propTypes = {
-  settings: ImmutablePropTypes.map.isRequired,
-  onChange: PropTypes.func.isRequired,
-  onSave: PropTypes.func.isRequired,
-  intl: PropTypes.shape({
-    formatMessage: PropTypes.func.isRequired
-  }).isRequired
-};
-
-export default injectIntl(ColumnSettings);
diff --git a/app/assets/javascripts/components/features/notifications/components/notification.jsx b/app/assets/javascripts/components/features/notifications/components/notification.jsx
deleted file mode 100644
index 34dd76bb7..000000000
--- a/app/assets/javascripts/components/features/notifications/components/notification.jsx
+++ /dev/null
@@ -1,88 +0,0 @@
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import StatusContainer from '../../../containers/status_container';
-import AccountContainer from '../../../containers/account_container';
-import { FormattedMessage } from 'react-intl';
-import Permalink from '../../../components/permalink';
-import emojify from '../../../emoji';
-import escapeTextContentForBrowser from 'escape-html';
-
-class Notification extends React.PureComponent {
-
-  renderFollow (account, link) {
-    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 }} />
-        </div>
-
-        <AccountContainer id={account.get('id')} withNote={false} />
-      </div>
-    );
-  }
-
-  renderMention (notification) {
-    return <StatusContainer id={notification.get('status')} />;
-  }
-
-  renderFavourite (notification, link) {
-    return (
-      <div className='notification notification-favourite'>
-        <div className='notification__message'>
-          <div className='notification__favourite-icon-wrapper'>
-            <i className='fa fa-fw fa-star star-icon'/>
-          </div>
-
-          <FormattedMessage id='notification.favourite' defaultMessage='{name} favourited your status' values={{ name: link }} />
-        </div>
-
-        <StatusContainer id={notification.get('status')} muted={true} />
-      </div>
-    );
-  }
-
-  renderReblog (notification, link) {
-    return (
-      <div className='notification notification-reblog'>
-        <div className='notification__message'>
-          <div className='notification__favourite-icon-wrapper'>
-            <i className='fa fa-fw fa-retweet' />
-          </div>
-
-          <FormattedMessage id='notification.reblog' defaultMessage='{name} boosted your status' values={{ name: link }} />
-        </div>
-
-        <StatusContainer id={notification.get('status')} muted={true} />
-      </div>
-    );
-  }
-
-  render () { // eslint-disable-line consistent-return
-    const { notification } = this.props;
-    const account          = notification.get('account');
-    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} />;
-
-    switch(notification.get('type')) {
-    case 'follow':
-      return this.renderFollow(account, link);
-    case 'mention':
-      return this.renderMention(notification);
-    case 'favourite':
-      return this.renderFavourite(notification, link);
-    case 'reblog':
-      return this.renderReblog(notification, link);
-    }
-  }
-
-}
-
-Notification.propTypes = {
-  notification: ImmutablePropTypes.map.isRequired
-};
-
-export default Notification;
diff --git a/app/assets/javascripts/components/features/notifications/components/setting_toggle.jsx b/app/assets/javascripts/components/features/notifications/components/setting_toggle.jsx
deleted file mode 100644
index e9bca5928..000000000
--- a/app/assets/javascripts/components/features/notifications/components/setting_toggle.jsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import PropTypes from 'prop-types';
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import Toggle from 'react-toggle';
-
-const SettingToggle = ({ settings, settingKey, label, onChange, htmlFor = '' }) => (
-  <label htmlFor={htmlFor} className='setting-toggle__label'>
-    <Toggle checked={settings.getIn(settingKey)} onChange={(e) => onChange(settingKey, e.target.checked)} />
-    <span className='setting-toggle'>{label}</span>
-  </label>
-);
-
-SettingToggle.propTypes = {
-  settings: ImmutablePropTypes.map.isRequired,
-  settingKey: PropTypes.array.isRequired,
-  label: PropTypes.node.isRequired,
-  onChange: PropTypes.func.isRequired,
-  htmlFor: PropTypes.string
-};
-
-export default SettingToggle;
diff --git a/app/assets/javascripts/components/features/notifications/containers/column_settings_container.jsx b/app/assets/javascripts/components/features/notifications/containers/column_settings_container.jsx
deleted file mode 100644
index bc24c75e0..000000000
--- a/app/assets/javascripts/components/features/notifications/containers/column_settings_container.jsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { connect } from 'react-redux';
-import ColumnSettings from '../components/column_settings';
-import { changeSetting, saveSettings } from '../../../actions/settings';
-
-const mapStateToProps = state => ({
-  settings: state.getIn(['settings', 'notifications'])
-});
-
-const mapDispatchToProps = dispatch => ({
-
-  onChange (key, checked) {
-    dispatch(changeSetting(['notifications', ...key], checked));
-  },
-
-  onSave () {
-    dispatch(saveSettings());
-  }
-
-});
-
-export default connect(mapStateToProps, mapDispatchToProps)(ColumnSettings);
diff --git a/app/assets/javascripts/components/features/notifications/containers/notification_container.jsx b/app/assets/javascripts/components/features/notifications/containers/notification_container.jsx
deleted file mode 100644
index 4ca1b1b7b..000000000
--- a/app/assets/javascripts/components/features/notifications/containers/notification_container.jsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { connect } from 'react-redux';
-import { makeGetNotification } from '../../../selectors';
-import Notification from '../components/notification';
-
-const makeMapStateToProps = () => {
-  const getNotification = makeGetNotification();
-
-  const mapStateToProps = (state, props) => ({
-    notification: getNotification(state, props.notification, props.accountId)
-  });
-
-  return mapStateToProps;
-};
-
-export default connect(makeMapStateToProps)(Notification);
diff --git a/app/assets/javascripts/components/features/notifications/index.jsx b/app/assets/javascripts/components/features/notifications/index.jsx
deleted file mode 100644
index da3ce2f62..000000000
--- a/app/assets/javascripts/components/features/notifications/index.jsx
+++ /dev/null
@@ -1,142 +0,0 @@
-import { connect } from 'react-redux';
-import PropTypes from 'prop-types';
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import Column from '../ui/components/column';
-import { expandNotifications, clearNotifications, scrollTopNotifications } from '../../actions/notifications';
-import NotificationContainer from './containers/notification_container';
-import { ScrollContainer } from 'react-router-scroll';
-import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-import ColumnSettingsContainer from './containers/column_settings_container';
-import { createSelector } from 'reselect';
-import Immutable from 'immutable';
-import LoadMore from '../../components/load_more';
-import ClearColumnButton from './components/clear_column_button';
-import { openModal } from '../../actions/modal';
-
-const messages = defineMessages({
-  title: { id: 'column.notifications', defaultMessage: 'Notifications' },
-  clearMessage: { id: 'notifications.clear_confirmation', defaultMessage: 'Are you sure you want to permanently clear all your notifications?' },
-  clearConfirm: { id: 'notifications.clear', defaultMessage: 'Clear notifications' }
-});
-
-const getNotifications = createSelector([
-  state => Immutable.List(state.getIn(['settings', 'notifications', 'shows']).filter(item => !item).keys()),
-  state => state.getIn(['notifications', 'items'])
-], (excludedTypes, notifications) => notifications.filterNot(item => excludedTypes.includes(item.get('type'))));
-
-const mapStateToProps = state => ({
-  notifications: getNotifications(state),
-  isLoading: state.getIn(['notifications', 'isLoading'], true),
-  isUnread: state.getIn(['notifications', 'unread']) > 0
-});
-
-class Notifications extends React.PureComponent {
-
-  constructor (props, context) {
-    super(props, context);
-    this.handleScroll = this.handleScroll.bind(this);
-    this.handleLoadMore = this.handleLoadMore.bind(this);
-    this.handleClear = this.handleClear.bind(this);
-    this.setRef = this.setRef.bind(this);
-  }
-
-  handleScroll (e) {
-    const { scrollTop, scrollHeight, clientHeight } = e.target;
-    const offset = scrollHeight - scrollTop - clientHeight;
-    this._oldScrollPosition = scrollHeight - scrollTop;
-
-    if (250 > offset && !this.props.isLoading) {
-      this.props.dispatch(expandNotifications());
-    } else if (scrollTop < 100) {
-      this.props.dispatch(scrollTopNotifications(true));
-    } else {
-      this.props.dispatch(scrollTopNotifications(false));
-    }
-  }
-
-  componentDidUpdate (prevProps) {
-    if (this.node.scrollTop > 0 && (prevProps.notifications.size < this.props.notifications.size && prevProps.notifications.first() !== this.props.notifications.first() && !!this._oldScrollPosition)) {
-      this.node.scrollTop = this.node.scrollHeight - this._oldScrollPosition;
-    }
-  }
-
-  handleLoadMore (e) {
-    e.preventDefault();
-    this.props.dispatch(expandNotifications());
-  }
-
-  handleClear () {
-    const { dispatch, intl } = this.props;
-
-    dispatch(openModal('CONFIRM', {
-      message: intl.formatMessage(messages.clearMessage),
-      confirm: intl.formatMessage(messages.clearConfirm),
-      onConfirm: () => dispatch(clearNotifications())
-    }));
-  }
-
-  setRef (c) {
-    this.node = c;
-  }
-
-  render () {
-    const { intl, notifications, shouldUpdateScroll, isLoading, isUnread } = this.props;
-
-    let loadMore       = '';
-    let scrollableArea = '';
-    let unread         = '';
-
-    if (!isLoading && notifications.size > 0) {
-      loadMore = <LoadMore onClick={this.handleLoadMore} />;
-    }
-
-    if (isUnread) {
-      unread = <div className='notifications__unread-indicator' />;
-    }
-
-    if (isLoading || notifications.size > 0) {
-      scrollableArea = (
-        <div className='scrollable' onScroll={this.handleScroll} ref={this.setRef}>
-          {unread}
-
-          <div>
-            {notifications.map(item => <NotificationContainer key={item.get('id')} notification={item} accountId={item.get('account')} />)}
-            {loadMore}
-          </div>
-        </div>
-      );
-    } else {
-      scrollableArea = (
-        <div className='empty-column-indicator' ref={this.setRef}>
-          <FormattedMessage id='empty_column.notifications' defaultMessage="You don't have any notifications yet. Interact with others to start the conversation." />
-        </div>
-      );
-    }
-
-    return (
-      <Column icon='bell' active={isUnread} heading={intl.formatMessage(messages.title)}>
-        <ColumnSettingsContainer />
-        <ClearColumnButton onClick={this.handleClear} />
-        <ScrollContainer scrollKey='notifications' shouldUpdateScroll={shouldUpdateScroll}>
-          {scrollableArea}
-        </ScrollContainer>
-      </Column>
-    );
-  }
-
-}
-
-Notifications.propTypes = {
-  notifications: ImmutablePropTypes.list.isRequired,
-  dispatch: PropTypes.func.isRequired,
-  shouldUpdateScroll: PropTypes.func,
-  intl: PropTypes.object.isRequired,
-  isLoading: PropTypes.bool,
-  isUnread: PropTypes.bool
-};
-
-Notifications.defaultProps = {
-  trackScroll: true
-};
-
-export default connect(mapStateToProps)(injectIntl(Notifications));