forked from cybrespace/mastodon
		
	Fix #614 - extra reply-boolean on statuses to account for cases when replied-to
status is not in the system at time of distribution; fix #607 - reset privacy settings to defaults when cancelling replies
This commit is contained in:
		
							parent
							
								
									c424df5192
								
							
						
					
					
						commit
						6331ed16e5
					
				
					 11 changed files with 32 additions and 100 deletions
				
			
		| 
						 | 
				
			
			@ -81,11 +81,16 @@ function appendMedia(state, media) {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
function removeMedia(state, mediaId) {
 | 
			
		||||
  const media = state.get('media_attachments').find(item => item.get('id') === mediaId);
 | 
			
		||||
  const media    = state.get('media_attachments').find(item => item.get('id') === mediaId);
 | 
			
		||||
  const prevSize = state.get('media_attachments').size;
 | 
			
		||||
 | 
			
		||||
  return state.withMutations(map => {
 | 
			
		||||
    map.update('media_attachments', list => list.filterNot(item => item.get('id') === mediaId));
 | 
			
		||||
    map.update('text', text => text.replace(media.get('text_url'), '').trim());
 | 
			
		||||
 | 
			
		||||
    if (prevSize === 1) {
 | 
			
		||||
      map.update('sensitive', false);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -126,6 +131,8 @@ export default function compose(state = initialState, action) {
 | 
			
		|||
    return state.withMutations(map => {
 | 
			
		||||
      map.set('in_reply_to', null);
 | 
			
		||||
      map.set('text', '');
 | 
			
		||||
      map.set('unlisted', state.get('default_privacy') === 'unlisted');
 | 
			
		||||
      map.set('private', state.get('default_privacy') === 'private');
 | 
			
		||||
    });
 | 
			
		||||
  case COMPOSE_SUBMIT_REQUEST:
 | 
			
		||||
    return state.set('is_submitting', true);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,22 +0,0 @@
 | 
			
		|||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
module ApplicationCable
 | 
			
		||||
  class Channel < ActionCable::Channel::Base
 | 
			
		||||
    protected
 | 
			
		||||
 | 
			
		||||
    def hydrate_status(encoded_message)
 | 
			
		||||
      message = Oj.load(encoded_message)
 | 
			
		||||
 | 
			
		||||
      return [nil, message] if message['event'] == 'delete'
 | 
			
		||||
 | 
			
		||||
      status_json = Oj.load(message['payload'])
 | 
			
		||||
      status      = Status.find(status_json['id'])
 | 
			
		||||
 | 
			
		||||
      [status, message]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def filter?(status)
 | 
			
		||||
      !status.nil? && FeedManager.instance.filter?(:public, status, current_user.account)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -1,22 +0,0 @@
 | 
			
		|||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
module ApplicationCable
 | 
			
		||||
  class Connection < ActionCable::Connection::Base
 | 
			
		||||
    identified_by :current_user
 | 
			
		||||
 | 
			
		||||
    def connect
 | 
			
		||||
      self.current_user = find_verified_user
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    protected
 | 
			
		||||
 | 
			
		||||
    def find_verified_user
 | 
			
		||||
      catch :warden do
 | 
			
		||||
        verified_user = env['warden'].user
 | 
			
		||||
        return verified_user if verified_user
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      reject_unauthorized_connection
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -1,13 +0,0 @@
 | 
			
		|||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
class HashtagChannel < ApplicationCable::Channel
 | 
			
		||||
  def subscribed
 | 
			
		||||
    tag = params[:tag].downcase
 | 
			
		||||
 | 
			
		||||
    stream_from "timeline:hashtag:#{tag}", lambda { |encoded_message|
 | 
			
		||||
      status, message = hydrate_status(encoded_message)
 | 
			
		||||
      next if filter?(status)
 | 
			
		||||
      transmit message
 | 
			
		||||
    }
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +0,0 @@
 | 
			
		|||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
class PublicChannel < ApplicationCable::Channel
 | 
			
		||||
  def subscribed
 | 
			
		||||
    stream_from 'timeline:public', lambda { |encoded_message|
 | 
			
		||||
      status, message = hydrate_status(encoded_message)
 | 
			
		||||
      next if filter?(status)
 | 
			
		||||
      transmit message
 | 
			
		||||
    }
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +0,0 @@
 | 
			
		|||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
class TimelineChannel < ApplicationCable::Channel
 | 
			
		||||
  def subscribed
 | 
			
		||||
    stream_from "timeline:#{current_user.account_id}"
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -16,8 +16,6 @@ class FeedManager
 | 
			
		|||
      filter_from_home?(status, receiver)
 | 
			
		||||
    elsif timeline_type == :mentions
 | 
			
		||||
      filter_from_mentions?(status, receiver)
 | 
			
		||||
    elsif timeline_type == :public
 | 
			
		||||
      filter_from_public?(status, receiver)
 | 
			
		||||
    else
 | 
			
		||||
      false
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +87,9 @@ class FeedManager
 | 
			
		|||
  def filter_from_home?(status, receiver)
 | 
			
		||||
    should_filter = false
 | 
			
		||||
 | 
			
		||||
    if status.reply? && !status.in_reply_to_account_id.nil?                   # Filter out if it's a reply
 | 
			
		||||
    if status.reply? && status.in_reply_to_id.nil?
 | 
			
		||||
      should_filter = true
 | 
			
		||||
    elsif status.reply? && !status.in_reply_to_account_id.nil?                # Filter out if it's a reply
 | 
			
		||||
      should_filter   = !receiver.following?(status.in_reply_to_account)      # and I'm not following the person it's a reply to
 | 
			
		||||
      should_filter &&= !(receiver.id == status.in_reply_to_account_id)       # and it's not a reply to me
 | 
			
		||||
      should_filter &&= !(status.account_id == status.in_reply_to_account_id) # and it's not a self-reply
 | 
			
		||||
| 
						 | 
				
			
			@ -115,17 +115,4 @@ class FeedManager
 | 
			
		|||
 | 
			
		||||
    should_filter
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def filter_from_public?(status, receiver)
 | 
			
		||||
    should_filter   = receiver.blocking?(status.account)
 | 
			
		||||
    should_filter ||= receiver.blocking?(status.mentions.includes(:account).map(&:account))
 | 
			
		||||
 | 
			
		||||
    if status.reply? && !status.in_reply_to_account_id.nil?
 | 
			
		||||
      should_filter ||= receiver.blocking?(status.in_reply_to_account)
 | 
			
		||||
    elsif status.reblog?
 | 
			
		||||
      should_filter ||= receiver.blocking?(status.reblog.account)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    should_filter
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,10 @@ class Status < ApplicationRecord
 | 
			
		|||
 | 
			
		||||
  cache_associated :account, :application, :media_attachments, :tags, :stream_entry, mentions: :account, reblog: [:account, :application, :stream_entry, :tags, :media_attachments, mentions: :account], thread: :account
 | 
			
		||||
 | 
			
		||||
  def reply?
 | 
			
		||||
    super || !in_reply_to_id.nil?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def local?
 | 
			
		||||
    uri.nil?
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -47,10 +51,6 @@ class Status < ApplicationRecord
 | 
			
		|||
    !reblog_of_id.nil?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def reply?
 | 
			
		||||
    !in_reply_to_id.nil?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def verb
 | 
			
		||||
    reblog? ? :share : :post
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -105,7 +105,7 @@ class Status < ApplicationRecord
 | 
			
		|||
    def as_public_timeline(account = nil, local_only = false)
 | 
			
		||||
      query = joins('LEFT OUTER JOIN accounts ON statuses.account_id = accounts.id')
 | 
			
		||||
              .where(visibility: :public)
 | 
			
		||||
              .where('(statuses.in_reply_to_id IS NULL OR statuses.in_reply_to_account_id = statuses.account_id)')
 | 
			
		||||
              .where('(statuses.reply = false OR statuses.in_reply_to_account_id = statuses.account_id)')
 | 
			
		||||
              .where('statuses.reblog_of_id IS NULL')
 | 
			
		||||
 | 
			
		||||
      query = query.where('accounts.domain IS NULL') if local_only
 | 
			
		||||
| 
						 | 
				
			
			@ -176,8 +176,9 @@ class Status < ApplicationRecord
 | 
			
		|||
    text.strip!
 | 
			
		||||
    spoiler_text&.strip!
 | 
			
		||||
 | 
			
		||||
    self.reply                  = !(in_reply_to_id.nil? && thread.nil?) unless attributes[:reply]
 | 
			
		||||
    self.reblog                 = reblog.reblog if reblog? && reblog.reblog?
 | 
			
		||||
    self.in_reply_to_account_id = (thread.account_id == account_id && thread.reply? ? thread.in_reply_to_account_id : thread.account_id) if reply?
 | 
			
		||||
    self.in_reply_to_account_id = (thread.account_id == account_id && thread.reply? ? thread.in_reply_to_account_id : thread.account_id) if reply? && !thread.nil?
 | 
			
		||||
    self.visibility             = (account.locked? ? :private : :public) if visibility.nil?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,7 +105,8 @@ class ProcessFeedService < BaseService
 | 
			
		|||
        account: account,
 | 
			
		||||
        text: content(entry),
 | 
			
		||||
        spoiler_text: content_warning(entry),
 | 
			
		||||
        created_at: published(entry)
 | 
			
		||||
        created_at: published(entry),
 | 
			
		||||
        reply: thread?(entry)
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
      if thread?(entry)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								db/migrate/20170209184350_add_reply_to_statuses.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								db/migrate/20170209184350_add_reply_to_statuses.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,10 @@
 | 
			
		|||
class AddReplyToStatuses < ActiveRecord::Migration[5.0]
 | 
			
		||||
  def up
 | 
			
		||||
    add_column :statuses, :reply, :boolean, nil: false, default: false
 | 
			
		||||
    Status.update_all('reply = (in_reply_to_id IS NOT NULL)')
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def down
 | 
			
		||||
    remove_column :statuses, :reply
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -10,7 +10,7 @@
 | 
			
		|||
#
 | 
			
		||||
# It's strongly recommended that you check this file into your version control system.
 | 
			
		||||
 | 
			
		||||
ActiveRecord::Schema.define(version: 20170205175257) do
 | 
			
		||||
ActiveRecord::Schema.define(version: 20170209184350) do
 | 
			
		||||
 | 
			
		||||
  # These are extensions that must be enabled in order to support this database
 | 
			
		||||
  enable_extension "plpgsql"
 | 
			
		||||
| 
						 | 
				
			
			@ -197,6 +197,7 @@ ActiveRecord::Schema.define(version: 20170205175257) do
 | 
			
		|||
    t.integer  "in_reply_to_account_id"
 | 
			
		||||
    t.integer  "application_id"
 | 
			
		||||
    t.text     "spoiler_text",           default: "",    null: false
 | 
			
		||||
    t.boolean  "reply",                  default: false
 | 
			
		||||
    t.index ["account_id"], name: "index_statuses_on_account_id", using: :btree
 | 
			
		||||
    t.index ["in_reply_to_id"], name: "index_statuses_on_in_reply_to_id", using: :btree
 | 
			
		||||
    t.index ["reblog_of_id"], name: "index_statuses_on_reblog_of_id", using: :btree
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue