Merge branch 'master' into glitch-soc/merge-upstream

This commit is contained in:
Thibaut Girka 2019-03-20 17:32:39 +01:00
commit cbf1d711ba
11 changed files with 50 additions and 12 deletions

View File

@ -2,11 +2,14 @@
class ActivityPub::InboxesController < Api::BaseController class ActivityPub::InboxesController < Api::BaseController
include SignatureVerification include SignatureVerification
include JsonLdHelper
before_action :set_account before_action :set_account
def create def create
if signed_request_account if unknown_deleted_account?
head 202
elsif signed_request_account
upgrade_account upgrade_account
process_payload process_payload
head 202 head 202
@ -17,12 +20,19 @@ class ActivityPub::InboxesController < Api::BaseController
private private
def unknown_deleted_account?
json = Oj.load(body, mode: :strict)
json['type'] == 'Delete' && json['actor'].present? && json['actor'] == value_or_id(json['object']) && !Account.where(uri: json['actor']).exists?
rescue Oj::ParseError
false
end
def set_account def set_account
@account = Account.find_local!(params[:account_username]) if params[:account_username] @account = Account.find_local!(params[:account_username]) if params[:account_username]
end end
def body def body
@body ||= request.body.read @body ||= request.body.read.force_encoding('UTF-8')
end end
def upgrade_account def upgrade_account
@ -36,6 +46,6 @@ class ActivityPub::InboxesController < Api::BaseController
end end
def process_payload def process_payload
ActivityPub::ProcessingWorker.perform_async(signed_request_account.id, body.force_encoding('UTF-8'), @account&.id) ActivityPub::ProcessingWorker.perform_async(signed_request_account.id, body, @account&.id)
end end
end end

View File

