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:
		| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user