Merge branch 'master' into glitch-soc/merge-upstream
Conflicts: Dockerfile app/javascript/packs/common.js config/webpack/loaders/sass.js config/webpack/shared.js db/schema.rb package.json yarn.lock A lot of the conflicts come from updating webpack. Even though upstream deleted app/javascript/packs/common.js, I kept glitch-soc's version as it unifies JS/CSS packs behavior across flavours. Ported glitch changes to webpack 4.x
This commit is contained in:
58
app/controllers/admin/relays_controller.rb
Normal file
58
app/controllers/admin/relays_controller.rb
Normal file
@@ -0,0 +1,58 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class RelaysController < BaseController
|
||||
before_action :set_relay, except: [:index, :new, :create]
|
||||
|
||||
def index
|
||||
authorize :relay, :update?
|
||||
@relays = Relay.all
|
||||
end
|
||||
|
||||
def new
|
||||
authorize :relay, :update?
|
||||
@relay = Relay.new(inbox_url: Relay::PRESET_RELAY)
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :relay, :update?
|
||||
|
||||
@relay = Relay.new(resource_params)
|
||||
|
||||
if @relay.save
|
||||
@relay.enable!
|
||||
redirect_to admin_relays_path
|
||||
else
|
||||
render action: :new
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize :relay, :update?
|
||||
@relay.destroy
|
||||
redirect_to admin_relays_path
|
||||
end
|
||||
|
||||
def enable
|
||||
authorize :relay, :update?
|
||||
@relay.enable!
|
||||
redirect_to admin_relays_path
|
||||
end
|
||||
|
||||
def disable
|
||||
authorize :relay, :update?
|
||||
@relay.disable!
|
||||
redirect_to admin_relays_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_relay
|
||||
@relay = Relay.find(params[:id])
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.require(:relay).permit(:inbox_url)
|
||||
end
|
||||
end
|
||||
end
|
@@ -67,7 +67,7 @@ module StreamEntriesHelper
|
||||
end
|
||||
|
||||
def acct(account)
|
||||
if embedded_view? && account.local?
|
||||
if account.local?
|
||||
"@#{account.acct}@#{Rails.configuration.x.local_domain}"
|
||||
else
|
||||
"@#{account.acct}"
|
||||
|
@@ -1,6 +1,9 @@
|
||||
// This file will be loaded on admin pages, regardless of theme.
|
||||
|
||||
import { delegate } from 'rails-ujs';
|
||||
import { start } from '../mastodon/common';
|
||||
|
||||
start();
|
||||
|
||||
function handleDeleteStatus(event) {
|
||||
const [data] = event.detail;
|
||||
|
@@ -128,7 +128,7 @@ export function expandDomainBlocks() {
|
||||
return (dispatch, getState) => {
|
||||
const url = getState().getIn(['domain_lists', 'blocks', 'next']);
|
||||
|
||||
if (url === null) {
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
8
app/javascript/mastodon/common.js
Normal file
8
app/javascript/mastodon/common.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import Rails from 'rails-ujs';
|
||||
|
||||
export function start() {
|
||||
require('font-awesome/css/font-awesome.css');
|
||||
require.context('../images/', true);
|
||||
|
||||
Rails.start();
|
||||
};
|
@@ -7,7 +7,7 @@ import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { me, invitesEnabled } from '../../initial_state';
|
||||
import { me, invitesEnabled, version } from '../../initial_state';
|
||||
import { fetchFollowRequests } from '../../actions/accounts';
|
||||
import { List as ImmutableList } from 'immutable';
|
||||
import { Link } from 'react-router-dom';
|
||||
@@ -149,7 +149,7 @@ export default class GettingStarted extends ImmutablePureComponent {
|
||||
<FormattedMessage
|
||||
id='getting_started.open_source_notice'
|
||||
defaultMessage='Mastodon is open source software. You can contribute or report issues on GitHub at {github}.'
|
||||
values={{ github: <a href='https://github.com/tootsuite/mastodon' rel='noopener' target='_blank'>tootsuite/mastodon</a> }}
|
||||
values={{ github: <span><a href='https://github.com/tootsuite/mastodon' rel='noopener' target='_blank'>tootsuite/mastodon</a> (v{version})</span> }}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { LoadingBar } from 'react-redux-loading-bar';
|
||||
import ZoomableImage from './zoomable_image';
|
||||
|
||||
export default class ImageLoader extends React.PureComponent {
|
||||
@@ -23,6 +24,7 @@ export default class ImageLoader extends React.PureComponent {
|
||||
state = {
|
||||
loading: true,
|
||||
error: false,
|
||||
width: null,
|
||||
}
|
||||
|
||||
removers = [];
|
||||
@@ -122,6 +124,7 @@ export default class ImageLoader extends React.PureComponent {
|
||||
|
||||
setCanvasRef = c => {
|
||||
this.canvas = c;
|
||||
if (c) this.setState({ width: c.offsetWidth });
|
||||
}
|
||||
|
||||
render () {
|
||||
@@ -135,6 +138,7 @@ export default class ImageLoader extends React.PureComponent {
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<LoadingBar loading={loading ? 1 : 0} className='loading-bar' style={{ width: this.state.width || width }} />
|
||||
{loading ? (
|
||||
<canvas
|
||||
className='image-loader__preview-canvas'
|
||||
|
@@ -13,5 +13,6 @@ export const me = getMeta('me');
|
||||
export const searchEnabled = getMeta('search_enabled');
|
||||
export const maxChars = getMeta('max_toot_chars') || 500;
|
||||
export const invitesEnabled = getMeta('invites_enabled');
|
||||
export const version = getMeta('version');
|
||||
|
||||
export default initialState;
|
||||
|
@@ -6,10 +6,10 @@
|
||||
"account.direct": "Direct message @{name}",
|
||||
"account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
|
||||
"account.domain_blocked": "Domain hidden",
|
||||
"account.edit_profile": "Edit profile",
|
||||
"account.follow": "Follow",
|
||||
"account.followers": "Followers",
|
||||
"account.follows": "Follows",
|
||||
"account.edit_profile": "Uprav profil",
|
||||
"account.follow": "Sleduj",
|
||||
"account.followers": "Sledovatelé",
|
||||
"account.follows": "Sleduje",
|
||||
"account.follows_you": "Follows you",
|
||||
"account.hide_reblogs": "Hide boosts from @{name}",
|
||||
"account.media": "Media",
|
||||
|
@@ -65,7 +65,7 @@
|
||||
"compose_form.hashtag_warning": "Αυτό το τουτ δεν θα εμφανίζεται κάτω από κανένα hashtag καθώς είναι αφανές. Μόνο τα δημόσια τουτ μπορούν να αναζητηθούν ανά hashtag.",
|
||||
"compose_form.lock_disclaimer": "Ο λογαριασμός σου δεν είναι {locked}. Οποιοσδήποτε μπορεί να σε ακολουθήσει για να δει τις δημοσιεύσεις σας προς τους ακολούθους σας.",
|
||||
"compose_form.lock_disclaimer.lock": "κλειδωμένος",
|
||||
"compose_form.placeholder": "Τι έχεις στο μυαλό σου;",
|
||||
"compose_form.placeholder": "Τι σκέφτεσαι;",
|
||||
"compose_form.publish": "Τουτ",
|
||||
"compose_form.publish_loud": "{publish}!",
|
||||
"compose_form.sensitive.marked": "Το πολυμέσο έχει σημειωθεί ως ευαίσθητο",
|
||||
|
@@ -166,7 +166,7 @@
|
||||
"navigation_bar.domain_blocks": "دامینهای پنهانشده",
|
||||
"navigation_bar.edit_profile": "ویرایش نمایه",
|
||||
"navigation_bar.favourites": "پسندیدهها",
|
||||
"navigation_bar.filters": "Muted words",
|
||||
"navigation_bar.filters": "واژگان بیصداشده",
|
||||
"navigation_bar.follow_requests": "درخواستهای پیگیری",
|
||||
"navigation_bar.info": "اطلاعات تکمیلی",
|
||||
"navigation_bar.keyboard_shortcuts": "میانبرهای صفحهکلید",
|
||||
|
@@ -170,7 +170,7 @@
|
||||
"navigation_bar.domain_blocks": "非表示にしたドメイン",
|
||||
"navigation_bar.edit_profile": "プロフィールを編集",
|
||||
"navigation_bar.favourites": "お気に入り",
|
||||
"navigation_bar.filters": "Muted words",
|
||||
"navigation_bar.filters": "フィルター設定",
|
||||
"navigation_bar.follow_requests": "フォローリクエスト",
|
||||
"navigation_bar.info": "このインスタンスについて",
|
||||
"navigation_bar.keyboard_shortcuts": "ホットキー",
|
||||
|
@@ -166,7 +166,7 @@
|
||||
"navigation_bar.domain_blocks": "Verborgen domeinen",
|
||||
"navigation_bar.edit_profile": "Profiel bewerken",
|
||||
"navigation_bar.favourites": "Favorieten",
|
||||
"navigation_bar.filters": "Muted words",
|
||||
"navigation_bar.filters": "Genegeerde woorden",
|
||||
"navigation_bar.follow_requests": "Volgverzoeken",
|
||||
"navigation_bar.info": "Over deze server",
|
||||
"navigation_bar.keyboard_shortcuts": "Sneltoetsen",
|
||||
|
@@ -166,7 +166,7 @@
|
||||
"navigation_bar.domain_blocks": "Domenis resconduts",
|
||||
"navigation_bar.edit_profile": "Modificar lo perfil",
|
||||
"navigation_bar.favourites": "Favorits",
|
||||
"navigation_bar.filters": "Muted words",
|
||||
"navigation_bar.filters": "Mots ignorats",
|
||||
"navigation_bar.follow_requests": "Demandas d’abonament",
|
||||
"navigation_bar.info": "Mai informacions",
|
||||
"navigation_bar.keyboard_shortcuts": "Acorchis clavièr",
|
||||
|
@@ -166,7 +166,7 @@
|
||||
"navigation_bar.domain_blocks": "Domínios escondidos",
|
||||
"navigation_bar.edit_profile": "Editar perfil",
|
||||
"navigation_bar.favourites": "Favoritos",
|
||||
"navigation_bar.filters": "Muted words",
|
||||
"navigation_bar.filters": "Palavras silenciadas",
|
||||
"navigation_bar.follow_requests": "Seguidores pendentes",
|
||||
"navigation_bar.info": "Mais informações",
|
||||
"navigation_bar.keyboard_shortcuts": "Atalhos de teclado",
|
||||
|
@@ -7,7 +7,7 @@
|
||||
"account.disclaimer_full": "Inofrmácie uvedené nižšie nemusia byť úplným odrazom uživateľovho účtu.",
|
||||
"account.domain_blocked": "Doména ukrytá",
|
||||
"account.edit_profile": "Upraviť profil",
|
||||
"account.follow": "Následovať",
|
||||
"account.follow": "Následuj",
|
||||
"account.followers": "Sledujúci",
|
||||
"account.follows": "Následuje",
|
||||
"account.follows_you": "Následuje ťa",
|
||||
|
@@ -1,4 +1,7 @@
|
||||
import loadPolyfills from '../mastodon/load_polyfills';
|
||||
import { start } from '../mastodon/common';
|
||||
|
||||
start();
|
||||
|
||||
function loaded() {
|
||||
const TimelineContainer = require('../mastodon/containers/timeline_container').default;
|
||||
|
@@ -1,4 +1,7 @@
|
||||
import loadPolyfills from '../mastodon/load_polyfills';
|
||||
import { start } from '../mastodon/common';
|
||||
|
||||
start();
|
||||
|
||||
loadPolyfills().then(() => {
|
||||
require('../mastodon/main').default();
|
||||
|
@@ -1,5 +1,8 @@
|
||||
import loadPolyfills from '../mastodon/load_polyfills';
|
||||
import ready from '../mastodon/ready';
|
||||
import { start } from '../mastodon/common';
|
||||
|
||||
start();
|
||||
|
||||
function main() {
|
||||
const IntlRelativeFormat = require('intl-relativeformat').default;
|
||||
|
@@ -1,4 +1,7 @@
|
||||
import loadPolyfills from '../mastodon/load_polyfills';
|
||||
import { start } from '../mastodon/common';
|
||||
|
||||
start();
|
||||
|
||||
function loaded() {
|
||||
const ComposeContainer = require('../mastodon/containers/compose_container').default;
|
||||
|
@@ -165,6 +165,11 @@
|
||||
color: $valid-value-color;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.negative-hint {
|
||||
color: $error-value-color;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.simple_form {
|
||||
|
@@ -1478,6 +1478,7 @@ a.account__display-name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
|
||||
.image-loader__preview-canvas {
|
||||
max-width: $media-modal-media-max-width;
|
||||
@@ -1486,8 +1487,8 @@ a.account__display-name {
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
&.image-loader--loading .image-loader__preview-canvas {
|
||||
filter: blur(2px);
|
||||
.loading-bar {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&.image-loader--amorphous .image-loader__preview-canvas {
|
||||
|
@@ -3,12 +3,16 @@
|
||||
class LanguageDetector
|
||||
include Singleton
|
||||
|
||||
CHARACTER_THRESHOLD = 140
|
||||
|
||||
def initialize
|
||||
@identifier = CLD3::NNetLanguageIdentifier.new(1, 2048)
|
||||
end
|
||||
|
||||
def detect(text, account)
|
||||
detect_language_code(text) || default_locale(account)
|
||||
input_text = prepare_text(text)
|
||||
return if input_text.blank?
|
||||
detect_language_code(input_text) || default_locale(account)
|
||||
end
|
||||
|
||||
def language_names
|
||||
@@ -23,8 +27,13 @@ class LanguageDetector
|
||||
simplify_text(text).strip
|
||||
end
|
||||
|
||||
def unreliable_input?(text)
|
||||
text.size < CHARACTER_THRESHOLD
|
||||
end
|
||||
|
||||
def detect_language_code(text)
|
||||
result = @identifier.find_language(prepare_text(text))
|
||||
return if unreliable_input?(text)
|
||||
result = @identifier.find_language(text)
|
||||
iso6391(result.language.to_s).to_sym if result.reliable?
|
||||
end
|
||||
|
||||
@@ -66,6 +75,6 @@ class LanguageDetector
|
||||
end
|
||||
|
||||
def default_locale(account)
|
||||
account.user_locale&.to_sym
|
||||
account.user_locale&.to_sym || I18n.default_locale
|
||||
end
|
||||
end
|
||||
|
@@ -12,6 +12,8 @@ class PotentialFriendshipTracker
|
||||
|
||||
class << self
|
||||
def record(account_id, target_account_id, action)
|
||||
return if account_id == target_account_id
|
||||
|
||||
key = "interactions:#{account_id}"
|
||||
weight = WEIGHTS[action]
|
||||
|
||||
|
74
app/models/relay.rb
Normal file
74
app/models/relay.rb
Normal file
@@ -0,0 +1,74 @@
|
||||
# frozen_string_literal: true
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: relays
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# inbox_url :string default(""), not null
|
||||
# enabled :boolean default(FALSE), not null
|
||||
# follow_activity_id :string
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
class Relay < ApplicationRecord
|
||||
PRESET_RELAY = 'https://relay.joinmastodon.org/inbox'
|
||||
|
||||
validates :inbox_url, presence: true, uniqueness: true, url: true, if: :will_save_change_to_inbox_url?
|
||||
|
||||
scope :enabled, -> { where(enabled: true) }
|
||||
|
||||
before_destroy :ensure_disabled
|
||||
|
||||
def enable!
|
||||
activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
|
||||
payload = Oj.dump(follow_activity(activity_id))
|
||||
|
||||
ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
|
||||
update(enabled: true, follow_activity_id: activity_id)
|
||||
end
|
||||
|
||||
def disable!
|
||||
activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
|
||||
payload = Oj.dump(unfollow_activity(activity_id))
|
||||
|
||||
ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
|
||||
update(enabled: false, follow_activity_id: nil)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def follow_activity(activity_id)
|
||||
{
|
||||
'@context': ActivityPub::TagManager::CONTEXT,
|
||||
id: activity_id,
|
||||
type: 'Follow',
|
||||
actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
|
||||
object: ActivityPub::TagManager::COLLECTIONS[:public],
|
||||
}
|
||||
end
|
||||
|
||||
def unfollow_activity(activity_id)
|
||||
{
|
||||
'@context': ActivityPub::TagManager::CONTEXT,
|
||||
id: activity_id,
|
||||
type: 'Undo',
|
||||
actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
|
||||
object: {
|
||||
id: follow_activity_id,
|
||||
type: 'Follow',
|
||||
actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
|
||||
object: ActivityPub::TagManager::COLLECTIONS[:public],
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
def some_local_account
|
||||
@some_local_account ||= Account.local.find_by(suspended: false)
|
||||
end
|
||||
|
||||
def ensure_disabled
|
||||
return unless enabled?
|
||||
disable!
|
||||
end
|
||||
end
|
7
app/policies/relay_policy.rb
Normal file
7
app/policies/relay_policy.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class RelayPolicy < ApplicationPolicy
|
||||
def update?
|
||||
admin?
|
||||
end
|
||||
end
|
@@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::DeleteActorSerializer < ActiveModel::Serializer
|
||||
attributes :id, :type, :actor
|
||||
attributes :id, :type, :actor, :to
|
||||
attribute :virtual_object, key: :object
|
||||
|
||||
def id
|
||||
@@ -19,4 +19,8 @@ class ActivityPub::DeleteActorSerializer < ActiveModel::Serializer
|
||||
def virtual_object
|
||||
actor
|
||||
end
|
||||
|
||||
def to
|
||||
[ActivityPub::TagManager::COLLECTIONS[:public]]
|
||||
end
|
||||
end
|
||||
|
@@ -17,7 +17,7 @@ class ActivityPub::DeleteSerializer < ActiveModel::Serializer
|
||||
end
|
||||
end
|
||||
|
||||
attributes :id, :type, :actor
|
||||
attributes :id, :type, :actor, :to
|
||||
|
||||
has_one :object, serializer: TombstoneSerializer
|
||||
|
||||
@@ -32,4 +32,8 @@ class ActivityPub::DeleteSerializer < ActiveModel::Serializer
|
||||
def actor
|
||||
ActivityPub::TagManager.instance.uri_for(object.account)
|
||||
end
|
||||
|
||||
def to
|
||||
[ActivityPub::TagManager::COLLECTIONS[:public]]
|
||||
end
|
||||
end
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::UndoAnnounceSerializer < ActiveModel::Serializer
|
||||
attributes :id, :type, :actor
|
||||
attributes :id, :type, :actor, :to
|
||||
|
||||
has_one :object, serializer: ActivityPub::ActivitySerializer
|
||||
|
||||
@@ -16,4 +16,8 @@ class ActivityPub::UndoAnnounceSerializer < ActiveModel::Serializer
|
||||
def actor
|
||||
ActivityPub::TagManager.instance.uri_for(object.account)
|
||||
end
|
||||
|
||||
def to
|
||||
[ActivityPub::TagManager::COLLECTIONS[:public]]
|
||||
end
|
||||
end
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::UpdateSerializer < ActiveModel::Serializer
|
||||
attributes :id, :type, :actor
|
||||
attributes :id, :type, :actor, :to
|
||||
|
||||
has_one :object, serializer: ActivityPub::ActorSerializer
|
||||
|
||||
@@ -16,4 +16,8 @@ class ActivityPub::UpdateSerializer < ActiveModel::Serializer
|
||||
def actor
|
||||
ActivityPub::TagManager.instance.uri_for(object)
|
||||
end
|
||||
|
||||
def to
|
||||
[ActivityPub::TagManager::COLLECTIONS[:public]]
|
||||
end
|
||||
end
|
||||
|
@@ -19,6 +19,7 @@ class InitialStateSerializer < ActiveModel::Serializer
|
||||
domain: Rails.configuration.x.local_domain,
|
||||
admin: object.admin&.id&.to_s,
|
||||
search_enabled: Chewy.enabled?,
|
||||
version: Mastodon::Version.to_s,
|
||||
invites_enabled: Setting.min_invite_role == 'user',
|
||||
}
|
||||
|
||||
|
@@ -90,6 +90,18 @@ class RemoveStatusService < BaseService
|
||||
ActivityPub::DeliveryWorker.push_bulk(@account.followers.inboxes) do |inbox_url|
|
||||
[signed_activity_json, @account.id, inbox_url]
|
||||
end
|
||||
|
||||
relay! if relayable?
|
||||
end
|
||||
|
||||
def relayable?
|
||||
@status.public_visibility?
|
||||
end
|
||||
|
||||
def relay!
|
||||
ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
|
||||
[signed_activity_json, @account.id, inbox_url]
|
||||
end
|
||||
end
|
||||
|
||||
def salmon_xml
|
||||
|
@@ -22,7 +22,13 @@ class SuspendAccountService < BaseService
|
||||
end
|
||||
|
||||
def purge_content!
|
||||
ActivityPub::RawDistributionWorker.perform_async(delete_actor_json, @account.id) if @account.local?
|
||||
if @account.local?
|
||||
ActivityPub::RawDistributionWorker.perform_async(delete_actor_json, @account.id)
|
||||
|
||||
ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
|
||||
[delete_actor_json, @account.id, inbox_url]
|
||||
end
|
||||
end
|
||||
|
||||
@account.statuses.reorder(nil).find_in_batches do |statuses|
|
||||
BatchedRemoveStatusService.new.call(statuses)
|
||||
@@ -59,12 +65,14 @@ class SuspendAccountService < BaseService
|
||||
end
|
||||
|
||||
def delete_actor_json
|
||||
return @delete_actor_json if defined?(@delete_actor_json)
|
||||
|
||||
payload = ActiveModelSerializers::SerializableResource.new(
|
||||
@account,
|
||||
serializer: ActivityPub::DeleteActorSerializer,
|
||||
adapter: ActivityPub::Adapter
|
||||
).as_json
|
||||
|
||||
Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@account))
|
||||
@delete_actor_json = Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@account))
|
||||
end
|
||||
end
|
||||
|
21
app/views/admin/relays/_relay.html.haml
Normal file
21
app/views/admin/relays/_relay.html.haml
Normal file
@@ -0,0 +1,21 @@
|
||||
%tr
|
||||
%td
|
||||
%samp= relay.inbox_url
|
||||
%td
|
||||
- if relay.enabled?
|
||||
%span.positive-hint
|
||||
= fa_icon('check')
|
||||
= ' '
|
||||
= t 'admin.relays.enabled'
|
||||
- else
|
||||
%span.negative-hint
|
||||
= fa_icon('times')
|
||||
= ' '
|
||||
= t 'admin.relays.disabled'
|
||||
%td
|
||||
- if relay.enabled?
|
||||
= table_link_to 'power-off', t('admin.relays.disable'), disable_admin_relay_path(relay), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
|
||||
- else
|
||||
= table_link_to 'power-off', t('admin.relays.enable'), enable_admin_relay_path(relay), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
|
||||
|
||||
= table_link_to 'times', t('admin.relays.delete'), admin_relay_path(relay), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
|
20
app/views/admin/relays/index.html.haml
Normal file
20
app/views/admin/relays/index.html.haml
Normal file
@@ -0,0 +1,20 @@
|
||||
- content_for :page_title do
|
||||
= t('admin.relays.title')
|
||||
|
||||
.simple_form
|
||||
%p.hint= t('admin.relays.description_html')
|
||||
= link_to @relays.empty? ? t('admin.relays.setup') : t('admin.relays.add_new'), new_admin_relay_path, class: 'block-button'
|
||||
|
||||
- unless @relays.empty?
|
||||
%hr.spacer
|
||||
|
||||
.table-wrapper
|
||||
%table.table
|
||||
%thead
|
||||
%tr
|
||||
%th= t('admin.relays.inbox_url')
|
||||
%th= t('admin.relays.status')
|
||||
%th
|
||||
%tbody
|
||||
= render @relays
|
||||
|
13
app/views/admin/relays/new.html.haml
Normal file
13
app/views/admin/relays/new.html.haml
Normal file
@@ -0,0 +1,13 @@
|
||||
- content_for :page_title do
|
||||
= t('admin.relays.add_new')
|
||||
|
||||
= simple_form_for @relay, url: admin_relays_path do |f|
|
||||
= render 'shared/error_messages', object: @relay
|
||||
|
||||
.field-group
|
||||
= f.input :inbox_url, as: :string, wrapper: :with_block_label
|
||||
|
||||
.actions
|
||||
= f.button :button, t('admin.relays.save_and_enable'), type: :submit
|
||||
|
||||
%p.hint.subtle-hint= t('admin.relays.enable_hint')
|
@@ -14,6 +14,8 @@ class ActivityPub::DistributionWorker
|
||||
ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
|
||||
[signed_payload, @account.id, inbox_url]
|
||||
end
|
||||
|
||||
relay! if relayable?
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
true
|
||||
end
|
||||
@@ -24,6 +26,10 @@ class ActivityPub::DistributionWorker
|
||||
@status.direct_visibility?
|
||||
end
|
||||
|
||||
def relayable?
|
||||
@status.public_visibility?
|
||||
end
|
||||
|
||||
def inboxes
|
||||
@inboxes ||= @account.followers.inboxes
|
||||
end
|
||||
@@ -39,4 +45,10 @@ class ActivityPub::DistributionWorker
|
||||
adapter: ActivityPub::Adapter
|
||||
).as_json
|
||||
end
|
||||
|
||||
def relay!
|
||||
ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
|
||||
[signed_payload, @account.id, inbox_url]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@@ -9,7 +9,11 @@ class ActivityPub::UpdateDistributionWorker
|
||||
@account = Account.find(account_id)
|
||||
|
||||
ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
|
||||
[payload, @account.id, inbox_url]
|
||||
[signed_payload, @account.id, inbox_url]
|
||||
end
|
||||
|
||||
ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
|
||||
[signed_payload, @account.id, inbox_url]
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
true
|
||||
@@ -21,6 +25,10 @@ class ActivityPub::UpdateDistributionWorker
|
||||
@inboxes ||= @account.followers.inboxes
|
||||
end
|
||||
|
||||
def signed_payload
|
||||
@signed_payload ||= Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@account))
|
||||
end
|
||||
|
||||
def payload
|
||||
@payload ||= ActiveModelSerializers::SerializableResource.new(
|
||||
@account,
|
||||
|
Reference in New Issue
Block a user