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 repliesgh/stable
parent
c424df5192
commit
6331ed16e5
|
@ -81,11 +81,16 @@ function appendMedia(state, media) {
|
||||||
};
|
};
|
||||||
|
|
||||||
function removeMedia(state, mediaId) {
|
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 => {
|
return state.withMutations(map => {
|
||||||
map.update('media_attachments', list => list.filterNot(item => item.get('id') === mediaId));
|
map.update('media_attachments', list => list.filterNot(item => item.get('id') === mediaId));
|
||||||
map.update('text', text => text.replace(media.get('text_url'), '').trim());
|
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 => {
|
return state.withMutations(map => {
|
||||||
map.set('in_reply_to', null);
|
map.set('in_reply_to', null);
|
||||||
map.set('text', '');
|
map.set('text', '');
|
||||||
|
map.set('unlisted', state.get('default_privacy') === 'unlisted');
|
||||||
|
map.set('private', state.get('default_privacy') === 'private');
|
||||||
});
|
});
|
||||||
case COMPOSE_SUBMIT_REQUEST:
|
case COMPOSE_SUBMIT_REQUEST:
|
||||||
return state.set('is_submitting', true);
|
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)
|
filter_from_home?(status, receiver)
|
||||||
elsif timeline_type == :mentions
|
elsif timeline_type == :mentions
|
||||||
filter_from_mentions?(status, receiver)
|
filter_from_mentions?(status, receiver)
|
||||||
elsif timeline_type == :public
|
|
||||||
filter_from_public?(status, receiver)
|
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
@ -89,7 +87,9 @@ class FeedManager
|
||||||
def filter_from_home?(status, receiver)
|
def filter_from_home?(status, receiver)
|
||||||
should_filter = false
|
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.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 &&= !(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
|
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
|
should_filter
|
||||||
end
|
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
|
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
|
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?
|
def local?
|
||||||
uri.nil?
|
uri.nil?
|
||||||
end
|
end
|
||||||
|
@ -47,10 +51,6 @@ class Status < ApplicationRecord
|
||||||
!reblog_of_id.nil?
|
!reblog_of_id.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def reply?
|
|
||||||
!in_reply_to_id.nil?
|
|
||||||
end
|
|
||||||
|
|
||||||
def verb
|
def verb
|
||||||
reblog? ? :share : :post
|
reblog? ? :share : :post
|
||||||
end
|
end
|
||||||
|
@ -105,7 +105,7 @@ class Status < ApplicationRecord
|
||||||
def as_public_timeline(account = nil, local_only = false)
|
def as_public_timeline(account = nil, local_only = false)
|
||||||
query = joins('LEFT OUTER JOIN accounts ON statuses.account_id = accounts.id')
|
query = joins('LEFT OUTER JOIN accounts ON statuses.account_id = accounts.id')
|
||||||
.where(visibility: :public)
|
.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')
|
.where('statuses.reblog_of_id IS NULL')
|
||||||
|
|
||||||
query = query.where('accounts.domain IS NULL') if local_only
|
query = query.where('accounts.domain IS NULL') if local_only
|
||||||
|
@ -176,8 +176,9 @@ class Status < ApplicationRecord
|
||||||
text.strip!
|
text.strip!
|
||||||
spoiler_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.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?
|
self.visibility = (account.locked? ? :private : :public) if visibility.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,8 @@ class ProcessFeedService < BaseService
|
||||||
account: account,
|
account: account,
|
||||||
text: content(entry),
|
text: content(entry),
|
||||||
spoiler_text: content_warning(entry),
|
spoiler_text: content_warning(entry),
|
||||||
created_at: published(entry)
|
created_at: published(entry),
|
||||||
|
reply: thread?(entry)
|
||||||
)
|
)
|
||||||
|
|
||||||
if thread?(entry)
|
if thread?(entry)
|
||||||
|
|
|
@ -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.
|
# 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
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -197,6 +197,7 @@ ActiveRecord::Schema.define(version: 20170205175257) do
|
||||||
t.integer "in_reply_to_account_id"
|
t.integer "in_reply_to_account_id"
|
||||||
t.integer "application_id"
|
t.integer "application_id"
|
||||||
t.text "spoiler_text", default: "", null: false
|
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 ["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 ["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
|
t.index ["reblog_of_id"], name: "index_statuses_on_reblog_of_id", using: :btree
|
||||||
|
|
Reference in New Issue