Merge commit 'a36b59be8ad7656b7ceab9751c9ec5b3563e3a30' into glitch-soc/merge-upstream

pull/2522/head
Claire 2023-12-18 19:10:43 +01:00
commit d6ad9d351e
113 changed files with 1438 additions and 1047 deletions

3
.watchmanconfig Normal file
View File

@ -0,0 +1,3 @@
{
"ignore_dirs": ["node_modules/", "public/"]
}

View File

@ -39,50 +39,51 @@ GIT
GEM
remote: https://rubygems.org/
specs:
actioncable (7.1.1)
actionpack (= 7.1.1)
activesupport (= 7.1.1)
actioncable (7.1.2)
actionpack (= 7.1.2)
activesupport (= 7.1.2)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
actionmailbox (7.1.1)
actionpack (= 7.1.1)
activejob (= 7.1.1)
activerecord (= 7.1.1)
activestorage (= 7.1.1)
activesupport (= 7.1.1)
actionmailbox (7.1.2)
actionpack (= 7.1.2)
activejob (= 7.1.2)
activerecord (= 7.1.2)
activestorage (= 7.1.2)
activesupport (= 7.1.2)
mail (>= 2.7.1)
net-imap
net-pop
net-smtp
actionmailer (7.1.1)
actionpack (= 7.1.1)
actionview (= 7.1.1)
activejob (= 7.1.1)
activesupport (= 7.1.1)
actionmailer (7.1.2)
actionpack (= 7.1.2)
actionview (= 7.1.2)
activejob (= 7.1.2)
activesupport (= 7.1.2)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.2)
actionpack (7.1.1)
actionview (= 7.1.1)
activesupport (= 7.1.1)
actionpack (7.1.2)
actionview (= 7.1.2)
activesupport (= 7.1.2)
nokogiri (>= 1.8.5)
racc
rack (>= 2.2.4)
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
actiontext (7.1.1)
actionpack (= 7.1.1)
activerecord (= 7.1.1)
activestorage (= 7.1.1)
activesupport (= 7.1.1)
actiontext (7.1.2)
actionpack (= 7.1.2)
activerecord (= 7.1.2)
activestorage (= 7.1.2)
activesupport (= 7.1.2)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.1.1)
activesupport (= 7.1.1)
actionview (7.1.2)
activesupport (= 7.1.2)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
@ -92,22 +93,22 @@ GEM
activemodel (>= 4.1)
case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
activejob (7.1.1)
activesupport (= 7.1.1)
activejob (7.1.2)
activesupport (= 7.1.2)
globalid (>= 0.3.6)
activemodel (7.1.1)
activesupport (= 7.1.1)
activerecord (7.1.1)
activemodel (= 7.1.1)
activesupport (= 7.1.1)
activemodel (7.1.2)
activesupport (= 7.1.2)
activerecord (7.1.2)
activemodel (= 7.1.2)
activesupport (= 7.1.2)
timeout (>= 0.4.0)
activestorage (7.1.1)
actionpack (= 7.1.1)
activejob (= 7.1.1)
activerecord (= 7.1.1)
activesupport (= 7.1.1)
activestorage (7.1.2)
actionpack (= 7.1.2)
activejob (= 7.1.2)
activerecord (= 7.1.2)
activesupport (= 7.1.2)
marcel (~> 1.0)
activesupport (7.1.1)
activesupport (7.1.2)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
@ -218,7 +219,7 @@ GEM
activerecord (>= 5.a)
database_cleaner-core (~> 2.0.0)
database_cleaner-core (2.0.1)
date (3.3.3)
date (3.3.4)
debug_inspector (1.1.0)
devise (4.9.3)
bcrypt (~> 3.0)
@ -369,7 +370,7 @@ GEM
terminal-table (>= 1.5.1)
idn-ruby (0.1.5)
io-console (0.6.0)
irb (1.8.1)
irb (1.8.3)
rdoc
reline (>= 0.3.8)
jmespath (1.6.2)
@ -462,13 +463,13 @@ GEM
uri
net-http-persistent (4.0.2)
connection_pool (~> 2.2)
net-imap (0.4.1)
net-imap (0.4.4)
date
net-protocol
net-ldap (0.18.0)
net-pop (0.1.2)
net-protocol
net-protocol (0.2.1)
net-protocol (0.2.2)
timeout
net-smtp (0.4.0)
net-protocol
@ -526,7 +527,7 @@ GEM
net-smtp
premailer (~> 1.7, >= 1.7.9)
private_address_check (0.5.0)
psych (5.1.1)
psych (5.1.1.1)
stringio
public_suffix (5.0.3)
puma (6.4.0)
@ -557,20 +558,20 @@ GEM
rackup (1.0.0)
rack (< 3)
webrick
rails (7.1.1)
actioncable (= 7.1.1)
actionmailbox (= 7.1.1)
actionmailer (= 7.1.1)
actionpack (= 7.1.1)
actiontext (= 7.1.1)
actionview (= 7.1.1)
activejob (= 7.1.1)
activemodel (= 7.1.1)
activerecord (= 7.1.1)
activestorage (= 7.1.1)
activesupport (= 7.1.1)
rails (7.1.2)
actioncable (= 7.1.2)
actionmailbox (= 7.1.2)
actionmailer (= 7.1.2)
actionpack (= 7.1.2)
actiontext (= 7.1.2)
actionview (= 7.1.2)
activejob (= 7.1.2)
activemodel (= 7.1.2)
activerecord (= 7.1.2)
activestorage (= 7.1.2)
activesupport (= 7.1.2)
bundler (>= 1.15.0)
railties (= 7.1.1)
railties (= 7.1.2)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
actionview (>= 5.0.1.rc1)
@ -585,9 +586,9 @@ GEM
rails-i18n (7.0.8)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
railties (7.1.1)
actionpack (= 7.1.1)
activesupport (= 7.1.1)
railties (7.1.2)
actionpack (= 7.1.2)
activesupport (= 7.1.2)
irb
rackup (>= 1.0.0)
rake (>= 12.2)
@ -737,7 +738,7 @@ GEM
statsd-ruby (1.5.0)
stoplight (3.0.2)
redlock (~> 1.0)
stringio (3.0.8)
stringio (3.0.9)
strong_migrations (1.6.4)
activerecord (>= 5.2)
swd (1.3.0)
@ -753,7 +754,7 @@ GEM
test-prof (1.2.3)
thor (1.3.0)
tilt (2.3.0)
timeout (0.4.0)
timeout (0.4.1)
tpm-key_attestation (0.12.0)
bindata (~> 2.4)
openssl (> 2.0)

View File

@ -53,7 +53,7 @@ class PublicStatusesIndex < Chewy::Index
index_scope ::Status.unscoped
.kept
.indexable
.includes(:media_attachments, :preloadable_poll, :preview_cards, :tags)
.includes(:media_attachments, :preloadable_poll, :tags, preview_cards_status: :preview_card)
root date_detection: false do
field(:id, type: 'long')

View File

@ -50,7 +50,7 @@ class StatusesIndex < Chewy::Index
},
}
index_scope ::Status.unscoped.kept.without_reblogs.includes(:media_attachments, :preview_cards, :local_mentioned, :local_favorited, :local_reblogged, :local_bookmarked, :tags, preloadable_poll: :local_voters), delete_if: ->(status) { status.searchable_by.empty? }
index_scope ::Status.unscoped.kept.without_reblogs.includes(:media_attachments, :local_mentioned, :local_favorited, :local_reblogged, :local_bookmarked, :tags, preview_cards_status: :preview_card, preloadable_poll: :local_voters), delete_if: ->(status) { status.searchable_by.empty? }
root date_detection: false do
field(:id, type: 'long')

View File

@ -1,6 +1,8 @@
# frozen_string_literal: true
class Api::V1::AccountsController < Api::BaseController
include RegistrationHelper
before_action -> { authorize_if_got_token! :read, :'read:accounts' }, except: [:create, :follow, :unfollow, :remove_from_followers, :block, :unblock, :mute, :unmute]
before_action -> { doorkeeper_authorize! :follow, :write, :'write:follows' }, only: [:follow, :unfollow, :remove_from_followers]
before_action -> { doorkeeper_authorize! :follow, :write, :'write:mutes' }, only: [:mute, :unmute]
@ -90,18 +92,14 @@ class Api::V1::AccountsController < Api::BaseController
end
def account_params
params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone)
params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone, :invite_code)
end
def invite
Invite.find_by(code: params[:invite_code]) if params[:invite_code].present?
end
def check_enabled_registrations
forbidden if single_user_mode? || omniauth_only? || !allowed_registrations?
end
def allowed_registrations?
Setting.registrations_mode != 'none'
end
def omniauth_only?
ENV['OMNIAUTH_ONLY'] == 'true'
forbidden unless allowed_registration?(request.remote_ip, invite)
end
end

View File

@ -41,10 +41,10 @@ class Api::V1::ConversationsController < Api::BaseController
account: :account_stat,
last_status: [
:media_attachments,
:preview_cards,
:status_stat,
:tags,
{
preview_cards_status: :preview_card,
active_mentions: [account: :account_stat],
account: :account_stat,
},

View File

@ -1,12 +1,8 @@
# frozen_string_literal: true
class Api::V1::Instances::ActivityController < Api::BaseController
class Api::V1::Instances::ActivityController < Api::V1::Instances::BaseController
before_action :require_enabled_api!
skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
vary_by ''
def show
cache_even_if_authenticated!
render_with_cache json: :activity, expires_in: 1.day

View File

@ -0,0 +1,8 @@
# frozen_string_literal: true
class Api::V1::Instances::BaseController < Api::BaseController
skip_before_action :require_authenticated_user!,
unless: :limited_federation_mode?
vary_by ''
end

View File

@ -1,8 +1,6 @@
# frozen_string_literal: true
class Api::V1::Instances::DomainBlocksController < Api::BaseController
skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
class Api::V1::Instances::DomainBlocksController < Api::V1::Instances::BaseController
before_action :require_enabled_api!
before_action :set_domain_blocks

View File

@ -1,13 +1,10 @@
# frozen_string_literal: true
class Api::V1::Instances::ExtendedDescriptionsController < Api::BaseController
skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
class Api::V1::Instances::ExtendedDescriptionsController < Api::V1::Instances::BaseController
skip_around_action :set_locale
before_action :set_extended_description
vary_by ''
# Override `current_user` to avoid reading session cookies unless in whitelist mode
def current_user
super if limited_federation_mode?

View File

@ -1,13 +1,10 @@
# frozen_string_literal: true
class Api::V1::Instances::LanguagesController < Api::BaseController
skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
class Api::V1::Instances::LanguagesController < Api::V1::Instances::BaseController
skip_around_action :set_locale
before_action :set_languages
vary_by ''
def show
cache_even_if_authenticated!
render json: @languages, each_serializer: REST::LanguageSerializer

View File

@ -1,13 +1,10 @@
# frozen_string_literal: true
class Api::V1::Instances::PeersController < Api::BaseController
class Api::V1::Instances::PeersController < Api::V1::Instances::BaseController
before_action :require_enabled_api!
skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
skip_around_action :set_locale
vary_by ''
# Override `current_user` to avoid reading session cookies unless in whitelist mode
def current_user
super if limited_federation_mode?

View File

@ -1,12 +1,8 @@
# frozen_string_literal: true
class Api::V1::Instances::PrivacyPoliciesController < Api::BaseController
skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
class Api::V1::Instances::PrivacyPoliciesController < Api::V1::Instances::BaseController
before_action :set_privacy_policy
vary_by ''
def show
cache_even_if_authenticated!
render json: @privacy_policy, serializer: REST::PrivacyPolicySerializer

View File

@ -1,13 +1,10 @@
# frozen_string_literal: true
class Api::V1::Instances::RulesController < Api::BaseController
skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
class Api::V1::Instances::RulesController < Api::V1::Instances::BaseController
skip_around_action :set_locale
before_action :set_rules
vary_by ''
# Override `current_user` to avoid reading session cookies unless in whitelist mode
def current_user
super if limited_federation_mode?

View File

@ -1,12 +1,8 @@
# frozen_string_literal: true
class Api::V1::Instances::TranslationLanguagesController < Api::BaseController
skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
class Api::V1::Instances::TranslationLanguagesController < Api::V1::Instances::BaseController
before_action :set_languages
vary_by ''
def show
cache_even_if_authenticated!
render json: @languages

View File

@ -0,0 +1,30 @@
# frozen_string_literal: true
class Api::V1::InvitesController < Api::BaseController
include RegistrationHelper
skip_before_action :require_authenticated_user!
skip_around_action :set_locale
before_action :set_invite
before_action :check_enabled_registrations!
# Override `current_user` to avoid reading session cookies
def current_user; end
def show
render json: { invite_code: params[:invite_code], instance_api_url: api_v2_instance_url }, status: 200
end
private
def set_invite
@invite = Invite.find_by!(code: params[:invite_code])
end
def check_enabled_registrations!
return render json: { error: I18n.t('invites.invalid') }, status: 401 unless @invite.valid_for_use?
raise Mastodon::NotPermittedError unless allowed_registration?(request.remote_ip, @invite)
end
end

View File

@ -1,6 +1,7 @@
# frozen_string_literal: true
class Auth::RegistrationsController < Devise::RegistrationsController
include RegistrationHelper
include RegistrationSpamConcern
layout :determine_layout
@ -83,19 +84,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
end
def check_enabled_registrations
redirect_to root_path if single_user_mode? || omniauth_only? || !allowed_registrations? || ip_blocked?
end
def allowed_registrations?
Setting.registrations_mode != 'none' || @invite&.valid_for_use?
end
def omniauth_only?
ENV['OMNIAUTH_ONLY'] == 'true'
end
def ip_blocked?
IpBlock.where(severity: :sign_up_block).where('ip >>= ?', request.remote_ip.to_s).exists?
redirect_to root_path unless allowed_registration?(request.remote_ip, @invite)
end
def invite_code

View File

@ -0,0 +1,21 @@
# frozen_string_literal: true
module RegistrationHelper
extend ActiveSupport::Concern
def allowed_registration?(remote_ip, invite)
!Rails.configuration.x.single_user_mode && !omniauth_only? && (registrations_open? || invite&.valid_for_use?) && !ip_blocked?(remote_ip)
end
def registrations_open?
Setting.registrations_mode != 'none'
end
def omniauth_only?
ENV['OMNIAUTH_ONLY'] == 'true'
end
def ip_blocked?(remote_ip)
IpBlock.where(severity: :sign_up_block).exists?(['ip >>= ?', remote_ip.to_s])
end
end

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Вынікі пошуку",
"emoji_button.symbols": "Сімвалы",
"emoji_button.travel": "Падарожжы і месцы",
"empty_column.account_hides_collections": "Гэты карыстальнік вырашыў схаваць гэтую інфармацыю",
"empty_column.account_suspended": "Уліковы запіс прыпынены",
"empty_column.account_timeline": "Тут няма допісаў!",
"empty_column.account_unavailable": "Профіль недаступны",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Canlyniadau chwilio",
"emoji_button.symbols": "Symbolau",
"emoji_button.travel": "Teithio a Llefydd",
"empty_column.account_hides_collections": "Mae'r defnyddiwr wedi dewis i beidio rhannu'r wybodaeth yma",
"empty_column.account_suspended": "Cyfrif wedi'i atal",
"empty_column.account_timeline": "Dim postiadau yma!",
"empty_column.account_unavailable": "Nid yw'r proffil ar gael",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Søgeresultater",
"emoji_button.symbols": "Symboler",
"emoji_button.travel": "Rejser og steder",
"empty_column.account_hides_collections": "Brugeren har valgt ikke at gøre denne information tilgængelig",
"empty_column.account_suspended": "Konto suspenderet",
"empty_column.account_timeline": "Ingen indlæg hér!",
"empty_column.account_unavailable": "Profil utilgængelig",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Suchergebnisse",
"emoji_button.symbols": "Symbole",
"emoji_button.travel": "Reisen & Orte",
"empty_column.account_hides_collections": "Das Konto hat sich dazu entschieden, diese Information nicht zu veröffentlichen",
"empty_column.account_suspended": "Konto gesperrt",
"empty_column.account_timeline": "Keine Beiträge vorhanden!",
"empty_column.account_unavailable": "Profil nicht verfügbar",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Resultados de búsqueda",
"emoji_button.symbols": "Símbolos",
"emoji_button.travel": "Viajes y lugares",
"empty_column.account_hides_collections": "Este usuario eligió no publicar esta información",
"empty_column.account_suspended": "Cuenta suspendida",
"empty_column.account_timeline": "¡No hay mensajes acá!",
"empty_column.account_unavailable": "Perfil no disponible",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Resultados de búsqueda",
"emoji_button.symbols": "Símbolos",
"emoji_button.travel": "Viajes y lugares",
"empty_column.account_hides_collections": "Este usuario ha elegido no hacer disponible esta información",
"empty_column.account_suspended": "Cuenta suspendida",
"empty_column.account_timeline": "¡No hay toots aquí!",
"empty_column.account_unavailable": "Perfil no disponible",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Resultados de búsqueda",
"emoji_button.symbols": "Símbolos",
"emoji_button.travel": "Viajes y lugares",
"empty_column.account_hides_collections": "Este usuario ha decidido no mostrar esta información",
"empty_column.account_suspended": "Cuenta suspendida",
"empty_column.account_timeline": "¡No hay publicaciones aquí!",
"empty_column.account_unavailable": "Perfil no disponible",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Otsitulemused",
"emoji_button.symbols": "Sümbolid",
"emoji_button.travel": "Reisimine & kohad",
"empty_column.account_hides_collections": "See kasutaja otsustas mitte teha seda infot saadavaks",
"empty_column.account_suspended": "Konto kustutatud",
"empty_column.account_timeline": "Siin postitusi ei ole!",
"empty_column.account_unavailable": "Profiil pole saadaval",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Bilaketaren emaitzak",
"emoji_button.symbols": "Sinboloak",
"emoji_button.travel": "Bidaiak eta tokiak",
"empty_column.account_hides_collections": "Erabiltzaile honek informazio hau erabilgarri ez egotea aukeratu du.",
"empty_column.account_suspended": "Kanporatutako kontua",
"empty_column.account_timeline": "Ez dago bidalketarik hemen!",
"empty_column.account_unavailable": "Profila ez dago eskuragarri",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "نتایج جست‌وجو",
"emoji_button.symbols": "نمادها",
"emoji_button.travel": "سفر و مکان",
"empty_column.account_hides_collections": "کاربر خواسته که این اطّلاعات در دسترس نباشند",
"empty_column.account_suspended": "حساب معلق شد",
"empty_column.account_timeline": "هیچ فرسته‌ای این‌جا نیست!",
"empty_column.account_unavailable": "نمایهٔ موجود نیست",
@ -358,13 +359,13 @@
"keyboard_shortcuts.profile": "گشودن نمایهٔ نویسنده",
"keyboard_shortcuts.reply": "پاسخ به فرسته",
"keyboard_shortcuts.requests": "گشودن سیاههٔ درخواست‌های پی‌گیری",
"keyboard_shortcuts.search": "تمرکز روی جست‌وجو",
"keyboard_shortcuts.search": "تمرکز روی نوار جست‌وجو",
"keyboard_shortcuts.spoilers": "نمایش/نهفتن زمینهٔ هشدار محتوا",
"keyboard_shortcuts.start": "گشودن ستون «آغاز کنید»",
"keyboard_shortcuts.toggle_hidden": "نمایش/نهفتن نوشتهٔ پشت هشدار محتوا",
"keyboard_shortcuts.toggle_sensitivity": "نمایش/نهفتن رسانه",
"keyboard_shortcuts.toot": "شروع یک فرستهٔ جدید",
"keyboard_shortcuts.unfocus": "برداشتن تمرکز از نوشتن/جست‌وجو",
"keyboard_shortcuts.unfocus": "برداشتن تمرکز از ناحیهٔ نوشتن یا جست‌وجو",
"keyboard_shortcuts.up": "بالا بردن در سیاهه",
"lightbox.close": "بستن",
"lightbox.compress": "فشرده‌سازی جعبهٔ نمایش تصویر",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Hakutulokset",
"emoji_button.symbols": "Symbolit",
"emoji_button.travel": "Matkailu ja paikat",
"empty_column.account_hides_collections": "Käyttäjä on päättänyt olla julkaisematta näitä tietoja",
"empty_column.account_suspended": "Tili jäädytetty",
"empty_column.account_timeline": "Ei viestejä täällä.",
"empty_column.account_unavailable": "Profiilia ei löydy",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Leitiúrslit",
"emoji_button.symbols": "Ímyndir",
"emoji_button.travel": "Ferðing og støð",
"empty_column.account_hides_collections": "Hesin brúkarin hevur valt, at hesar upplýsingarnar ikki skulu vera tøkar",
"empty_column.account_suspended": "Kontan gjørd óvirkin",
"empty_column.account_timeline": "Einki uppslag her!",
"empty_column.account_unavailable": "Vangin er ikki tøkur",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Résultats",
"emoji_button.symbols": "Symboles",
"emoji_button.travel": "Voyage et lieux",
"empty_column.account_hides_collections": "Cet utilisateur·ice préfère ne pas rendre publiques ces informations",
"empty_column.account_suspended": "Compte suspendu",
"empty_column.account_timeline": "Aucune publication ici!",
"empty_column.account_unavailable": "Profil non disponible",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Résultats de la recherche",
"emoji_button.symbols": "Symboles",
"emoji_button.travel": "Voyage et lieux",
"empty_column.account_hides_collections": "Cet utilisateur·ice préfère ne pas rendre publiques ces informations",
"empty_column.account_suspended": "Compte suspendu",
"empty_column.account_timeline": "Aucun message ici !",
"empty_column.account_unavailable": "Profil non disponible",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Resultados da procura",
"emoji_button.symbols": "Símbolos",
"emoji_button.travel": "Viaxes e Lugares",
"empty_column.account_hides_collections": "A usuaria decideu non facer pública esta información",
"empty_column.account_suspended": "Conta suspendida",
"empty_column.account_timeline": "Non hai publicacións aquí!",
"empty_column.account_unavailable": "Perfil non dispoñible",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "תוצאות חיפוש",
"emoji_button.symbols": "סמלים",
"emoji_button.travel": "טיולים ואתרים",
"empty_column.account_hides_collections": "המשתמש.ת בחר.ה להסתיר מידע זה",
"empty_column.account_suspended": "חשבון מושהה",
"empty_column.account_timeline": "אין עדיין אף הודעה!",
"empty_column.account_unavailable": "פרופיל לא זמין",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Keresési találatok",
"emoji_button.symbols": "Szimbólumok",
"emoji_button.travel": "Utazás és Helyek",
"empty_column.account_hides_collections": "Ez a felhasználó úgy döntött, hogy nem teszi elérhetővé ezt az információt.",
"empty_column.account_suspended": "Fiók felfüggesztve",
"empty_column.account_timeline": "Itt nincs bejegyzés!",
"empty_column.account_unavailable": "A profil nem érhető el",

View File

@ -1,8 +1,11 @@
{
"account.add_or_remove_from_list": "Tinye ma ọ bụ Wepu na ndepụta",
"account.badges.bot": "Bot",
"account.badges.group": "Otù",
"account.cancel_follow_request": "Withdraw follow request",
"account.follow": "Soro",
"account.followers": "Ndị na-eso",
"account.following": "Na-eso",
"account.follows_you": "Na-eso gị",
"account.mute": "Mee ogbi @{name}",
"account.unfollow": "Kwụsị iso",
@ -11,16 +14,20 @@
"audio.hide": "Zoo ụda",
"bundle_column_error.retry": "Nwaa ọzọ",
"bundle_column_error.routing.title": "404",
"bundle_modal_error.close": "Mechie",
"bundle_modal_error.retry": "Nwaa ọzọ",
"column.about": "Maka",
"column.blocks": "Ojiarụ egbochiri",
"column.bookmarks": "Ebenrụtụakā",
"column.home": "Be",
"column.lists": "Ndepụta",
"column.pins": "Pinned post",
"column_header.pin": "Gbado na profaịlụ gị",
"column_subheading.settings": "Mwube",
"community.column_settings.media_only": "Media only",
"compose.language.change": "Gbanwee asụsụ",
"compose.language.search": "Chọọ asụsụ...",
"compose.published.open": "Mepe",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.placeholder": "What is on your mind?",
@ -32,7 +39,10 @@
"confirmations.delete.message": "Are you sure you want to delete this status?",
"confirmations.delete_list.confirm": "Hichapụ",
"confirmations.domain_block.confirm": "Hide entire domain",
"confirmations.edit.confirm": "Dezie",
"confirmations.mute.confirm": "Mee ogbi",
"confirmations.reply.confirm": "Zaa",
"confirmations.unfollow.confirm": "Kwụsị iso",
"conversation.delete": "Hichapụ nkata",
"dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.",
"dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.",
@ -76,6 +86,7 @@
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
"keyboard_shortcuts.up": "to move up in the list",
"lists.delete": "Hichapụ ndepụta",
"lists.edit": "Dezie ndepụta",
"lists.subheading": "Ndepụta gị",
"loading_indicator.label": "Na-adọnye...",
"navigation_bar.about": "Maka",
@ -100,20 +111,27 @@
"privacy.change": "Adjust status privacy",
"privacy.direct.short": "Direct",
"privacy.private.short": "Followers-only",
"relative_time.full.just_now": "kịta",
"relative_time.just_now": "kịta",
"relative_time.today": "taa",
"reply_indicator.cancel": "Kagbuo",
"report.categories.other": "Ọzọ",
"report.categories.spam": "Nzipụ Ozièlètrọniìk Nkeāchọghị",
"report.mute": "Mee ogbi",
"report.placeholder": "Type or paste additional comments",
"report.submit": "Submit report",
"report.target": "Report {target}",
"report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached",
"report_notification.categories.other": "Ọzọ",
"search.placeholder": "Chọọ",
"server_banner.active_users": "ojiarụ dị ìrè",
"server_banner.learn_more": "Mụtakwuo",
"sign_in_banner.sign_in": "Sign in",
"status.admin_status": "Open this status in the moderation interface",
"status.bookmark": "Kee ebenrụtụakā",
"status.copy": "Copy link to status",
"status.delete": "Hichapụ",
"status.edit": "Dezie",
"status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}",
"status.open": "Expand this status",
"status.remove_bookmark": "Wepu ebenrụtụakā",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Leitarniðurstöður",
"emoji_button.symbols": "Tákn",
"emoji_button.travel": "Ferðalög og staðir",
"empty_column.account_hides_collections": "Notandinn hefur valið að gera ekki tiltækar þessar upplýsingar",
"empty_column.account_suspended": "Notandaaðgangur í frysti",
"empty_column.account_timeline": "Engar færslur hér!",
"empty_column.account_unavailable": "Notandasnið ekki tiltækt",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Risultati della ricerca",
"emoji_button.symbols": "Simboli",
"emoji_button.travel": "Viaggi & Luoghi",
"empty_column.account_hides_collections": "Questo utente ha scelto di non rendere disponibili queste informazioni",
"empty_column.account_suspended": "Profilo sospeso",
"empty_column.account_timeline": "Nessun post qui!",
"empty_column.account_unavailable": "Profilo non disponibile",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "検索結果",
"emoji_button.symbols": "記号",
"emoji_button.travel": "旅行と場所",
"empty_column.account_hides_collections": "このユーザーはこの情報を開示しないことにしています。",
"empty_column.account_suspended": "アカウントは停止されています",
"empty_column.account_timeline": "投稿がありません!",
"empty_column.account_unavailable": "プロフィールは利用できません",
@ -585,8 +586,8 @@
"search.no_recent_searches": "検索履歴はありません",
"search.placeholder": "検索",
"search.quick_action.account_search": "{x}に該当するプロフィール",
"search.quick_action.go_to_account": "{x}のプロフィールを見る",
"search.quick_action.go_to_hashtag": "{x}に該当するハッシュタグ",
"search.quick_action.go_to_account": "プロフィール {x} を見る",
"search.quick_action.go_to_hashtag": "ハッシュタグ {x} を見る",
"search.quick_action.open_url": "MastodonでURLを開く",
"search.quick_action.status_search": "{x}に該当する投稿",
"search.search_or_paste": "検索またはURLを入力",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "검색 결과",
"emoji_button.symbols": "기호",
"emoji_button.travel": "여행과 장소",
"empty_column.account_hides_collections": "이 사용자는 이 정보를 사용할 수 없도록 설정했습니다",
"empty_column.account_suspended": "계정 정지됨",
"empty_column.account_timeline": "이곳에는 게시물이 없습니다!",
"empty_column.account_unavailable": "프로필 사용 불가",

View File

@ -1,25 +1,46 @@
{
"about.blocks": "Moderatorių prižiūrimi serveriai",
"about.contact": "Kontaktai:",
"about.disclaimer": "Mastodon, tai nemokama, atviro kodo programa, kuriuos prekybinis ženklas priklauso Mastodon GmbH.",
"about.blocks": "Prižiūrimi serveriai",
"about.contact": "Kontaktuoti:",
"about.disclaimer": "Mastodon nemokama atvirojo šaltinio programa ir Mastodon gGmbH prekės ženklas.",
"about.domain_blocks.no_reason_available": "Priežastis nežinoma",
"about.domain_blocks.suspended.title": "Uždraustas",
"about.not_available": "Šiame serveryje informacijos nėra.",
"about.domain_blocks.preamble": "Mastodon paprastai leidžia peržiūrėti turinį ir bendrauti su naudotojais iš bet kurio kito fediverse esančio serverio. Šios yra išimtys, kurios buvo padarytos šiame konkrečiame serveryje.",
"about.domain_blocks.silenced.explanation": "Paprastai nematysi profilių ir turinio iš šio serverio, nebent jį aiškiai ieškosi arba pasirinksi jį sekdamas (-a).",
"about.domain_blocks.silenced.title": "Ribota",
"about.domain_blocks.suspended.explanation": "Jokie duomenys iš šio serverio nebus apdorojami, saugomi ar keičiami, todėl bet kokia sąveika ar bendravimas su šio serverio naudotojais bus neįmanomas.",
"about.domain_blocks.suspended.title": "Uždrausta",
"about.not_available": "Ši informacija nebuvo pateikta šiame serveryje.",
"about.powered_by": "Decentralizuota socialinė žiniasklaida, kurią valdo {mastodon}",
"about.rules": "Serverio taisyklės",
"account.account_note_header": "Pastaba",
"account.add_or_remove_from_list": "Pridėti arba ištrinti iš sąrašo",
"account.badges.bot": "Robotas",
"account.add_or_remove_from_list": "Pridėti arba ištrinti iš sąrašų",
"account.badges.bot": "Automatizuotas",
"account.badges.group": "Grupė",
"account.block": "Užblokuoti @{name}",
"account.block_domain": "Hide everything from {domain}",
"account.block": "Blokuoti @{name}",
"account.block_domain": "Blokuoti domeną {domain}",
"account.block_short": "Blokuoti",
"account.blocked": "Užblokuota",
"account.cancel_follow_request": "Withdraw follow request",
"account.domain_blocked": "Domain hidden",
"account.browse_more_on_origin_server": "Naršyti daugiau originaliame profilyje",
"account.cancel_follow_request": "Atšaukti sekimą",
"account.direct": "Privačiai paminėti @{name}",
"account.disable_notifications": "Nustoti man pranešti, kai @{name} paskelbia",
"account.domain_blocked": "Užblokuotas domenas",
"account.edit_profile": "Redaguoti profilį",
"account.enable_notifications": "Pranešti man, kai @{name} paskelbia",
"account.featured_tags.last_status_at": "Paskutinį kartą paskelbta {date}",
"account.featured_tags.last_status_never": "Nėra įrašų",
"account.follow": "Sekti",
"account.follows_you": "Seka jus",
"account.followers": "Sekėjai",
"account.followers.empty": "Šio naudotojo dar niekas neseka.",
"account.followers_counter": "{count, plural, one {{counter} sekėjas (-a)} few {{counter} sekėjai} many {{counter} sekėjo} other {{counter} sekėjų}}",
"account.following": "Seka",
"account.follows.empty": "Šis naudotojas (-a) dar nieko neseka.",
"account.follows_you": "Seka tave",
"account.go_to_profile": "Eiti į profilį",
"account.in_memoriam": "Atminimui.",
"account.joined_short": "Prisijungė",
"account.media": "Media",
"account.languages": "Keisti prenumeruojamas kalbas",
"account.locked_info": "Šios paskyros privatumo būsena nustatyta kaip užrakinta. Savininkas (-ė) rankiniu būdu peržiūri, kas gali sekti.",
"account.media": "Medija",
"account.mute": "Užtildyti @{name}",
"account.muted": "Užtildytas",
"account.posts": "Toots",
@ -33,6 +54,10 @@
"account.unmute_short": "Atitildyti",
"account_note.placeholder": "Click to add a note",
"alert.unexpected.title": "Oi!",
"announcement.announcement": "Skelbimas",
"audio.hide": "Slėpti garsą",
"autosuggest_hashtag.per_week": "{count} per savaitę",
"bundle_column_error.error.title": "O, ne!",
"column.domain_blocks": "Hidden domains",
"column.lists": "Sąrašai",
"column.mutes": "Užtildyti vartotojai",
@ -43,24 +68,50 @@
"column_header.show_settings": "Rodyti nustatymus",
"column_header.unpin": "Atsegti",
"column_subheading.settings": "Nustatymai",
"community.column_settings.media_only": "Media only",
"community.column_settings.media_only": "Tik medija",
"compose.language.change": "Keisti kalbą",
"compose.language.search": "Ieškoti kalbų...",
"compose.published.body": "Įrašas paskelbtas.",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.placeholder": "What is on your mind?",
"compose_form.publish_form": "Publish",
"compose_form.sensitive.hide": "{count, plural, one {Žymėti mediją kaip jautrią} few {Žymėti medijas kaip jautrias} many {Žymėti medijos kaip jautrios} other {Žymėti medijų kaip jautrių}}",
"compose_form.sensitive.marked": "{count, plural, one {Medija pažymėta kaip jautri} few {Medijos pažymėtos kaip jautrios} many {Medijos pažymėta kaip jautrios} other {Medijų pažymėtos kaip jautrios}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Medija nepažymėta kaip jautri} few {Medijos nepažymėtos kaip jautrios} many {Medijos nepažymėta kaip jautri} other {Medijų nepažymėta kaip jautrios}}",
"compose_form.spoiler.marked": "Text is hidden behind warning",
"compose_form.spoiler.unmarked": "Text is not hidden",
"confirmations.delete.confirm": "Ištrinti",
"confirmations.delete.message": "Are you sure you want to delete this status?",
"confirmations.discard_edit_media.confirm": "Atmesti",
"confirmations.discard_edit_media.message": "Turi neišsaugotų medijos aprašymo ar peržiūros pakeitimų, vis tiek juos atmesti?",
"confirmations.domain_block.confirm": "Hide entire domain",
"confirmations.reply.confirm": "Atsakyti",
"confirmations.reply.message": "Atsakydamas (-a) dabar perrašysi šiuo metu rašomą žinutę. Ar tikrai nori tęsti?",
"confirmations.unfollow.confirm": "Nebesekti",
"dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.",
"dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.",
"embed.instructions": "Embed this status on your website by copying the code below.",
"emoji_button.search": "Paieška...",
"empty_column.account_hides_collections": "Šis naudotojas (-a) pasirinko nepadaryti šią informaciją prieinamą",
"empty_column.account_timeline": "No toots here!",
"empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",
"empty_column.domain_blocks": "There are no hidden domains yet.",
"empty_column.hashtag": "Nėra nieko šiame saitažodyje kol kas.",
"empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}",
"empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
"firehose.local": "Šis serveris",
"follow_requests.unlocked_explanation": "Nors tavo paskyra neužrakinta, {domain} personalas mano, kad galbūt norėsi rankiniu būdu patikrinti šių paskyrų sekimo užklausas.",
"followed_tags": "Sekamos saitažodžiai",
"footer.about": "Apie",
"footer.invite": "Kviesti žmones",
"hashtag.column_settings.tag_toggle": "Include additional tags in this column",
"interaction_modal.no_account_yet": "Nesi Mastodon?",
"interaction_modal.on_another_server": "Kitame serveryje",
"interaction_modal.on_this_server": "Šiame serveryje",
"interaction_modal.sign_in": "Nesi prisijungęs (-usi) prie šio serverio. Kur yra laikoma tavo paskyra?",
"interaction_modal.sign_in_hint": "Patarimas: tai svetainė, kurioje užsiregistravai. Jei neprisimeni, ieškok sveikinimo el. laiško savo pašto dėžutėje. Taip pat gali įvesti visą savo naudotojo vardą (pvz., @Mastodon@mastodon.social).",
"interaction_modal.title.favourite": "Mėgstamiausias {name} įrašas",
"keyboard_shortcuts.back": "to navigate back",
"keyboard_shortcuts.blocked": "to open blocked users list",
"keyboard_shortcuts.boost": "to boost",
@ -72,13 +123,14 @@
"keyboard_shortcuts.federated": "to open federated timeline",
"keyboard_shortcuts.heading": "Keyboard Shortcuts",
"keyboard_shortcuts.home": "to open home timeline",
"keyboard_shortcuts.hotkey": "Spartusis klavišas",
"keyboard_shortcuts.legend": "to display this legend",
"keyboard_shortcuts.local": "to open local timeline",
"keyboard_shortcuts.mention": "to mention author",
"keyboard_shortcuts.muted": "to open muted users list",
"keyboard_shortcuts.my_profile": "to open your profile",
"keyboard_shortcuts.notifications": "to open notifications column",
"keyboard_shortcuts.open_media": "to open media",
"keyboard_shortcuts.open_media": "Atidaryti mediją",
"keyboard_shortcuts.pinned": "to open pinned toots list",
"keyboard_shortcuts.profile": "to open author's profile",
"keyboard_shortcuts.reply": "to reply",
@ -87,21 +139,39 @@
"keyboard_shortcuts.spoilers": "to show/hide CW field",
"keyboard_shortcuts.start": "to open \"get started\" column",
"keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
"keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
"keyboard_shortcuts.toggle_sensitivity": "Rodyti / slėpti mediją",
"keyboard_shortcuts.toot": "to start a brand new toot",
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
"keyboard_shortcuts.up": "to move up in the list",
"lightbox.close": "Uždaryti",
"media_gallery.toggle_visible": "{number, plural, one {Slėpti vaizdą} few {Slėpti vaizdus} many {Slėpti vaizdo} other {Slėpti vaizdų}}",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.follows_and_followers": "Sekimai ir sekėjai",
"navigation_bar.lists": "Sąrašai",
"navigation_bar.logout": "Atsijungti",
"navigation_bar.mutes": "Užtildyti naudotojai",
"navigation_bar.opened_in_classic_interface": "Įrašai, paskyros ir kiti konkretūs puslapiai pagal numatytuosius nustatymus atidaromi klasikinėje žiniatinklio sąsajoje.",
"navigation_bar.personal": "Asmeninis",
"navigation_bar.pins": "Pinned toots",
"navigation_bar.preferences": "Nuostatos",
"not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.",
"notification.own_poll": "Tavo apklausa baigėsi",
"notification.poll": "Apklausa, kurioje balsavai, pasibaigė",
"notification.reblog": "{name} boosted your status",
"notification.status": "{name} ką tik paskelbė",
"notification.update": "{name} redagavo įrašą",
"notifications.clear": "Išvalyti pranešimus",
"notifications.clear_confirmation": "Ar tikrai nori visam laikui išvalyti visus pranešimus?",
"notifications.column_settings.admin.report": "Nauji ataskaitos:",
"notifications.column_settings.status": "New toots:",
"notifications.filter.mentions": "Paminėjimai",
"onboarding.actions.go_to_explore": "See what's trending",
"onboarding.actions.go_to_home": "Go to your home feed",
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
"onboarding.follows.title": "Popular on Mastodon",
"onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:",
"onboarding.share.message": "Aš {username} #Mastodon! Ateik sekti manęs adresu {url}",
"onboarding.start.lead": "Dabar esi Mastodon dalis unikalios decentralizuotos socialinės žiniasklaidos platformos, kurioje tu, o ne algoritmas, pats nustatai savo patirtį. Pradėkime tavo kelionę šioje naujoje socialinėje erdvėje:",
"onboarding.start.skip": "Want to skip right ahead?",
"onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.",
"onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}",
@ -110,11 +180,17 @@
"onboarding.steps.setup_profile.title": "Customize your profile",
"onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!",
"onboarding.steps.share_profile.title": "Share your profile",
"poll.vote": "Balsuoti",
"poll.voted": "Tu balsavai už šį atsakymą",
"poll.votes": "{votes, plural, one {# balsas} few {# balsai} many {# balso} other {# balsų}}",
"privacy.change": "Adjust status privacy",
"privacy.direct.long": "Post to mentioned users only",
"privacy.direct.short": "Direct",
"privacy.private.long": "Post to followers only",
"privacy.private.short": "Followers-only",
"privacy.unlisted.long": "Matomas visiems, bet atsisakyta atradimo funkcijų",
"privacy.unlisted.short": "Neįtrauktas į sąrašą",
"privacy_policy.last_updated": "Paskutinį kartą atnaujinta {date}",
"report.placeholder": "Type or paste additional comments",
"report.submit": "Submit report",
"report.target": "Report {target}",
@ -124,14 +200,19 @@
"status.admin_status": "Open this status in the moderation interface",
"status.copy": "Copy link to status",
"status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}",
"status.media.open": "Spausk, kad atidaryti",
"status.media.show": "Spausk, kad pamatyti",
"status.media_hidden": "Paslėpta medija",
"status.open": "Expand this status",
"status.pinned": "Pinned toot",
"status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
"status.title.with_attachments": "{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}",
"status.uncached_media_warning": "Peržiūra nepasiekiama",
"timeline_hint.resources.statuses": "Older toots",
"trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}",
"upload_form.audio_description": "Describe for people with hearing loss",
"upload_form.description": "Describe for the visually impaired",
"upload_form.video_description": "Describe for people with hearing loss or visual impairment",
"upload_modal.edit_media": "Redaguoti mediją",
"upload_progress.label": "Uploading…"
}

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Meklēšanas rezultāti",
"emoji_button.symbols": "Simboli",
"emoji_button.travel": "Ceļošana un vietas",
"empty_column.account_hides_collections": "Šis lietotājs ir izvēlējies nedarīt šo informāciju pieejamu",
"empty_column.account_suspended": "Konta darbība ir apturēta",
"empty_column.account_timeline": "Šeit ziņojumu nav!",
"empty_column.account_unavailable": "Profils nav pieejams",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Zoekresultaten",
"emoji_button.symbols": "Symbolen",
"emoji_button.travel": "Reizen en locaties",
"empty_column.account_hides_collections": "Deze gebruiker heeft ervoor gekozen deze informatie niet beschikbaar te maken",
"empty_column.account_suspended": "Account opgeschort",
"empty_column.account_timeline": "Hier zijn geen berichten!",
"empty_column.account_unavailable": "Profiel is niet beschikbaar",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Søkeresultat",
"emoji_button.symbols": "Symbol",
"emoji_button.travel": "Reise & stader",
"empty_column.account_hides_collections": "Denne brukaren har valt å ikkje gjere denne informasjonen tilgjengeleg",
"empty_column.account_suspended": "Kontoen er suspendert",
"empty_column.account_timeline": "Ingen tut her!",
"empty_column.account_unavailable": "Profil ikkje tilgjengeleg",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Søkeresultat",
"emoji_button.symbols": "Symboler",
"emoji_button.travel": "Reise & steder",
"empty_column.account_hides_collections": "Denne brukeren har valgt å ikke gjøre denne informasjonen tilgjengelig",
"empty_column.account_suspended": "Kontoen er suspendert",
"empty_column.account_timeline": "Ingen innlegg her!",
"empty_column.account_unavailable": "Profilen er utilgjengelig",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Wyniki wyszukiwania",
"emoji_button.symbols": "Symbole",
"emoji_button.travel": "Podróże i miejsca",
"empty_column.account_hides_collections": "Użytkownik postanowił nie udostępniać tych informacji",
"empty_column.account_suspended": "Konto zawieszone",
"empty_column.account_timeline": "Brak wpisów tutaj!",
"empty_column.account_unavailable": "Profil niedostępny",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Resultado da pesquisa",
"emoji_button.symbols": "Símbolos",
"emoji_button.travel": "Viagem e Lugares",
"empty_column.account_hides_collections": "A pessoa optou por não disponibilizar esta informação",
"empty_column.account_suspended": "Conta suspensa",
"empty_column.account_timeline": "Nada aqui.",
"empty_column.account_unavailable": "Perfil indisponível",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Resultados da pesquisa",
"emoji_button.symbols": "Símbolos",
"emoji_button.travel": "Viagens & Lugares",
"empty_column.account_hides_collections": "Este utilizador escolheu não disponibilizar esta informação",
"empty_column.account_suspended": "Conta suspensa",
"empty_column.account_timeline": "Sem publicações por aqui!",
"empty_column.account_unavailable": "Perfil indisponível",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Përfundime kërkimi",
"emoji_button.symbols": "Simbole",
"emoji_button.travel": "Udhëtime & Vende",
"empty_column.account_hides_collections": "Ky përdorues ka zgjedhur të mos e japë këtë informacion",
"empty_column.account_suspended": "Llogaria u pezullua",
"empty_column.account_timeline": "Ska mesazhe këtu!",
"empty_column.account_unavailable": "Profil jashtë funksionimi",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Sökresultat",
"emoji_button.symbols": "Symboler",
"emoji_button.travel": "Resor & platser",
"empty_column.account_hides_collections": "Användaren har valt att inte göra denna information tillgänglig",
"empty_column.account_suspended": "Kontot är avstängt",
"empty_column.account_timeline": "Inga inlägg här!",
"empty_column.account_unavailable": "Profilen ej tillgänglig",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "ผลลัพธ์การค้นหา",
"emoji_button.symbols": "สัญลักษณ์",
"emoji_button.travel": "การเดินทางและสถานที่",
"empty_column.account_hides_collections": "ผู้ใช้นี้ได้เลือกที่จะไม่ทำให้ข้อมูลนี้พร้อมใช้งาน",
"empty_column.account_suspended": "ระงับบัญชีอยู่",
"empty_column.account_timeline": "ไม่มีโพสต์ที่นี่!",
"empty_column.account_unavailable": "โปรไฟล์ไม่พร้อมใช้งาน",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Arama sonuçları",
"emoji_button.symbols": "Semboller",
"emoji_button.travel": "Seyahat ve Yerler",
"empty_column.account_hides_collections": "Bu kullanıcı bu bilgiyi sağlamayı tercih etmemiştir",
"empty_column.account_suspended": "Hesap askıya alındı",
"empty_column.account_timeline": "Burada hiç gönderi yok!",
"empty_column.account_unavailable": "Profil kullanılamıyor",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Результати пошуку",
"emoji_button.symbols": "Символи",
"emoji_button.travel": "Подорожі та місця",
"empty_column.account_hides_collections": "Цей користувач вирішив не робити цю інформацію доступною",
"empty_column.account_suspended": "Обліковий запис заблоковано",
"empty_column.account_timeline": "Тут немає дописів!",
"empty_column.account_unavailable": "Профіль недоступний",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "Kết quả tìm kiếm",
"emoji_button.symbols": "Biểu tượng",
"emoji_button.travel": "Du lịch",
"empty_column.account_hides_collections": "Người này đã chọn ẩn thông tin",
"empty_column.account_suspended": "Tài khoản vô hiệu hóa",
"empty_column.account_timeline": "Chưa có tút nào!",
"empty_column.account_unavailable": "Tài khoản bị đình chỉ",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "搜索结果",
"emoji_button.symbols": "符号",
"emoji_button.travel": "旅行和地点",
"empty_column.account_hides_collections": "该用户选择不提供此信息",
"empty_column.account_suspended": "账户已被停用",
"empty_column.account_timeline": "这里没有嘟文!",
"empty_column.account_unavailable": "个人资料不可用",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "搜尋結果",
"emoji_button.symbols": "符號",
"emoji_button.travel": "旅遊景物",
"empty_column.account_hides_collections": "這位使用者選擇不公開此資訊",
"empty_column.account_suspended": "帳號已停權",
"empty_column.account_timeline": "這裡還沒有嘟文!",
"empty_column.account_unavailable": "無法取得個人資料",

View File

@ -222,6 +222,7 @@
"emoji_button.search_results": "搜尋結果",
"emoji_button.symbols": "符號",
"emoji_button.travel": "旅遊與地點",
"empty_column.account_hides_collections": "這位使用者選擇不提供此資訊",
"empty_column.account_suspended": "帳號已被停權",
"empty_column.account_timeline": "這裡還沒有嘟文!",
"empty_column.account_unavailable": "無法取得個人檔案",

View File

@ -5226,6 +5226,7 @@ a.status-card {
.modal-root__modal {
pointer-events: auto;
user-select: text;
display: flex;
}

View File

@ -611,7 +611,7 @@ class FeedManager
def build_crutches(receiver_id, statuses)
crutches = {}
crutches[:active_mentions] = Mention.active.where(status_id: statuses.flat_map { |s| [s.id, s.reblog_of_id] }.compact).pluck(:status_id, :account_id).each_with_object({}) { |(id, account_id), mapping| (mapping[id] ||= []).push(account_id) }
crutches[:active_mentions] = crutches_active_mentions(statuses)
check_for_blocks = statuses.flat_map do |s|
arr = crutches[:active_mentions][s.id] || []
@ -638,4 +638,12 @@ class FeedManager
crutches
end
def crutches_active_mentions(statuses)
Mention
.active
.where(status_id: statuses.flat_map { |status| [status.id, status.reblog_of_id] }.compact)
.pluck(:status_id, :account_id)
.each_with_object({}) { |(id, account_id), mapping| (mapping[id] ||= []).push(account_id) }
end
end

View File

@ -74,7 +74,7 @@ class Admin::StatusBatchAction
# Can't use a transaction here because UpdateStatusService queues
# Sidekiq jobs
statuses.includes(:media_attachments, :preview_cards).find_each do |status|
statuses.includes(:media_attachments, preview_cards_status: :preview_card).find_each do |status|
next if status.discarded? || !(status.with_media? || status.with_preview_card?)
authorize([:admin, status], :update?)

View File

@ -40,7 +40,7 @@ module StatusSearchConcern
properties << 'media' if with_media?
properties << 'poll' if with_poll?
properties << 'link' if with_preview_card?
properties << 'embed' if preview_cards.any?(&:video?)
properties << 'embed' if preview_card&.video?
properties << 'sensitive' if sensitive?
properties << 'reply' if reply?
end

View File

@ -50,7 +50,9 @@ class PreviewCard < ApplicationRecord
enum type: { link: 0, photo: 1, video: 2, rich: 3 }
enum link_type: { unknown: 0, article: 1 }
has_and_belongs_to_many :statuses
has_many :preview_cards_statuses, dependent: :delete_all, inverse_of: :preview_card
has_many :statuses, through: :preview_cards_statuses
has_one :trend, class_name: 'PreviewCardTrend', inverse_of: :preview_card, dependent: :destroy
has_attached_file :image, processors: [:thumbnail, :blurhash_transcoder], styles: ->(f) { image_styles(f) }, convert_options: { all: '-quality 90 +profile "!icc,*" +set date:modify +set date:create +set date:timestamp' }, validate_media_type: false
@ -64,6 +66,9 @@ class PreviewCard < ApplicationRecord
before_save :extract_dimensions, if: :link?
# This can be set by the status when retrieving the preview card using the join model
attr_accessor :original_url
def appropriate_for_trends?
link? && article? && title.present? && description.present? && image.present? && provider_name.present?
end

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
# == Schema Information
#
# Table name: preview_cards_statuses
#
# preview_card_id :bigint(8) not null
# status_id :bigint(8) not null
# url :string
#
class PreviewCardsStatus < ApplicationRecord
# Composite primary keys are not properly supported in Rails. However,
# we shouldn't need this anyway...
self.primary_key = nil
belongs_to :preview_card
belongs_to :status
end

View File

@ -81,8 +81,8 @@ class Status < ApplicationRecord
has_many :local_bookmarked, -> { merge(Account.local) }, through: :bookmarks, source: :account
has_and_belongs_to_many :tags
has_and_belongs_to_many :preview_cards
has_one :preview_cards_status, inverse_of: :status # Because of a composite primary key, the dependent option cannot be used
has_one :notification, as: :activity, dependent: :destroy
has_one :status_stat, inverse_of: :status
has_one :poll, inverse_of: :status, dependent: :destroy
@ -149,24 +149,25 @@ class Status < ApplicationRecord
# The `prepend: true` option below ensures this runs before
# the `dependent: destroy` callbacks remove relevant records
before_destroy :unlink_from_conversations!, prepend: true
before_destroy :reset_preview_card!
cache_associated :application,
:media_attachments,
:conversation,
:status_stat,
:tags,
:preview_cards,
:preloadable_poll,
preview_cards_status: [:preview_card],
account: [:account_stat, user: :role],
active_mentions: { account: :account_stat },
reblog: [
:application,
:tags,
:preview_cards,
:media_attachments,
:conversation,
:status_stat,
:preloadable_poll,
preview_cards_status: [:preview_card],
account: [:account_stat, user: :role],
active_mentions: { account: :account_stat },
],
@ -233,7 +234,11 @@ class Status < ApplicationRecord
end
def preview_card
preview_cards.first
preview_cards_status&.preview_card&.tap { |x| x.original_url = preview_cards_status.url }
end
def reset_preview_card!
PreviewCardsStatus.where(status_id: id).delete_all
end
def hidden?
@ -251,7 +256,7 @@ class Status < ApplicationRecord
end
def with_preview_card?
preview_cards.any?
preview_cards_status.present?
end
def with_poll?

View File

@ -54,9 +54,7 @@ class Trends::Links < Trends::Base
!(original_status.account.silenced? || status.account.silenced?) &&
!(original_status.spoiler_text? || original_status.sensitive?)
original_status.preview_cards.each do |preview_card|
add(preview_card, status.account_id, at_time) if preview_card.appropriate_for_trends?
end
add(original_status.preview_card, status.account_id, at_time) if original_status.preview_card&.appropriate_for_trends?
end
def add(preview_card, account_id, at_time = Time.now.utc)

View File

@ -8,6 +8,10 @@ class REST::PreviewCardSerializer < ActiveModel::Serializer
:provider_url, :html, :width, :height,
:image, :image_description, :embed_url, :blurhash, :published_at
def url
object.original_url.presence || object.url
end
def image
object.image? ? full_asset_url(object.image.url(:original)) : nil
end

View File

@ -280,7 +280,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
end
def reset_preview_card!
@status.preview_cards.clear
@status.reset_preview_card!
LinkCrawlWorker.perform_in(rand(1..59).seconds, @status.id)
end

View File

@ -1,12 +1,14 @@
# frozen_string_literal: true
class AppSignUpService < BaseService
include RegistrationHelper
def call(app, remote_ip, params)
@app = app
@remote_ip = remote_ip
@params = params
raise Mastodon::NotPermittedError unless allowed_registrations?
raise Mastodon::NotPermittedError unless allowed_registration?(remote_ip, invite)
ApplicationRecord.transaction do
create_user!
@ -34,8 +36,12 @@ class AppSignUpService < BaseService
)
end
def invite
Invite.find_by(code: @params[:invite_code]) if @params[:invite_code].present?
end
def user_params
@params.slice(:email, :password, :agreement, :locale, :time_zone)
@params.slice(:email, :password, :agreement, :locale, :time_zone, :invite_code)
end
def account_params
@ -45,24 +51,4 @@ class AppSignUpService < BaseService
def invite_request_params
{ text: @params[:reason] }
end
def allowed_registrations?
registrations_open? && !single_user_mode? && !omniauth_only? && !ip_blocked?
end
def registrations_open?
Setting.registrations_mode != 'none'
end
def single_user_mode?
Rails.configuration.x.single_user_mode
end
def omniauth_only?
ENV['OMNIAUTH_ONLY'] == 'true'
end
def ip_blocked?
IpBlock.where(severity: :sign_up_block).where('ip >>= ?', @remote_ip.to_s).exists?
end
end

View File

@ -19,7 +19,7 @@ class FetchLinkCardService < BaseService
@status = status
@original_url = parse_urls
return if @original_url.nil? || @status.preview_cards.any?
return if @original_url.nil? || @status.with_preview_card?
@url = @original_url.to_s
@ -62,9 +62,9 @@ class FetchLinkCardService < BaseService
def attach_card
with_redis_lock("attach_card:#{@status.id}") do
return if @status.preview_cards.any?
return if @status.with_preview_card?
@status.preview_cards << @card
PreviewCardsStatus.create(status: @status, preview_card: @card, url: @original_url)
Rails.cache.delete(@status)
Trends.links.register(@status)
end

View File

@ -125,7 +125,7 @@ class UpdateStatusService < BaseService
def reset_preview_card!
return unless @status.text_previously_changed?
@status.preview_cards.clear
@status.reset_preview_card!
LinkCrawlWorker.perform_async(@status.id)
end

View File

@ -1 +1,195 @@
---
lt:
activerecord:
attributes:
doorkeeper/application:
name: Programėlės pavadinimas
redirect_uri: Peradresavimo URI
scopes: Aprėptys
website: Programėlės svetainė
errors:
models:
doorkeeper/application:
attributes:
redirect_uri:
fragment_present: negali turėti fragmento.
invalid_uri: turi būti tinkamas URI.
relative_uri: turi būti absoliutus URI.
secured_uri: turi būti HTTPS/SSL URI.
doorkeeper:
applications:
buttons:
authorize: Įgalinti
cancel: Atšaukti
destroy: Sunaikinti
edit: Redaguoti
submit: Pateikti
confirmations:
destroy: Ar esi įsitikinęs (-usi)?
edit:
title: Redaguoti programėlę
form:
error: Ups! Patikrink, ar formoje nėra galimų klaidų.
help:
native_redirect_uri: Naudoti %{native_redirect_uri} vietiniams bandymams
redirect_uri: Naudoti po vieną eilutę kiekvienam URI
scopes: Atskirk aprėptis tarpais. Palik tuščią, jei nori naudoti numatytąsias aprėtis.
index:
application: Programėlė
callback_url: Atgalinis URL
delete: Ištrinti
empty: Neturi jokių programėlių.
name: Pavadinimas
new: Nauja programėlė
scopes: Aprėptys
show: Rodyti
title: Tavo programėlės
new:
title: Nauja programėlė
show:
actions: Veiksmai
application_id: Kliento raktas
callback_urls: Atgalinių URL adresų
scopes: Aprėptys
secret: Kliento paslaptis
title: 'Programėlė: %{name}'
authorizations:
buttons:
authorize: Įgalinti
deny: Atmesti
error:
title: Įvyko klaida.
new:
prompt_html: "%{client_name} norėtų gauti leidimą prieigos prie tavo paskyros. Tai trečiosios šalies programėlė. <strong>Jei ja nepasitiki, neturėtum jai leisti.</strong>"
review_permissions: Peržiūrėti leidimus
title: Reikalingas įgaliojimas
show:
title: Nukopijuok šį įgaliojimo kodą ir įklijuok jį į programėlę.
authorized_applications:
buttons:
revoke: Naikinti
confirmations:
revoke: Ar esi įsitikinęs (-usi)?
index:
authorized_at: Įgaliota %{date}
description_html: Tai programėlės, kurios gali pasiekti tavo paskyrą naudojant API. Jei čia yra programėlių, kurių neatpažįsti, arba jei programėlė elgiasi netinkamai, gali panaikinti jos prieigą.
last_used_at: Paskutinį kartą naudota %{date}
never_used: Niekada nenaudotas
scopes: Leidimai
superapp: Vidinis
title: Tavo įgaliotos programėlės
errors:
messages:
access_denied: Išteklių savininkas (-ė) arba įgaliojimų serveris atmetė užklausą.
credential_flow_not_configured: Išteklių savininko slaptažodžio kredencialų srautas nepavyko, nes Doorkeeper.configure.resource_owner_from_credentials nėra nesukonfigūruotas.
invalid_client: Kliento tapatybės nustatymas nepavyko dėl nežinomo kliento, neįtraukto kliento tapatybės nustatymo arba nepalaikomo tapatybės nustatymo metodo.
invalid_grant: Pateiktas įgaliojimas yra netinkamas, pasibaigęs, panaikintas, neatitinka įgaliojimo užklausoje naudoto nukreipimo URI arba buvo išduotas kitam klientui.
invalid_redirect_uri: Nukreipimo uri įtrauktas yra netinkamas.
invalid_request:
missing_param: 'Trūksta privalomo parametro: %{value}.'
request_not_authorized: Užklausą reikia įgalioti. Reikalingo parametro užklausai įgalioti trūksta arba jis netinkamas.
unknown: Užklausoje trūksta privalomo parametro, turi nepalaikomą parametro reikšmę arba yra kitaip netinkamai suformuota.
invalid_resource_owner: Pateikti išteklių savininko įgaliojimai yra netinkami arba išteklių savininko negalima surasti.
invalid_scope: Užklausos aprėptis yra netinkama, nežinoma arba netinkamai suformuota.
invalid_token:
expired: Baigėsi prieigos rakto galiojimas.
revoked: Prieigos raktas buvo panaikintas.
unknown: Prieigos raktas yra netinkamas.
resource_owner_authenticator_not_configured: Išteklių savininko suradimas nepavyko dėl to, kad Doorkeeper.configure.resource_owner_authenticator nėra sukonfigūruotas.
server_error: Įgaliojimų serveris susidūrė su netikėta sąlyga, dėl kurios negalėjo užpildyti užklausos.
temporarily_unavailable: Įgaliojimų serveris šiuo metu negali apdoroti užklausos dėl laikinos serverio perkrovos arba techninės priežiūros.
unauthorized_client: Klientas nėra įgaliotas atlikti šią užklausą šiuo metodu.
unsupported_grant_type: Įgaliojimų suteikimo tipas nepalaikomas įgaliojimų serveryje.
unsupported_response_type: Įgaliojimų serveris nepalaiko šio atsako tipo.
flash:
applications:
create:
notice: Programėlė sukurta.
destroy:
notice: Programėlė ištrinta.
update:
notice: Programėlė atnaujinta.
authorized_applications:
destroy:
notice: Programėlė panaikinta.
grouped_scopes:
access:
read: Tik skaitymo prieiga
read/write: Skaitymo ir rašymo prieiga
write: Tik rašymo prieiga
title:
accounts: Paskyros
admin/accounts: Paskyrų administravimas
admin/all: Visi administraciniai funkcijos
admin/reports: Ataskaitų administravimas
all: Pilna prieiga prie tavo Mastodon paskyros
blocks: Blokavimai
bookmarks: Žymės
conversations: Pokalbiai
crypto: Galo iki galo užšifravimas
favourites: Mėgstami
filters: Filtrai
follow: Sekimai, nutildymai ir blokavimai
follows: Sekimai
lists: Sąrašai
media: Medijos priedai
mutes: Užtildymai
notifications: Pranešimai
push: Stumdomieji pranešimai
reports: Ataskaitos
search: Paieška
statuses: Įrašai
layouts:
admin:
nav:
applications: Programėlės
oauth2_provider: OAuth2 teikėjas
application:
title: Reikalingas OAuth įgaliojimas
scopes:
admin:read: skaityti visus serveryje esančius duomenis
admin:read:accounts: skaityti neskelbtiną visų paskyrų informaciją
admin:read:canonical_email_blocks: skaityti neskelbtiną visų kanoninių el. laiško blokavimų informaciją
admin:read:domain_allows: skaityti neskelbtiną visų domeno leidimus informaciją
admin:read:domain_blocks: skaityti neskelbtiną visų domeno blokavimų informaciją
admin:read:email_domain_blocks: skaityti neskelbtiną visų el. laiško domeno blokavimų informaciją
admin:read:ip_blocks: skaityti neskelbtiną visų IP blokavimų informaciją
admin:read:reports: skaityti neskelbtiną visų ataskaitų ir praneštų paskyrų informaciją
admin:write: modifikuoti visus serveryje esančius duomenis
admin:write:accounts: atlikti paskyrų prižiūrėjimo veiksmus
admin:write:canonical_email_blocks: atlikti kanoninių el. laiško blokavimų prižiūrėjimo veiksmus
admin:write:domain_allows: atlikti prižiūrėjimo veiksmus su domeno leidimais
admin:write:domain_blocks: atlikti prižiūrėjimo veiksmus su domenų blokavimais
admin:write:email_domain_blocks: atlikti prižiūrėjimo veiksmus su el. laiško domenų blokavimais
admin:write:ip_blocks: atlikti prižiūrėjimo veiksmus su IP blokavimais
admin:write:reports: atlikti paskyrų prižiūrėjimo veiksmus atsakaitams
crypto: naudoti galo iki galo šifravimą
follow: modifikuoti paskyros santykius
push: gauti tavo stumiamuosius pranešimus
read: skaityti tavo visus paskyros duomenis
read:accounts: matyti paskyrų informaciją
read:blocks: matyti tavo blokavimus
read:bookmarks: matyti tavo žymes
read:favourites: matyti tavo mėgstamiausius
read:filters: matyti tavo filtrus
read:follows: matyti tavo sekimus
read:lists: matyti tavo sąrašus
read:mutes: matyti tavo nutildymus
read:notifications: matyti tavo pranešimus
read:reports: matyti tavo ataskaitas
read:search: ieškoti tavo vardu
read:statuses: matyti visus įrašus
write: modifikuoti visus tavo paskyros duomenis
write:accounts: modifikuoti tavo profilį
write:blocks: blokuoti paskyras ir domenus
write:bookmarks: įrašyti įrašus
write:conversations: nutildyti ir ištrinti pokalbius
write:favourites: mėgti įrašai
write:filters: sukurti filtrus
write:follows: sekti žmones
write:lists: sukurti sąrašus
write:media: įkelti medijos failus
write:mutes: nutildyti žmones ir pokalbius
write:notifications: išvalyti tavo pranešimus
write:reports: pranešti kitus asmenus
write:statuses: skelbti įrašus

View File

@ -1368,6 +1368,7 @@ en:
'86400': 1 day
expires_in_prompt: Never
generate: Generate invite link
invalid: This invite is not valid
invited_by: 'You were invited by:'
max_uses:
one: 1 use

View File

@ -131,7 +131,7 @@ fa:
reset_password: بازنشانی گذرواژه
resubscribe: اشتراک دوباره
role: نقش
search: جستجو
search: جست‌وجو
search_same_email_domain: دیگر کاربران با دامنهٔ رایانامهٔ یکسان
search_same_ip: دیگر کاربران با IP یکسان
security: امنیت
@ -386,6 +386,10 @@ fa:
confirm_suspension:
cancel: لغو
confirm: تعلیق
permanent_action: برگرداندن تعلیق هیچ داده یا ارتباطی را برنخواهد گرداند.
preamble_html: در حال تعلیق <strong>%{domain}</strong> و همهٔ زیردامنه‌هایش هستید.
remove_all_data: این کار همهٔ داده‌های نمایه، محتوا و رسانه‌های حساب‌های این دامنه را از کارسازتان برمی‌دارد.
stop_communication: کارسازتان دیگر با این کارسازها ارتباط برقرار نخواهد کرد.
title: تأیید انسداد دامنه برای %{domain}
created_msg: مسدودسازی دامنه در حال پردازش است
destroyed_msg: انسداد دامنه واگردانده شد
@ -1219,7 +1223,7 @@ fa:
followers: این کار همهٔ پیگیران شما را از حساب فعلی به حساب تازه منتقل خواهد کرد
only_redirect_html: شما همچنین می‌توانید حساب خود را <a href="%{path}">به یک حساب دیگر اشاره دهید</a>.
other_data: هیچ دادهٔ دیگری خودبه‌خود منتقل نخواهد شد
redirect: نمایهٔ حساب فعلی شما به حساب تازه اشاره خواهد کرد و خودش در نتیجهٔ جستجوها ظاهر نخواهد شد
redirect: نمایهٔ حساب کنونیتان به حساب تازه اشاره خواهد کرد و از جست‌وجوها حذف خواهد شد
moderation:
title: مدیریت کاربران
move_handler:

View File

@ -1041,13 +1041,13 @@ fi:
hint_html: Vielä yksi juttu! Meidän on vahvistettava, että olet ihminen (tämän avulla pidämme roskapostin poissa!). Ratkaise alla oleva CAPTCHA-vahvistus ja paina "Jatka".
title: Turvatarkastus
confirmations:
awaiting_review: Sähköpostiosoitteesi on vahvistettu! Seuraavaksi palvelimen %{domain} ylläpito tarkistaa rekisteröitymisesi ja saat lopuksi ilmoituksen sähköpostitse, jos tilisi hyväksytään!
awaiting_review: Sähköpostiosoitteesi on vahvistettu! Seuraavaksi palvelimen %{domain} ylläpito tarkistaa rekisteröitymisesi, ja saat lopuksi ilmoituksen sähköpostitse, jos tilisi hyväksytään!
awaiting_review_title: Rekisteröitymisesi on tarkistettavana
clicking_this_link: tästä linkistä
login_link: kirjautumalla sisään
proceed_to_login_html: Voit nyt jatkaa %{login_link}.
redirect_to_app_html: Sinun olisi pitänyt ohjautua sovellukseen <strong>%{app_name}</strong>. Jos näin ei tapahtunut, yritä avata se %{clicking_this_link} tai palaa sovellukseen manuaalisesti.
registration_complete: Rekisteröitymisesi palvelimelle %{domain} on suoritettu!
registration_complete: Rekisteröitymisesi palvelimelle %{domain} on nyt valmis!
welcome_title: Tervetuloa, %{name}!
wrong_email_hint: Jos sähköpostiosoite ei ole oikein, voit muuttaa sen tilin asetuksista.
delete_account: Poista tili

View File

@ -1 +1,5 @@
---
ig:
filters:
contexts:
home: Ụlọ na ndepụta

View File

@ -1023,14 +1023,14 @@ ja:
hint_html: もう一つだけ!あなたが人間であることを確認する必要があります(スパムを防ぐためです!)。 以下のCAPTCHAを解き、「続ける」をクリックします。
title: セキュリティチェック
confirmations:
awaiting_review: メールアドレスは確認済みです。%{domain} のモデレーターによりアカウント登録の審査が完了すると、メールでお知らせします。
awaiting_review: メールアドレスが確認できました。%{domain} のスタッフが登録審査を行います。承認されたらメールでお知らせします!
awaiting_review_title: 登録の審査待ちです
clicking_this_link: ちらのリンク
login_link: こちらのリンク
proceed_to_login_html: "%{login_link}から早速ログインしてみましょう。"
redirect_to_app_html: "<strong>%{app_name}</strong>に戻ります。自動で移動しない場合は%{clicking_this_link}を押すか、手動でアプリを切り替えてください。"
clicking_this_link: のリンクを押す
login_link: ログイン
proceed_to_login_html: それでは%{login_link}しましょう。
redirect_to_app_html: 自動的に<strong>%{app_name}</strong>に戻らなかった場合、%{clicking_this_link}か、手動でアプリを切り替えてください。
registration_complete: "%{domain} へのアカウント登録が完了しました。"
welcome_title: Mastodonへようこそ、%{name}さん
welcome_title: ようこそ、%{name}さん
wrong_email_hint: メールアドレスが正しくない場合は、アカウント設定で変更できます。
delete_account: アカウントの削除
delete_account_html: アカウントを削除したい場合、<a href="%{path}">こちら</a>から手続きが行えます。削除する前に、確認画面があります。

View File

@ -1689,8 +1689,8 @@ ko:
keep_polls_hint: 설문을 삭제하지 않았음
keep_self_bookmark: 북마크한 게시물 유지
keep_self_bookmark_hint: 북마크한 본인의 게시물을 삭제하지 않습니다
keep_self_fav: 마음에 들어한 게시물 유지
keep_self_fav_hint: 내 스스로 마음에 들어한 본인의 게시물을 삭제하지 않습니다
keep_self_fav: 내가 좋아요한 게시물 유지
keep_self_fav_hint: 스스로 좋아요를 누른 본인의 게시물을 삭제하지 않습니다
min_age:
'1209600': 2
'15778476': 6 개월

View File

@ -58,6 +58,7 @@ lt:
follows: Seka
header: Antraštė
inbox_url: Gautųjų URL
invite_request_text: Priežastys prisijungiant
invited_by: Pakvietė
ip: IP
joined: Prisijungė
@ -183,10 +184,10 @@ lt:
deactivate_all: Deaktyvuoti visus
filter:
all: Visi
available: Prieinamas
available: Pasiekiamas
expired: Pasibaigęs
title: Filtras
title: Pakvietimai
title: Kvietimai
relays:
add_new: Pridėti naują pamainą
delete: Ištrinti
@ -236,6 +237,8 @@ lt:
everyone: Numatytieji leidimai
everyone_full_description_html: Tai <strong>bazinis vaidmuo</strong>, turintis įtakos <strong>visiems naudotojams</strong>, net ir tiems, kurie neturi priskirto vaidmens. Visi kiti vaidmenys iš jo paveldi teises.
settings:
captcha_enabled:
desc_html: Tai priklauso nuo hCaptcha išorinių skriptų, kurie gali kelti susirūpinimą dėl saugumo ir privatumo. Be to, <strong>dėl to registracijos procesas kai kuriems žmonėms (ypač neįgaliesiems) gali būti gerokai sunkiau prieinami</strong>. Dėl šių priežasčių apsvarstyk alternatyvias priemones, pavyzdžiui, patvirtinimu arba kvietimu grindžiamą registraciją.
domain_blocks:
all: Visiems
statuses:
@ -285,6 +288,9 @@ lt:
or_log_in_with: Arba prisijungti su
register: Užsiregistruoti
reset_password: Atstatyti slaptažodį
rules:
invited_by: 'Gali prisijungti prie %{domain} pagal kvietimą, kurį gavai iš:'
preamble_invited: Prieš tęsiant, atsižvelk į pagrindines taisykles, kurias nustatė %{domain} prižiūrėtojai.
security: Apsauga
set_new_password: Nustatyti naują slaptažodį
datetime:
@ -367,7 +373,7 @@ lt:
upload: Įkelti
invites:
delete: Deaktyvuoti
expired: Pasibaigęs
expired: Pasibaigė
expires_in:
'1800': 30 minučių
'21600': 6 valandų
@ -378,10 +384,15 @@ lt:
expires_in_prompt: Niekada
generate: Generuoti
invited_by: 'Jus pakvietė:'
max_uses_prompt: Be limito
prompt: Generuoti ir dalintis įrašais su kitais, kad sukurti prieigą prie serverio
max_uses:
few: "%{count} panaudojimai"
many: "%{count} panaudojimo"
one: 1 panaudojimas
other: "%{count} panaudojimų"
max_uses_prompt: Nėra limito
prompt: Generuok ir bendrink nuorodas su kitais, kad suteiktum prieigą prie šio serverio
table:
expires_at: Pasibaigia
expires_at: Baigsis
uses: Naudojimai
title: Pakviesti žmones
media_attachments:

View File

@ -343,7 +343,7 @@ lv:
title: Pielāgotās emocijzīmes
uncategorized: Nekategorizētās
unlist: Izslēgt
unlisted: Nerindota
unlisted: Neminētie
update_failed_msg: Nevarēja atjaunināt šo emocijzīmi
updated_msg: Emocijzīme veiksmīgi atjaunināta!
upload: Augšupielādēt
@ -545,6 +545,7 @@ lv:
total_reported: Ziņojumi par viņiem
total_storage: Multividesu pielikumi
totals_time_period_hint_html: Tālāk redzamajās summās ir iekļauti dati par visu laiku.
unknown_instance: Pašlaik šajā serverī nav ierakstu par šo domēnu.
invites:
deactivate_all: Deaktivēt visu
filter:
@ -1058,6 +1059,14 @@ lv:
hint_html: Vēl tikai viena lieta! Mums ir jāapstiprina, ka tu esi cilvēks (tas ir tāpēc, lai mēs varētu nepieļaut surogātpasta izsūtīšanu!). Atrisini tālāk norādīto CAPTCHA un noklikšķini uz "Turpināt".
title: Drošības pārbaude
confirmations:
awaiting_review: Tava e-pasta adrese ir apstiprināta! %{domain} darbinieki tagad pārskata tavu reģistrāciju. Tu saņemsi e-pastu, ja viņi apstiprinās tavu kontu!
awaiting_review_title: Tava reģistrācija tiek izskatīta
clicking_this_link: klikšķinot šo saiti
login_link: pieteikties
proceed_to_login_html: Tagad vari doties uz %{login_link}.
redirect_to_app_html: Tev vajadzētu būt novirzītam uz lietotni <strong>%{app_name}</strong>. Ja tas nenotika, mēģini %{clicking_this_link} vai manuāli atgriezieties lietotnē.
registration_complete: Tava reģistrācija domēnā %{domain} tagad ir pabeigta!
welcome_title: Laipni lūdzam, %{name}!
wrong_email_hint: Ja šī e-pasta adrese nav pareiza, varat to mainīt konta iestatījumos.
delete_account: Dzēst kontu
delete_account_html: Ja vēlies dzēst savu kontu, tu vari <a href="%{path}">turpināt šeit</a>. Tev tiks lūgts apstiprinājums.
@ -1119,6 +1128,7 @@ lv:
functional: Tavs konts ir pilnībā darboties spējīgs.
pending: Tavu pieteikumu gaida mūsu darbinieku izskatīšana. Tas var aizņemt kādu laiku. Ja tavs pieteikums tiks apstiprināts, tu saņemsi e-pastu.
redirecting_to: Tavs konts ir neaktīvs, jo pašlaik tas tiek novirzīts uz %{acct}.
self_destruct: Tā kā %{domain} tiek slēgts, tu iegūsi tikai ierobežotu piekļuvi savam kontam.
view_strikes: Skati iepriekšējos brīdinājumus par savu kontu
too_fast: Veidlapa ir iesniegta pārāk ātri, mēģini vēlreiz.
use_security_key: Lietot drošības atslēgu
@ -1596,6 +1606,9 @@ lv:
over_daily_limit: Tu esi pārsniedzis šodien ieplānoto %{limit} ziņu ierobežojumu
over_total_limit: Tu esi pārsniedzis ieplānoto %{limit} ziņu ierobežojumu
too_soon: Ieplānotajam datumam ir jābūt nākotnē
self_destruct:
lead_html: Diemžēl domēns <strong>%{domain}</strong> tiek neatgriezeniski slēgts. Ja tev tur bija konts, tu nevarēsi turpināt to lietot, taču joprojām vari pieprasīt savu datu kopiju.
title: Šis serveris tiek slēgts
sessions:
activity: Pēdējā aktivitāte
browser: Pārlūks

View File

@ -1041,6 +1041,14 @@ nn:
hint_html: Berre ein ting til! Vi må bekrefte at du er et menneske (så vi kan halde spam ute!). Løys CAPTCHA-en nedanfor og klikk "Fortsett".
title: Sikkerheitssjekk
confirmations:
awaiting_review: Din e-post adresse er bekreftet! %{domain} ansatte gjennomgår nå registreringen din. Du vil motta en e-post hvis de godkjenner din konto!
awaiting_review_title: Din registrering blir vurdert
clicking_this_link: klikke på denne lenken
login_link: logg inn
proceed_to_login_html: Du kan nå fortsette til %{login_link}.
redirect_to_app_html: Du burde bli omdirigert til <strong>%{app_name}</strong> -appen. Hvis det ikke skjedde, kan du prøve %{clicking_this_link} eller manuelt gå tilbake til appen.
registration_complete: Registreringen på %{domain} er nå fullført!
welcome_title: Velkommen, %{name}!
wrong_email_hint: Viss epostadressa er feil, kan du endra ho i kontoinnstillingane.
delete_account: Slett konto
delete_account_html: Om du vil sletta kontoen din, kan du <a href="%{path}">gå hit</a>. Du vert spurd etter stadfesting.

View File

@ -772,6 +772,11 @@
approved: Godkjenning kreves for påmelding
none: Ingen kan melde seg inn
open: Hvem som helst kan melde seg inn
security:
authorized_fetch: Krev autentisering fra fødererte servere
authorized_fetch_hint: Krav om godkjenning fra fødererte servere muliggjør strengere håndhevelse av blokker på både brukernivå og servernivå. Dette går imidlertid på bekostning av en ytelsesstraff, reduserer rekkevidden til svarene dine og kan introdusere kompatibilitetsproblemer med enkelte fødererte tjenester. I tillegg vil dette ikke hindre dedikerte aktører i å hente dine offentlige innlegg og kontoer.
authorized_fetch_overridden_hint: Du kan for øyeblikket ikke endre denne innstillingen fordi den overstyres av en miljøvariabel.
federation_authentication: Håndheving av føderasjonsautentisering
title: Serverinnstillinger
site_uploads:
delete: Slett den opplastede filen
@ -1036,6 +1041,14 @@
hint_html: Bare en ting til! Vi må bekrefte at du er et menneske (dette er slik at vi kan holde spam ute!). Løs CAPTCHA nedenfor og klikk "Fortsett".
title: Sikkerhetskontroll
confirmations:
awaiting_review: Din e-post adresse er bekreftet! %{domain} ansatte gjennomgår nå registreringen din. Du vil motta en e-post hvis de godkjenner din konto!
awaiting_review_title: Din registrering blir vurdert
clicking_this_link: klikke på denne lenken
login_link: logg inn
proceed_to_login_html: Du kan nå fortsette til %{login_link}.
redirect_to_app_html: Du burde bli omdirigert til <strong>%{app_name}</strong> -appen. Hvis det ikke skjedde, kan du prøve %{clicking_this_link} eller manuelt gå tilbake til appen.
registration_complete: Registreringen på %{domain} er nå fullført!
welcome_title: Velkommen, %{name}!
wrong_email_hint: Hvis e-postadressen ikke er riktig, kan du endre den i kontoinnstillingene.
delete_account: Slett konto
delete_account_html: Hvis du ønsker å slette kontoen din, kan du <a href="%{path}">gå hit</a>. Du vil bli spurt om bekreftelse.
@ -1739,6 +1752,10 @@
month: "%b %Y"
time: "%H:%M"
with_time_zone: "%-d. %b %Y, %H:%M %Z"
translation:
errors:
quota_exceeded: Den serveromfattende brukskvoten for oversettelsestjenesten er overskredet.
too_many_requests: Det har nylig vært for mange forespørsler til oversettelsestjenesten.
two_factor_authentication:
add: Legg til
disable: Skru av

View File

@ -5,7 +5,7 @@ he:
account:
discoverable: הפוסטים והפרופיל שלך עשויים להיות מוצגים או מומלצים באזורים שונים באתר וייתכן שהפרופיל שלך יוצע למשתמשים אחרים.
display_name: שמך המלא או שם הכיף שלך.
fields: עמוד הבית שלך, כינויי גוף, גיל, וכל מידע אחר לפי העדפתך האישית.
fields: עמוד הבית שלך, לשון הפנייה, גיל, וכל מידע אחר לפי העדפתך האישית.
indexable: ההודעות הפומביות שלך עשויות להופיע בתוצאות חיפוש במסטודון. אחרים שהדהדו, חיבבו או ענו להודעות האלו יוכלו למצוא אותן בחיפוש בכל מקרה.
note: 'ניתן לאזכר @אחרים או #תגיות.'
show_collections: אנשים יוכלו לדפדף בין העוקבים והנעקבים שלך. אנשים שאת.ה עוקב.ת אחריהם יראו את המעקב אחריהם כרגיל.

View File

@ -247,7 +247,7 @@ ja:
mascot: カスタムマスコット(レガシー)
media_cache_retention_period: メディアキャッシュの保持期間
peers_api_enabled: 発見したサーバーのリストをAPIで公開する
profile_directory: ディレクトリを有効にする
profile_directory: プロフィール一覧を有効にする
registrations_mode: 新規登録が可能な人
require_invite_text: 申請事由の入力を必須にする
show_domain_blocks: ドメインブロックを表示
@ -258,7 +258,7 @@ ja:
site_short_description: サーバーの説明
site_terms: プライバシーポリシー
site_title: サーバーの名前
status_page_url: ステータスページのURL
status_page_url: サーバーの状態ページのURL
theme: デフォルトテーマ
thumbnail: サーバーのサムネイル
timeline_preview: 公開タイムラインへの未認証のアクセスを許可する

View File

@ -323,6 +323,7 @@
url: Endepunkt lenke
'no': Nei
not_recommended: Ikke anbefalt
overridden: Overstyrt
recommended: Anbefalt
required:
mark: "*"

View File

@ -82,6 +82,8 @@ Rails.application.routes.draw do
resource :outbox, only: [:show], module: :activitypub
end
get '/invite/:invite_code', constraints: ->(req) { req.format == :json }, to: 'api/v1/invites#show'
devise_scope :user do
get '/invite/:invite_code', to: 'auth/registrations#new', as: :public_invite

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddURLToPreviewCardsStatuses < ActiveRecord::Migration[7.0]
def change
add_column :preview_cards_statuses, :url, :string
end
end

View File

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2023_09_07_150100) do
ActiveRecord::Schema[7.0].define(version: 2023_10_06_183200) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -811,6 +811,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_09_07_150100) do
create_table "preview_cards_statuses", primary_key: ["status_id", "preview_card_id"], force: :cascade do |t|
t.bigint "preview_card_id", null: false
t.bigint "status_id", null: false
t.string "url"
end
create_table "relays", force: :cascade do |t|

