Merge branch 'master' into glitch-soc/merge-upstream
Conflicts: - `app/javascript/mastodon/features/compose/components/poll_form.js` conflict because of the poll option limit being different than upstream's
This commit is contained in:
@@ -205,10 +205,11 @@ export function uploadCompose(files) {
|
||||
return function (dispatch, getState) {
|
||||
const uploadLimit = 4;
|
||||
const media = getState().getIn(['compose', 'media_attachments']);
|
||||
const pending = getState().getIn(['compose', 'pending_media_attachments']);
|
||||
const progress = new Array(files.length).fill(0);
|
||||
let total = Array.from(files).reduce((a, v) => a + v.size, 0);
|
||||
|
||||
if (files.length + media.size > uploadLimit) {
|
||||
if (files.length + media.size + pending > uploadLimit) {
|
||||
dispatch(showAlert(undefined, messages.uploadErrorLimit));
|
||||
return;
|
||||
}
|
||||
@@ -235,7 +236,7 @@ export function uploadCompose(files) {
|
||||
dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
|
||||
},
|
||||
}).then(({ data }) => dispatch(uploadComposeSuccess(data, f)));
|
||||
}).catch(error => dispatch(uploadComposeFail(error)));
|
||||
}).catch(error => dispatch(uploadComposeFail(error, true)));
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -266,10 +267,11 @@ export function changeUploadComposeSuccess(media) {
|
||||
};
|
||||
};
|
||||
|
||||
export function changeUploadComposeFail(error) {
|
||||
export function changeUploadComposeFail(error, decrement = false) {
|
||||
return {
|
||||
type: COMPOSE_UPLOAD_CHANGE_FAIL,
|
||||
error: error,
|
||||
decrement: decrement,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
@@ -142,9 +142,7 @@ class PollForm extends ImmutablePureComponent {
|
||||
</ul>
|
||||
|
||||
<div className='poll__footer'>
|
||||
{options.size < 5 && (
|
||||
<button className='button button-secondary' onClick={this.handleAddOption}><Icon id='plus' /> <FormattedMessage {...messages.add_option} /></button>
|
||||
)}
|
||||
<button disabled={options.size >= 5} className='button button-secondary' onClick={this.handleAddOption}><Icon id='plus' /> <FormattedMessage {...messages.add_option} /></button>
|
||||
|
||||
<select value={expiresIn} onChange={this.handleSelectDuration}>
|
||||
<option value={300}>{intl.formatMessage(messages.minutes, { number: 5 })}</option>
|
||||
|
@@ -3,7 +3,7 @@ import UploadButton from '../components/upload_button';
|
||||
import { uploadCompose } from '../../../actions/compose';
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size > 3 || state.getIn(['compose', 'media_attachments']).some(m => ['video', 'audio'].includes(m.get('type')))),
|
||||
disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size + state.getIn(['compose', 'pending_media_attachments']) > 3 || state.getIn(['compose', 'media_attachments']).some(m => ['video', 'audio'].includes(m.get('type')))),
|
||||
unavailable: state.getIn(['compose', 'poll']) !== null,
|
||||
resetFileKey: state.getIn(['compose', 'resetFileKey']),
|
||||
});
|
||||
|
@@ -61,6 +61,7 @@ const initialState = ImmutableMap({
|
||||
is_uploading: false,
|
||||
progress: 0,
|
||||
media_attachments: ImmutableList(),
|
||||
pending_media_attachments: 0,
|
||||
poll: null,
|
||||
suggestion_token: null,
|
||||
suggestions: ImmutableList(),
|
||||
@@ -114,6 +115,7 @@ function appendMedia(state, media, file) {
|
||||
map.set('is_uploading', false);
|
||||
map.set('resetFileKey', Math.floor((Math.random() * 0x10000)));
|
||||
map.set('idempotencyKey', uuid());
|
||||
map.update('pending_media_attachments', n => n - 1);
|
||||
|
||||
if (prevSize === 0 && (state.get('default_sensitive') || state.get('spoiler'))) {
|
||||
map.set('sensitive', true);
|
||||
@@ -322,11 +324,11 @@ export default function compose(state = initialState, action) {
|
||||
case COMPOSE_UPLOAD_CHANGE_FAIL:
|
||||
return state.set('is_changing_upload', false);
|
||||
case COMPOSE_UPLOAD_REQUEST:
|
||||
return state.set('is_uploading', true);
|
||||
return state.set('is_uploading', true).update('pending_media_attachments', n => n + 1);
|
||||
case COMPOSE_UPLOAD_SUCCESS:
|
||||
return appendMedia(state, fromJS(action.media), action.file);
|
||||
case COMPOSE_UPLOAD_FAIL:
|
||||
return state.set('is_uploading', false);
|
||||
return state.set('is_uploading', false).update('pending_media_attachments', n => action.decrement ? n - 1 : n);
|
||||
case COMPOSE_UPLOAD_UNDO:
|
||||
return removeMedia(state, action.media_id);
|
||||
case COMPOSE_UPLOAD_PROGRESS:
|
||||
|
@@ -392,6 +392,7 @@
|
||||
.autosuggest-input,
|
||||
.spoiler-input {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.spoiler-input {
|
||||
|
@@ -6,7 +6,7 @@ class AccountRelationshipsPresenter
|
||||
:endorsed
|
||||
|
||||
def initialize(account_ids, current_account_id, **options)
|
||||
@account_ids = account_ids.map { |a| a.is_a?(Account) ? a.id : a }
|
||||
@account_ids = account_ids.map { |a| a.is_a?(Account) ? a.id : a.to_i }
|
||||
@current_account_id = current_account_id
|
||||
|
||||
@following = cached[:following].merge(Account.following_map(@uncached_account_ids, @current_account_id))
|
||||
|
@@ -8,7 +8,7 @@ class FollowService < BaseService
|
||||
# @param [Account] source_account From which to follow
|
||||
# @param [String, Account] uri User URI to follow in the form of username@domain (or account record)
|
||||
# @param [true, false, nil] reblogs Whether or not to show reblogs, defaults to true
|
||||
def call(source_account, target_account, reblogs: nil)
|
||||
def call(source_account, target_account, reblogs: nil, bypass_locked: false)
|
||||
reblogs = true if reblogs.nil?
|
||||
target_account = ResolveAccountService.new.call(target_account, skip_webfinger: true)
|
||||
|
||||
@@ -30,7 +30,7 @@ class FollowService < BaseService
|
||||
|
||||
ActivityTracker.increment('activity:interactions')
|
||||
|
||||
if target_account.locked? || source_account.silenced? || target_account.activitypub?
|
||||
if (target_account.locked? && !bypass_locked) || source_account.silenced? || target_account.activitypub?
|
||||
request_follow(source_account, target_account, reblogs: reblogs)
|
||||
elsif target_account.local?
|
||||
direct_follow(source_account, target_account, reblogs: reblogs)
|
||||
|
@@ -7,7 +7,7 @@ class MoveWorker
|
||||
@source_account = Account.find(source_account_id)
|
||||
@target_account = Account.find(target_account_id)
|
||||
|
||||
if @target_account.local?
|
||||
if @target_account.local? && @source_account.local?
|
||||
rewrite_follows!
|
||||
else
|
||||
queue_follow_unfollows!
|
||||
@@ -21,13 +21,17 @@ class MoveWorker
|
||||
def rewrite_follows!
|
||||
@source_account.passive_relationships
|
||||
.where(account: Account.local)
|
||||
.where.not(account: @target_account.followers.local)
|
||||
.where.not(account_id: @target_account.id)
|
||||
.in_batches
|
||||
.update_all(target_account_id: @target_account.id)
|
||||
end
|
||||
|
||||
def queue_follow_unfollows!
|
||||
bypass_locked = @target_account.local?
|
||||
|
||||
@source_account.followers.local.select(:id).find_in_batches do |accounts|
|
||||
UnfollowFollowWorker.push_bulk(accounts.map(&:id)) { |follower_id| [follower_id, @source_account.id, @target_account.id] }
|
||||
UnfollowFollowWorker.push_bulk(accounts.map(&:id)) { |follower_id| [follower_id, @source_account.id, @target_account.id, bypass_locked] }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@@ -5,12 +5,15 @@ class UnfollowFollowWorker
|
||||
|
||||
sidekiq_options queue: 'pull'
|
||||
|
||||
def perform(follower_account_id, old_target_account_id, new_target_account_id)
|
||||
def perform(follower_account_id, old_target_account_id, new_target_account_id, bypass_locked = false)
|
||||
follower_account = Account.find(follower_account_id)
|
||||
old_target_account = Account.find(old_target_account_id)
|
||||
new_target_account = Account.find(new_target_account_id)
|
||||
|
||||
FollowService.new.call(follower_account, new_target_account)
|
||||
follow = follower_account.active_relationships.find_by(target_account: old_target_account)
|
||||
reblogs = follow&.show_reblogs?
|
||||
|
||||
FollowService.new.call(follower_account, new_target_account, reblogs: reblogs, bypass_locked: bypass_locked)
|
||||
UnfollowService.new.call(follower_account, old_target_account, skip_unmerge: true)
|
||||
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
|
||||
true
|
||||
|
Reference in New Issue
Block a user