@ -71,9 +71,11 @@ export function normalizeStatus(status, normalOldStatus) {
export function normalizePoll(poll) { export function normalizePoll(poll) {
const normalPoll = { ...poll }; const normalPoll = { ...poll };
const emojiMap = makeEmojiMap(normalPoll);
normalPoll.options = poll.options.map(option => ({ normalPoll.options = poll.options.map(option => ({
...option, ...option,
title_emojified: emojify(escapeTextContentForBrowser(option.title)), title_emojified: emojify(escapeTextContentForBrowser(option.title), emojiMap),
})); }));
return normalPoll; return normalPoll;

View File

@ -44,6 +44,11 @@ const timeRemainingString = (intl, date, now) => {
return relativeTime; return relativeTime;
}; };
const makeEmojiMap = record => record.get('emojis').reduce((obj, emoji) => {
obj[`:${emoji.get('shortcode')}:`] = emoji.toJS();
return obj;
}, {});
export default @injectIntl export default @injectIntl
class Poll extends ImmutablePureComponent { class Poll extends ImmutablePureComponent {
@ -99,6 +104,12 @@ class Poll extends ImmutablePureComponent {
const active = !!this.state.selected[`${optionIndex}`]; const active = !!this.state.selected[`${optionIndex}`];
const showResults = poll.get('voted') || poll.get('expired'); const showResults = poll.get('voted') || poll.get('expired');
let titleEmojified = option.get('title_emojified');
if (!titleEmojified) {
const emojiMap = makeEmojiMap(poll);
titleEmojified = emojify(escapeTextContentForBrowser(option.get('title')), emojiMap);
}
return ( return (
<li key={option.get('title')}> <li key={option.get('title')}>
{showResults && ( {showResults && (
@ -122,7 +133,7 @@ class Poll extends ImmutablePureComponent {
{!showResults && <span className={classNames('poll__input', { checkbox: poll.get('multiple'), active })} />} {!showResults && <span className={classNames('poll__input', { checkbox: poll.get('multiple'), active })} />}
{showResults && <span className='poll__number'>{Math.round(percent)}%</span>} {showResults && <span className='poll__number'>{Math.round(percent)}%</span>}
<span dangerouslySetInnerHTML={{ __html: option.get('title_emojified', emojify(escapeTextContentForBrowser(option.get('title')))) }} /> <span dangerouslySetInnerHTML={{ __html: titleEmojified }} />
</label> </label>
</li> </li>
); );

View File

@ -71,6 +71,12 @@ class Formatter
html.html_safe # rubocop:disable Rails/OutputSafety html.html_safe # rubocop:disable Rails/OutputSafety
end end
def format_poll_option(status, option, **options)
html = encode(option.title)
html = encode_custom_emojis(html, status.emojis, options[:autoplay])
html.html_safe # rubocop:disable Rails/OutputSafety
end
def format_display_name(account, **options) def format_display_name(account, **options)
html = encode(account.display_name.presence || account.username) html = encode(account.display_name.presence || account.username)
html = encode_custom_emojis(html, account.emojis, options[:autoplay]) if options[:custom_emojify] html = encode_custom_emojis(html, account.emojis, options[:autoplay]) if options[:custom_emojify]

View File

@ -60,6 +60,10 @@ class Poll < ApplicationRecord
!local? !local?
end end
def emojis
@emojis ||= CustomEmoji.from_text(options.join(' '), account.domain)
end
class Option < ActiveModelSerializers::Model class Option < ActiveModelSerializers::Model
attributes :id, :title, :votes_count, :poll attributes :id, :title, :votes_count, :poll

View File

@ -218,7 +218,11 @@ class Status < ApplicationRecord
end end
def emojis def emojis
@emojis ||= CustomEmoji.from_text([spoiler_text, text].join(' '), account.domain) return @emojis if defined?(@emojis)
fields = [spoiler_text, text]
fields += owned_poll.options unless owned_poll.nil?
@emojis = CustomEmoji.from_text(fields.join(' '), account.domain)
@emojis
end end
def mark_for_mass_destruction! def mark_for_mass_destruction!

View File

@ -5,6 +5,7 @@ class REST::PollSerializer < ActiveModel::Serializer
:multiple, :votes_count :multiple, :votes_count
has_many :loaded_options, key: :options has_many :loaded_options, key: :options
has_many :emojis, serializer: REST::CustomEmojiSerializer
attribute :voted, if: :current_user? attribute :voted, if: :current_user?

View File

@ -24,7 +24,7 @@
- if status.poll - if status.poll
= react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do = react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do
= render partial: 'stream_entries/poll', locals: { poll: status.poll } = render partial: 'stream_entries/poll', locals: { status: status, poll: status.poll, autoplay: autoplay }
- elsif !status.media_attachments.empty? - elsif !status.media_attachments.empty?
- if status.media_attachments.first.video? - if status.media_attachments.first.video?
- video = status.media_attachments.first - video = status.media_attachments.first

View File

@ -10,11 +10,11 @@
%label.poll__text>< %label.poll__text><
%span.poll__number= percent.round %span.poll__number= percent.round
= option.title = Formatter.instance.format_poll_option(status, option, autoplay: autoplay)
- else - else
%label.poll__text>< %label.poll__text><
%span.poll__input{ class: poll.multiple? ? 'checkbox' : nil}>< %span.poll__input{ class: poll.multiple? ? 'checkbox' : nil}><
= option.title = Formatter.instance.format_poll_option(status, option, autoplay: autoplay)
.poll__footer .poll__footer
- unless show_results - unless show_results
%button.button.button-secondary{ disabled: true } %button.button.button-secondary{ disabled: true }

View File

@ -29,7 +29,7 @@
- if status.poll - if status.poll
= react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do = react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do
= render partial: 'stream_entries/poll', locals: { poll: status.poll } = render partial: 'stream_entries/poll', locals: { status: status, poll: status.poll, autoplay: autoplay }
- elsif !status.media_attachments.empty? - elsif !status.media_attachments.empty?
- if status.media_attachments.first.video? - if status.media_attachments.first.video?
- video = status.media_attachments.first - video = status.media_attachments.first

View File

@ -10,7 +10,7 @@ RSpec.describe ActivityPub::InboxesController, type: :controller do
Fabricate(:account) Fabricate(:account)
end end
post :create post :create, body: '{}'
expect(response).to have_http_status(202) expect(response).to have_http_status(202)
end end
end end
@ -21,7 +21,7 @@ RSpec.describe ActivityPub::InboxesController, type: :controller do
false false
end end
post :create post :create, body: '{}'
expect(response).to have_http_status(401) expect(response).to have_http_status(401)
end end
end end