Merge branch 'master' into glitch-soc/merge-upstream
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
class Api::ProofsController < Api::BaseController
|
||||
include AccountOwnedConcern
|
||||
|
||||
skip_before_action :require_authenticated_user!
|
||||
|
||||
before_action :set_provider
|
||||
|
||||
def index
|
||||
|
||||
@@ -236,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, true)));
|
||||
}).catch(error => dispatch(uploadComposeFail(error)));
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -267,11 +267,10 @@ export function changeUploadComposeSuccess(media) {
|
||||
};
|
||||
};
|
||||
|
||||
export function changeUploadComposeFail(error, decrement = false) {
|
||||
export function changeUploadComposeFail(error) {
|
||||
return {
|
||||
type: COMPOSE_UPLOAD_CHANGE_FAIL,
|
||||
error: error,
|
||||
decrement: decrement,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -214,6 +214,22 @@ class Status extends ImmutablePureComponent {
|
||||
this.props.onOpenVideo(media, startTime);
|
||||
}
|
||||
|
||||
handleHotkeyOpenMedia = e => {
|
||||
const { status, onOpenMedia, onOpenVideo } = this.props;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
if (status.get('media_attachments').size > 0) {
|
||||
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
||||
// TODO: toggle play/paused?
|
||||
} else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
||||
onOpenVideo(status.getIn(['media_attachments', 0]), 0);
|
||||
} else {
|
||||
onOpenMedia(status.get('media_attachments'), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleHotkeyReply = e => {
|
||||
e.preventDefault();
|
||||
this.props.onReply(this._properStatus(), this.context.router.history);
|
||||
@@ -293,6 +309,7 @@ class Status extends ImmutablePureComponent {
|
||||
moveDown: this.handleHotkeyMoveDown,
|
||||
toggleHidden: this.handleHotkeyToggleHidden,
|
||||
toggleSensitive: this.handleHotkeyToggleSensitive,
|
||||
openMedia: this.handleHotkeyOpenMedia,
|
||||
};
|
||||
|
||||
if (hidden) {
|
||||
|
||||
@@ -56,6 +56,10 @@ class KeyboardShortcuts extends ImmutablePureComponent {
|
||||
<td><kbd>enter</kbd>, <kbd>o</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.enter' defaultMessage='to open status' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>e</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.open_media' defaultMessage='to open media' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>x</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.toggle_hidden' defaultMessage='to show/hide text behind CW' /></td>
|
||||
|
||||
@@ -281,6 +281,22 @@ class Status extends ImmutablePureComponent {
|
||||
this.props.dispatch(openModal('VIDEO', { media, time }));
|
||||
}
|
||||
|
||||
handleHotkeyOpenMedia = e => {
|
||||
const { status } = this.props;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
if (status.get('media_attachments').size > 0) {
|
||||
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
||||
// TODO: toggle play/paused?
|
||||
} else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
||||
this.handleOpenVideo(status.getIn(['media_attachments', 0]), 0);
|
||||
} else {
|
||||
this.handleOpenMedia(status.get('media_attachments'), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleMuteClick = (account) => {
|
||||
this.props.dispatch(initMuteModal(account));
|
||||
}
|
||||
@@ -506,6 +522,7 @@ class Status extends ImmutablePureComponent {
|
||||
openProfile: this.handleHotkeyOpenProfile,
|
||||
toggleHidden: this.handleHotkeyToggleHidden,
|
||||
toggleSensitive: this.handleHotkeyToggleSensitive,
|
||||
openMedia: this.handleHotkeyOpenMedia,
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -214,7 +214,7 @@ class FocalPointModal extends ImmutablePureComponent {
|
||||
langPath: `${assetHost}/ocr/lang-data`,
|
||||
});
|
||||
|
||||
let media_url = media.get('file');
|
||||
let media_url = media.get('url');
|
||||
|
||||
if (window.URL && URL.createObjectURL) {
|
||||
try {
|
||||
|
||||
@@ -100,6 +100,7 @@ const keyMap = {
|
||||
goToRequests: 'g r',
|
||||
toggleHidden: 'x',
|
||||
toggleSensitive: 'h',
|
||||
openMedia: 'e',
|
||||
};
|
||||
|
||||
class SwitchingColumnsArea extends React.PureComponent {
|
||||
|
||||
@@ -467,7 +467,7 @@ class Video extends React.PureComponent {
|
||||
|
||||
<div className='video-player__buttons-bar'>
|
||||
<div className='video-player__buttons left'>
|
||||
<button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
|
||||
<button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay} autoFocus={detailed}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
|
||||
<button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
|
||||
|
||||
<div className='video-player__volume' onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
|
||||
|
||||
@@ -328,7 +328,7 @@ export default function compose(state = initialState, action) {
|
||||
case COMPOSE_UPLOAD_SUCCESS:
|
||||
return appendMedia(state, fromJS(action.media), action.file);
|
||||
case COMPOSE_UPLOAD_FAIL:
|
||||
return state.set('is_uploading', false).update('pending_media_attachments', n => action.decrement ? n - 1 : n);
|
||||
return state.set('is_uploading', false).update('pending_media_attachments', n => n - 1);
|
||||
case COMPOSE_UPLOAD_UNDO:
|
||||
return removeMedia(state, action.media_id);
|
||||
case COMPOSE_UPLOAD_PROGRESS:
|
||||
|
||||
@@ -646,7 +646,7 @@
|
||||
}
|
||||
|
||||
.counter {
|
||||
width: 33.3%;
|
||||
min-width: 33.3%;
|
||||
box-sizing: border-box;
|
||||
flex: 0 0 auto;
|
||||
color: $darker-text-color;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class StatusRelationshipsPresenter
|
||||
attr_reader :reblogs_map, :favourites_map, :mutes_map, :pins_map
|
||||
attr_reader :reblogs_map, :favourites_map, :mutes_map, :pins_map,
|
||||
:bookmarks_map
|
||||
|
||||
def initialize(statuses, current_account_id = nil, **options)
|
||||
if current_account_id.nil?
|
||||
|
||||
@@ -97,8 +97,8 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
||||
end
|
||||
|
||||
def bookmarked
|
||||
if instance_options && instance_options[:bookmarks]
|
||||
instance_options[:bookmarks].bookmarks_map[object.id] || false
|
||||
if instance_options && instance_options[:relationships]
|
||||
instance_options[:relationships].bookmarks_map[object.id] || false
|
||||
else
|
||||
current_user.account.bookmarked?(object)
|
||||
end
|
||||
|
||||
@@ -30,7 +30,7 @@ class ActivityPub::ProcessPollService < BaseService
|
||||
|
||||
voters_count = @json['votersCount']
|
||||
|
||||
latest_options = items.map { |item| item['name'].presence || item['content'] }
|
||||
latest_options = items.map { |item| item['name'].presence || item['content'] }.compact
|
||||
|
||||
# If for some reasons the options were changed, it invalidates all previous
|
||||
# votes, so we need to remove them
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
= simple_form_for current_user, url: settings_preferences_notifications_path, html: { method: :put } do |f|
|
||||
= render 'shared/error_messages', object: current_user
|
||||
|
||||
%h4= t('notifications.email_events')
|
||||
|
||||
%p.hint = t('notifications.email_events_hint')
|
||||
|
||||
.fields-group
|
||||
= f.simple_fields_for :notification_emails, hash_to_object(current_user.settings.notification_emails) do |ff|
|
||||
= ff.input :follow, as: :boolean, wrapper: :with_label
|
||||
@@ -21,6 +25,8 @@
|
||||
= f.simple_fields_for :notification_emails, hash_to_object(current_user.settings.notification_emails) do |ff|
|
||||
= ff.input :digest, as: :boolean, wrapper: :with_label
|
||||
|
||||
%h4 = t('notifications.other_settings')
|
||||
|
||||
.fields-group
|
||||
= f.simple_fields_for :interactions, hash_to_object(current_user.settings.interactions) do |ff|
|
||||
= ff.input :must_be_follower, as: :boolean, wrapper: :with_label
|
||||
|
||||
Reference in New Issue
Block a user