View File

@ -20,7 +20,7 @@ const config = {
// Those packages are ESM, so we need them to be processed by Babel
transformIgnorePatterns: ['/node_modules/(?!(redent|strip-indent)/)'],
coverageDirectory: '<rootDir>/coverage',
moduleDirectories: ['<rootDir>/node_modules', '<rootDir>/app/javascript'],
moduleDirectories: ['node_modules', '<rootDir>/app/javascript'],
moduleNameMapper: {
'\\.svg$': '<rootDir>/app/javascript/__mocks__/svg.js',
},

View File

@ -69,7 +69,7 @@ namespace :tests do
exit(1)
end
unless Status.find(12).preview_cards.pluck(:url) == ['https://joinmastodon.org/']
unless PreviewCard.where(id: PreviewCardsStatus.where(status_id: 12).select(:preview_card_id)).pluck(:url) == ['https://joinmastodon.org/']
puts 'Preview cards not deduplicated as expected'
exit(1)
end

View File

@ -47,7 +47,7 @@
"@formatjs/intl-pluralrules": "^5.2.2",
"@gamestdio/websocket": "^0.3.2",
"@github/webauthn-json": "^2.1.1",
"@material-symbols/svg-600": "^0.13.1",
"@material-symbols/svg-600": "^0.14.0",
"@rails/ujs": "^7.1.1",
"@reduxjs/toolkit": "^1.9.5",
"@svgr/webpack": "^5.5.0",

View File

@ -2,14 +2,44 @@
require 'rails_helper'
describe Api::V1::Trends::LinksController do
RSpec.describe Api::V1::Trends::LinksController do
render_views
describe 'GET #index' do
around do |example|
previous = Setting.trends
example.run
Setting.trends = previous
end
context 'when trends are disabled' do
before { Setting.trends = false }
it 'returns http success' do
get :index
expect(response).to have_http_status(200)
end
end
context 'when trends are enabled' do
before { Setting.trends = true }
it 'returns http success' do
prepare_trends
stub_const('Api::V1::Trends::LinksController::DEFAULT_LINKS_LIMIT', 2)
get :index
expect(response).to have_http_status(200)
expect(response.headers).to include('Link')
end
def prepare_trends
Fabricate.times(3, :preview_card, trendable: true, language: 'en').each do |link|
2.times { |i| Trends.links.add(link, i) }
end
Trends::Links.new(threshold: 1).refresh
end
end
end
end

View File

@ -2,14 +2,44 @@
require 'rails_helper'
describe Api::V1::Trends::StatusesController do
RSpec.describe Api::V1::Trends::StatusesController do
render_views
describe 'GET #index' do
around do |example|
previous = Setting.trends
example.run
Setting.trends = previous
end
context 'when trends are disabled' do
before { Setting.trends = false }
it 'returns http success' do
get :index
expect(response).to have_http_status(200)
end
end
context 'when trends are enabled' do
before { Setting.trends = true }
it 'returns http success' do
prepare_trends
stub_const('Api::BaseController::DEFAULT_STATUSES_LIMIT', 2)
get :index
expect(response).to have_http_status(200)
expect(response.headers).to include('Link')
end
def prepare_trends
Fabricate.times(3, :status, trendable: true, language: 'en').each do |status|
2.times { |i| Trends.statuses.add(status, i) }
end
Trends::Statuses.new(threshold: 1, decay_threshold: -1).refresh
end
end
end
end

View File

@ -6,16 +6,41 @@ RSpec.describe Api::V1::Trends::TagsController do
render_views
describe 'GET #index' do
before do
Fabricate.times(10, :tag).each do |tag|
10.times { |i| Trends.tags.add(tag, i) }
around do |example|
previous = Setting.trends
example.run
Setting.trends = previous
end
get :index
end
context 'when trends are disabled' do
before { Setting.trends = false }
it 'returns http success' do
get :index
expect(response).to have_http_status(200)
expect(response.headers).to_not include('Link')
end
end
context 'when trends are enabled' do
before { Setting.trends = true }
it 'returns http success' do
prepare_trends
stub_const('Api::V1::Trends::TagsController::DEFAULT_TAGS_LIMIT', 2)
get :index
expect(response).to have_http_status(200)
expect(response.headers).to include('Link')
end
def prepare_trends
Fabricate.times(3, :tag, trendable: true).each do |tag|
2.times { |i| Trends.tags.add(tag, i) }
end
Trends::Tags.new(threshold: 1).refresh
end
end
end
end

View File

@ -17,11 +17,8 @@ describe Settings::AliasesController do
get :index
end
it 'returns http success' do
it 'returns http success with private cache control headers', :aggregate_failures do
expect(response).to have_http_status(200)
end
it 'returns private cache control headers' do
expect(response.headers['Cache-Control']).to include('private, no-store')
end
end

View File

@ -18,11 +18,8 @@ describe Settings::ApplicationsController do
get :index
end
it 'returns http success' do
it 'returns http success with private cache control headers', :aggregate_failures do
expect(response).to have_http_status(200)
end
it 'returns private cache control headers' do
expect(response.headers['Cache-Control']).to include('private, no-store')
end
end
@ -51,7 +48,7 @@ describe Settings::ApplicationsController do
describe 'POST #create' do
context 'when success (passed scopes as a String)' do
def call_create
subject do
post :create, params: {
doorkeeper_application: {
name: 'My New App',
@ -60,20 +57,16 @@ describe Settings::ApplicationsController do
scopes: 'read write follow',
},
}
response
end
it 'creates an entry in the database' do
expect { call_create }.to change(Doorkeeper::Application, :count)
end
it 'redirects back to applications page' do
expect(call_create).to redirect_to(settings_applications_path)
it 'creates an entry in the database', :aggregate_failures do
expect { subject }.to change(Doorkeeper::Application, :count)
expect(response).to redirect_to(settings_applications_path)
end
end
context 'when success (passed scopes as an Array)' do
def call_create
subject do
post :create, params: {
doorkeeper_application: {
name: 'My New App',
@ -82,15 +75,11 @@ describe Settings::ApplicationsController do
scopes: %w(read write follow),
},
}
response
end
it 'creates an entry in the database' do
expect { call_create }.to change(Doorkeeper::Application, :count)
end
it 'redirects back to applications page' do
expect(call_create).to redirect_to(settings_applications_path)
it 'creates an entry in the database', :aggregate_failures do
expect { subject }.to change(Doorkeeper::Application, :count)
expect(response).to redirect_to(settings_applications_path)
end
end
@ -106,11 +95,8 @@ describe Settings::ApplicationsController do
}
end
it 'returns http success' do
it 'returns http success and renders form', :aggregate_failures do
expect(response).to have_http_status(200)
end
it 'renders form again' do
expect(response).to render_template(:new)
end
end
@ -118,13 +104,7 @@ describe Settings::ApplicationsController do
describe 'PATCH #update' do
context 'when success' do
let(:opts) do
{
website: 'https://foo.bar/',
}
end
def call_update
subject do
patch :update, params: {
id: app.id,
doorkeeper_application: opts,
@ -132,13 +112,17 @@ describe Settings::ApplicationsController do
response
end
it 'updates existing application' do
call_update
expect(app.reload.website).to eql(opts[:website])
let(:opts) do
{
website: 'https://foo.bar/',
}
end
it 'redirects back to applications page' do
expect(call_update).to redirect_to(settings_application_path(app))
it 'updates existing application' do
subject
expect(app.reload.website).to eql(opts[:website])
expect(response).to redirect_to(settings_application_path(app))
end
end
@ -155,11 +139,8 @@ describe Settings::ApplicationsController do
}
end
it 'returns http success' do
it 'returns http success and renders form', :aggregate_failures do
expect(response).to have_http_status(200)
end
it 'renders form again' do
expect(response).to render_template(:show)
end
end
@ -170,11 +151,8 @@ describe Settings::ApplicationsController do
post :destroy, params: { id: app.id }
end
it 'redirects back to applications page' do
it 'redirects back to applications page and removes the app' do
expect(response).to redirect_to(settings_applications_path)
end
it 'removes the app' do
expect(Doorkeeper::Application.find_by(id: app.id)).to be_nil
end
end

View File

@ -14,22 +14,16 @@ describe Settings::DeletesController do
get :show
end
it 'renders confirmation page' do
it 'renders confirmation page with private cache control headers', :aggregate_failures do
expect(response).to have_http_status(200)
end
it 'returns private cache control headers' do
expect(response.headers['Cache-Control']).to include('private, no-store')
end
context 'when suspended' do
let(:user) { Fabricate(:user, account_attributes: { suspended_at: Time.now.utc }) }
it 'returns http forbidden' do
it 'returns http forbidden with private cache control headers', :aggregate_failures do
expect(response).to have_http_status(403)
end
it 'returns private cache control headers' do
expect(response.headers['Cache-Control']).to include('private, no-store')
end
end
@ -56,19 +50,10 @@ describe Settings::DeletesController do
delete :destroy, params: { form_delete_confirmation: { password: 'petsmoldoggos' } }
end
it 'redirects to sign in page' do
it 'removes user record and redirects', :aggregate_failures do
expect(response).to redirect_to '/auth/sign_in'
end
it 'removes user record' do
expect(User.find_by(id: user.id)).to be_nil
end
it 'marks account as suspended' do
expect(user.account.reload).to be_suspended
end
it 'does not create an email block' do
expect(CanonicalEmailBlock.block?(user.email)).to be false
end

