Merge branch 'master' into glitch-soc/merge-upstream
commit
f030541264
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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!
|
||||||
|
|
|
@ -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?
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue