about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2017-02-07 00:06:40 +0100
committerEugen Rochko <eugen@zeonfederated.com>2017-02-07 00:06:40 +0100
commitac035108aaa2585af146fc28e4a2314c06e63e65 (patch)
tree61c7bc0a34792d1d7378e71d80f7f2670eeae8b3
parentc8252759df98f41860b0580b029d9efa374c7125 (diff)
Add "clear notifications" button, exclude posts from people who have blocked *you* from public/hashtag timelines
-rw-r--r--app/assets/javascripts/components/actions/notifications.jsx12
-rw-r--r--app/assets/javascripts/components/features/notifications/components/clear_column_button.jsx21
-rw-r--r--app/assets/javascripts/components/features/notifications/index.jsx9
-rw-r--r--app/assets/javascripts/components/reducers/notifications.jsx5
-rw-r--r--app/assets/stylesheets/components.scss8
-rw-r--r--app/models/status.rb2
6 files changed, 54 insertions, 3 deletions
diff --git a/app/assets/javascripts/components/actions/notifications.jsx b/app/assets/javascripts/components/actions/notifications.jsx
index 4caf9c75b..df82e73fc 100644
--- a/app/assets/javascripts/components/actions/notifications.jsx
+++ b/app/assets/javascripts/components/actions/notifications.jsx
@@ -14,6 +14,8 @@ export const NOTIFICATIONS_EXPAND_REQUEST = 'NOTIFICATIONS_EXPAND_REQUEST';
 export const NOTIFICATIONS_EXPAND_SUCCESS = 'NOTIFICATIONS_EXPAND_SUCCESS';
 export const NOTIFICATIONS_EXPAND_FAIL    = 'NOTIFICATIONS_EXPAND_FAIL';
 
+export const NOTIFICATIONS_CLEAR = 'NOTIFICATIONS_CLEAR';
+
 const fetchRelatedRelationships = (dispatch, notifications) => {
   const accountIds = notifications.filter(item => item.type === 'follow').map(item => item.account.id);
 
@@ -139,3 +141,13 @@ export function expandNotificationsFail(error) {
     error
   };
 };
+
+export function clearNotifications() {
+  return (dispatch, getState) => {
+    dispatch({
+      type: NOTIFICATIONS_CLEAR
+    });
+
+    api(getState).post('/api/v1/notifications/clear');
+  };
+};
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
new file mode 100644
index 000000000..d20a4d170
--- /dev/null
+++ b/app/assets/javascripts/components/features/notifications/components/clear_column_button.jsx
@@ -0,0 +1,21 @@
+const iconStyle = {
+  fontSize: '16px',
+  padding: '15px',
+  position: 'absolute',
+  right: '48px',
+  top: '0',
+  cursor: 'pointer',
+  background: '#2f3441'
+};
+
+const ClearColumnButton = ({ onClick }) => (
+  <div className='column-icon' style={iconStyle} onClick={onClick}>
+    <i className='fa fa-trash' />
+  </div>
+);
+
+ClearColumnButton.propTypes = {
+  onClick: React.PropTypes.func.isRequired
+};
+
+export default ClearColumnButton;
diff --git a/app/assets/javascripts/components/features/notifications/index.jsx b/app/assets/javascripts/components/features/notifications/index.jsx
index d3300acd5..6d10768de 100644
--- a/app/assets/javascripts/components/features/notifications/index.jsx
+++ b/app/assets/javascripts/components/features/notifications/index.jsx
@@ -2,7 +2,7 @@ import { connect } from 'react-redux';
 import PureRenderMixin from 'react-addons-pure-render-mixin';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import Column from '../ui/components/column';
-import { expandNotifications } from '../../actions/notifications';
+import { expandNotifications, clearNotifications } from '../../actions/notifications';
 import NotificationContainer from './containers/notification_container';
 import { ScrollContainer } from 'react-router-scroll';
 import { defineMessages, injectIntl } from 'react-intl';
@@ -10,6 +10,7 @@ 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';
 
 const messages = defineMessages({
   title: { id: 'column.notifications', defaultMessage: 'Notifications' }
@@ -64,6 +65,10 @@ const Notifications = React.createClass({
     this.props.dispatch(expandNotifications());
   },
 
+  handleClear () {
+    this.props.dispatch(clearNotifications());
+  },
+
   setRef (c) {
     this.node = c;
   },
@@ -90,6 +95,7 @@ const Notifications = React.createClass({
       return (
         <Column icon='bell' heading={intl.formatMessage(messages.title)}>
           <ColumnSettingsContainer />
+          <ClearColumnButton onClick={this.handleClear} />
           <ScrollContainer scrollKey='notifications'>
             {scrollableArea}
           </ScrollContainer>
@@ -99,6 +105,7 @@ const Notifications = React.createClass({
       return (
         <Column icon='bell' heading={intl.formatMessage(messages.title)}>
           <ColumnSettingsContainer />
+          <ClearColumnButton onClick={this.handleClear} />
           {scrollableArea}
         </Column>
       );
diff --git a/app/assets/javascripts/components/reducers/notifications.jsx b/app/assets/javascripts/components/reducers/notifications.jsx
index 482093c33..4a7af8856 100644
--- a/app/assets/javascripts/components/reducers/notifications.jsx
+++ b/app/assets/javascripts/components/reducers/notifications.jsx
@@ -5,7 +5,8 @@ import {
   NOTIFICATIONS_REFRESH_REQUEST,
   NOTIFICATIONS_EXPAND_REQUEST,
   NOTIFICATIONS_REFRESH_FAIL,
-  NOTIFICATIONS_EXPAND_FAIL
+  NOTIFICATIONS_EXPAND_FAIL,
+  NOTIFICATIONS_CLEAR
 } from '../actions/notifications';
 import { ACCOUNT_BLOCK_SUCCESS } from '../actions/accounts';
 import Immutable from 'immutable';
@@ -75,6 +76,8 @@ export default function notifications(state = initialState, action) {
     return appendNormalizedNotifications(state, action.notifications, action.next);
   case ACCOUNT_BLOCK_SUCCESS:
     return filterNotifications(state, action.relationship);
+  case NOTIFICATIONS_CLEAR:
+    return state.set('items', Immutable.List()).set('next', null);
   default:
     return state;
   }
diff --git a/app/assets/stylesheets/components.scss b/app/assets/stylesheets/components.scss
index 40c39678f..13df099b1 100644
--- a/app/assets/stylesheets/components.scss
+++ b/app/assets/stylesheets/components.scss
@@ -32,6 +32,14 @@
   }
 }
 
+.column-icon {
+  color: $color3;
+
+  &:hover {
+    color: lighten($color3, 7%);
+  }
+}
+
 .icon-button {
   color: lighten($color1, 26%);
   border: none;
diff --git a/app/models/status.rb b/app/models/status.rb
index 142dec64e..6ef0b2bdd 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -161,7 +161,7 @@ class Status < ApplicationRecord
     private
 
     def filter_timeline(query, account)
-      blocked = Block.where(account: account).pluck(:target_account_id)
+      blocked = Block.where(account: account).pluck(:target_account_id) + Block.where(target_account: account).pluck(:account_id)
       query   = query.where('statuses.account_id NOT IN (?)', blocked) unless blocked.empty?
       query   = query.where('accounts.silenced = TRUE') if account.silenced?
       query