View File

@ -14,11 +14,8 @@ describe Settings::ExportsController do
get :show
end
it 'returns http success' do
it 'returns http success with private cache control headers', :aggregate_failures do
expect(response).to have_http_status(200)
end
it 'returns private cache control headers' do
expect(response.headers['Cache-Control']).to include('private, no-store')
end
end

View File

@ -19,15 +19,9 @@ RSpec.describe Settings::ImportsController do
get :index
end
it 'assigns the expected imports' do
expect(assigns(:recent_imports)).to eq [import]
end
it 'returns http success' do
it 'assigns the expected imports', :aggregate_failures do
expect(response).to have_http_status(200)
end
it 'returns private cache control headers' do
expect(assigns(:recent_imports)).to eq [import]
expect(response.headers['Cache-Control']).to include('private, no-store')
end
end
@ -72,17 +66,10 @@ RSpec.describe Settings::ImportsController do
context 'with someone else\'s import' do
let(:bulk_import) { Fabricate(:bulk_import, state: :unconfirmed) }
it 'does not change the import\'s state' do
it 'does not change the import\'s state and returns missing', :aggregate_failures do
expect { subject }.to_not(change { bulk_import.reload.state })
end
it 'does not fire the import worker' do
subject
expect(BulkImportWorker).to_not have_received(:perform_async)
end
it 'returns http not found' do
subject
expect(response).to have_http_status(404)
end
end
@ -90,17 +77,10 @@ RSpec.describe Settings::ImportsController do
context 'with an already-confirmed import' do
let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :in_progress) }
it 'does not change the import\'s state' do
it 'does not change the import\'s state and returns missing', :aggregate_failures do
expect { subject }.to_not(change { bulk_import.reload.state })
end
it 'does not fire the import worker' do
subject
expect(BulkImportWorker).to_not have_received(:perform_async)
end
it 'returns http not found' do
subject
expect(response).to have_http_status(404)
end
end
@ -108,17 +88,10 @@ RSpec.describe Settings::ImportsController do
context 'with an unconfirmed import' do
let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :unconfirmed) }
it 'changes the import\'s state to scheduled' do
it 'changes the import\'s state to scheduled and redirects', :aggregate_failures do
expect { subject }.to change { bulk_import.reload.state.to_sym }.from(:unconfirmed).to(:scheduled)
end
it 'fires the import worker on the expected import' do
subject
expect(BulkImportWorker).to have_received(:perform_async).with(bulk_import.id)
end
it 'redirects to imports path' do
subject
expect(response).to redirect_to(settings_imports_path)
end
end
@ -130,12 +103,9 @@ RSpec.describe Settings::ImportsController do
context 'with someone else\'s import' do
let(:bulk_import) { Fabricate(:bulk_import, state: :unconfirmed) }
it 'does not delete the import' do
it 'does not delete the import and returns missing', :aggregate_failures do
expect { subject }.to_not(change { BulkImport.exists?(bulk_import.id) })
end
it 'returns http not found' do
subject
expect(response).to have_http_status(404)
end
end
@ -143,12 +113,9 @@ RSpec.describe Settings::ImportsController do
context 'with an already-confirmed import' do
let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :in_progress) }
it 'does not delete the import' do
it 'does not delete the import and returns missing', :aggregate_failures do
expect { subject }.to_not(change { BulkImport.exists?(bulk_import.id) })
end
it 'returns http not found' do
subject
expect(response).to have_http_status(404)
end
end
@ -156,12 +123,9 @@ RSpec.describe Settings::ImportsController do
context 'with an unconfirmed import' do
let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :unconfirmed) }
it 'deletes the import' do
it 'deletes the import and redirects', :aggregate_failures do
expect { subject }.to change { BulkImport.exists?(bulk_import.id) }.from(true).to(false)
end
it 'redirects to imports path' do
subject
expect(response).to redirect_to(settings_imports_path)
end
end
@ -177,13 +141,10 @@ RSpec.describe Settings::ImportsController do
bulk_import.update(total_items: bulk_import.rows.count, processed_items: bulk_import.rows.count, imported_items: 0)
end
it 'returns http success' do
it 'returns expected contents', :aggregate_failures do
subject
expect(response).to have_http_status(200)
end
it 'returns expected contents' do
subject
expect(response).to have_http_status(200)
expect(response.body).to eq expected_contents
end
end
@ -283,12 +244,9 @@ RSpec.describe Settings::ImportsController do
let(:import_file) { file }
let(:import_mode) { mode }
it 'creates an unconfirmed bulk_import with expected type' do
it 'creates an unconfirmed bulk_import with expected type and redirects', :aggregate_failures do
expect { subject }.to change { user.account.bulk_imports.pluck(:state, :type) }.from([]).to([['unconfirmed', import_type]])
end
it 'redirects to confirmation page for the import' do
subject
expect(response).to redirect_to(settings_import_path(user.account.bulk_imports.first))
end
end
@ -298,12 +256,9 @@ RSpec.describe Settings::ImportsController do
let(:import_file) { file }
let(:import_mode) { mode }
it 'does not creates an unconfirmed bulk_import' do
it 'does not creates an unconfirmed bulk_import', :aggregate_failures do
expect { subject }.to_not(change { user.account.bulk_imports.count })
end
it 'sets error to the import' do
subject
expect(assigns(:import).errors).to_not be_empty
end
end

View File

@ -16,11 +16,8 @@ describe Settings::LoginActivitiesController do
get :index
end
it 'returns http success' do
it 'returns http success with private cache control headers', :aggregate_failures do
expect(response).to have_http_status(200)
end
it 'returns private cache control headers' do
expect(response.headers['Cache-Control']).to include('private, no-store')
end
end

View File

@ -16,11 +16,8 @@ describe Settings::Migration::RedirectsController do
get :new
end
it 'returns http success' do
it 'returns http success with private cache control headers', :aggregate_failures do
expect(response).to have_http_status(200)
end
it 'returns private cache control headers' do
expect(response.headers['Cache-Control']).to include('private, no-store')
end
end

Some files were not shown because too many files have changed in this diff Show More