mirror of
https://github.com/glitch-soc/mastodon.git
synced 2024-11-23 16:44:04 -05:00
Merge remote-tracking branch 'tootsuite/master' into glitchsoc/master
This commit is contained in:
commit
c69a23ae46
@ -299,13 +299,11 @@ GEM
|
|||||||
sidekiq (>= 3.5.0)
|
sidekiq (>= 3.5.0)
|
||||||
statsd-ruby (~> 1.2.0)
|
statsd-ruby (~> 1.2.0)
|
||||||
oj (3.3.9)
|
oj (3.3.9)
|
||||||
openssl (2.0.6)
|
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
ostatus2 (2.0.1)
|
ostatus2 (2.0.2)
|
||||||
addressable (~> 2.4)
|
addressable (~> 2.4)
|
||||||
http (~> 2.0)
|
http (~> 2.0)
|
||||||
nokogiri (~> 1.6)
|
nokogiri (~> 1.6)
|
||||||
openssl (~> 2.0)
|
|
||||||
ox (2.8.2)
|
ox (2.8.2)
|
||||||
paperclip (5.1.0)
|
paperclip (5.1.0)
|
||||||
activemodel (>= 4.2.0)
|
activemodel (>= 4.2.0)
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
class AccountsController < ApplicationController
|
class AccountsController < ApplicationController
|
||||||
include AccountControllerConcern
|
include AccountControllerConcern
|
||||||
include SignatureVerification
|
|
||||||
|
before_action :set_cache_headers
|
||||||
|
|
||||||
def show
|
def show
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
@ -27,10 +28,11 @@ class AccountsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
format.json do
|
format.json do
|
||||||
render json: @account,
|
skip_session!
|
||||||
serializer: ActivityPub::ActorSerializer,
|
|
||||||
adapter: ActivityPub::Adapter,
|
render_cached_json(['activitypub', 'actor', @account.cache_key], content_type: 'application/activity+json') do
|
||||||
content_type: 'application/activity+json'
|
ActiveModelSerializers::SerializableResource.new(@account, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -4,15 +4,19 @@ class ActivityPub::FollowsController < Api::BaseController
|
|||||||
include SignatureVerification
|
include SignatureVerification
|
||||||
|
|
||||||
def show
|
def show
|
||||||
render(
|
render json: follow_request,
|
||||||
json: FollowRequest.includes(:account).references(:account).find_by!(
|
serializer: ActivityPub::FollowSerializer,
|
||||||
id: params.require(:id),
|
adapter: ActivityPub::Adapter,
|
||||||
accounts: { domain: nil, username: params.require(:account_username) },
|
content_type: 'application/activity+json'
|
||||||
target_account: signed_request_account
|
end
|
||||||
),
|
|
||||||
serializer: ActivityPub::FollowSerializer,
|
private
|
||||||
adapter: ActivityPub::Adapter,
|
|
||||||
content_type: 'application/activity+json'
|
def follow_request
|
||||||
|
FollowRequest.includes(:account).references(:account).find_by!(
|
||||||
|
id: params.require(:id),
|
||||||
|
accounts: { domain: nil, username: params.require(:account_username) },
|
||||||
|
target_account: signed_request_account
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -198,11 +198,24 @@ class ApplicationController < ActionController::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def render_cached_json(cache_key, **options)
|
def render_cached_json(cache_key, **options)
|
||||||
|
options[:expires_in] ||= 3.minutes
|
||||||
|
options[:public] ||= true
|
||||||
|
cache_key = cache_key.join(':') if cache_key.is_a?(Enumerable)
|
||||||
|
content_type = options.delete(:content_type) || 'application/json'
|
||||||
|
|
||||||
data = Rails.cache.fetch(cache_key, { raw: true }.merge(options)) do
|
data = Rails.cache.fetch(cache_key, { raw: true }.merge(options)) do
|
||||||
yield.to_json
|
yield.to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
expires_in options[:expires_in], public: true
|
expires_in options[:expires_in], public: options[:public]
|
||||||
render json: data
|
render json: data, content_type: content_type
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_cache_headers
|
||||||
|
response.headers['Vary'] = 'Accept'
|
||||||
|
end
|
||||||
|
|
||||||
|
def skip_session!
|
||||||
|
request.session_options[:skip] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -2,14 +2,16 @@
|
|||||||
|
|
||||||
class EmojisController < ApplicationController
|
class EmojisController < ApplicationController
|
||||||
before_action :set_emoji
|
before_action :set_emoji
|
||||||
|
before_action :set_cache_headers
|
||||||
|
|
||||||
def show
|
def show
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.json do
|
format.json do
|
||||||
render json: @emoji,
|
skip_session!
|
||||||
serializer: ActivityPub::EmojiSerializer,
|
|
||||||
adapter: ActivityPub::Adapter,
|
render_cached_json(['activitypub', 'emoji', @emoji.cache_key], content_type: 'application/activity+json') do
|
||||||
content_type: 'application/activity+json'
|
ActiveModelSerializers::SerializableResource.new(@emoji, serializer: ActivityPub::EmojiSerializer, adapter: ActivityPub::Adapter)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -10,7 +10,7 @@ class StatusesController < ApplicationController
|
|||||||
before_action :set_link_headers
|
before_action :set_link_headers
|
||||||
before_action :check_account_suspension
|
before_action :check_account_suspension
|
||||||
before_action :redirect_to_original, only: [:show]
|
before_action :redirect_to_original, only: [:show]
|
||||||
before_action { response.headers['Vary'] = 'Accept' }
|
before_action :set_cache_headers
|
||||||
|
|
||||||
def show
|
def show
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
@ -23,25 +23,21 @@ class StatusesController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
format.json do
|
format.json do
|
||||||
render json: @status,
|
skip_session! unless @stream_entry.hidden?
|
||||||
serializer: ActivityPub::NoteSerializer,
|
|
||||||
adapter: ActivityPub::Adapter,
|
|
||||||
content_type: 'application/activity+json'
|
|
||||||
|
|
||||||
# Allow HTTP caching for 3 minutes if the status is public
|
render_cached_json(['activitypub', 'note', @status.cache_key], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do
|
||||||
unless @stream_entry.hidden?
|
ActiveModelSerializers::SerializableResource.new(@status, serializer: ActivityPub::NoteSerializer, adapter: ActivityPub::Adapter)
|
||||||
request.session_options[:skip] = true
|
|
||||||
expires_in(3.minutes, public: true)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def activity
|
def activity
|
||||||
render json: @status,
|
skip_session!
|
||||||
serializer: ActivityPub::ActivitySerializer,
|
|
||||||
adapter: ActivityPub::Adapter,
|
render_cached_json(['activitypub', 'activity', @status.cache_key], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do
|
||||||
content_type: 'application/activity+json'
|
ActiveModelSerializers::SerializableResource.new(@status, serializer: ActivityPub::ActivitySerializer, adapter: ActivityPub::Adapter)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def embed
|
def embed
|
||||||
|
@ -34,7 +34,7 @@ module Admin::ActionLogsHelper
|
|||||||
link_to attributes['domain'], "https://#{attributes['domain']}"
|
link_to attributes['domain'], "https://#{attributes['domain']}"
|
||||||
when 'Status'
|
when 'Status'
|
||||||
tmp_status = Status.new(attributes)
|
tmp_status = Status.new(attributes)
|
||||||
link_to tmp_status.account.acct, TagManager.instance.url_for(tmp_status)
|
link_to tmp_status.account&.acct || "##{tmp_status.account_id}", TagManager.instance.url_for(tmp_status)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ module RoutingHelper
|
|||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
include Rails.application.routes.url_helpers
|
include Rails.application.routes.url_helpers
|
||||||
include ActionView::Helpers::AssetTagHelper
|
include ActionView::Helpers::AssetTagHelper
|
||||||
|
include Webpacker::Helper
|
||||||
|
|
||||||
included do
|
included do
|
||||||
def default_url_options
|
def default_url_options
|
||||||
@ -17,6 +18,10 @@ module RoutingHelper
|
|||||||
URI.join(root_url, source).to_s
|
URI.join(root_url, source).to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def full_pack_url(source, **options)
|
||||||
|
full_asset_url(asset_pack_path(source, options))
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def use_storage?
|
def use_storage?
|
||||||
|
@ -70,30 +70,28 @@ export default class GettingStarted extends ImmutablePureComponent {
|
|||||||
|
|
||||||
navItems.push(
|
navItems.push(
|
||||||
<ColumnLink key='4' icon='star' text={intl.formatMessage(messages.favourites)} to='/favourites' />,
|
<ColumnLink key='4' icon='star' text={intl.formatMessage(messages.favourites)} to='/favourites' />,
|
||||||
<ColumnLink key='5' icon='thumb-tack' text={intl.formatMessage(messages.pins)} to='/pinned' />,
|
<ColumnLink key='5' icon='bars' text={intl.formatMessage(messages.lists)} to='/lists' />
|
||||||
<ColumnLink key='6' icon='bars' text={intl.formatMessage(messages.lists)} to='/lists' />
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (myAccount.get('locked')) {
|
if (myAccount.get('locked')) {
|
||||||
navItems.push(<ColumnLink key='7' icon='users' text={intl.formatMessage(messages.follow_requests)} to='/follow_requests' />);
|
navItems.push(<ColumnLink key='6' icon='users' text={intl.formatMessage(messages.follow_requests)} to='/follow_requests' />);
|
||||||
}
|
}
|
||||||
|
|
||||||
navItems.push(
|
|
||||||
<ColumnLink key='8' icon='volume-off' text={intl.formatMessage(messages.mutes)} to='/mutes' />,
|
|
||||||
<ColumnLink key='9' icon='ban' text={intl.formatMessage(messages.blocks)} to='/blocks' />
|
|
||||||
);
|
|
||||||
|
|
||||||
if (multiColumn) {
|
if (multiColumn) {
|
||||||
navItems.push(<ColumnLink key='10' icon='question' text={intl.formatMessage(messages.keyboard_shortcuts)} to='/keyboard-shortcuts' />);
|
navItems.push(<ColumnLink key='7' icon='question' text={intl.formatMessage(messages.keyboard_shortcuts)} to='/keyboard-shortcuts' />);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
navItems.push(<ColumnLink key='8' icon='book' text={intl.formatMessage(messages.info)} href='/about/more' />);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column icon='asterisk' heading={intl.formatMessage(messages.heading)} hideHeadingOnMobile>
|
<Column icon='asterisk' heading={intl.formatMessage(messages.heading)} hideHeadingOnMobile>
|
||||||
<div className='getting-started__wrapper'>
|
<div className='getting-started__wrapper'>
|
||||||
<ColumnSubheading text={intl.formatMessage(messages.navigation_subheading)} />
|
<ColumnSubheading text={intl.formatMessage(messages.navigation_subheading)} />
|
||||||
{navItems}
|
{navItems}
|
||||||
<ColumnSubheading text={intl.formatMessage(messages.settings_subheading)} />
|
<ColumnSubheading text={intl.formatMessage(messages.settings_subheading)} />
|
||||||
<ColumnLink icon='book' text={intl.formatMessage(messages.info)} href='/about/more' />
|
<ColumnLink icon='thumb-tack' text={intl.formatMessage(messages.pins)} to='/pinned' />
|
||||||
|
<ColumnLink icon='volume-off' text={intl.formatMessage(messages.mutes)} to='/mutes' />
|
||||||
|
<ColumnLink icon='ban' text={intl.formatMessage(messages.blocks)} to='/blocks' />
|
||||||
<ColumnLink icon='cog' text={intl.formatMessage(messages.preferences)} href='/settings/preferences' />
|
<ColumnLink icon='cog' text={intl.formatMessage(messages.preferences)} href='/settings/preferences' />
|
||||||
<ColumnLink icon='sign-out' text={intl.formatMessage(messages.sign_out)} href='/auth/sign_out' method='delete' />
|
<ColumnLink icon='sign-out' text={intl.formatMessage(messages.sign_out)} href='/auth/sign_out' method='delete' />
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
"account.media": "Mediji",
|
"account.media": "Mediji",
|
||||||
"account.mention": "Pomeni korisnika @{name}",
|
"account.mention": "Pomeni korisnika @{name}",
|
||||||
"account.moved_to": "{name} se pomerio na:",
|
"account.moved_to": "{name} se pomerio na:",
|
||||||
"account.mute": "Mutiraj @{name}",
|
"account.mute": "Ućutkaj korisnika @{name}",
|
||||||
"account.mute_notifications": "Isključi obaveštenja od korisnika @{name}",
|
"account.mute_notifications": "Isključi obaveštenja od korisnika @{name}",
|
||||||
"account.posts": "Statusa",
|
"account.posts": "Statusa",
|
||||||
"account.report": "Prijavi @{name}",
|
"account.report": "Prijavi @{name}",
|
||||||
@ -21,7 +21,7 @@
|
|||||||
"account.unblock": "Odblokiraj korisnika @{name}",
|
"account.unblock": "Odblokiraj korisnika @{name}",
|
||||||
"account.unblock_domain": "Odblokiraj domen {domain}",
|
"account.unblock_domain": "Odblokiraj domen {domain}",
|
||||||
"account.unfollow": "Otprati",
|
"account.unfollow": "Otprati",
|
||||||
"account.unmute": "Odmutiraj @{name}",
|
"account.unmute": "Ukloni ućutkavanje korisniku @{name}",
|
||||||
"account.unmute_notifications": "Uključi nazad obaveštenja od korisnika @{name}",
|
"account.unmute_notifications": "Uključi nazad obaveštenja od korisnika @{name}",
|
||||||
"account.view_full_profile": "Vidi ceo profil",
|
"account.view_full_profile": "Vidi ceo profil",
|
||||||
"boost_modal.combo": "Možete pritisnuti {combo} da preskočite ovo sledeći put",
|
"boost_modal.combo": "Možete pritisnuti {combo} da preskočite ovo sledeći put",
|
||||||
@ -37,10 +37,10 @@
|
|||||||
"column.follow_requests": "Zahtevi za praćenje",
|
"column.follow_requests": "Zahtevi za praćenje",
|
||||||
"column.home": "Početna",
|
"column.home": "Početna",
|
||||||
"column.lists": "Liste",
|
"column.lists": "Liste",
|
||||||
"column.mutes": "Mutirani korisnici",
|
"column.mutes": "Ućutkani korisnici",
|
||||||
"column.notifications": "Obaveštenja",
|
"column.notifications": "Obaveštenja",
|
||||||
"column.pins": "Prikačeni tutovi",
|
"column.pins": "Prikačeni tutovi",
|
||||||
"column.public": "Združena lajna",
|
"column.public": "Federisana lajna",
|
||||||
"column_back_button.label": "Nazad",
|
"column_back_button.label": "Nazad",
|
||||||
"column_header.hide_settings": "Sakrij postavke",
|
"column_header.hide_settings": "Sakrij postavke",
|
||||||
"column_header.moveLeft_settings": "Pomeri kolonu ulevo",
|
"column_header.moveLeft_settings": "Pomeri kolonu ulevo",
|
||||||
@ -50,6 +50,7 @@
|
|||||||
"column_header.unpin": "Otkači",
|
"column_header.unpin": "Otkači",
|
||||||
"column_subheading.navigation": "Navigacija",
|
"column_subheading.navigation": "Navigacija",
|
||||||
"column_subheading.settings": "Postavke",
|
"column_subheading.settings": "Postavke",
|
||||||
|
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||||
"compose_form.lock_disclaimer": "Vaš nalog nije {locked}. Svako može da Vas zaprati i da vidi objave namenjene samo Vašim pratiocima.",
|
"compose_form.lock_disclaimer": "Vaš nalog nije {locked}. Svako može da Vas zaprati i da vidi objave namenjene samo Vašim pratiocima.",
|
||||||
"compose_form.lock_disclaimer.lock": "zaključan",
|
"compose_form.lock_disclaimer.lock": "zaključan",
|
||||||
"compose_form.placeholder": "Šta Vam je na umu?",
|
"compose_form.placeholder": "Šta Vam je na umu?",
|
||||||
@ -66,9 +67,9 @@
|
|||||||
"confirmations.delete_list.confirm": "Obriši",
|
"confirmations.delete_list.confirm": "Obriši",
|
||||||
"confirmations.delete_list.message": "Da li ste sigurni da želite da bespovratno obrišete ovu listu?",
|
"confirmations.delete_list.message": "Da li ste sigurni da želite da bespovratno obrišete ovu listu?",
|
||||||
"confirmations.domain_block.confirm": "Sakrij ceo domen",
|
"confirmations.domain_block.confirm": "Sakrij ceo domen",
|
||||||
"confirmations.domain_block.message": "Da li ste stvarno, stvarno sigurno da želite da blokirate ceo domen {domain}? U većini slučajeva, par dobrih blokiranja ili mutiranja su dovoljna i preporučljiva.",
|
"confirmations.domain_block.message": "Da li ste stvarno, stvarno sigurno da želite da blokirate ceo domen {domain}? U većini slučajeva, par dobrih blokiranja ili ućutkavanja su dovoljna i preporučljiva.",
|
||||||
"confirmations.mute.confirm": "Mutiraj",
|
"confirmations.mute.confirm": "Ućutkaj",
|
||||||
"confirmations.mute.message": "Da li stvarno želite da mutirate korisnika {name}?",
|
"confirmations.mute.message": "Da li stvarno želite da ućutkate korisnika {name}?",
|
||||||
"confirmations.unfollow.confirm": "Otprati",
|
"confirmations.unfollow.confirm": "Otprati",
|
||||||
"confirmations.unfollow.message": "Da li ste sigurni da želite da otpratite korisnika {name}?",
|
"confirmations.unfollow.message": "Da li ste sigurni da želite da otpratite korisnika {name}?",
|
||||||
"embed.instructions": "Ugradi ovaj status na Vaš veb sajt kopiranjem koda ispod.",
|
"embed.instructions": "Ugradi ovaj status na Vaš veb sajt kopiranjem koda ispod.",
|
||||||
@ -148,10 +149,10 @@
|
|||||||
"navigation_bar.keyboard_shortcuts": "Prečice na tastaturi",
|
"navigation_bar.keyboard_shortcuts": "Prečice na tastaturi",
|
||||||
"navigation_bar.lists": "Liste",
|
"navigation_bar.lists": "Liste",
|
||||||
"navigation_bar.logout": "Odjava",
|
"navigation_bar.logout": "Odjava",
|
||||||
"navigation_bar.mutes": "Mutirani korisnici",
|
"navigation_bar.mutes": "Ućutkani korisnici",
|
||||||
"navigation_bar.pins": "Prikačeni tutovi",
|
"navigation_bar.pins": "Prikačeni tutovi",
|
||||||
"navigation_bar.preferences": "Podešavanja",
|
"navigation_bar.preferences": "Podešavanja",
|
||||||
"navigation_bar.public_timeline": "Združena lajna",
|
"navigation_bar.public_timeline": "Federisana lajna",
|
||||||
"notification.favourite": "{name} je stavio Vaš status kao omiljeni",
|
"notification.favourite": "{name} je stavio Vaš status kao omiljeni",
|
||||||
"notification.follow": "{name} Vas je zapratio",
|
"notification.follow": "{name} Vas je zapratio",
|
||||||
"notification.mention": "{name} Vas je pomenuo",
|
"notification.mention": "{name} Vas je pomenuo",
|
||||||
@ -169,7 +170,7 @@
|
|||||||
"notifications.column_settings.sound": "Puštaj zvuk",
|
"notifications.column_settings.sound": "Puštaj zvuk",
|
||||||
"onboarding.done": "Gotovo",
|
"onboarding.done": "Gotovo",
|
||||||
"onboarding.next": "Sledeće",
|
"onboarding.next": "Sledeće",
|
||||||
"onboarding.page_five.public_timelines": "Lokalna lajna prikazuje sve javne statuse od svih na domenu {domain}. Združena lajna prikazuje javne statuse od svih ljudi koje prate korisnici sa domena {domain}. Ovo su javne lajne, sjajan način da otkrijete nove ljude.",
|
"onboarding.page_five.public_timelines": "Lokalna lajna prikazuje sve javne statuse od svih na domenu {domain}. Federisana lajna prikazuje javne statuse od svih ljudi koje prate korisnici sa domena {domain}. Ovo su javne lajne, sjajan način da otkrijete nove ljude.",
|
||||||
"onboarding.page_four.home": "Početna lajna prikazuje statuse ljudi koje Vi pratite.",
|
"onboarding.page_four.home": "Početna lajna prikazuje statuse ljudi koje Vi pratite.",
|
||||||
"onboarding.page_four.notifications": "Kolona sa obaveštenjima Vam prikazuje kada neko priča sa Vama.",
|
"onboarding.page_four.notifications": "Kolona sa obaveštenjima Vam prikazuje kada neko priča sa Vama.",
|
||||||
"onboarding.page_one.federation": "Mastodont je mreža nezavisnih servera koji se uvezuju da naprave jednu veću društvenu mrežu. Ove servere zovemo instancama.",
|
"onboarding.page_one.federation": "Mastodont je mreža nezavisnih servera koji se uvezuju da naprave jednu veću društvenu mrežu. Ove servere zovemo instancama.",
|
||||||
@ -213,6 +214,7 @@
|
|||||||
"search_popout.tips.user": "korisnik",
|
"search_popout.tips.user": "korisnik",
|
||||||
"search_results.total": "{count, number} {count, plural, one {rezultat} few {rezultata} other {rezultata}}",
|
"search_results.total": "{count, number} {count, plural, one {rezultat} few {rezultata} other {rezultata}}",
|
||||||
"standalone.public_title": "Pogled iznutra...",
|
"standalone.public_title": "Pogled iznutra...",
|
||||||
|
"status.block": "Block @{name}",
|
||||||
"status.cannot_reblog": "Ovaj status ne može da se podrži",
|
"status.cannot_reblog": "Ovaj status ne može da se podrži",
|
||||||
"status.delete": "Obriši",
|
"status.delete": "Obriši",
|
||||||
"status.embed": "Ugradi na sajt",
|
"status.embed": "Ugradi na sajt",
|
||||||
@ -221,7 +223,8 @@
|
|||||||
"status.media_hidden": "Multimedija sakrivena",
|
"status.media_hidden": "Multimedija sakrivena",
|
||||||
"status.mention": "Pomeni korisnika @{name}",
|
"status.mention": "Pomeni korisnika @{name}",
|
||||||
"status.more": "Još",
|
"status.more": "Još",
|
||||||
"status.mute_conversation": "Mutiraj prepisku",
|
"status.mute": "Mute @{name}",
|
||||||
|
"status.mute_conversation": "Ućutkaj prepisku",
|
||||||
"status.open": "Proširi ovaj status",
|
"status.open": "Proširi ovaj status",
|
||||||
"status.pin": "Prikači na profil",
|
"status.pin": "Prikači na profil",
|
||||||
"status.reblog": "Podrži",
|
"status.reblog": "Podrži",
|
||||||
@ -237,7 +240,7 @@
|
|||||||
"status.unmute_conversation": "Uključi prepisku",
|
"status.unmute_conversation": "Uključi prepisku",
|
||||||
"status.unpin": "Otkači sa profila",
|
"status.unpin": "Otkači sa profila",
|
||||||
"tabs_bar.compose": "Napiši",
|
"tabs_bar.compose": "Napiši",
|
||||||
"tabs_bar.federated_timeline": "Združeno",
|
"tabs_bar.federated_timeline": "Federisano",
|
||||||
"tabs_bar.home": "Početna",
|
"tabs_bar.home": "Početna",
|
||||||
"tabs_bar.local_timeline": "Lokalno",
|
"tabs_bar.local_timeline": "Lokalno",
|
||||||
"tabs_bar.notifications": "Obaveštenja",
|
"tabs_bar.notifications": "Obaveštenja",
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
"account.media": "Медији",
|
"account.media": "Медији",
|
||||||
"account.mention": "Помени корисника @{name}",
|
"account.mention": "Помени корисника @{name}",
|
||||||
"account.moved_to": "{name} се померио на:",
|
"account.moved_to": "{name} се померио на:",
|
||||||
"account.mute": "Мутирај @{name}",
|
"account.mute": "Ућуткај корисника @{name}",
|
||||||
"account.mute_notifications": "Искључи обавештења од корисника @{name}",
|
"account.mute_notifications": "Искључи обавештења од корисника @{name}",
|
||||||
"account.posts": "Статуса",
|
"account.posts": "Статуса",
|
||||||
"account.report": "Пријави @{name}",
|
"account.report": "Пријави @{name}",
|
||||||
@ -21,7 +21,7 @@
|
|||||||
"account.unblock": "Одблокирај корисника @{name}",
|
"account.unblock": "Одблокирај корисника @{name}",
|
||||||
"account.unblock_domain": "Одблокирај домен {domain}",
|
"account.unblock_domain": "Одблокирај домен {domain}",
|
||||||
"account.unfollow": "Отпрати",
|
"account.unfollow": "Отпрати",
|
||||||
"account.unmute": "Одмутирај @{name}",
|
"account.unmute": "Уклони ућуткавање кориснику @{name}",
|
||||||
"account.unmute_notifications": "Укључи назад обавештења од корисника @{name}",
|
"account.unmute_notifications": "Укључи назад обавештења од корисника @{name}",
|
||||||
"account.view_full_profile": "Види цео профил",
|
"account.view_full_profile": "Види цео профил",
|
||||||
"boost_modal.combo": "Можете притиснути {combo} да прескочите ово следећи пут",
|
"boost_modal.combo": "Можете притиснути {combo} да прескочите ово следећи пут",
|
||||||
@ -37,10 +37,10 @@
|
|||||||
"column.follow_requests": "Захтеви за праћење",
|
"column.follow_requests": "Захтеви за праћење",
|
||||||
"column.home": "Почетна",
|
"column.home": "Почетна",
|
||||||
"column.lists": "Листе",
|
"column.lists": "Листе",
|
||||||
"column.mutes": "Мутирани корисници",
|
"column.mutes": "Ућуткани корисници",
|
||||||
"column.notifications": "Обавештења",
|
"column.notifications": "Обавештења",
|
||||||
"column.pins": "Прикачени тутови",
|
"column.pins": "Прикачени тутови",
|
||||||
"column.public": "Здружена лајна",
|
"column.public": "Федерисана лајна",
|
||||||
"column_back_button.label": "Назад",
|
"column_back_button.label": "Назад",
|
||||||
"column_header.hide_settings": "Сакриј поставке",
|
"column_header.hide_settings": "Сакриј поставке",
|
||||||
"column_header.moveLeft_settings": "Помери колону улево",
|
"column_header.moveLeft_settings": "Помери колону улево",
|
||||||
@ -67,9 +67,9 @@
|
|||||||
"confirmations.delete_list.confirm": "Обриши",
|
"confirmations.delete_list.confirm": "Обриши",
|
||||||
"confirmations.delete_list.message": "Да ли сте сигурни да желите да бесповратно обришете ову листу?",
|
"confirmations.delete_list.message": "Да ли сте сигурни да желите да бесповратно обришете ову листу?",
|
||||||
"confirmations.domain_block.confirm": "Сакриј цео домен",
|
"confirmations.domain_block.confirm": "Сакриј цео домен",
|
||||||
"confirmations.domain_block.message": "Да ли сте стварно, стварно сигурно да желите да блокирате цео домен {domain}? У већини случајева, пар добрих блокирања или мутирања су довољна и препоручљива.",
|
"confirmations.domain_block.message": "Да ли сте стварно, стварно сигурно да желите да блокирате цео домен {domain}? У већини случајева, пар добрих блокирања или ућуткавања су довољна и препоручљива.",
|
||||||
"confirmations.mute.confirm": "Мутирај",
|
"confirmations.mute.confirm": "Ућуткај",
|
||||||
"confirmations.mute.message": "Да ли стварно желите да мутирате корисника {name}?",
|
"confirmations.mute.message": "Да ли стварно желите да ућуткате корисника {name}?",
|
||||||
"confirmations.unfollow.confirm": "Отпрати",
|
"confirmations.unfollow.confirm": "Отпрати",
|
||||||
"confirmations.unfollow.message": "Да ли сте сигурни да желите да отпратите корисника {name}?",
|
"confirmations.unfollow.message": "Да ли сте сигурни да желите да отпратите корисника {name}?",
|
||||||
"embed.instructions": "Угради овај статус на Ваш веб сајт копирањем кода испод.",
|
"embed.instructions": "Угради овај статус на Ваш веб сајт копирањем кода испод.",
|
||||||
@ -149,10 +149,10 @@
|
|||||||
"navigation_bar.keyboard_shortcuts": "Пречице на тастатури",
|
"navigation_bar.keyboard_shortcuts": "Пречице на тастатури",
|
||||||
"navigation_bar.lists": "Листе",
|
"navigation_bar.lists": "Листе",
|
||||||
"navigation_bar.logout": "Одјава",
|
"navigation_bar.logout": "Одјава",
|
||||||
"navigation_bar.mutes": "Мутирани корисници",
|
"navigation_bar.mutes": "Ућуткани корисници",
|
||||||
"navigation_bar.pins": "Прикачени тутови",
|
"navigation_bar.pins": "Прикачени тутови",
|
||||||
"navigation_bar.preferences": "Подешавања",
|
"navigation_bar.preferences": "Подешавања",
|
||||||
"navigation_bar.public_timeline": "Здружена лајна",
|
"navigation_bar.public_timeline": "Федерисана лајна",
|
||||||
"notification.favourite": "{name} је ставио Ваш статус као омиљени",
|
"notification.favourite": "{name} је ставио Ваш статус као омиљени",
|
||||||
"notification.follow": "{name} Вас је запратио",
|
"notification.follow": "{name} Вас је запратио",
|
||||||
"notification.mention": "{name} Вас је поменуо",
|
"notification.mention": "{name} Вас је поменуо",
|
||||||
@ -170,7 +170,7 @@
|
|||||||
"notifications.column_settings.sound": "Пуштај звук",
|
"notifications.column_settings.sound": "Пуштај звук",
|
||||||
"onboarding.done": "Готово",
|
"onboarding.done": "Готово",
|
||||||
"onboarding.next": "Следеће",
|
"onboarding.next": "Следеће",
|
||||||
"onboarding.page_five.public_timelines": "Локална лајна приказује све јавне статусе од свих на домену {domain}. Здружена лајна приказује јавне статусе од свих људи које прате корисници са домена {domain}. Ово су јавне лајне, сјајан начин да откријете нове људе.",
|
"onboarding.page_five.public_timelines": "Локална лајна приказује све јавне статусе од свих на домену {domain}. Федерисана лајна приказује јавне статусе од свих људи које прате корисници са домена {domain}. Ово су јавне лајне, сјајан начин да откријете нове људе.",
|
||||||
"onboarding.page_four.home": "Почетна лајна приказује статусе људи које Ви пратите.",
|
"onboarding.page_four.home": "Почетна лајна приказује статусе људи које Ви пратите.",
|
||||||
"onboarding.page_four.notifications": "Колона са обавештењима Вам приказује када неко прича са Вама.",
|
"onboarding.page_four.notifications": "Колона са обавештењима Вам приказује када неко прича са Вама.",
|
||||||
"onboarding.page_one.federation": "Мастодонт је мрежа независних сервера који се увезују да направе једну већу друштвену мрежу. Ове сервере зовемо инстанцама.",
|
"onboarding.page_one.federation": "Мастодонт је мрежа независних сервера који се увезују да направе једну већу друштвену мрежу. Ове сервере зовемо инстанцама.",
|
||||||
@ -224,7 +224,7 @@
|
|||||||
"status.mention": "Помени корисника @{name}",
|
"status.mention": "Помени корисника @{name}",
|
||||||
"status.more": "Још",
|
"status.more": "Још",
|
||||||
"status.mute": "Mute @{name}",
|
"status.mute": "Mute @{name}",
|
||||||
"status.mute_conversation": "Мутирај преписку",
|
"status.mute_conversation": "Ућуткај преписку",
|
||||||
"status.open": "Прошири овај статус",
|
"status.open": "Прошири овај статус",
|
||||||
"status.pin": "Прикачи на профил",
|
"status.pin": "Прикачи на профил",
|
||||||
"status.reblog": "Подржи",
|
"status.reblog": "Подржи",
|
||||||
@ -240,7 +240,7 @@
|
|||||||
"status.unmute_conversation": "Укључи преписку",
|
"status.unmute_conversation": "Укључи преписку",
|
||||||
"status.unpin": "Откачи са профила",
|
"status.unpin": "Откачи са профила",
|
||||||
"tabs_bar.compose": "Напиши",
|
"tabs_bar.compose": "Напиши",
|
||||||
"tabs_bar.federated_timeline": "Здружено",
|
"tabs_bar.federated_timeline": "Федерисано",
|
||||||
"tabs_bar.home": "Почетна",
|
"tabs_bar.home": "Почетна",
|
||||||
"tabs_bar.local_timeline": "Локално",
|
"tabs_bar.local_timeline": "Локално",
|
||||||
"tabs_bar.notifications": "Обавештења",
|
"tabs_bar.notifications": "Обавештења",
|
||||||
|
@ -64,8 +64,8 @@
|
|||||||
"confirmations.block.message": "你確定要封鎖 {name} ?",
|
"confirmations.block.message": "你確定要封鎖 {name} ?",
|
||||||
"confirmations.delete.confirm": "刪除",
|
"confirmations.delete.confirm": "刪除",
|
||||||
"confirmations.delete.message": "你確定要刪除這個狀態?",
|
"confirmations.delete.message": "你確定要刪除這個狀態?",
|
||||||
"confirmations.delete_list.confirm": "Delete",
|
"confirmations.delete_list.confirm": "刪除",
|
||||||
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
"confirmations.delete_list.message": "確定要永久性地刪除這個名單嗎?",
|
||||||
"confirmations.domain_block.confirm": "隱藏整個網域",
|
"confirmations.domain_block.confirm": "隱藏整個網域",
|
||||||
"confirmations.domain_block.message": "你真的真的確定要隱藏整個 {domain} ?多數情況下,比較推薦封鎖或消音幾個特定目標就好。",
|
"confirmations.domain_block.message": "你真的真的確定要隱藏整個 {domain} ?多數情況下,比較推薦封鎖或消音幾個特定目標就好。",
|
||||||
"confirmations.mute.confirm": "消音",
|
"confirmations.mute.confirm": "消音",
|
||||||
@ -128,14 +128,14 @@
|
|||||||
"lightbox.close": "關閉",
|
"lightbox.close": "關閉",
|
||||||
"lightbox.next": "繼續",
|
"lightbox.next": "繼續",
|
||||||
"lightbox.previous": "回退",
|
"lightbox.previous": "回退",
|
||||||
"lists.account.add": "Add to list",
|
"lists.account.add": "加到名單裡",
|
||||||
"lists.account.remove": "Remove from list",
|
"lists.account.remove": "從名單中移除",
|
||||||
"lists.delete": "Delete list",
|
"lists.delete": "刪除名單",
|
||||||
"lists.edit": "Edit list",
|
"lists.edit": "修改名單",
|
||||||
"lists.new.create": "Add list",
|
"lists.new.create": "新增名單",
|
||||||
"lists.new.title_placeholder": "New list title",
|
"lists.new.title_placeholder": "名單名稱",
|
||||||
"lists.search": "Search among people you follow",
|
"lists.search": "搜尋您關注的使用者",
|
||||||
"lists.subheading": "Your lists",
|
"lists.subheading": "您的名單",
|
||||||
"loading_indicator.label": "讀取中...",
|
"loading_indicator.label": "讀取中...",
|
||||||
"media_gallery.toggle_visible": "切換可見性",
|
"media_gallery.toggle_visible": "切換可見性",
|
||||||
"missing_indicator.label": "找不到",
|
"missing_indicator.label": "找不到",
|
||||||
@ -146,8 +146,8 @@
|
|||||||
"navigation_bar.favourites": "最愛",
|
"navigation_bar.favourites": "最愛",
|
||||||
"navigation_bar.follow_requests": "關注請求",
|
"navigation_bar.follow_requests": "關注請求",
|
||||||
"navigation_bar.info": "關於本站",
|
"navigation_bar.info": "關於本站",
|
||||||
"navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
|
"navigation_bar.keyboard_shortcuts": "快速鍵",
|
||||||
"navigation_bar.lists": "Lists",
|
"navigation_bar.lists": "名單",
|
||||||
"navigation_bar.logout": "登出",
|
"navigation_bar.logout": "登出",
|
||||||
"navigation_bar.mutes": "消音的使用者",
|
"navigation_bar.mutes": "消音的使用者",
|
||||||
"navigation_bar.pins": "置頂貼文",
|
"navigation_bar.pins": "置頂貼文",
|
||||||
|
@ -398,10 +398,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
max-width: calc(100% - 90px);
|
||||||
|
}
|
||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
overflow: hidden;
|
word-wrap: break-word;
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__timestamp {
|
&__timestamp {
|
||||||
@ -415,7 +417,7 @@
|
|||||||
color: $ui-primary-color;
|
color: $ui-primary-color;
|
||||||
font-family: 'mastodon-font-monospace', monospace;
|
font-family: 'mastodon-font-monospace', monospace;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
white-space: nowrap;
|
word-wrap: break-word;
|
||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,18 +126,18 @@ class User < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def confirm
|
def confirm
|
||||||
return if confirmed?
|
new_user = !confirmed?
|
||||||
|
|
||||||
super
|
super
|
||||||
update_statistics!
|
update_statistics! if new_user
|
||||||
end
|
end
|
||||||
|
|
||||||
def confirm!
|
def confirm!
|
||||||
return if confirmed?
|
new_user = !confirmed?
|
||||||
|
|
||||||
skip_confirmation!
|
skip_confirmation!
|
||||||
save!
|
save!
|
||||||
update_statistics!
|
update_statistics! if new_user
|
||||||
end
|
end
|
||||||
|
|
||||||
def promote!
|
def promote!
|
||||||
|
22
app/serializers/activitypub/delete_actor_serializer.rb
Normal file
22
app/serializers/activitypub/delete_actor_serializer.rb
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class ActivityPub::DeleteActorSerializer < ActiveModel::Serializer
|
||||||
|
attributes :id, :type, :actor
|
||||||
|
attribute :virtual_object, key: :object
|
||||||
|
|
||||||
|
def id
|
||||||
|
[ActivityPub::TagManager.instance.uri_for(object), '#delete'].join
|
||||||
|
end
|
||||||
|
|
||||||
|
def type
|
||||||
|
'Delete'
|
||||||
|
end
|
||||||
|
|
||||||
|
def actor
|
||||||
|
ActivityPub::TagManager.instance.uri_for(object)
|
||||||
|
end
|
||||||
|
|
||||||
|
def virtual_object
|
||||||
|
actor
|
||||||
|
end
|
||||||
|
end
|
@ -27,7 +27,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
|
|||||||
end
|
end
|
||||||
|
|
||||||
def thumbnail
|
def thumbnail
|
||||||
full_asset_url(instance_presenter.thumbnail.file.url) if instance_presenter.thumbnail
|
instance_presenter.thumbnail ? full_asset_url(instance_presenter.thumbnail.file.url) : full_pack_url('preview.jpg')
|
||||||
end
|
end
|
||||||
|
|
||||||
def max_toot_chars
|
def max_toot_chars
|
||||||
|
@ -17,9 +17,7 @@ class BatchedRemoveStatusService < BaseService
|
|||||||
|
|
||||||
@stream_entry_batches = []
|
@stream_entry_batches = []
|
||||||
@salmon_batches = []
|
@salmon_batches = []
|
||||||
@activity_json_batches = []
|
|
||||||
@json_payloads = statuses.map { |s| [s.id, Oj.dump(event: :delete, payload: s.id.to_s)] }.to_h
|
@json_payloads = statuses.map { |s| [s.id, Oj.dump(event: :delete, payload: s.id.to_s)] }.to_h
|
||||||
@activity_json = {}
|
|
||||||
@activity_xml = {}
|
@activity_xml = {}
|
||||||
|
|
||||||
# Ensure that rendered XML reflects destroyed state
|
# Ensure that rendered XML reflects destroyed state
|
||||||
@ -32,10 +30,7 @@ class BatchedRemoveStatusService < BaseService
|
|||||||
unpush_from_home_timelines(account, account_statuses)
|
unpush_from_home_timelines(account, account_statuses)
|
||||||
unpush_from_list_timelines(account, account_statuses)
|
unpush_from_list_timelines(account, account_statuses)
|
||||||
|
|
||||||
if account.local?
|
batch_stream_entries(account, account_statuses) if account.local?
|
||||||
batch_stream_entries(account, account_statuses)
|
|
||||||
batch_activity_json(account, account_statuses)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Cannot be batched
|
# Cannot be batched
|
||||||
@ -47,7 +42,6 @@ class BatchedRemoveStatusService < BaseService
|
|||||||
|
|
||||||
Pubsubhubbub::RawDistributionWorker.push_bulk(@stream_entry_batches) { |batch| batch }
|
Pubsubhubbub::RawDistributionWorker.push_bulk(@stream_entry_batches) { |batch| batch }
|
||||||
NotificationWorker.push_bulk(@salmon_batches) { |batch| batch }
|
NotificationWorker.push_bulk(@salmon_batches) { |batch| batch }
|
||||||
ActivityPub::DeliveryWorker.push_bulk(@activity_json_batches) { |batch| batch }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -58,22 +52,6 @@ class BatchedRemoveStatusService < BaseService
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def batch_activity_json(account, statuses)
|
|
||||||
account.followers.inboxes.each do |inbox_url|
|
|
||||||
statuses.each do |status|
|
|
||||||
@activity_json_batches << [build_json(status), account.id, inbox_url]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
statuses.each do |status|
|
|
||||||
other_recipients = (status.mentions + status.reblogs).map(&:account).reject(&:local?).select(&:activitypub?).uniq(&:id)
|
|
||||||
|
|
||||||
other_recipients.each do |target_account|
|
|
||||||
@activity_json_batches << [build_json(status), account.id, target_account.inbox_url]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def unpush_from_home_timelines(account, statuses)
|
def unpush_from_home_timelines(account, statuses)
|
||||||
recipients = account.followers.local.to_a
|
recipients = account.followers.local.to_a
|
||||||
|
|
||||||
@ -134,23 +112,9 @@ class BatchedRemoveStatusService < BaseService
|
|||||||
Redis.current
|
Redis.current
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_json(status)
|
|
||||||
return @activity_json[status.id] if @activity_json.key?(status.id)
|
|
||||||
|
|
||||||
@activity_json[status.id] = sign_json(status, ActiveModelSerializers::SerializableResource.new(
|
|
||||||
status,
|
|
||||||
serializer: status.reblog? ? ActivityPub::UndoAnnounceSerializer : ActivityPub::DeleteSerializer,
|
|
||||||
adapter: ActivityPub::Adapter
|
|
||||||
).as_json)
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_xml(stream_entry)
|
def build_xml(stream_entry)
|
||||||
return @activity_xml[stream_entry.id] if @activity_xml.key?(stream_entry.id)
|
return @activity_xml[stream_entry.id] if @activity_xml.key?(stream_entry.id)
|
||||||
|
|
||||||
@activity_xml[stream_entry.id] = stream_entry_to_xml(stream_entry)
|
@activity_xml[stream_entry.id] = stream_entry_to_xml(stream_entry)
|
||||||
end
|
end
|
||||||
|
|
||||||
def sign_json(status, json)
|
|
||||||
Oj.dump(ActivityPub::LinkedDataSignature.new(json).sign!(status.account))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
@ -50,7 +50,7 @@ class FetchAtomService < BaseService
|
|||||||
@unsupported_activity = true
|
@unsupported_activity = true
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
elsif @response['Link'] && !terminal
|
elsif @response['Link'] && !terminal && link_header.find_link(%w(rel alternate))
|
||||||
process_headers
|
process_headers
|
||||||
elsif @response.mime_type == 'text/html' && !terminal
|
elsif @response.mime_type == 'text/html' && !terminal
|
||||||
process_html
|
process_html
|
||||||
@ -70,8 +70,6 @@ class FetchAtomService < BaseService
|
|||||||
end
|
end
|
||||||
|
|
||||||
def process_headers
|
def process_headers
|
||||||
link_header = LinkHeader.parse(@response['Link'].is_a?(Array) ? @response['Link'].first : @response['Link'])
|
|
||||||
|
|
||||||
json_link = link_header.find_link(%w(rel alternate), %w(type application/activity+json)) || link_header.find_link(%w(rel alternate), ['type', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'])
|
json_link = link_header.find_link(%w(rel alternate), %w(type application/activity+json)) || link_header.find_link(%w(rel alternate), ['type', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'])
|
||||||
atom_link = link_header.find_link(%w(rel alternate), %w(type application/atom+xml))
|
atom_link = link_header.find_link(%w(rel alternate), %w(type application/atom+xml))
|
||||||
|
|
||||||
@ -80,4 +78,8 @@ class FetchAtomService < BaseService
|
|||||||
|
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def link_header
|
||||||
|
@link_header ||= LinkHeader.parse(@response['Link'].is_a?(Array) ? @response['Link'].first : @response['Link'])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -22,6 +22,8 @@ class SuspendAccountService < BaseService
|
|||||||
end
|
end
|
||||||
|
|
||||||
def purge_content!
|
def purge_content!
|
||||||
|
ActivityPub::RawDistributionWorker.perform_async(delete_actor_json, @account.id) if @account.local?
|
||||||
|
|
||||||
@account.statuses.reorder(nil).find_in_batches do |statuses|
|
@account.statuses.reorder(nil).find_in_batches do |statuses|
|
||||||
BatchedRemoveStatusService.new.call(statuses)
|
BatchedRemoveStatusService.new.call(statuses)
|
||||||
end
|
end
|
||||||
@ -54,4 +56,14 @@ class SuspendAccountService < BaseService
|
|||||||
def destroy_all(association)
|
def destroy_all(association)
|
||||||
association.in_batches.destroy_all
|
association.in_batches.destroy_all
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def delete_actor_json
|
||||||
|
payload = ActiveModelSerializers::SerializableResource.new(
|
||||||
|
@account,
|
||||||
|
serializer: ActivityPub::DeleteActorSerializer,
|
||||||
|
adapter: ActivityPub::Adapter
|
||||||
|
).as_json
|
||||||
|
|
||||||
|
Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@account))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -160,6 +160,7 @@ pl:
|
|||||||
update_status: "%{name} zaktualizował wpis użytkownika %{target}"
|
update_status: "%{name} zaktualizował wpis użytkownika %{target}"
|
||||||
title: Dziennik działań administracyjnych
|
title: Dziennik działań administracyjnych
|
||||||
custom_emojis:
|
custom_emojis:
|
||||||
|
by_domain: Według domeny
|
||||||
copied_msg: Pomyślnie utworzono lokalną kopię emoji
|
copied_msg: Pomyślnie utworzono lokalną kopię emoji
|
||||||
copy: Kopiuj
|
copy: Kopiuj
|
||||||
copy_failed_msg: Nie udało się utworzyć lokalnej kopii emoji
|
copy_failed_msg: Nie udało się utworzyć lokalnej kopii emoji
|
||||||
@ -620,6 +621,7 @@ pl:
|
|||||||
private: Nie możesz przypiąć niepublicznego wpisu
|
private: Nie możesz przypiąć niepublicznego wpisu
|
||||||
reblog: Nie możesz przypiąć podbicia wpisu
|
reblog: Nie możesz przypiąć podbicia wpisu
|
||||||
show_more: Pokaż więcej
|
show_more: Pokaż więcej
|
||||||
|
title: '%{name}: "%{quote}"'
|
||||||
visibilities:
|
visibilities:
|
||||||
private: Tylko dla śledzących
|
private: Tylko dla śledzących
|
||||||
private_long: Widoczne tylko dla osób, które Cię śledzą
|
private_long: Widoczne tylko dla osób, które Cię śledzą
|
||||||
|
@ -21,7 +21,7 @@ zh-TW:
|
|||||||
data: 資料
|
data: 資料
|
||||||
display_name: 顯示名稱
|
display_name: 顯示名稱
|
||||||
email: 電子信箱
|
email: 電子信箱
|
||||||
filtered_languages: 封鎖下面语言的文章
|
filtered_languages: 封鎖下面語言的文章
|
||||||
header: 個人頁面頂部
|
header: 個人頁面頂部
|
||||||
locale: 語言
|
locale: 語言
|
||||||
locked: 將帳號轉為「私密」
|
locked: 將帳號轉為「私密」
|
||||||
@ -29,7 +29,16 @@ zh-TW:
|
|||||||
note: 簡介
|
note: 簡介
|
||||||
otp_attempt: 雙因子驗證碼
|
otp_attempt: 雙因子驗證碼
|
||||||
password: 密碼
|
password: 密碼
|
||||||
|
setting_auto_play_gif: 自動播放 GIFs
|
||||||
|
setting_boost_modal: 轉推前跳出確認視窗
|
||||||
setting_default_privacy: 文章預設隱私度
|
setting_default_privacy: 文章預設隱私度
|
||||||
|
setting_default_sensitive: 預設我的內容為敏感內容
|
||||||
|
setting_delete_modal: 刪推前跳出確認視窗
|
||||||
|
setting_noindex: 不被搜尋引擎檢索
|
||||||
|
setting_reduce_motion: 減低動畫效果
|
||||||
|
setting_system_font_ui: 使用系統預設字體
|
||||||
|
setting_theme: 網站主題
|
||||||
|
setting_unfollow_modal: 取消關注前跳出確認視窗
|
||||||
type: 匯入資料類型
|
type: 匯入資料類型
|
||||||
username: 使用者名稱
|
username: 使用者名稱
|
||||||
interactions:
|
interactions:
|
||||||
|
@ -409,8 +409,8 @@ sr-Latn:
|
|||||||
exports:
|
exports:
|
||||||
blocks: Blokirali ste
|
blocks: Blokirali ste
|
||||||
csv: CSV
|
csv: CSV
|
||||||
follows: PRatite
|
follows: Pratite
|
||||||
mutes: Mutirali ste
|
mutes: Ućutkali ste
|
||||||
storage: Multimedijalno skladište
|
storage: Multimedijalno skladište
|
||||||
followers:
|
followers:
|
||||||
domain: Domen
|
domain: Domen
|
||||||
@ -441,7 +441,7 @@ sr-Latn:
|
|||||||
types:
|
types:
|
||||||
blocking: Lista blokiranja
|
blocking: Lista blokiranja
|
||||||
following: Lista pratilaca
|
following: Lista pratilaca
|
||||||
muting: Lista mutiranih
|
muting: Lista ućutkanih
|
||||||
upload: Otpremi
|
upload: Otpremi
|
||||||
in_memoriam_html: In Memoriam.
|
in_memoriam_html: In Memoriam.
|
||||||
invites:
|
invites:
|
||||||
|
@ -409,8 +409,8 @@ sr:
|
|||||||
exports:
|
exports:
|
||||||
blocks: Блокирали сте
|
blocks: Блокирали сте
|
||||||
csv: CSV
|
csv: CSV
|
||||||
follows: ПРатите
|
follows: Пратите
|
||||||
mutes: Мутирали сте
|
mutes: Ућуткали сте
|
||||||
storage: Мултимедијално складиште
|
storage: Мултимедијално складиште
|
||||||
followers:
|
followers:
|
||||||
domain: Домен
|
domain: Домен
|
||||||
@ -441,7 +441,7 @@ sr:
|
|||||||
types:
|
types:
|
||||||
blocking: Листа блокирања
|
blocking: Листа блокирања
|
||||||
following: Листа пратилаца
|
following: Листа пратилаца
|
||||||
muting: Листа мутираних
|
muting: Листа ућутканих
|
||||||
upload: Отпреми
|
upload: Отпреми
|
||||||
in_memoriam_html: In Memoriam.
|
in_memoriam_html: In Memoriam.
|
||||||
invites:
|
invites:
|
||||||
|
@ -55,7 +55,7 @@ zh-TW:
|
|||||||
perform_full_suspension: 進行停權
|
perform_full_suspension: 進行停權
|
||||||
profile_url: 個人檔案網址
|
profile_url: 個人檔案網址
|
||||||
public: 公開
|
public: 公開
|
||||||
push_subscription_expires: PuSH 訂閱逾期
|
push_subscription_expires: 推播訂閱過期
|
||||||
salmon_url: Salmon URL
|
salmon_url: Salmon URL
|
||||||
silence: 靜音
|
silence: 靜音
|
||||||
statuses: 狀態
|
statuses: 狀態
|
||||||
@ -133,12 +133,14 @@ zh-TW:
|
|||||||
forgot_password: 忘記密碼?
|
forgot_password: 忘記密碼?
|
||||||
login: 登入
|
login: 登入
|
||||||
logout: 登出
|
logout: 登出
|
||||||
|
migrate_account: 轉移到另一個帳號
|
||||||
|
migrate_account_html: 想要將這個帳號指向另一個帳號可到<a href="%{path}">到這裡設定</a>。
|
||||||
register: 註冊
|
register: 註冊
|
||||||
resend_confirmation: 重寄驗證信
|
resend_confirmation: 重寄驗證信
|
||||||
reset_password: 重設密碼
|
reset_password: 重設密碼
|
||||||
set_new_password: 設定新密碼
|
set_new_password: 設定新密碼
|
||||||
authorize_follow:
|
authorize_follow:
|
||||||
error: 對不起,尋找這個跨站使用者的過程發生錯誤
|
error: 對不起,搜尋遠端使用者出現錯誤
|
||||||
follow: 關注
|
follow: 關注
|
||||||
title: 關注 %{acct}
|
title: 關注 %{acct}
|
||||||
datetime:
|
datetime:
|
||||||
@ -165,7 +167,16 @@ zh-TW:
|
|||||||
blocks: 您封鎖的使用者
|
blocks: 您封鎖的使用者
|
||||||
csv: CSV
|
csv: CSV
|
||||||
follows: 您關注的使用者
|
follows: 您關注的使用者
|
||||||
|
mutes: 您靜音的使用者
|
||||||
storage: 儲存空間大小
|
storage: 儲存空間大小
|
||||||
|
followers:
|
||||||
|
domain: 網域
|
||||||
|
explanation_html: 為確保個人隱私,您必須知道有哪些使用者正關注你。<strong>您的私密內容會被發送到所有您有被關注的服務站上</strong>。如果您不信任這些服務站的管理者,您可以選擇檢查或刪除您的關注者。
|
||||||
|
followers_count: 關注者數
|
||||||
|
lock_link: 鎖住你的帳號
|
||||||
|
purge: 移除關注者
|
||||||
|
unlocked_warning_html: 所有人都可以關注並檢索你的隱藏狀態。%{lock_link}以檢查或拒絕關注。
|
||||||
|
unlocked_warning_title: 你的帳號是公開的
|
||||||
generic:
|
generic:
|
||||||
changes_saved_msg: 已成功儲存修改
|
changes_saved_msg: 已成功儲存修改
|
||||||
powered_by: 網站由 %{link} 開發
|
powered_by: 網站由 %{link} 開發
|
||||||
@ -179,6 +190,7 @@ zh-TW:
|
|||||||
types:
|
types:
|
||||||
blocking: 您封鎖的使用者名單
|
blocking: 您封鎖的使用者名單
|
||||||
following: 您關注的使用者名單
|
following: 您關注的使用者名單
|
||||||
|
muting: 您靜音的使用者名單
|
||||||
upload: 上傳
|
upload: 上傳
|
||||||
landing_strip_html: "<strong>%{name}</strong> 是一個在 %{link_to_root_path} 的使用者。只要您有任何 Mastodon 服務站、或者聯盟網站的帳號,便可以跨站關注此站使用者,或者與他們互動。"
|
landing_strip_html: "<strong>%{name}</strong> 是一個在 %{link_to_root_path} 的使用者。只要您有任何 Mastodon 服務站、或者聯盟網站的帳號,便可以跨站關注此站使用者,或者與他們互動。"
|
||||||
landing_strip_signup_html: 如果您沒有這些帳號,歡迎在<a href="%{sign_up_path}">這裡註冊</a>。
|
landing_strip_signup_html: 如果您沒有這些帳號,歡迎在<a href="%{sign_up_path}">這裡註冊</a>。
|
||||||
@ -231,15 +243,26 @@ zh-TW:
|
|||||||
missing_resource: 無法找到資源
|
missing_resource: 無法找到資源
|
||||||
proceed: 下一步
|
proceed: 下一步
|
||||||
prompt: 您希望關注︰
|
prompt: 您希望關注︰
|
||||||
|
sessions:
|
||||||
|
activity: 最近活動
|
||||||
|
browser: 瀏覽器
|
||||||
|
current_session: 目前的 session
|
||||||
|
description: "%{platform} 上的 %{browser}"
|
||||||
|
explanation: 這些是現在正登入於你的 Mastodon 帳號的瀏覽器。
|
||||||
|
revoke: 取消
|
||||||
|
revoke_success: Session 取消成功。
|
||||||
settings:
|
settings:
|
||||||
authorized_apps: 已授權應用程式
|
authorized_apps: 已授權應用程式
|
||||||
back: 回到 Mastodon
|
back: 回到 Mastodon
|
||||||
|
development: 開發
|
||||||
edit_profile: 修改個人資料
|
edit_profile: 修改個人資料
|
||||||
export: 匯出
|
export: 匯出
|
||||||
|
followers: 授權追蹤者
|
||||||
import: 匯入
|
import: 匯入
|
||||||
|
notifications: 通知
|
||||||
preferences: 偏好設定
|
preferences: 偏好設定
|
||||||
settings: 設定
|
settings: 設定
|
||||||
two_factor_authentication: 雙因子認證
|
two_factor_authentication: 兩階段認證
|
||||||
statuses:
|
statuses:
|
||||||
open_in_web: 以網頁開啟
|
open_in_web: 以網頁開啟
|
||||||
over_character_limit: 超過了 %{max} 字的限制
|
over_character_limit: 超過了 %{max} 字的限制
|
||||||
@ -257,14 +280,14 @@ zh-TW:
|
|||||||
default: "%Y年%-m月%d日 %H:%M"
|
default: "%Y年%-m月%d日 %H:%M"
|
||||||
two_factor_authentication:
|
two_factor_authentication:
|
||||||
code_hint: 請輸入您認證器產生的代碼,以進行認證
|
code_hint: 請輸入您認證器產生的代碼,以進行認證
|
||||||
description_html: 當您啟用<strong>雙因子認證</strong>後,您登入時將需要使您手機、或其他種類認證器產生的代碼。
|
description_html: 啟用<strong>兩階段認證</strong>後,登入時將需要使手機、或其他種類認證器產生的代碼。
|
||||||
disable: 停用
|
disable: 停用
|
||||||
enable: 啟用
|
enable: 啟用
|
||||||
enabled_success: 已成功啟用雙因子認證
|
enabled_success: 已成功啟用兩階段認證
|
||||||
instructions_html: "<strong>請用您手機的認證器應用程式(如 Google Authenticator、Authy),掃描這裡的 QR 圖形碼</strong>。在雙因子認證啟用後,您登入時將須要使用此應用程式產生的認證碼。"
|
instructions_html: "<strong>請用您手機的認證器應用程式(如 Google Authenticator、Authy),掃描這裡的 QR 圖形碼</strong>。在兩階段認證啟用後,您登入時將須要使用此應用程式產生的認證碼。"
|
||||||
manual_instructions: 如果您無法掃描 QR 圖形碼,請手動輸入︰
|
manual_instructions: 如果您無法掃描 QR 圖形碼,請手動輸入︰
|
||||||
setup: 設定
|
setup: 設定
|
||||||
wrong_code: 您輸入的認證碼並不正確!可能伺服器時間和您手機不一致,請檢查您手機的時間,或與本站管理員聯絡。
|
wrong_code: 您輸入的認證碼並不正確!可能伺服器時間和您手機不一致,請檢查您手機的時間,或與本站管理員聯絡。
|
||||||
users:
|
users:
|
||||||
invalid_email: 信箱地址格式不正確
|
invalid_email: 信箱地址格式不正確
|
||||||
invalid_otp_token: 雙因子認證碼不正確
|
invalid_otp_token: 兩階段認證碼不正確
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
class AddIndexOnStreamEntries < ActiveRecord::Migration[5.1]
|
class AddIndexOnStreamEntries < ActiveRecord::Migration[5.1]
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
def change
|
def change
|
||||||
commit_db_transaction
|
|
||||||
add_index :stream_entries, [:account_id, :activity_type, :id], algorithm: :concurrently
|
add_index :stream_entries, [:account_id, :activity_type, :id], algorithm: :concurrently
|
||||||
remove_index :stream_entries, name: :index_stream_entries_on_account_id
|
remove_index :stream_entries, name: :index_stream_entries_on_account_id
|
||||||
end
|
end
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
class MoreFasterIndexOnNotifications < ActiveRecord::Migration[5.1]
|
class MoreFasterIndexOnNotifications < ActiveRecord::Migration[5.1]
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
def change
|
def change
|
||||||
commit_db_transaction
|
|
||||||
add_index :notifications, [:account_id, :id], order: { id: :desc }, algorithm: :concurrently
|
add_index :notifications, [:account_id, :id], order: { id: :desc }, algorithm: :concurrently
|
||||||
remove_index :notifications, name: :index_notifications_on_id_and_account_id_and_activity_type
|
remove_index :notifications, name: :index_notifications_on_id_and_account_id_and_activity_type
|
||||||
end
|
end
|
||||||
|
@ -13,7 +13,7 @@ module Mastodon
|
|||||||
end
|
end
|
||||||
|
|
||||||
def patch
|
def patch
|
||||||
0
|
1
|
||||||
end
|
end
|
||||||
|
|
||||||
def pre
|
def pre
|
||||||
|
@ -12,20 +12,40 @@ describe Auth::ConfirmationsController, type: :controller do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET #show' do
|
describe 'GET #show' do
|
||||||
let!(:user) { Fabricate(:user, confirmation_token: 'foobar', confirmed_at: nil) }
|
context 'when user is unconfirmed' do
|
||||||
|
let!(:user) { Fabricate(:user, confirmation_token: 'foobar', confirmed_at: nil) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(BootstrapTimelineWorker).to receive(:perform_async)
|
allow(BootstrapTimelineWorker).to receive(:perform_async)
|
||||||
@request.env['devise.mapping'] = Devise.mappings[:user]
|
@request.env['devise.mapping'] = Devise.mappings[:user]
|
||||||
get :show, params: { confirmation_token: 'foobar' }
|
get :show, params: { confirmation_token: 'foobar' }
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'redirects to login' do
|
||||||
|
expect(response).to redirect_to(new_user_session_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'queues up bootstrapping of home timeline' do
|
||||||
|
expect(BootstrapTimelineWorker).to have_received(:perform_async).with(user.account_id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'redirects to login' do
|
context 'when user is updating email' do
|
||||||
expect(response).to redirect_to(new_user_session_path)
|
let!(:user) { Fabricate(:user, confirmation_token: 'foobar', unconfirmed_email: 'new-email@example.com') }
|
||||||
end
|
|
||||||
|
|
||||||
it 'queues up bootstrapping of home timeline' do
|
before do
|
||||||
expect(BootstrapTimelineWorker).to have_received(:perform_async).with(user.account_id)
|
allow(BootstrapTimelineWorker).to receive(:perform_async)
|
||||||
|
@request.env['devise.mapping'] = Devise.mappings[:user]
|
||||||
|
get :show, params: { confirmation_token: 'foobar' }
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'redirects to login' do
|
||||||
|
expect(response).to redirect_to(new_user_session_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not queue up bootstrapping of home timeline' do
|
||||||
|
expect(BootstrapTimelineWorker).to_not have_received(:perform_async)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -148,6 +148,14 @@ RSpec.describe User, type: :model do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#confirm' do
|
||||||
|
it 'sets email to unconfirmed_email' do
|
||||||
|
user = Fabricate.build(:user, confirmed_at: Time.now.utc, unconfirmed_email: 'new-email@example.com')
|
||||||
|
user.confirm
|
||||||
|
expect(user.email).to eq 'new-email@example.com'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#disable_two_factor!' do
|
describe '#disable_two_factor!' do
|
||||||
it 'saves false for otp_required_for_login' do
|
it 'saves false for otp_required_for_login' do
|
||||||
user = Fabricate.build(:user, otp_required_for_login: true)
|
user = Fabricate.build(:user, otp_required_for_login: true)
|
||||||
|
Loading…
Reference in New Issue
Block a user