From ac035108aaa2585af146fc28e4a2314c06e63e65 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 7 Feb 2017 00:06:40 +0100 Subject: [PATCH] Add "clear notifications" button, exclude posts from people who have blocked *you* from public/hashtag timelines --- .../components/actions/notifications.jsx | 12 +++++++++++ .../components/clear_column_button.jsx | 21 +++++++++++++++++++ .../features/notifications/index.jsx | 9 +++++++- .../components/reducers/notifications.jsx | 5 ++++- app/assets/stylesheets/components.scss | 8 +++++++ app/models/status.rb | 2 +- 6 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 app/assets/javascripts/components/features/notifications/components/clear_column_button.jsx 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 }) => ( +
+ +
+); + +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 ( + {scrollableArea} @@ -99,6 +105,7 @@ const Notifications = React.createClass({ return ( + {scrollableArea} ); 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