forked from cybrespace/mastodon
		
	Do not push DMs into the home feed (#8940)
* Do not push DMs into the home feed * Show DMs column after sending a DM, if DMs column is not already shown
This commit is contained in:
		
							parent
							
								
									790d3bc637
								
							
						
					
					
						commit
						87fdd139b8
					
				
					 11 changed files with 52 additions and 64 deletions
				
			
		| 
						 | 
				
			
			@ -56,7 +56,7 @@ export function changeCompose(text) {
 | 
			
		|||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function replyCompose(status, router) {
 | 
			
		||||
export function replyCompose(status, routerHistory) {
 | 
			
		||||
  return (dispatch, getState) => {
 | 
			
		||||
    dispatch({
 | 
			
		||||
      type: COMPOSE_REPLY,
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +64,7 @@ export function replyCompose(status, router) {
 | 
			
		|||
    });
 | 
			
		||||
 | 
			
		||||
    if (!getState().getIn(['compose', 'mounted'])) {
 | 
			
		||||
      router.push('/statuses/new');
 | 
			
		||||
      routerHistory.push('/statuses/new');
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ export function resetCompose() {
 | 
			
		|||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function mentionCompose(account, router) {
 | 
			
		||||
export function mentionCompose(account, routerHistory) {
 | 
			
		||||
  return (dispatch, getState) => {
 | 
			
		||||
    dispatch({
 | 
			
		||||
      type: COMPOSE_MENTION,
 | 
			
		||||
| 
						 | 
				
			
			@ -89,12 +89,12 @@ export function mentionCompose(account, router) {
 | 
			
		|||
    });
 | 
			
		||||
 | 
			
		||||
    if (!getState().getIn(['compose', 'mounted'])) {
 | 
			
		||||
      router.push('/statuses/new');
 | 
			
		||||
      routerHistory.push('/statuses/new');
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function directCompose(account, router) {
 | 
			
		||||
export function directCompose(account, routerHistory) {
 | 
			
		||||
  return (dispatch, getState) => {
 | 
			
		||||
    dispatch({
 | 
			
		||||
      type: COMPOSE_DIRECT,
 | 
			
		||||
| 
						 | 
				
			
			@ -102,12 +102,12 @@ export function directCompose(account, router) {
 | 
			
		|||
    });
 | 
			
		||||
 | 
			
		||||
    if (!getState().getIn(['compose', 'mounted'])) {
 | 
			
		||||
      router.push('/statuses/new');
 | 
			
		||||
      routerHistory.push('/statuses/new');
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function submitCompose() {
 | 
			
		||||
export function submitCompose(routerHistory) {
 | 
			
		||||
  return function (dispatch, getState) {
 | 
			
		||||
    const status = getState().getIn(['compose', 'text'], '');
 | 
			
		||||
    const media  = getState().getIn(['compose', 'media_attachments']);
 | 
			
		||||
| 
						 | 
				
			
			@ -133,21 +133,22 @@ export function submitCompose() {
 | 
			
		|||
      dispatch(insertIntoTagHistory(response.data.tags, status));
 | 
			
		||||
      dispatch(submitComposeSuccess({ ...response.data }));
 | 
			
		||||
 | 
			
		||||
      // To make the app more responsive, immediately get the status into the columns
 | 
			
		||||
      // To make the app more responsive, immediately push the status
 | 
			
		||||
      // into the columns
 | 
			
		||||
 | 
			
		||||
      const insertIfOnline = (timelineId) => {
 | 
			
		||||
      const insertIfOnline = timelineId => {
 | 
			
		||||
        if (getState().getIn(['timelines', timelineId, 'items', 0]) !== null) {
 | 
			
		||||
          dispatch(updateTimeline(timelineId, { ...response.data }));
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      insertIfOnline('home');
 | 
			
		||||
 | 
			
		||||
      if (response.data.in_reply_to_id === null && response.data.visibility === 'public') {
 | 
			
		||||
      if (response.data.visibility === 'direct' && getState().getIn(['conversations', 'mounted']) <= 0) {
 | 
			
		||||
        routerHistory.push('/timelines/direct');
 | 
			
		||||
      } else if (response.data.visibility !== 'direct') {
 | 
			
		||||
        insertIfOnline('home');
 | 
			
		||||
      } else if (response.data.in_reply_to_id === null && response.data.visibility === 'public') {
 | 
			
		||||
        insertIfOnline('community');
 | 
			
		||||
        insertIfOnline('public');
 | 
			
		||||
      } else if (response.data.visibility === 'direct') {
 | 
			
		||||
        insertIfOnline('direct');
 | 
			
		||||
      }
 | 
			
		||||
    }).catch(function (error) {
 | 
			
		||||
      dispatch(submitComposeFail(error));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,11 +5,22 @@ import {
 | 
			
		|||
  importFetchedStatus,
 | 
			
		||||
} from './importer';
 | 
			
		||||
 | 
			
		||||
export const CONVERSATIONS_MOUNT   = 'CONVERSATIONS_MOUNT';
 | 
			
		||||
export const CONVERSATIONS_UNMOUNT = 'CONVERSATIONS_UNMOUNT';
 | 
			
		||||
 | 
			
		||||
export const CONVERSATIONS_FETCH_REQUEST = 'CONVERSATIONS_FETCH_REQUEST';
 | 
			
		||||
export const CONVERSATIONS_FETCH_SUCCESS = 'CONVERSATIONS_FETCH_SUCCESS';
 | 
			
		||||
export const CONVERSATIONS_FETCH_FAIL    = 'CONVERSATIONS_FETCH_FAIL';
 | 
			
		||||
export const CONVERSATIONS_UPDATE        = 'CONVERSATIONS_UPDATE';
 | 
			
		||||
 | 
			
		||||
export const mountConversations = () => ({
 | 
			
		||||
  type: CONVERSATIONS_MOUNT,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const unmountConversations = () => ({
 | 
			
		||||
  type: CONVERSATIONS_UNMOUNT,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const expandConversations = ({ maxId } = {}) => (dispatch, getState) => {
 | 
			
		||||
  dispatch(expandConversationsRequest());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,10 @@ const messages = defineMessages({
 | 
			
		|||
export default @injectIntl
 | 
			
		||||
class ComposeForm extends ImmutablePureComponent {
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    intl: PropTypes.object.isRequired,
 | 
			
		||||
    text: PropTypes.string.isRequired,
 | 
			
		||||
| 
						 | 
				
			
			@ -84,7 +88,7 @@ class ComposeForm extends ImmutablePureComponent {
 | 
			
		|||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.props.onSubmit();
 | 
			
		||||
    this.props.onSubmit(this.context.router.history);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onSuggestionsClearRequested = () => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,10 @@ const messages = defineMessages({
 | 
			
		|||
export default @injectIntl
 | 
			
		||||
class Upload extends ImmutablePureComponent {
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    router: PropTypes.object,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    media: ImmutablePropTypes.map.isRequired,
 | 
			
		||||
    intl: PropTypes.object.isRequired,
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +41,7 @@ class Upload extends ImmutablePureComponent {
 | 
			
		|||
 | 
			
		||||
  handleSubmit = () => {
 | 
			
		||||
    this.handleInputBlur();
 | 
			
		||||
    this.props.onSubmit();
 | 
			
		||||
    this.props.onSubmit(this.context.router.history);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleUndoClick = () => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,8 +33,8 @@ const mapDispatchToProps = (dispatch) => ({
 | 
			
		|||
    dispatch(changeCompose(text));
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onSubmit () {
 | 
			
		||||
    dispatch(submitCompose());
 | 
			
		||||
  onSubmit (router) {
 | 
			
		||||
    dispatch(submitCompose(router));
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onClearSuggestions () {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,8 +22,8 @@ const mapDispatchToProps = dispatch => ({
 | 
			
		|||
    dispatch(openModal('FOCAL_POINT', { id }));
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onSubmit () {
 | 
			
		||||
    dispatch(submitCompose());
 | 
			
		||||
  onSubmit (router) {
 | 
			
		||||
    dispatch(submitCompose(router));
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@ import { connect } from 'react-redux';
 | 
			
		|||
import PropTypes from 'prop-types';
 | 
			
		||||
import Column from '../../components/column';
 | 
			
		||||
import ColumnHeader from '../../components/column_header';
 | 
			
		||||
import { expandConversations } from '../../actions/conversations';
 | 
			
		||||
import { mountConversations, unmountConversations, expandConversations } from '../../actions/conversations';
 | 
			
		||||
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
 | 
			
		||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 | 
			
		||||
import { connectDirectStream } from '../../actions/streaming';
 | 
			
		||||
| 
						 | 
				
			
			@ -48,11 +48,14 @@ class DirectTimeline extends React.PureComponent {
 | 
			
		|||
  componentDidMount () {
 | 
			
		||||
    const { dispatch } = this.props;
 | 
			
		||||
 | 
			
		||||
    dispatch(mountConversations());
 | 
			
		||||
    dispatch(expandConversations());
 | 
			
		||||
    this.disconnect = dispatch(connectDirectStream());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  componentWillUnmount () {
 | 
			
		||||
    this.props.dispatch(unmountConversations());
 | 
			
		||||
 | 
			
		||||
    if (this.disconnect) {
 | 
			
		||||
      this.disconnect();
 | 
			
		||||
      this.disconnect = null;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,7 @@
 | 
			
		|||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
 | 
			
		||||
import {
 | 
			
		||||
  CONVERSATIONS_MOUNT,
 | 
			
		||||
  CONVERSATIONS_UNMOUNT,
 | 
			
		||||
  CONVERSATIONS_FETCH_REQUEST,
 | 
			
		||||
  CONVERSATIONS_FETCH_SUCCESS,
 | 
			
		||||
  CONVERSATIONS_FETCH_FAIL,
 | 
			
		||||
| 
						 | 
				
			
			@ -11,6 +13,7 @@ const initialState = ImmutableMap({
 | 
			
		|||
  items: ImmutableList(),
 | 
			
		||||
  isLoading: false,
 | 
			
		||||
  hasMore: true,
 | 
			
		||||
  mounted: false,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const conversationToMap = item => ImmutableMap({
 | 
			
		||||
| 
						 | 
				
			
			@ -73,6 +76,10 @@ export default function conversations(state = initialState, action) {
 | 
			
		|||
    return expandNormalizedConversations(state, action.conversations, action.next);
 | 
			
		||||
  case CONVERSATIONS_UPDATE:
 | 
			
		||||
    return updateConversation(state, action.conversation);
 | 
			
		||||
  case CONVERSATIONS_MOUNT:
 | 
			
		||||
    return state.update('mounted', count => count + 1);
 | 
			
		||||
  case CONVERSATIONS_UNMOUNT:
 | 
			
		||||
    return state.update('mounted', count => count - 1);
 | 
			
		||||
  default:
 | 
			
		||||
    return state;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,6 @@ class BatchedRemoveStatusService < BaseService
 | 
			
		|||
    # Cannot be batched
 | 
			
		||||
    statuses.each do |status|
 | 
			
		||||
      unpush_from_public_timelines(status)
 | 
			
		||||
      unpush_from_direct_timelines(status) if status.direct_visibility?
 | 
			
		||||
      batch_salmon_slaps(status) if status.local?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -96,16 +95,6 @@ class BatchedRemoveStatusService < BaseService
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def unpush_from_direct_timelines(status)
 | 
			
		||||
    payload = @json_payloads[status.id]
 | 
			
		||||
    redis.pipelined do
 | 
			
		||||
      @mentions[status.id].each do |mention|
 | 
			
		||||
        redis.publish("timeline:direct:#{mention.account.id}", payload) if mention.account.local?
 | 
			
		||||
      end
 | 
			
		||||
      redis.publish("timeline:direct:#{status.account.id}", payload) if status.account.local?
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def batch_salmon_slaps(status)
 | 
			
		||||
    return if @mentions[status.id].empty?
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,15 +6,12 @@ class FanOutOnWriteService < BaseService
 | 
			
		|||
  def call(status)
 | 
			
		||||
    raise Mastodon::RaceConditionError if status.visibility.nil?
 | 
			
		||||
 | 
			
		||||
    deliver_to_self(status) if status.account.local?
 | 
			
		||||
 | 
			
		||||
    render_anonymous_payload(status)
 | 
			
		||||
 | 
			
		||||
    if status.direct_visibility?
 | 
			
		||||
      deliver_to_mentioned_followers(status)
 | 
			
		||||
      deliver_to_direct_timelines(status)
 | 
			
		||||
      deliver_to_own_conversation(status)
 | 
			
		||||
    else
 | 
			
		||||
      deliver_to_self(status) if status.account.local?
 | 
			
		||||
      deliver_to_followers(status)
 | 
			
		||||
      deliver_to_lists(status)
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -56,16 +53,6 @@ class FanOutOnWriteService < BaseService
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def deliver_to_mentioned_followers(status)
 | 
			
		||||
    Rails.logger.debug "Delivering status #{status.id} to mentioned followers"
 | 
			
		||||
 | 
			
		||||
    status.mentions.includes(:account).each do |mention|
 | 
			
		||||
      mentioned_account = mention.account
 | 
			
		||||
      next if !mentioned_account.local? || !mentioned_account.following?(status.account) || FeedManager.instance.filter?(:home, status, mention.account_id)
 | 
			
		||||
      FeedManager.instance.push_to_home(mentioned_account, status)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def render_anonymous_payload(status)
 | 
			
		||||
    @payload = InlineRenderer.render(status, nil, :status)
 | 
			
		||||
    @payload = Oj.dump(event: :update, payload: @payload)
 | 
			
		||||
| 
						 | 
				
			
			@ -94,16 +81,6 @@ class FanOutOnWriteService < BaseService
 | 
			
		|||
    Redis.current.publish('timeline:public:local:media', @payload) if status.local?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def deliver_to_direct_timelines(status)
 | 
			
		||||
    Rails.logger.debug "Delivering status #{status.id} to direct timelines"
 | 
			
		||||
 | 
			
		||||
    status.mentions.includes(:account).each do |mention|
 | 
			
		||||
      Redis.current.publish("timeline:direct:#{mention.account.id}", @payload) if mention.account.local?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    Redis.current.publish("timeline:direct:#{status.account.id}", @payload) if status.account.local?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def deliver_to_own_conversation(status)
 | 
			
		||||
    AccountConversation.add_status(status.account, status)
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,6 @@ class RemoveStatusService < BaseService
 | 
			
		|||
    remove_from_hashtags
 | 
			
		||||
    remove_from_public
 | 
			
		||||
    remove_from_media if status.media_attachments.any?
 | 
			
		||||
    remove_from_direct if status.direct_visibility?
 | 
			
		||||
 | 
			
		||||
    @status.destroy!
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -153,13 +152,6 @@ class RemoveStatusService < BaseService
 | 
			
		|||
    Redis.current.publish('timeline:public:local:media', @payload) if @status.local?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def remove_from_direct
 | 
			
		||||
    @mentions.each do |mention|
 | 
			
		||||
      Redis.current.publish("timeline:direct:#{mention.account.id}", @payload) if mention.account.local?
 | 
			
		||||
    end
 | 
			
		||||
    Redis.current.publish("timeline:direct:#{@account.id}", @payload) if @account.local?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def redis
 | 
			
		||||
    Redis.current
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue