Merge pull request #649 from ThibG/glitch-soc/merge-upstream

Merge upstream changes
lolsob-rspec
ThibG 2018-08-18 18:22:54 +02:00 committed by GitHub
commit 79280c6fbe
49 changed files with 1970 additions and 232 deletions

View File

@ -64,12 +64,17 @@ aliases:
- run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version - run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
- *restore_ruby_dependencies - *restore_ruby_dependencies
- run: bundle install --clean --jobs 16 --path ./vendor/bundle/ --retry 3 --with pam_authentication --without development production - run: bundle install --clean --jobs 16 --path ./vendor/bundle/ --retry 3 --with pam_authentication --without development production && bundle clean
- save_cache: - save_cache:
key: v2-ruby-dependencies-{{ checksum "/tmp/.ruby-version" }}-{{ checksum "Gemfile.lock" }} key: v2-ruby-dependencies-{{ checksum "/tmp/.ruby-version" }}-{{ checksum "Gemfile.lock" }}
paths: paths:
- ./.bundle/ - ./.bundle/
- ./vendor/bundle/ - ./vendor/bundle/
- persist_to_workspace:
root: ~/projects/
paths:
- ./mastodon/.bundle/
- ./mastodon/vendor/bundle/
- &test_steps - &test_steps
steps: steps:
@ -78,9 +83,6 @@ aliases:
- *install_system_dependencies - *install_system_dependencies
- run: sudo apt-get install -y ffmpeg - run: sudo apt-get install -y ffmpeg
- run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
- *restore_ruby_dependencies
- run: - run:
name: Prepare Tests name: Prepare Tests
command: ./bin/rails parallel:create parallel:load_schema parallel:prepare command: ./bin/rails parallel:create parallel:load_schema parallel:prepare
@ -116,8 +118,6 @@ jobs:
steps: steps:
- *attach_workspace - *attach_workspace
- *install_system_dependencies - *install_system_dependencies
- run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
- *restore_ruby_dependencies
- run: - run:
name: Precompile assets name: Precompile assets
command: ./bin/rails assets:precompile command: ./bin/rails assets:precompile
@ -173,8 +173,6 @@ jobs:
<<: *defaults <<: *defaults
steps: steps:
- *attach_workspace - *attach_workspace
- run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
- *restore_ruby_dependencies
- run: bundle exec i18n-tasks check-normalized - run: bundle exec i18n-tasks check-normalized
- run: bundle exec i18n-tasks unused - run: bundle exec i18n-tasks unused
@ -189,9 +187,11 @@ workflows:
- install-ruby2.4: - install-ruby2.4:
requires: requires:
- install - install
- install-ruby2.5
- install-ruby2.3: - install-ruby2.3:
requires: requires:
- install - install
- install-ruby2.5
- build: - build:
requires: requires:
- install-ruby2.5 - install-ruby2.5

View File

@ -1,71 +0,0 @@
# frozen_string_literal: true
class AuthorizeFollowsController < ApplicationController
layout 'modal'
before_action :authenticate_user!
before_action :set_pack
before_action :set_body_classes
def show
@account = located_account || render(:error)
end
def create
@account = follow_attempt.try(:target_account)
if @account.nil?
render :error
else
render :success
end
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
render :error
end
private
def set_pack
use_pack 'modal'
end
def follow_attempt
FollowService.new.call(current_account, acct_without_prefix)
end
def located_account
if acct_param_is_url?
account_from_remote_fetch
else
account_from_remote_follow
end
end
def account_from_remote_fetch
FetchRemoteAccountService.new.call(acct_without_prefix)
end
def account_from_remote_follow
ResolveAccountService.new.call(acct_without_prefix)
end
def acct_param_is_url?
parsed_uri.path && %w(http https).include?(parsed_uri.scheme)
end
def parsed_uri
Addressable::URI.parse(acct_without_prefix).normalize
end
def acct_without_prefix
acct_params.gsub(/\Aacct:/, '')
end
def acct_params
params.fetch(:acct, '')
end
def set_body_classes
@body_classes = 'modal-layout'
end
end

View File

@ -0,0 +1,71 @@
# frozen_string_literal: true
class AuthorizeInteractionsController < ApplicationController
include Authorization
layout 'modal'
before_action :authenticate_user!
before_action :set_body_classes
before_action :set_resource
before_action :set_pack
def show
if @resource.is_a?(Account)
render :show
elsif @resource.is_a?(Status)
redirect_to web_url("statuses/#{@resource.id}")
else
render :error
end
end
def create
if @resource.is_a?(Account) && FollowService.new.call(current_account, @resource)
render :success
else
render :error
end
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
render :error
end
private
def set_resource
@resource = located_resource || render(:error)
authorize(@resource, :show?) if @resource.is_a?(Status)
end
def located_resource
if uri_param_is_url?
ResolveURLService.new.call(uri_param)
else
account_from_remote_follow
end
end
def account_from_remote_follow
ResolveAccountService.new.call(uri_param)
end
def uri_param_is_url?
parsed_uri.path && %w(http https).include?(parsed_uri.scheme)
end
def parsed_uri
Addressable::URI.parse(uri_param).normalize
end
def uri_param
params[:uri] || params.fetch(:acct, '').gsub(/\Aacct:/, '')
end
def set_body_classes
@body_classes = 'modal-layout'
end
def set_pack
use_pack 'modal'
end
end

View File

@ -8,7 +8,7 @@ class IntentsController < ApplicationController
if uri.scheme == 'web+mastodon' if uri.scheme == 'web+mastodon'
case uri.host case uri.host
when 'follow' when 'follow'
return redirect_to authorize_follow_path(acct: uri.query_values['uri'].gsub(/\Aacct:/, '')) return redirect_to authorize_interaction_path(uri: uri.query_values['uri'].gsub(/\Aacct:/, ''))
when 'share' when 'share'
return redirect_to share_path(text: uri.query_values['text']) return redirect_to share_path(text: uri.query_values['text'])
end end

View File

@ -47,5 +47,6 @@ class RemoteFollowController < ApplicationController
def set_body_classes def set_body_classes
@body_classes = 'modal-layout' @body_classes = 'modal-layout'
@hide_header = true
end end
end end

View File

@ -0,0 +1,53 @@
# frozen_string_literal: true
class RemoteInteractionController < ApplicationController
include Authorization
layout 'modal'
before_action :set_status
before_action :set_body_classes
before_action :set_pack
def new
@remote_follow = RemoteFollow.new(session_params)
end
def create
@remote_follow = RemoteFollow.new(resource_params)
if @remote_follow.valid?
session[:remote_follow] = @remote_follow.acct
redirect_to @remote_follow.interact_address_for(@status)
else
render :new
end
end
private
def resource_params
params.require(:remote_follow).permit(:acct)
end
def session_params
{ acct: session[:remote_follow] }
end
def set_status
@status = Status.find(params[:id])
authorize @status, :show?
rescue Mastodon::NotPermittedError
# Reraise in order to get a 404
raise ActiveRecord::RecordNotFound
end
def set_body_classes
@body_classes = 'modal-layout'
@hide_header = true
end
def set_pack
use_pack 'modal'
end
end

View File

@ -38,4 +38,14 @@ module HomeHelper
end end
end end
end end
def obscured_counter(count)
if count <= 0
0
elsif count == 1
1
else
'1+'
end
end
end end

View File

@ -26,6 +26,7 @@ module SettingsHelper
io: 'Ido', io: 'Ido',
it: 'Italiano', it: 'Italiano',
ja: '日本語', ja: '日本語',
ka: 'ქართული',
ko: '한국어', ko: '한국어',
nl: 'Nederlands', nl: 'Nederlands',
no: 'Norsk', no: 'Norsk',

View File

@ -37,3 +37,17 @@ delegate(document, '.status__content__spoiler-link', 'click', ({ target }) => {
return false; return false;
}); });
delegate(document, '.modal-button', 'click', e => {
e.preventDefault();
let href;
if (e.target.nodeName !== 'A') {
href = e.target.parentNode.href;
} else {
href = e.target.href;
}
window.open(href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
});

View File

@ -50,7 +50,7 @@ class Item extends React.PureComponent {
handleClick = (e) => { handleClick = (e) => {
const { index, onClick } = this.props; const { index, onClick } = this.props;
if (e.button === 0) { if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault(); e.preventDefault();
onClick(index); onClick(index);
} }

View File

@ -65,7 +65,7 @@ export default class Status extends ImmutablePureComponent {
} }
handleAccountClick = (e) => { handleAccountClick = (e) => {
if (this.context.router && e.button === 0) { if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
const id = e.currentTarget.getAttribute('data-id'); const id = e.currentTarget.getAttribute('data-id');
e.preventDefault(); e.preventDefault();
this.context.router.history.push(`/accounts/${id}`); this.context.router.history.push(`/accounts/${id}`);

View File

@ -64,7 +64,7 @@ export default class StatusContent extends React.PureComponent {
} }
onMentionClick = (mention, e) => { onMentionClick = (mention, e) => {
if (this.context.router && e.button === 0) { if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault(); e.preventDefault();
this.context.router.history.push(`/accounts/${mention.get('id')}`); this.context.router.history.push(`/accounts/${mention.get('id')}`);
} }
@ -73,7 +73,7 @@ export default class StatusContent extends React.PureComponent {
onHashtagClick = (hashtag, e) => { onHashtagClick = (hashtag, e) => {
hashtag = hashtag.replace(/^#/, '').toLowerCase(); hashtag = hashtag.replace(/^#/, '').toLowerCase();
if (this.context.router && e.button === 0) { if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault(); e.preventDefault();
this.context.router.history.push(`/timelines/tag/${hashtag}`); this.context.router.history.push(`/timelines/tag/${hashtag}`);
} }

View File

@ -30,7 +30,7 @@ export default class ReplyIndicator extends ImmutablePureComponent {
} }
handleAccountClick = (e) => { handleAccountClick = (e) => {
if (e.button === 0) { if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault(); e.preventDefault();
this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`); this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`);
} }

View File

@ -26,7 +26,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
}; };
handleAccountClick = (e) => { handleAccountClick = (e) => {
if (e.button === 0) { if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault(); e.preventDefault();
this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`); this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`);
} }

View File

@ -37,7 +37,7 @@ export default class BoostModal extends ImmutablePureComponent {
} }
handleAccountClick = (e) => { handleAccountClick = (e) => {
if (e.button === 0) { if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault(); e.preventDefault();
this.props.onClose(); this.props.onClose();
this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`); this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`);

View File

@ -0,0 +1,311 @@
{
"account.badges.bot": "ბოტი",
"account.block": "დაბლოკე @{name}",
"account.block_domain": "დაიმალოს ყველაფერი დომენიდან {domain}",
"account.blocked": "დაიბლოკა",
"account.direct": "პირდაპირი წერილი @{name}-ს",
"account.disclaimer_full": "ქვემოთ მოცემულმა ინფორმაციამ შეიძლება სრულად არ ასახოს მომხმარებლის პროფილი.",
"account.domain_blocked": "დომენი დამალულია",
"account.edit_profile": "პროფილის ცვლილება",
"account.endorse": "გამორჩევა პროფილზე",
"account.follow": "გაყოლა",
"account.followers": "მიმდევრები",
"account.follows": "მიდევნებები",
"account.follows_you": "მოგყვებათ",
"account.hide_reblogs": "დაიმალოს ბუსტები @{name}-სგან",
"account.media": "მედია",
"account.mention": "ასახელეთ @{name}",
"account.moved_to": "{name} გადავიდა:",
"account.mute": "გააჩუმე @{name}",
"account.mute_notifications": "გააჩუმე შეტყობინებები @{name}-სგან",
"account.muted": "გაჩუმებული",
"account.posts": "ტუტები",
"account.posts_with_replies": "ტუტები და პასუხები",
"account.report": "დაარეპორტე @{name}",
"account.requested": "დამტკიცების მოლოდინში. დააწკაპუნეთ რომ უარყოთ დადევნების მოთხონვა",
"account.share": "გააზიარე @{name}-ის პროფილი",
"account.show_reblogs": "აჩვენე ბუსტები @{name}-სგან",
"account.unblock": "განბლოკე @{name}",
"account.unblock_domain": "გამოაჩინე {domain}",
"account.unendorse": "არ გამოირჩეს პროფილზე",
"account.unfollow": "ნუღარ მიჰყვები",
"account.unmute": "ნუღარ აჩუმებ @{name}-ს",
"account.unmute_notifications": "ნუღარ აჩუმებ შეტყობინებებს @{name}-სგან",
"account.view_full_profile": "სრული პროფილის ჩვენება",
"alert.unexpected.message": "წარმოიშვა მოულოდნელი შეცდომა.",
"alert.unexpected.title": "უპს!",
"boost_modal.combo": "შეგიძლიათ დააჭიროთ {combo}-ს რათა შემდეგ ჯერზე გამოტოვოთ ეს",
"bundle_column_error.body": "ამ კომპონენტის ჩატვირთვისას რაღაც აირია.",
"bundle_column_error.retry": "სცადეთ კიდევ ერთხელ",
"bundle_column_error.title": "ქსელის შეცდომა",
"bundle_modal_error.close": "დახურვა",
"bundle_modal_error.message": "ამ კომპონენტის ჩატვირთვისას რაღაც აირია.",
"bundle_modal_error.retry": "სცადეთ კიდევ ერთხელ",
"column.blocks": "დაბლოკილი მომხმარებლები",
"column.community": "ლოკალური თაიმლაინი",
"column.direct": "პირდაპირი წერილები",
"column.domain_blocks": "დამალული დომენები",
"column.favourites": "ფავორიტები",
"column.follow_requests": "დადევნების მოთხოვნები",
"column.home": "სახლი",
"column.lists": "სიები",
"column.mutes": "გაჩუმებული მომხმარებლები",
"column.notifications": "შეტყობინებები",
"column.pins": "აპინული ტუტები",
"column.public": "ფედერალური თაიმლაინი",
"column_back_button.label": "უკან",
"column_header.hide_settings": "პარამეტრების დამალვა",
"column_header.moveLeft_settings": "სვეტის მარცხნივ გადატანა",
"column_header.moveRight_settings": "სვეტის მარჯვნივ გადატანა",
"column_header.pin": "აპინვა",
"column_header.show_settings": "პარამეტრების ჩვენება",
"column_header.unpin": "პინის მოხსნა",
"column_subheading.settings": "პარამეტრები",
"community.column_settings.media_only": "მხოლოდ მედია",
"compose_form.direct_message_warning": "ეს ტუტი გაეგზავნება მხოლოდ ნახსენებ მომხმარებლებს.",
"compose_form.direct_message_warning_learn_more": "გაიგე მეტი",
"compose_form.hashtag_warning": "ეს ტუტი არ მოექცევა ჰეშტეგების ქვეს, რამეთუ ის არაა მითითებული. მხოლოდ ღია ტუტები მოიძებნება ჰეშტეგით.",
"compose_form.lock_disclaimer": "თქვენი ანგარიში არაა {locked}. ნებისმიერს შეიძლია გამოგყვეთ, რომ იხილოს თქვენი მიმდევრებზე გათვლილი პოსტები.",
"compose_form.lock_disclaimer.lock": "ჩაკეტილი",
"compose_form.placeholder": "რაზე ფიქრობ?",
"compose_form.publish": "ტუტი",
"compose_form.publish_loud": "{publish}!",
"compose_form.sensitive.marked": "მედია მონიშნულია მგრძნობიარედ",
"compose_form.sensitive.unmarked": "მედია არაა მონიშნული მგრძნობიარედ",
"compose_form.spoiler.marked": "გაფრთხილების უკან ტექსტი დამალულია",
"compose_form.spoiler.unmarked": "ტექსტი არაა დამალული",
"compose_form.spoiler_placeholder": "თქვენი გაფრთხილება დაწერეთ აქ",
"confirmation_modal.cancel": "უარყოფა",
"confirmations.block.confirm": "ბლოკი",
"confirmations.block.message": "დარწმუნებული ხართ, გსურთ დაბლოკოთ {name}?",
"confirmations.delete.confirm": "გაუქმება",
"confirmations.delete.message": "დარწმუნებული ხართ, გსურთ გააუქმოთ ეს სტატუსი?",
"confirmations.delete_list.confirm": "გაუქმება",
"confirmations.delete_list.message": "დარწმუნებული ხართ, გსურთ სამუდამოდ გააუქმოთ ეს სია?",
"confirmations.domain_block.confirm": "მთელი დომენის დამალვა",
"confirmations.domain_block.message": "ნაღდად, ნაღდად, დარწმუნებული ხართ, გსურთ დაბლოკოთ მთელი {domain}? უმეტეს შემთხვევაში რამდენიმე გამიზნული ბლოკი ან გაჩუმება საკმარისი და უკეთესია. კონტენტს ამ დომენიდან ვერ იხილავთ ვერც ერთ ღია თაიმლაინზე ან თქვენს შეტყობინებებში. ამ დომენიდან არსებული მიმდევრები ამოიშლება.",
"confirmations.mute.confirm": "გაჩუმება",
"confirmations.mute.message": "დარწმუნებული ხართ, გსურთ გააჩუმოთ {name}?",
"confirmations.redraft.confirm": "გაუქმება და გადანაწილება",
"confirmations.redraft.message": "დარწმუნებული ხართ, გსურთ გააუქმოთ ეს სტატუსი და გადაანაწილოთ? დაკარგავთ ყველა პასუხს, ბუსტს და მასზედ არსებულ ფავორიტს.",
"confirmations.unfollow.confirm": "ნუღარ მიჰყვები",
"confirmations.unfollow.message": "დარწმუნებული ხართ, აღარ გსურთ მიჰყვებოდეთ {name}-ს?",
"embed.instructions": "ეს სტატუსი ჩასვით თქვენს ვებ-საიტზე შემდეგი კოდის კოპირებით.",
"embed.preview": "ესაა თუ როგორც გამოჩნდება:",
"emoji_button.activity": "აქტივობა",
"emoji_button.custom": "პერსონალიზირებული",
"emoji_button.flags": "დროშები",
"emoji_button.food": "საჭმელი და სასლმელი",
"emoji_button.label": "ემოჯის ჩასმა",
"emoji_button.nature": "ბუმება",
"emoji_button.not_found": "არაა ემოჯი!! (╯°□°)╯︵ ┻━┻",
"emoji_button.objects": "ობიექტები",
"emoji_button.people": "ხალხი",
"emoji_button.recent": "ხშირად გამოყენებული",
"emoji_button.search": "ძებნა...",
"emoji_button.search_results": "ძებნის შედეგები",
"emoji_button.symbols": "სიმბოლოები",
"emoji_button.travel": "მოგზაურობა და ადგილები",
"empty_column.community": "ლოკალური თაიმლაინი ცარიელია. დაწერეთ რაიმე ღიად ან ქენით რაიმე სხვა!",
"empty_column.direct": "ჯერ პირდაპირი წერილები არ გაქვთ. როდესაც მიიღებთ ან გააგზავნით, გამოჩნდება აქ.",
"empty_column.hashtag": "ამ ჰეშტეგში ჯერ არაფერია.",
"empty_column.home": "თქვენი სახლის თაიმლაინი ცარიელია! ესტუმრეთ {public}-ს ან დასაწყისისთვის გამოიყენეთ ძებნა, რომ შეხვდეთ სხვა მომხმარებლებს.",
"empty_column.home.public_timeline": "ღია თაიმლაინი",
"empty_column.list": "ამ სიაში ჯერ არაფერია. როდესაც სიის წევრები დაპოსტავენ ახალ სტატუსებს, ისინი გამოჩნდებიან აქ.",
"empty_column.notifications": "ჯერ შეტყობინებები არ გაქვთ. საუბრის დასაწყებად იურთიერთქმედეთ სხვებთან.",
"empty_column.public": "აქ არაფერია! შესავსებად, დაწერეთ რაიმე ღიად ან ხელით გაჰყევით მომხმარებლებს სხვა ინსტანციებისგან",
"follow_request.authorize": "ავტორიზაცია",
"follow_request.reject": "უარყოფა",
"getting_started.developers": "დეველოპერები",
"getting_started.documentation": "დოკუმენტაცია",
"getting_started.find_friends": "იპოვეთ მეგობრები ტვიტერიდან",
"getting_started.heading": "დაწყება",
"getting_started.invite": "ხალხის მოწვევა",
"getting_started.open_source_notice": "მასტოდონი ღია პროგრამაა. შეგიძლიათ შეუწყოთ ხელი ან შექმნათ პრობემის რეპორტი {github}-ზე.",
"getting_started.security": "უსაფრთხოება",
"getting_started.terms": "მომსახურების პირობები",
"home.column_settings.basic": "ძირითადი",
"home.column_settings.show_reblogs": "ბუსტების ჩვენება",
"home.column_settings.show_replies": "პასუხების ჩვენება",
"keyboard_shortcuts.back": "უკან გადასასვლელად",
"keyboard_shortcuts.boost": "დასაბუსტად",
"keyboard_shortcuts.column": "ერთ-ერთი სვეტში სტატუსზე ფოკუსირებისთვის",
"keyboard_shortcuts.compose": "შედგენის ტექსტ-არეაზე ფოკუსირებისთვის",
"keyboard_shortcuts.description": "აღწერილობა",
"keyboard_shortcuts.down": "სიაში ქვემოთ გადასაადგილებლად",
"keyboard_shortcuts.enter": "სტატუსის გასახსნელად",
"keyboard_shortcuts.favourite": "ფავორიტად ქცევისთვის",
"keyboard_shortcuts.heading": "კლავიატურის სწრაფი ბმულები",
"keyboard_shortcuts.hotkey": "ცხელი კლავიში",
"keyboard_shortcuts.legend": "ამ ლეგენდის გამოსაჩენად",
"keyboard_shortcuts.mention": "ავტორის დასახელებლად",
"keyboard_shortcuts.profile": "ავტორის პროფილის გასახსნელად",
"keyboard_shortcuts.reply": "პასუხისთვის",
"keyboard_shortcuts.search": "ძიებაზე ფოკუსირებისთვის",
"keyboard_shortcuts.toggle_hidden": "გაფრთხილების უკან ტექსტის გამოსაჩენად/დასამალვად",
"keyboard_shortcuts.toot": "ახალი ტუტის დასაწყებად",
"keyboard_shortcuts.unfocus": "შედგენის ტექსტ-არეაზე ფოკუსის მოსაშორებლად",
"keyboard_shortcuts.up": "სიაში ზემოთ გადასაადგილებლად",
"lightbox.close": "დახურვა",
"lightbox.next": "შემდეგი",
"lightbox.previous": "წინა",
"lists.account.add": "სიაში დამატება",
"lists.account.remove": "სიიდან ამოშლა",
"lists.delete": "სიის წაშლა",
"lists.edit": "სიის შეცვლა",
"lists.new.create": "სიის დამატება",
"lists.new.title_placeholder": "ახალი სიის სათაური",
"lists.search": "ძებნა ადამიანებს შორის რომელთაც მიჰყვებით",
"lists.subheading": "თქვენი სიები",
"loading_indicator.label": "იტვირთება...",
"media_gallery.toggle_visible": "ხილვადობის ჩართვა",
"missing_indicator.label": "არაა ნაპოვნი",
"missing_indicator.sublabel": "ამ რესურსის პოვნა ვერ მოხერხდა",
"mute_modal.hide_notifications": "დავმალოთ შეტყობინებები ამ მომხმარებლისგან?",
"navigation_bar.blocks": "დაბლოკილი მომხმარებლები",
"navigation_bar.community_timeline": "ლოკალური თაიმლაინი",
"navigation_bar.direct": "პირდაპირი წერილები",
"navigation_bar.discover": "აღმოაჩინე",
"navigation_bar.domain_blocks": "დამალული დომენები",
"navigation_bar.edit_profile": "შეცვალე პროფილი",
"navigation_bar.favourites": "ფავორიტები",
"navigation_bar.filters": "გაჩუმებული სიტყვები",
"navigation_bar.follow_requests": "დადევნების მოთხოვნები",
"navigation_bar.info": "ამ ინსტანციის შესახებ",
"navigation_bar.keyboard_shortcuts": "ცხელი კლავიშები",
"navigation_bar.lists": "სიები",
"navigation_bar.logout": "გასვლა",
"navigation_bar.mutes": "გაჩუმებული მომხმარებლები",
"navigation_bar.personal": "პირადი",
"navigation_bar.pins": "აპინული ტუტები",
"navigation_bar.preferences": "პრეფერენსიები",
"navigation_bar.public_timeline": "ფედერალური თაიმლაინი",
"navigation_bar.security": "უსაფრთხოება",
"notification.favourite": "{name}-მა თქვენი სტატუსი აქცია ფავორიტად",
"notification.follow": "{name} გამოგყვათ",
"notification.mention": "{name}-მა გასახელათ",
"notification.reblog": "{name}-მა დაბუსტა თქვენი სტატუსი",
"notifications.clear": "შეტყობინებების გასუფთავება",
"notifications.clear_confirmation": "დარწმუნებული ხართ, გსურთ სამუდამოდ წაშალოთ ყველა თქვენი შეტყობინება?",
"notifications.column_settings.alert": "დესკტოპ შეტყობინებები",
"notifications.column_settings.favourite": "ფავორიტები:",
"notifications.column_settings.follow": "ახალი მიმდევრები:",
"notifications.column_settings.mention": "ხსენებები:",
"notifications.column_settings.push": "ფუშ შეტყობინებები",
"notifications.column_settings.push_meta": "ეს მოწყობილობა",
"notifications.column_settings.reblog": "ბუსტები:",
"notifications.column_settings.show": "გამოჩნდეს სვეტში",
"notifications.column_settings.sound": "ხმის დაკვრა",
"notifications.group": "{count} შეტყობინება",
"onboarding.done": "დასასრული",
"onboarding.next": "შემდეგი",
"onboarding.page_five.public_timelines": "ლოკალური თაიმლაინი {domain}-ზე საჯარო პოსტებს აჩვენებს ყველასგან. ფედერალური თაიმლაინი {domain}-ზე აჩვენებს საჯარო პოსტებს ყველასგან ვინც მიჰყვება. ეს საჯარო თაიმლაინებია, ახალი ადამიანების აღმოჩენის კარგი გზაა.",
"onboarding.page_four.home": "სახლის თაიმლაინი აჩვენებს პოსტებს ადამიანებისგან, რომლებსაც მიჰყვებით.",
"onboarding.page_four.notifications": "შეტყობინებების სვეტი აჩვენებს სხვის ურთიერთქმედებებს თქვენთან.",
"onboarding.page_one.federation": "მასტოდონი დამოუკიდებელი სერვერების ქსელია, რომლებიც ერთიანდებიან ერთი დიდი სოციალური ქსელის შექმნისთვის. ამ სერვერებს ჩვენ ვეძახით ინსტანციებს.",
"onboarding.page_one.full_handle": "თქვენი სრული სახელური",
"onboarding.page_one.handle_hint": "ეს არის ის რასაც ეტყოდით თქვენს მეგობრებს რომ მოძიონ.",
"onboarding.page_one.welcome": "კეთილი იყოს თქვენი მასტოდონში მობრძანება!",
"onboarding.page_six.admin": "თქვენი ინსტანციის ადმინისტრატორია {admin}.",
"onboarding.page_six.almost_done": "თითქმის დასრულდა...",
"onboarding.page_six.appetoot": "ბონ აპეტუტ!",
"onboarding.page_six.apps_available": "ხელმისაწვდომია {apps} აი-ოსისთვის, ანდროიდისთვის და სხვა პლატფორმებისთვის.",
"onboarding.page_six.github": "მასტოდონი უფასო ღია პროგრამაა. შეგიძლიათ დაარეპორტოთ შეცდომები, მოითხოვოთ ფუნქციები, შეუწყოთ ხელი კოდს {github}-ზე.",
"onboarding.page_six.guidelines": "საზოგადოების სახელმძღვანელო",
"onboarding.page_six.read_guidelines": "გთხოვთ გაეცნოთ {domain}-ს {guidelines}!",
"onboarding.page_six.various_app": "მობაილ აპები",
"onboarding.page_three.profile": "შეცვალეთ თქვენი პროფილი რომ შეცვალოთ ავატარი, ბიოგრაფია და დისპლეის სახელი. იქ, ასევე იხილავთ სხვა პრეფერენსიების.",
"onboarding.page_three.search": "გამოიყენეთ ძიება რომ იპოვნოთ ადამიანები და იხილოთ ჰეშტეგები, ისეთები როგორებიცაა {illustration} და {introductions}. რომ მოძებნოთ ადამიანი ვინც არაა ამ ინსტანციაზე, გამოიყენეთ სრული სახელური.",
"onboarding.page_two.compose": "პოსტები შექმენით კომპოზიციის სვეტიდან. შეგიძლიათ ატვირთოთ სურათები, შეცვალოთ კონფიდენციალურობა და ქვემოთ მოცემული პიქტოგრამით დაამატოთ კონტენტის გაფრთხილება.",
"onboarding.skip": "გამოტოვება",
"privacy.change": "სტატუსის კონფიდენციალურობის მითითება",
"privacy.direct.long": "დაიპოსტოს მხოლოდ დასახელებულ მომხმარებლებთან",
"privacy.direct.short": "პირდაპირი",
"privacy.private.long": "დაიპოსტოს მხოლოდ მიმდევრებთან",
"privacy.private.short": "მხოლოდ-მიმდევრებისთვის",
"privacy.public.long": "დაიპოსტოს საჯარო თაიმლაინებზე",
"privacy.public.short": "საჯარო",
"privacy.unlisted.long": "არ დაიპოსტოს საჯარო თაიმლაინებზე",
"privacy.unlisted.short": "ჩამოუთვლელი",
"regeneration_indicator.label": "იტვირთება…",
"regeneration_indicator.sublabel": "თქვენი სახლის ლენტა მზადდება!",
"relative_time.days": "{number}დღ",
"relative_time.hours": "{number}სთ",
"relative_time.just_now": "ახლა",
"relative_time.minutes": "{number}წთ",
"relative_time.seconds": "{number}წმ",
"reply_indicator.cancel": "უარყოფა",
"report.forward": "ფორვარდი {target}-ს",
"report.forward_hint": "ანგარიში სხვა სერვერიდანაა. გავაგზავნოთ რეპორტის ანონიმური ასლიც?",
"report.hint": "რეპორტი გაეგზავნება თქვენი ინსტანციის მოდერატორებს. ქვემოთ შეგიძლიათ დაამატოთ მიზეზი თუ რატომ არეპორტებთ ამ ანგარიშს:",
"report.placeholder": "დამატებითი კომენტარები",
"report.submit": "დასრულება",
"report.target": "არეპორტებთ {target}",
"search.placeholder": "ძებნა",
"search_popout.search_format": "დეტალური ძებნის ფორმა",
"search_popout.tips.full_text": "მარტივი ტექსტი აბრუნებს სტატუსებს რომლებიც შექმენით, აქციეთ ფავორიტად, დაბუსტეთ, ან რაშიც ასახელეთ, ასევე ემთხვევა მომხმარებლის სახელებს, დისპლეი სახელებს, და ჰეშტეგებს.",
"search_popout.tips.hashtag": "ჰეშტეგი",
"search_popout.tips.status": "სტატუსი",
"search_popout.tips.text": "მარტივი ტექსტი აბრუნებს დამთხვეულ დისპლეი სახელებს, მომხმარებლის სახელებს და ჰეშტეგებს",
"search_popout.tips.user": "მომხმარებელი",
"search_results.accounts": "ხალხი",
"search_results.hashtags": "ჰეშტეგები",
"search_results.statuses": "ტუტები",
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
"standalone.public_title": "შიდა ხედი...",
"status.block": "დაბლოკე @{name}",
"status.cancel_reblog_private": "ბუსტის მოშორება",
"status.cannot_reblog": "ეს პოსტი ვერ დაიბუსტება",
"status.delete": "წაშლა",
"status.direct": "პირდაპირი წერილი @{name}-ს",
"status.embed": "ჩართვა",
"status.favourite": "ფავორიტი",
"status.filtered": "ფილტრირებული",
"status.load_more": "მეტის ჩატვირთვა",
"status.media_hidden": "მედია დამალულია",
"status.mention": "ასახელე @{name}",
"status.more": "მეტი",
"status.mute": "გააჩუმე @{name}",
"status.mute_conversation": "გააჩუმე საუბარი",
"status.open": "ამ სტატუსის გაფართოება",
"status.pin": "აპინე პროფილზე",
"status.pinned": "აპინული ტუტი",
"status.reblog": "ბუსტი",
"status.reblog_private": "დაიბუსტოს საწყის აუდიტორიაზე",
"status.reblogged_by": "{name} დაიბუსტა",
"status.redraft": "გაუქმდეს და გადანაწილდეს",
"status.reply": "პასუხი",
"status.replyAll": "უპასუხე თემას",
"status.report": "დაარეპორტე @{name}",
"status.sensitive_toggle": "დააწკაპუნეთ სანახავად",
"status.sensitive_warning": "მგრძნობიარე კონტენტი",
"status.share": "გაზიარება",
"status.show_less": "აჩვენე ნაკლები",
"status.show_less_all": "აჩვენე ნაკლები ყველაზე",
"status.show_more": "აჩვენე მეტი",
"status.show_more_all": "აჩვენე მეტი ყველაზე",
"status.unmute_conversation": "საუბარზე გაჩუმების მოშორება",
"status.unpin": "პროფილიდან პინის მოშორება",
"tabs_bar.federated_timeline": "ფედერალური",
"tabs_bar.home": "სახლი",
"tabs_bar.local_timeline": "ლოკალური",
"tabs_bar.notifications": "შეტყობინებები",
"tabs_bar.search": "ძებნა",
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} საუბრობს",
"ui.beforeunload": "თქვენი დრაფტი გაუქმდება თუ დატოვებთ მასტოდონს.",
"upload_area.title": "გადმოწიეთ და ჩააგდეთ ასატვირთათ",
"upload_button.label": "მედიის დამატება",
"upload_form.description": "აღწერილობა ვიზუალურად უფასურისთვის",
"upload_form.focus": "კროპი",
"upload_form.undo": "გაუქმება",
"upload_progress.label": "იტვირთება...",
"video.close": "ვიდეოს დახურვა",
"video.exit_fullscreen": "სრულ ეკრანზე ჩვენების გათიშვა",
"video.expand": "ვიდეოს გაფართოება",
"video.fullscreen": "ჩვენება სრულ ეკრანზე",
"video.hide": "ვიდეოს დამალვა",
"video.mute": "ხმის გაჩუმება",
"video.pause": "პაუზა",
"video.play": "დაკვრა",
"video.unmute": "ხმის გაჩუმების მოშორება"
}

View File

@ -0,0 +1,2 @@
[
]

View File

@ -51,13 +51,6 @@ function main() {
}, datetime, now, datetime.getFullYear()); }, datetime, now, datetime.getFullYear());
}); });
[].forEach.call(document.querySelectorAll('.modal-button'), (content) => {
content.addEventListener('click', (e) => {
e.preventDefault();
window.open(e.target.href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
});
});
const reactComponents = document.querySelectorAll('[data-component]'); const reactComponents = document.querySelectorAll('[data-component]');
if (reactComponents.length > 0) { if (reactComponents.length > 0) {
import(/* webpackChunkName: "containers/media_container" */ '../mastodon/containers/media_container') import(/* webpackChunkName: "containers/media_container" */ '../mastodon/containers/media_container')

View File

@ -628,6 +628,7 @@
overflow: hidden; overflow: hidden;
white-space: pre-wrap; white-space: pre-wrap;
padding-top: 2px; padding-top: 2px;
color: $primary-text-color;
&:focus { &:focus {
outline: 0; outline: 0;

View File

@ -3,6 +3,7 @@
border-radius: 4px; border-radius: 4px;
overflow: hidden; overflow: hidden;
margin-bottom: 10px; margin-bottom: 10px;
text-align: left;
@media screen and (max-width: $no-gap-breakpoint) { @media screen and (max-width: $no-gap-breakpoint) {
margin-bottom: 0; margin-bottom: 0;
@ -36,7 +37,8 @@
&:last-child { &:last-child {
.detailed-status, .detailed-status,
.status { .status,
.load-more {
border-bottom: 0; border-bottom: 0;
border-radius: 0 0 4px 4px; border-radius: 0 0 4px 4px;
} }
@ -44,13 +46,15 @@
&:first-child { &:first-child {
.detailed-status, .detailed-status,
.status { .status,
.load-more {
border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0;
} }
&:last-child { &:last-child {
.detailed-status, .detailed-status,
.status { .status,
.load-more {
border-radius: 4px; border-radius: 4px;
} }
} }
@ -58,11 +62,16 @@
@media screen and (max-width: 740px) { @media screen and (max-width: 740px) {
.detailed-status, .detailed-status,
.status { .status,
.load-more {
border-radius: 0 !important; border-radius: 0 !important;
} }
} }
} }
&--highlighted .entry {
background: lighten($ui-base-color, 8%);
}
} }
.button.logo-button { .button.logo-button {

View File

@ -32,11 +32,11 @@ class Favourite < ApplicationRecord
private private
def increment_cache_counters def increment_cache_counters
status.increment_count!(:favourites_count) status&.increment_count!(:favourites_count)
end end
def decrement_cache_counters def decrement_cache_counters
return if association(:status).loaded? && (status.marked_for_destruction? || status.marked_for_mass_destruction?) return if association(:status).loaded? && (status.marked_for_destruction? || status.marked_for_mass_destruction?)
status.decrement_count!(:favourites_count) status&.decrement_count!(:favourites_count)
end end
end end

View File

@ -22,6 +22,10 @@ class RemoteFollow
addressable_template.expand(uri: account.local_username_and_domain).to_s addressable_template.expand(uri: account.local_username_and_domain).to_s
end end
def interact_address_for(status)
addressable_template.expand(uri: ActivityPub::TagManager.instance.uri_for(status)).to_s
end
private private
def populate_template def populate_template

View File

@ -416,6 +416,8 @@ class Status < ApplicationRecord
private private
def update_status_stat!(attrs) def update_status_stat!(attrs)
return if marked_for_destruction? || destroyed?
record = status_stat || build_status_stat record = status_stat || build_status_stat
record.update(attrs) record.update(attrs)
end end
@ -482,8 +484,8 @@ class Status < ApplicationRecord
Account.where(id: account_id).update_all('statuses_count = COALESCE(statuses_count, 0) + 1') Account.where(id: account_id).update_all('statuses_count = COALESCE(statuses_count, 0) + 1')
end end
reblog.increment_count!(:reblogs_count) if reblog? reblog&.increment_count!(:reblogs_count) if reblog?
thread.increment_count!(:replies_count) if in_reply_to_id.present? && (public_visibility? || unlisted_visibility?) thread&.increment_count!(:replies_count) if in_reply_to_id.present? && (public_visibility? || unlisted_visibility?)
end end
def decrement_counter_caches def decrement_counter_caches
@ -495,7 +497,7 @@ class Status < ApplicationRecord
Account.where(id: account_id).update_all('statuses_count = GREATEST(COALESCE(statuses_count, 0) - 1, 0)') Account.where(id: account_id).update_all('statuses_count = GREATEST(COALESCE(statuses_count, 0) - 1, 0)')
end end
reblog.decrement_count!(:reblogs_count) if reblog? reblog&.decrement_count!(:reblogs_count) if reblog?
thread.decrement_count!(:replies_count) if in_reply_to_id.present? && (public_visibility? || unlisted_visibility?) thread&.decrement_count!(:replies_count) if in_reply_to_id.present? && (public_visibility? || unlisted_visibility?)
end end
end end

View File

@ -20,7 +20,7 @@ class WebfingerSerializer < ActiveModel::Serializer
{ rel: 'self', type: 'application/activity+json', href: account_url(object) }, { rel: 'self', type: 'application/activity+json', href: account_url(object) },
{ rel: 'salmon', href: api_salmon_url(object.id) }, { rel: 'salmon', href: api_salmon_url(object.id) },
{ rel: 'magic-public-key', href: "data:application/magic-public-key,#{object.magic_key}" }, { rel: 'magic-public-key', href: "data:application/magic-public-key,#{object.magic_key}" },
{ rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_follow_url}?acct={uri}" }, { rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_interaction_url}?uri={uri}" },
] ]
end end
end end

View File

@ -1,17 +0,0 @@
- content_for :page_title do
= t('authorize_follow.title', acct: @account.acct)
.form-container
.follow-prompt
= render 'application/card', account: @account
- if current_account.following?(@account)
.flash-message
%strong
= t('authorize_follow.already_following')
= render 'post_follow_actions'
- else
= form_tag authorize_follow_path, method: :post, class: 'simple_form' do
= hidden_field_tag :acct, @account.acct
= button_tag t('authorize_follow.follow'), type: :submit

View File

@ -1,4 +1,4 @@
.post-follow-actions .post-follow-actions
%div= link_to t('authorize_follow.post_follow.web'), web_url("accounts/#{@account.id}"), class: 'button button--block' %div= link_to t('authorize_follow.post_follow.web'), web_url("accounts/#{@resource.id}"), class: 'button button--block'
%div= link_to t('authorize_follow.post_follow.return'), TagManager.instance.url_for(@account), class: 'button button--block' %div= link_to t('authorize_follow.post_follow.return'), TagManager.instance.url_for(@resource), class: 'button button--block'
%div= t('authorize_follow.post_follow.close') %div= t('authorize_follow.post_follow.close')

View File

@ -0,0 +1,18 @@
- content_for :page_title do
= t('authorize_follow.title', acct: @resource.acct)
.form-container
.follow-prompt
= render 'application/card', account: @resource
- if current_account.following?(@resource)
.flash-message
%strong
= t('authorize_follow.already_following')
= render 'post_follow_actions'
- else
= form_tag authorize_interaction_path, method: :post, class: 'simple_form' do
= hidden_field_tag :action, :follow
= hidden_field_tag :acct, @resource.acct
= button_tag t('authorize_follow.follow'), type: :submit

View File

@ -1,13 +1,13 @@
- content_for :page_title do - content_for :page_title do
= t('authorize_follow.title', acct: @account.acct) = t('authorize_follow.title', acct: @resource.acct)
.form-container .form-container
.follow-prompt .follow-prompt
- if @account.locked? - if @resource.locked?
%h2= t('authorize_follow.follow_request') %h2= t('authorize_follow.follow_request')
- else - else
%h2= t('authorize_follow.following') %h2= t('authorize_follow.following')
= render 'application/card', account: @account = render 'application/card', account: @resource
= render 'post_follow_actions' = render 'post_follow_actions'

View File

@ -1,5 +1,5 @@
- content_for :content do - content_for :content do
- if user_signed_in? - if user_signed_in? && !@hide_header
.account-header .account-header
.avatar= image_tag current_account.avatar.url(:original) .avatar= image_tag current_account.avatar.url(:original)
.name .name

View File

@ -0,0 +1,17 @@
.form-container
.follow-prompt
%h2= t('remote_interaction.prompt')
.public-layout
.activity-stream.activity-stream--highlighted
= render 'stream_entries/status', status: @status
= simple_form_for @remote_follow, as: :remote_follow, url: remote_interaction_path(@status) do |f|
= render 'shared/error_messages', object: @remote_follow
= f.input :acct, placeholder: t('remote_follow.acct'), input_html: { autocapitalize: 'none', autocorrect: 'off' }
.actions
= f.button :button, t('remote_interaction.proceed'), type: :submit
%p.hint.subtle-hint= t('remote_follow.no_account_html', sign_up_path: open_registrations? ? new_user_registration_path : 'https://joinmastodon.org/#getting-started')

View File

@ -39,6 +39,11 @@
- else - else
= link_to status.application.name, status.application.website, class: 'detailed-status__application', target: '_blank', rel: 'noopener' = link_to status.application.name, status.application.website, class: 'detailed-status__application', target: '_blank', rel: 'noopener'
· ·
= link_to remote_interaction_path(status), class: 'modal-button detailed-status__link' do
= fa_icon('reply')
%span.detailed-status__reblogs>= number_to_human status.replies_count, strip_insignificant_zeros: true
= " "
·
- if status.direct_visibility? - if status.direct_visibility?
%span.detailed-status__link< %span.detailed-status__link<
= fa_icon('envelope') = fa_icon('envelope')
@ -46,13 +51,15 @@
%span.detailed-status__link< %span.detailed-status__link<
= fa_icon('lock') = fa_icon('lock')
- else - else
%span.detailed-status__link< = link_to remote_interaction_path(status), class: 'modal-button detailed-status__link' do
= fa_icon('retweet') = fa_icon('retweet')
%span.detailed-status__reblogs= number_to_human status.reblogs_count, strip_insignificant_zeros: true %span.detailed-status__reblogs>= number_to_human status.reblogs_count, strip_insignificant_zeros: true
= " "
· ·
%span.detailed-status__link< = link_to remote_interaction_path(status), class: 'modal-button detailed-status__link' do
= fa_icon('star') = fa_icon('star')
%span.detailed-status__favorites= number_to_human status.favourites_count, strip_insignificant_zeros: true %span.detailed-status__favorites>= number_to_human status.favourites_count, strip_insignificant_zeros: true
= " "
- if user_signed_in? - if user_signed_in?
· ·

View File

@ -30,14 +30,16 @@
= react_component :media_gallery, height: 343, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } = react_component :media_gallery, height: 343, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
.status__action-bar .status__action-bar
.status__action-bar-button.static-icon-button< .status__action-bar__counter
= link_to remote_interaction_path(status), class: 'status__action-bar-button icon-button modal-button', style: 'font-size: 18px; width: 23.1429px; height: 23.1429px; line-height: 23.15px;' do
= fa_icon 'reply fw'
.status__action-bar__counter__label= obscured_counter status.replies_count
= link_to remote_interaction_path(status), class: 'status__action-bar-button icon-button modal-button', style: 'font-size: 18px; width: 23.1429px; height: 23.1429px; line-height: 23.15px;' do
- if status.public_visibility? || status.unlisted_visibility? - if status.public_visibility? || status.unlisted_visibility?
= fa_icon 'retweet fw' = fa_icon 'retweet fw'
%span.detailed-status__reblogs= number_to_human status.reblogs_count, strip_insignificant_zeros: true
- elsif status.private_visibility? - elsif status.private_visibility?
= fa_icon 'lock fw' = fa_icon 'lock fw'
- else - else
= fa_icon 'envelope fw' = fa_icon 'envelope fw'
.status__action-bar-button.static-icon-button< = link_to remote_interaction_path(status), class: 'status__action-bar-button icon-button modal-button', style: 'font-size: 18px; width: 23.1429px; height: 23.1429px; line-height: 23.15px;' do
= fa_icon 'star fw' = fa_icon 'star fw'
%span.detailed-status__favorites= number_to_human status.favourites_count, strip_insignificant_zeros: true

View File

@ -53,3 +53,9 @@
- if @next_descendant_thread - if @next_descendant_thread
.entry{ class: entry_classes } .entry{ class: entry_classes }
= link_to_more short_account_status_url(status.account.username, status, since_descendant_thread_id: @max_descendant_thread_id - 1) = link_to_more short_account_status_url(status.account.username, status, since_descendant_thread_id: @max_descendant_thread_id - 1)
- if include_threads && !embedded_view? && !user_signed_in?
.entry{ class: entry_classes }
= link_to new_user_session_path, class: 'load-more load-gap' do
= fa_icon 'comments'
= t('statuses.sign_in_to_participate')

View File

@ -19,7 +19,7 @@
.grid .grid
.column-0 .column-0
.activity-stream.activity-stream-headless.h-entry .activity-stream.h-entry
= render partial: "stream_entries/#{@type}", locals: { @type.to_sym => @stream_entry.activity, include_threads: true } = render partial: "stream_entries/#{@type}", locals: { @type.to_sym => @stream_entry.activity, include_threads: true }
.column-1 .column-1
= render 'application/sidebar' = render 'application/sidebar'

View File

@ -37,7 +37,7 @@ doc << Ox::Element.new('XRD').tap do |xrd|
xrd << Ox::Element.new('Link').tap do |link| xrd << Ox::Element.new('Link').tap do |link|
link['rel'] = 'http://ostatus.org/schema/1.0/subscribe' link['rel'] = 'http://ostatus.org/schema/1.0/subscribe'
link['template'] = "#{authorize_follow_url}?acct={uri}" link['template'] = "#{authorize_interaction_url}?acct={uri}"
end end
end end

View File

@ -61,6 +61,7 @@ module Mastodon
:io, :io,
:it, :it,
:ja, :ja,
:ka,
:ko, :ko,
:nl, :nl,
:no, :no,

View File

@ -1,5 +1,25 @@
{ {
"ignored_warnings": [ "ignored_warnings": [
{
"warning_type": "SQL Injection",
"warning_code": 0,
"fingerprint": "04dbbc249b989db2e0119bbb0f59c9818e12889d2b97c529cdc0b1526002ba4b",
"check_name": "SQL",
"message": "Possible SQL injection",
"file": "app/models/report.rb",
"line": 86,
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
"code": "Admin::ActionLog.from(\"(#{[Admin::ActionLog.where(:target_type => \"Report\", :target_id => id, :created_at => ((created_at..updated_at))).unscope(:order), Admin::ActionLog.where(:target_type => \"Account\", :target_id => target_account_id, :created_at => ((created_at..updated_at))).unscope(:order), Admin::ActionLog.where(:target_type => \"Status\", :target_id => status_ids, :created_at => ((created_at..updated_at))).unscope(:order)].map do\n \"(#{query.to_sql})\"\n end.join(\" UNION ALL \")}) AS admin_action_logs\")",
"render_path": null,
"location": {
"type": "method",
"class": "Report",
"method": "history"
},
"user_input": "Admin::ActionLog.where(:target_type => \"Status\", :target_id => status_ids, :created_at => ((created_at..updated_at))).unscope(:order)",
"confidence": "High",
"note": ""
},
{ {
"warning_type": "Cross-Site Scripting", "warning_type": "Cross-Site Scripting",
"warning_code": 4, "warning_code": 4,
@ -7,8 +27,8 @@
"check_name": "LinkToHref", "check_name": "LinkToHref",
"message": "Potentially unsafe model attribute in link_to href", "message": "Potentially unsafe model attribute in link_to href",
"file": "app/views/admin/accounts/show.html.haml", "file": "app/views/admin/accounts/show.html.haml",
"line": 147, "line": 167,
"link": "http://brakemanscanner.org/docs/warning_types/link_to_href", "link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
"code": "link_to(Account.find(params[:id]).inbox_url, Account.find(params[:id]).inbox_url)", "code": "link_to(Account.find(params[:id]).inbox_url, Account.find(params[:id]).inbox_url)",
"render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}], "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}],
"location": { "location": {
@ -26,8 +46,8 @@
"check_name": "LinkToHref", "check_name": "LinkToHref",
"message": "Potentially unsafe model attribute in link_to href", "message": "Potentially unsafe model attribute in link_to href",
"file": "app/views/admin/accounts/show.html.haml", "file": "app/views/admin/accounts/show.html.haml",
"line": 153, "line": 173,
"link": "http://brakemanscanner.org/docs/warning_types/link_to_href", "link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
"code": "link_to(Account.find(params[:id]).shared_inbox_url, Account.find(params[:id]).shared_inbox_url)", "code": "link_to(Account.find(params[:id]).shared_inbox_url, Account.find(params[:id]).shared_inbox_url)",
"render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}], "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}],
"location": { "location": {
@ -45,8 +65,8 @@
"check_name": "LinkToHref", "check_name": "LinkToHref",
"message": "Potentially unsafe model attribute in link_to href", "message": "Potentially unsafe model attribute in link_to href",
"file": "app/views/admin/accounts/show.html.haml", "file": "app/views/admin/accounts/show.html.haml",
"line": 57, "line": 75,
"link": "http://brakemanscanner.org/docs/warning_types/link_to_href", "link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
"code": "link_to(Account.find(params[:id]).url, Account.find(params[:id]).url)", "code": "link_to(Account.find(params[:id]).url, Account.find(params[:id]).url)",
"render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}], "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}],
"location": { "location": {
@ -57,6 +77,26 @@
"confidence": "Weak", "confidence": "Weak",
"note": "" "note": ""
}, },
{
"warning_type": "Mass Assignment",
"warning_code": 105,
"fingerprint": "28d81cc22580ef76e912b077b245f353499aa27b3826476667224c00227af2a9",
"check_name": "PermitAttributes",
"message": "Potentially dangerous key allowed for mass assignment",
"file": "app/controllers/admin/reports_controller.rb",
"line": 86,
"link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/",
"code": "params.permit(:account_id, :resolved, :target_account_id)",
"render_path": null,
"location": {
"type": "method",
"class": "Admin::ReportsController",
"method": "filter_params"
},
"user_input": ":account_id",
"confidence": "High",
"note": ""
},
{ {
"warning_type": "Dynamic Render Path", "warning_type": "Dynamic Render Path",
"warning_code": 15, "warning_code": 15,
@ -65,9 +105,9 @@
"message": "Render path contains parameter value", "message": "Render path contains parameter value",
"file": "app/views/stream_entries/embed.html.haml", "file": "app/views/stream_entries/embed.html.haml",
"line": 3, "line": 3,
"link": "http://brakemanscanner.org/docs/warning_types/dynamic_render_path/", "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
"code": "render(action => \"stream_entries/#{Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity_type.downcase}\", { Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity_type.downcase.to_sym => Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity, :centered => true })", "code": "render(action => \"stream_entries/#{Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity_type.downcase}\", { Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity_type.downcase.to_sym => Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity, :centered => true })",
"render_path": [{"type":"controller","class":"StatusesController","method":"embed","line":45,"file":"app/controllers/statuses_controller.rb"}], "render_path": [{"type":"controller","class":"StatusesController","method":"embed","line":58,"file":"app/controllers/statuses_controller.rb"}],
"location": { "location": {
"type": "template", "type": "template",
"template": "stream_entries/embed" "template": "stream_entries/embed"
@ -83,8 +123,8 @@
"check_name": "Render", "check_name": "Render",
"message": "Render path contains parameter value", "message": "Render path contains parameter value",
"file": "app/views/admin/action_logs/index.html.haml", "file": "app/views/admin/action_logs/index.html.haml",
"line": 5, "line": 4,
"link": "http://brakemanscanner.org/docs/warning_types/dynamic_render_path/", "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
"code": "render(action => Admin::ActionLog.page(params[:page]), {})", "code": "render(action => Admin::ActionLog.page(params[:page]), {})",
"render_path": [{"type":"controller","class":"Admin::ActionLogsController","method":"index","line":7,"file":"app/controllers/admin/action_logs_controller.rb"}], "render_path": [{"type":"controller","class":"Admin::ActionLogsController","method":"index","line":7,"file":"app/controllers/admin/action_logs_controller.rb"}],
"location": { "location": {
@ -95,6 +135,26 @@
"confidence": "Weak", "confidence": "Weak",
"note": "" "note": ""
}, },
{
"warning_type": "Redirect",
"warning_code": 18,
"fingerprint": "5fad11cd67f905fab9b1d5739d01384a1748ebe78c5af5ac31518201925265a7",
"check_name": "Redirect",
"message": "Possible unprotected redirect",
"file": "app/controllers/remote_interaction_controller.rb",
"line": 20,
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
"code": "redirect_to(RemoteFollow.new(resource_params).interact_address_for(Status.find(params[:id])))",
"render_path": null,
"location": {
"type": "method",
"class": "RemoteInteractionController",
"method": "create"
},
"user_input": "RemoteFollow.new(resource_params).interact_address_for(Status.find(params[:id]))",
"confidence": "High",
"note": ""
},
{ {
"warning_type": "Cross-Site Scripting", "warning_type": "Cross-Site Scripting",
"warning_code": 4, "warning_code": 4,
@ -102,8 +162,8 @@
"check_name": "LinkToHref", "check_name": "LinkToHref",
"message": "Potentially unsafe model attribute in link_to href", "message": "Potentially unsafe model attribute in link_to href",
"file": "app/views/admin/accounts/show.html.haml", "file": "app/views/admin/accounts/show.html.haml",
"line": 156, "line": 176,
"link": "http://brakemanscanner.org/docs/warning_types/link_to_href", "link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
"code": "link_to(Account.find(params[:id]).followers_url, Account.find(params[:id]).followers_url)", "code": "link_to(Account.find(params[:id]).followers_url, Account.find(params[:id]).followers_url)",
"render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}], "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}],
"location": { "location": {
@ -121,8 +181,8 @@
"check_name": "LinkToHref", "check_name": "LinkToHref",
"message": "Potentially unsafe model attribute in link_to href", "message": "Potentially unsafe model attribute in link_to href",
"file": "app/views/admin/accounts/show.html.haml", "file": "app/views/admin/accounts/show.html.haml",
"line": 130, "line": 149,
"link": "http://brakemanscanner.org/docs/warning_types/link_to_href", "link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
"code": "link_to(Account.find(params[:id]).salmon_url, Account.find(params[:id]).salmon_url)", "code": "link_to(Account.find(params[:id]).salmon_url, Account.find(params[:id]).salmon_url)",
"render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}], "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}],
"location": { "location": {
@ -141,7 +201,7 @@
"message": "Render path contains parameter value", "message": "Render path contains parameter value",
"file": "app/views/admin/custom_emojis/index.html.haml", "file": "app/views/admin/custom_emojis/index.html.haml",
"line": 45, "line": 45,
"link": "http://brakemanscanner.org/docs/warning_types/dynamic_render_path/", "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
"code": "render(action => filtered_custom_emojis.eager_load(:local_counterpart).page(params[:page]), {})", "code": "render(action => filtered_custom_emojis.eager_load(:local_counterpart).page(params[:page]), {})",
"render_path": [{"type":"controller","class":"Admin::CustomEmojisController","method":"index","line":11,"file":"app/controllers/admin/custom_emojis_controller.rb"}], "render_path": [{"type":"controller","class":"Admin::CustomEmojisController","method":"index","line":11,"file":"app/controllers/admin/custom_emojis_controller.rb"}],
"location": { "location": {
@ -160,7 +220,7 @@
"message": "Possible SQL injection", "message": "Possible SQL injection",
"file": "lib/mastodon/snowflake.rb", "file": "lib/mastodon/snowflake.rb",
"line": 87, "line": 87,
"link": "http://brakemanscanner.org/docs/warning_types/sql_injection/", "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
"code": "connection.execute(\" CREATE OR REPLACE FUNCTION timestamp_id(table_name text)\\n RETURNS bigint AS\\n $$\\n DECLARE\\n time_part bigint;\\n sequence_base bigint;\\n tail bigint;\\n BEGIN\\n time_part := (\\n -- Get the time in milliseconds\\n ((date_part('epoch', now()) * 1000))::bigint\\n -- And shift it over two bytes\\n << 16);\\n\\n sequence_base := (\\n 'x' ||\\n -- Take the first two bytes (four hex characters)\\n substr(\\n -- Of the MD5 hash of the data we documented\\n md5(table_name ||\\n '#{SecureRandom.hex(16)}' ||\\n time_part::text\\n ),\\n 1, 4\\n )\\n -- And turn it into a bigint\\n )::bit(16)::bigint;\\n\\n -- Finally, add our sequence number to our base, and chop\\n -- it to the last two bytes\\n tail := (\\n (sequence_base + nextval(table_name || '_id_seq'))\\n & 65535);\\n\\n -- Return the time part and the sequence part. OR appears\\n -- faster here than addition, but they're equivalent:\\n -- time_part has no trailing two bytes, and tail is only\\n -- the last two bytes.\\n RETURN time_part | tail;\\n END\\n $$ LANGUAGE plpgsql VOLATILE;\\n\")", "code": "connection.execute(\" CREATE OR REPLACE FUNCTION timestamp_id(table_name text)\\n RETURNS bigint AS\\n $$\\n DECLARE\\n time_part bigint;\\n sequence_base bigint;\\n tail bigint;\\n BEGIN\\n time_part := (\\n -- Get the time in milliseconds\\n ((date_part('epoch', now()) * 1000))::bigint\\n -- And shift it over two bytes\\n << 16);\\n\\n sequence_base := (\\n 'x' ||\\n -- Take the first two bytes (four hex characters)\\n substr(\\n -- Of the MD5 hash of the data we documented\\n md5(table_name ||\\n '#{SecureRandom.hex(16)}' ||\\n time_part::text\\n ),\\n 1, 4\\n )\\n -- And turn it into a bigint\\n )::bit(16)::bigint;\\n\\n -- Finally, add our sequence number to our base, and chop\\n -- it to the last two bytes\\n tail := (\\n (sequence_base + nextval(table_name || '_id_seq'))\\n & 65535);\\n\\n -- Return the time part and the sequence part. OR appears\\n -- faster here than addition, but they're equivalent:\\n -- time_part has no trailing two bytes, and tail is only\\n -- the last two bytes.\\n RETURN time_part | tail;\\n END\\n $$ LANGUAGE plpgsql VOLATILE;\\n\")",
"render_path": null, "render_path": null,
"location": { "location": {
@ -180,7 +240,7 @@
"message": "Render path contains parameter value", "message": "Render path contains parameter value",
"file": "app/views/admin/accounts/index.html.haml", "file": "app/views/admin/accounts/index.html.haml",
"line": 67, "line": 67,
"link": "http://brakemanscanner.org/docs/warning_types/dynamic_render_path/", "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
"code": "render(action => filtered_accounts.page(params[:page]), {})", "code": "render(action => filtered_accounts.page(params[:page]), {})",
"render_path": [{"type":"controller","class":"Admin::AccountsController","method":"index","line":12,"file":"app/controllers/admin/accounts_controller.rb"}], "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"index","line":12,"file":"app/controllers/admin/accounts_controller.rb"}],
"location": { "location": {
@ -191,25 +251,6 @@
"confidence": "Weak", "confidence": "Weak",
"note": "" "note": ""
}, },
{
"warning_type": "Cross-Site Request Forgery",
"warning_code": 7,
"fingerprint": "ab491f72606337a348482d006eb67a3b1616685fd48644d5ac909bbcd62a5000",
"check_name": "ForgerySetting",
"message": "'protect_from_forgery' should be called in WellKnown::HostMetaController",
"file": "app/controllers/well_known/host_meta_controller.rb",
"line": 4,
"link": "http://brakemanscanner.org/docs/warning_types/cross-site_request_forgery/",
"code": null,
"render_path": null,
"location": {
"type": "controller",
"controller": "WellKnown::HostMetaController"
},
"user_input": null,
"confidence": "High",
"note": ""
},
{ {
"warning_type": "Redirect", "warning_type": "Redirect",
"warning_code": 18, "warning_code": 18,
@ -218,7 +259,7 @@
"message": "Possible unprotected redirect", "message": "Possible unprotected redirect",
"file": "app/controllers/media_controller.rb", "file": "app/controllers/media_controller.rb",
"line": 10, "line": 10,
"link": "http://brakemanscanner.org/docs/warning_types/redirect/", "link": "https://brakemanscanner.org/docs/warning_types/redirect/",
"code": "redirect_to(MediaAttachment.attached.find_by!(:shortcode => ((params[:id] or params[:medium_id]))).file.url(:original))", "code": "redirect_to(MediaAttachment.attached.find_by!(:shortcode => ((params[:id] or params[:medium_id]))).file.url(:original))",
"render_path": null, "render_path": null,
"location": { "location": {
@ -237,8 +278,8 @@
"check_name": "LinkToHref", "check_name": "LinkToHref",
"message": "Potentially unsafe model attribute in link_to href", "message": "Potentially unsafe model attribute in link_to href",
"file": "app/views/admin/accounts/show.html.haml", "file": "app/views/admin/accounts/show.html.haml",
"line": 119, "line": 138,
"link": "http://brakemanscanner.org/docs/warning_types/link_to_href", "link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
"code": "link_to(Account.find(params[:id]).remote_url, Account.find(params[:id]).remote_url)", "code": "link_to(Account.find(params[:id]).remote_url, Account.find(params[:id]).remote_url)",
"render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}], "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}],
"location": { "location": {
@ -256,8 +297,8 @@
"check_name": "Redirect", "check_name": "Redirect",
"message": "Possible unprotected redirect", "message": "Possible unprotected redirect",
"file": "app/controllers/remote_follow_controller.rb", "file": "app/controllers/remote_follow_controller.rb",
"line": 18, "line": 19,
"link": "http://brakemanscanner.org/docs/warning_types/redirect/", "link": "https://brakemanscanner.org/docs/warning_types/redirect/",
"code": "redirect_to(RemoteFollow.new(resource_params).subscribe_address_for(Account.find_local!(params[:account_username])))", "code": "redirect_to(RemoteFollow.new(resource_params).subscribe_address_for(Account.find_local!(params[:account_username])))",
"render_path": null, "render_path": null,
"location": { "location": {
@ -276,8 +317,8 @@
"check_name": "Render", "check_name": "Render",
"message": "Render path contains parameter value", "message": "Render path contains parameter value",
"file": "app/views/admin/reports/index.html.haml", "file": "app/views/admin/reports/index.html.haml",
"line": 25, "line": 22,
"link": "http://brakemanscanner.org/docs/warning_types/dynamic_render_path/", "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
"code": "render(action => filtered_reports.page(params[:page]), {})", "code": "render(action => filtered_reports.page(params[:page]), {})",
"render_path": [{"type":"controller","class":"Admin::ReportsController","method":"index","line":10,"file":"app/controllers/admin/reports_controller.rb"}], "render_path": [{"type":"controller","class":"Admin::ReportsController","method":"index","line":10,"file":"app/controllers/admin/reports_controller.rb"}],
"location": { "location": {
@ -288,25 +329,6 @@
"confidence": "Weak", "confidence": "Weak",
"note": "" "note": ""
}, },
{
"warning_type": "Cross-Site Request Forgery",
"warning_code": 7,
"fingerprint": "d4278f04e807ec58a23925f8ab31fad5e84692f2fb9f2f57e7931aff05d57cf8",
"check_name": "ForgerySetting",
"message": "'protect_from_forgery' should be called in WellKnown::WebfingerController",
"file": "app/controllers/well_known/webfinger_controller.rb",
"line": 4,
"link": "http://brakemanscanner.org/docs/warning_types/cross-site_request_forgery/",
"code": null,
"render_path": null,
"location": {
"type": "controller",
"controller": "WellKnown::WebfingerController"
},
"user_input": null,
"confidence": "High",
"note": ""
},
{ {
"warning_type": "Cross-Site Scripting", "warning_type": "Cross-Site Scripting",
"warning_code": 4, "warning_code": 4,
@ -314,8 +336,8 @@
"check_name": "LinkToHref", "check_name": "LinkToHref",
"message": "Potentially unsafe model attribute in link_to href", "message": "Potentially unsafe model attribute in link_to href",
"file": "app/views/admin/accounts/show.html.haml", "file": "app/views/admin/accounts/show.html.haml",
"line": 150, "line": 170,
"link": "http://brakemanscanner.org/docs/warning_types/link_to_href", "link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
"code": "link_to(Account.find(params[:id]).outbox_url, Account.find(params[:id]).outbox_url)", "code": "link_to(Account.find(params[:id]).outbox_url, Account.find(params[:id]).outbox_url)",
"render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}], "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}],
"location": { "location": {
@ -326,6 +348,26 @@
"confidence": "Weak", "confidence": "Weak",
"note": "" "note": ""
}, },
{
"warning_type": "Mass Assignment",
"warning_code": 105,
"fingerprint": "e867661b2c9812bc8b75a5df12b28e2a53ab97015de0638b4e732fe442561b28",
"check_name": "PermitAttributes",
"message": "Potentially dangerous key allowed for mass assignment",
"file": "app/controllers/api/v1/reports_controller.rb",
"line": 42,
"link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/",
"code": "params.permit(:account_id, :comment, :forward, :status_ids => ([]))",
"render_path": null,
"location": {
"type": "method",
"class": "Api::V1::ReportsController",
"method": "report_params"
},
"user_input": ":account_id",
"confidence": "High",
"note": ""
},
{ {
"warning_type": "Dynamic Render Path", "warning_type": "Dynamic Render Path",
"warning_code": 15, "warning_code": 15,
@ -333,10 +375,10 @@
"check_name": "Render", "check_name": "Render",
"message": "Render path contains parameter value", "message": "Render path contains parameter value",
"file": "app/views/stream_entries/show.html.haml", "file": "app/views/stream_entries/show.html.haml",
"line": 24, "line": 23,
"link": "http://brakemanscanner.org/docs/warning_types/dynamic_render_path/", "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
"code": "render(partial => \"stream_entries/#{Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity_type.downcase}\", { :locals => ({ Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity_type.downcase.to_sym => Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity, :include_threads => true }) })", "code": "render(partial => \"stream_entries/#{Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity_type.downcase}\", { :locals => ({ Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity_type.downcase.to_sym => Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity, :include_threads => true }) })",
"render_path": [{"type":"controller","class":"StatusesController","method":"show","line":22,"file":"app/controllers/statuses_controller.rb"}], "render_path": [{"type":"controller","class":"StatusesController","method":"show","line":30,"file":"app/controllers/statuses_controller.rb"}],
"location": { "location": {
"type": "template", "type": "template",
"template": "stream_entries/show" "template": "stream_entries/show"
@ -346,6 +388,6 @@
"note": "" "note": ""
} }
], ],
"updated": "2018-02-16 06:42:53 +0100", "updated": "2018-08-18 00:49:25 +0200",
"brakeman_version": "4.0.1" "brakeman_version": "4.2.1"
} }

View File

@ -0,0 +1,13 @@
---
ka:
activerecord:
errors:
models:
account:
attributes:
username:
invalid: მხოლოდ ასოები, ციფრები და "ქვედა-ტირე"
status:
attributes:
reblog:
taken: სტატუსის უკვე არსებობს

View File

@ -0,0 +1,82 @@
---
ka:
devise:
confirmations:
confirmed: თქვენი ელ-ფოსტის მისამართი წარმატებით დამოწმდა.
send_instructions: თქვენ მიიღებთ ელ-ფოსტას ინსტრუქციებით თუ როგორც დაამოწმოთ თქვენი ელ-ფოსტის მისამართი რამდენიმე წუთში. გთხოვთ შეხედოთ თქვენი სპამის ფოლდერს თუ არ მიიღებთ ამ წერილს.
send_paranoid_instructions: თუ თქვენი ელ-ფოსტა არსებობს ჩვენს მონაცემთა ბაზაში, თქვენ მიიღებთ ელ-ფოსტას ინსტრუქციებით თუ როგორც დაამოწმოთ თქვენი ელ-ფოსტის მისამართი რამდენიმე წუთში. გთხოვთ შეხედოთ თქვენი სპამის ფოლდერს თუ არ მიიღებთ ამ წერილს.
failure:
already_authenticated: უკვე შესული ხართ.
inactive: თქვენი ანგარიში ჯერ არაა აქტივირებული.
invalid: არასწორი %{authentication_keys} ან პაროლი.
last_attempt: თქვენი ანგარიშის ჩაკეტვამდე დაგრჩათ კიდევ ერთი მცდელობა.
locked: თქვენი ანგარიში ჩაიკეტა.
not_found_in_database: არასწორი %{authentication_keys} ან პაროლი.
timeout: თქვენს სესიას გაუვიდა ვადა. გთხოვთ შედით ახლიდან რომ გააგრძელოთ.
unauthenticated: გაგრძელებამდე საჭიროა შეხვიდეთ ან დარეგისტრირდეთ.
unconfirmed: გაგრძელებამდე საჭიროა დაამოწმოთ თქვენი ელ-ფოსტა.
mailer:
confirmation_instructions:
action: დაამოწმეთ ელ-ფოსტის მისამართი
explanation: თქვენ ამ ელ-ფოსტის მისამართი ანგარიში შექმენით %{host}-ზე. დარჩა ერთი დაწკაპუნება მის აქტივაციამდე. თუ ეს თქვენ არ იყავით, გთხოვთ არ მიაქციოთ ყურადღება ამ წერილს.
extra_html: გთხოვთ ასევე გაეცნოთ <a href="%{terms_path}">ინსტანციის წესებს</a> და <a href="%{policy_path}">ჩვენს კონფინდენციალურობის პოლიტიკას</a>.
subject: 'მასტოდონი: დამოწმების ინსტრუქციები %{instance}-თვის'
title: ელ-ფოსტის მისამართის დამოწმება
email_changed:
explanation: 'თქვენი ანგარიშის ელ-ფოსტის მისამართი იცვლება შემდეგზე:'
extra: თუ თქვენ არ შეგიცვლიათ თქვენი ელ-ფოსტის მისამართი, როგორც ჩანს სხვამ ხელთ იგდო თქვენი ანგარიში. გთოხვთ შეცვალოთ თქვენი პაროლი რაც შეიძლება მალე, ან დაუკავშირდეთ ინსტანციის ადმინისტრატორს თუ თქვენი ანგარიში ჩაიკეტა.
subject: 'მასტოდონი: ელ-ფოსტა შეიცვალა'
title: ახალი ელ-ფოსტის მისამართი
password_change:
explanation: თქვენი ანგარიშის პაროლი შეიცვალა.
extra: თუ თქვენ არ შეგიცვლიათ პაროლი, როგორც ჩანს სხვამ ხელთ იგდო თქვენი ანგარიში. გთოხვთ შეცვალოთ თქვენი პაროლი რაც შეიძლება მალე, ან დაუკავშირდეთ ინსტანციის ადმინისტრატორს თუ თქვენი ანგარიში ჩაიკეტა.
subject: 'მასტოდონი: პაროლი შეიცვალა'
title: პაროლი შეიცვალა
reconfirmation_instructions:
explanation: დაამოწმეთ ახალი ელ-ფოსტის მისამართი ცვლილებისთვის.
extra: თუ თქვენ არ გამოიწვიეთ ეს ცვლილება, გთხოვთ არ მიაქციოთ ყურადღება ამ წერილს. მასტოდონის ელ-ფოსტის მისამართი არ შეიცვლება სანამ არ გადახვალთ ზემოთ მოცემულ ბმულზე.
subject: 'მასტოდონი: დაამოწმეთ ელ-ფოსტის მისამართი %{instance}-თვის'
title: დაამოწმეთ ელ-ფოსტის მისამართი
reset_password_instructions:
action: შეცვალეთ პაროლი
explanation: თქვენ მოითხოვეთ ახალი პაროლი თქვენი ანგარიშისთვის.
extra: თუ ეს თქვენ არ მოგითხოვიათ, გთხოვთ არ მიაქციოთ ყურადღება ამ წერილს. თქვენი პაროლი არ შეიცვლება, სანამ არ გადახვალთ ზემოთ მოცემულ ბმულზე.
subject: 'მასტოდონი: პაროლის განახლების ინსტრუქცეიბი'
title: პაროლის განახლება
unlock_instructions:
subject: 'მასტოდონი: ჩაკეტვის მოხსნის ინსტრუქციები'
omniauth_callbacks:
failure: 'ვერ მოხდა აუტენტიფიკაცია %{kind}-თან. მიზეზი: "%{reason}".'
success: წარმატებით შედგა აუტენტიფიკაცია %{kind} ანგარიშთან.
passwords:
no_token: ამ გვერდზე წვდომა ვერ გექნებათ თუ არ მოდიხართ პაროლის აღდგენის ელ-ფოსტის წერილიდან. თუ მოდიხართ პაროლის აღგენის წერილიდან, დაამოწმეთ რომ გადადიხართ სრულ ურლ-ზე.
send_instructions: თუ თქვენი ელ-ფოსტა არსებობს ჩვენს მონაცემთა ბაზაში, თქვენ მიიღებთ ელ-ფოსტაზე წერილს პაროლის განახლების ბმულით, რამდენიმე წუთში. გთხოვთ შეხედოთ თქვენი სპამის ფოლდერს თუ არ მიიღებთ ამ წერილს.
send_paranoid_instructions: თუ თქვენი ელ-ფოსტა არსებობს ჩვენს მონაცემთა ბაზაში, თქვენ მიიღებთ ელ-ფოსტაზე წერილს პაროლის განახლების ბმულით, რამდენიმე წუთში. გთხოვთ შეხედოთ თქვენი სპამის ფოლდერს თუ არ მიიღებთ ამ წერილს.
updated: თქვენი პაროლი წარმატებით შეიცვალა. ახლა შესული ხართ.
updated_not_active: თქვენი პაროლი წარმატებით შეიცვალა.
registrations:
destroyed: ნახვამდის! თქვენი ანგარიში წარმატებით გაუქმდა. იმედი გვაქვს ისევ შევხვდებით.
signed_up: გამარჯობა! თქვენ წარმატებით დარეგისტრირდით.
signed_up_but_inactive: თქვენ წარმატებით დარეგისტრირდით. თუმცა, ავტორიზაცია ვერ შედგა, თქვენი ანგარიში ჯერ არაა გააქტიურებული.
signed_up_but_locked: თქვენ წარმატებით დარეგისტრირდით. თუმცა, აცტორიზაცია ვერ შედგა, თქვენი ანგარიში ჩაკეტილია.
signed_up_but_unconfirmed: წერილი დამოწმების ბმულით თქვენს ელ-ფოსტაზე გამოგზავნილია. გთხოვთ გაჰყევით ბმულს, რათა გაააქტიუროთ ანგარიში. გთხოვთ შეხედოთ თქვენი სპამის ფოლდერს თუ არ მიიღებთ ამ წერილს.
update_needs_confirmation: თქვენი ანგარიში წარმატებით განახლდა, მაგრამ გვესაჭიროება თქვენი ელ-ფოსტის მისამართის დამოწმება. შეამოწმეთ ელ-ფოსტა და დასამოწმებლად გადადით მიღებულ ბმულზე. გთხოვთ შეხედოთ თქვენი სპამის ფოლდერს თუ არ მიიღებთ ამ წერილს.
updated: თქვენი ანგარიში წარმატებით განახლდა.
sessions:
already_signed_out: წარმატებით გახვედით.
signed_in: წარმატებით შეხვედით.
signed_out: წარმატებით გახვედით.
unlocks:
send_instructions: წერილს, ინსტრუქციებით თუ როგორ მოხსნათ ჩაკეტვა თქვენს ანგარიშს, მიიღებთ რამდენიმე წუთში. გთხოვთ შეხედოთ თქვენი სპამის ფოლდერს თუ არ მიიღებთ ამ წერილს.
send_paranoid_instructions: თუ თქვენი ელ-ფოსტა არსებობს ჩვენს მონაცემთა ბაზაში, თქვენ მიიღებთ ელ-ფოსტაზე წერილს ჩაკეტვის მოხნის ინსტრუქციებით. გთხოვთ შეხედოთ თქვენი სპამის ფოლდერს თუ არ მიიღებთ ამ წერილს.
unlocked: თქვენს ანგარიშს ჩაკეტვა წარმატებით მოეხსნა. გაგრძელებისთვის, გთხოვთ გაიაროთ ავტორიზაცია.
errors:
messages:
already_confirmed: უკვე დამოწმდა, გთხოვთ სცადოთ ავტორიზაციის გავლა
confirmation_period_expired: საჭიროებს დამოწმებას პერიოდში %{period}, გთხოვთ მოითხოვოთ ახლიდან
expired: გაუვიდა ვადა, გთხოვთ მოითხოვოთ ახალი
not_found: ვერ იქნა ნაპოვნი
not_locked: არ ჩაკეტილა
not_saved:
one: "%{resource} ვერ დამახსოვრდა ერთი შეცდომის გამო:"
other: "%{resource} ვერ დამახსოვრდა %{count} შეცდომის გამო:"

View File

@ -0,0 +1,142 @@
---
ka:
activerecord:
attributes:
doorkeeper/application:
name: აპლიკაციის სახელი
redirect_uri: გადამისამართების ური
scopes: ფარგლები
website: აპლიკაციის ვებ-საიტი
errors:
models:
doorkeeper/application:
attributes:
redirect_uri:
fragment_present: ვერ ექნება ფრაგმეტი.
invalid_uri: უნდა იყოს ვალიდური ური.
relative_uri: უნდა იყოს აბსოლუტური ური.
secured_uri: უნდა იყოს ჰტტპს/სსლ ური.
doorkeeper:
applications:
buttons:
authorize: ავტორიზაცია
cancel: უარყოფა
destroy: გაუქმება
edit: შეცვლა
submit: გაგრძელება
confirmations:
destroy: დარწმუნებული ხართ?
edit:
title: აპლიკაციის შეცვლა
form:
error: უპს! შესაძლო შეცდომებზე შეამოწმეთ თქვენი ფორმა
help:
native_redirect_uri: ლოკალური ტესტებისთვის მოიხმარეთ %{native_redirect_uri}
redirect_uri: გამოიყენეთ ერთი ხაზი თითო ური-სთვის
scopes: ფარგლები გამოჰყავით სიცარიელით. საწყისი ფარგლის გამოსაყენებლად დატოვეთ ცარიელი.
index:
application: აპლიკაცია
callback_url: ქოლბექ ურლ
delete: გაუქმება
name: სახელი
new: ახალი აპლიკაცია
scopes: ფარგლები
show: ჩვენება
title: თქვენი აპლიკაციები
new:
title: ახალი აპლიკაცია
show:
actions: მოქმედებები
application_id: კლიენტის გასაღები
callback_urls: ქოლბექ ურლები
scopes: ფარგლები
secret: კლიენტის სერვერი
title: 'აპლიკაცია: %{name}'
authorizations:
buttons:
authorize: ავტორიზაცია
deny: აკრძალვა
error:
title: წარმოიშვა შეცდომა
new:
able_to: ის შეძლებს
prompt: აპლიკაცია %{client_name} ითხოვს წვდომას თქვენს ანგარიშზე
title: საჭიროა ავტორიზაცია
show:
title: დააკოპირეთ ეს ავტორიზაციის კოდი და ჩასვით აპლიკაციაში.
authorized_applications:
buttons:
revoke: გაუქმება
confirmations:
revoke: დარწმუნებული ხართ?
index:
application: აპლიკაცია
created_at: ავტორიზებული
date_format: "%Y-%m-%d %H:%M:%S"
scopes: ფარგლები
title: თქვენი ავტორიზებული აპლიკაციები
errors:
messages:
access_denied: რესურსის მფლობელმა ან აუტორიზაციის სერვერმა აკრძალა ეს მოთხოვნა.
credential_flow_not_configured: რესურის მფლობელის პაროლის რწმუნებულებების ნაკადი ვერ შესრულდა არაკონფიგურირებული Doorkeeper.configure.resource_owner_from_credentials გამო.
invalid_client: ამოუცნობი კლიენტის გამო კლიენტ აუტენტიფიკაცია ვერ მოხერხდა, კლიენტის აუტენტიფიკაცია არ იყო თან დართული, ან მხარდაუჭერელი აუტენტიფიკაციის მეთოდი.
invalid_grant: მოწოდებული ავტორიზაციის გრანტი არასწორია, ვადაგასულია, გაუქმებულია არ ემთხვევა გადამისამართების ურის, რომელიც მოიხმარება ავტორიზაცის მოთხოვნაში, ან მიეცა სხვა კლიენტს.
invalid_redirect_uri: მითითებული გადამისამართების ური არაა ვალიდური.
invalid_request: მოთხოვნას აკლია აუცილებელი პარამეტრი, მოიცავს მხარდაუჭერელ პარამეტრის მნიშვნელობას, ან სხვაგვარად არაა გამართული.
invalid_resource_owner: მოწოდებული რესურსის მფლობელის რწმუნებულებები არაა ვალიდური, ან მფლობელის პონვა ვერ ხერხდება
invalid_scope: მოთხოვნილი ფარგალი არასწორია, ამოუცნობია ან არაა გამართული.
invalid_token:
expired: წვდომის ტოკენს გაუვიდა ვადა
revoked: წვდომის ტოკენი გაუქმდა
unknown: წვდომის ტოკენი არაა ვალიდური
resource_owner_authenticator_not_configured: რესურსის მფლობელის მოპოვება არ შედგა Doorkeeper.configure.resource_owner_authenticator კონფიგურაციის არ არსებობის გამო.
server_error: აუტორიზაციის სერვერს შეხვდა მოულოდნელი მდგომარეობა, რამაც ხელი შეუშალა მას აღესრულებინა მოთხონვა.
temporarily_unavailable: ავტორიზაციის სერვერი ამჟამად ვერ ახერხებს მოთხოვნის შემუშავებას დროებითი გადატვირთვის ან სერვერის შენარჩუნების გამო.
unauthorized_client: კლიენტი არაა ავტორიზებული შეასრულოს ეს მოთხოვნა ამ მეთოდით.
unsupported_grant_type: ავტორიზაციის გრანტის სახეობა არაა მხარდაჭერილი ავტორიზაციის სერვერის მიერ.
unsupported_response_type: ავტორიზაციის სერვერი არ უჭერს მხარს ამ პასუხის სახეობას.
flash:
applications:
create:
notice: აპლიკაცია შეიქმნა.
destroy:
notice: აპლიკაცია გაუქმდა.
update:
notice: აპლიკაცია განახლდა.
authorized_applications:
destroy:
notice: აპლიკაცია წაიშალა.
layouts:
admin:
nav:
applications: აპლიკაციები
oauth2_provider: ოუ-აუთ2 პროვაიდერი
application:
title: საჭიროა ოუ-აუთ ავტორიზაცია
scopes:
follow: შეცვალეთ ანგარიშის ურთიერთობები
push: მიიღეთ თქვენი ფუშ შეტყობინებები
read: წაიკითხოს მთელი თქვენი ანგარიშის მონაცემები
read:accounts: იხილოს ანგარიშის ინფორმაცია
read:blocks: იხილოს თქვენი ბლოკები
read:favourites: იხილოს თქვენი ფავორიტები
read:filters: იხილოს თქვენი ფილრები
read:follows: იხილოს თქვენი მიდევნებები
read:lists: იხილოს თქვენი სიები
read:mutes: იხილოს თქვენი გაჩუმებები
read:notifications: იხილოს თქვენი შეტყობინებები
read:reports: იხილოს თქვენი რეპორტები
read:search: მოძებნოს თქვენი სახელით
read:statuses: იხილოს ყველა სტატუსი
write: შეცვალოს მთელი თქვენი ანგარიშის მონაცემები
write:accounts: შეცვალოს თქვენი პროფილი
write:blocks: დაბლოკოს ანგარიშები და დომენები
write:favourites: ფავორიტი სტატუსები
write:filters: შექმნას ფილტრები
write:follows: გაყვეს ხალხს
write:lists: შექმნას სიები
write:media: ატვირთოს მედია ფაილები
write:mutes: გააგჩუმოს ადამიანები და საუბრები
write:notifications: გაასუფთავოს თქვენი შეტყობინებები
write:reports: დაარეპორტოს სხვა ადამიანები
write:statuses: გამოაქვეყნოს სტატუსები

View File

@ -656,11 +656,14 @@ en:
publishing: Publishing publishing: Publishing
web: Web web: Web
remote_follow: remote_follow:
acct: Enter your username@domain you want to follow from acct: Enter your username@domain you want to act from
missing_resource: Could not find the required redirect URL for your account missing_resource: Could not find the required redirect URL for your account
no_account_html: Don't have an account? You can <a href='%{sign_up_path}' target='_blank'>sign up here</a> no_account_html: Don't have an account? You can <a href='%{sign_up_path}' target='_blank'>sign up here</a>
proceed: Proceed to follow proceed: Proceed to follow
prompt: 'You are going to follow:' prompt: 'You are going to follow:'
remote_interaction:
proceed: Proceed to interact
prompt: 'You want to interact with this toot:'
remote_unfollow: remote_unfollow:
error: Error error: Error
title: Title title: Title
@ -745,6 +748,7 @@ en:
private: Non-public toot cannot be pinned private: Non-public toot cannot be pinned
reblog: A boost cannot be pinned reblog: A boost cannot be pinned
show_more: Show more show_more: Show more
sign_in_to_participate: Sign in to participate in the conversation
title: '%{name}: "%{quote}"' title: '%{name}: "%{quote}"'
visibilities: visibilities:
private: Followers-only private: Followers-only

893
config/locales/ka.yml Normal file
View File

@ -0,0 +1,893 @@
---
ka:
about:
about_hashtag_html: ეს საჯარო ტუტებია, რომლებიც ატარებენ <strong>#%{hashtag}</strong> ტეგს. მათთან ინტერაქციას შეძლებთ, თუ ფედივერსში გაქვთ რაიმე ანგარიში.
about_mastodon_html: მასტოდონი ღია ვებ პროტოკოლებზე და უფასო, ღია პროგრამებზე დაფუძნებული სოციალური ქსელია. ის ისეთი დეცენტრალიზებულია როგორც ელ-ფოსტა.
about_this: შესახებ
administered_by: 'ადმინისტრატორი:'
api: აპი
closed_registrations: რეგისტრაციები ამჟამად ინსტანციაზე დახურულია. თუმცა! ანგარიშის შესაქმნელად შეგიძლიათ იპოვოთ სხვა ინსტანცია და იმავე ქსელზე იქონიოთ წვდომა იქიდან.
contact: კონტაქტი
contact_missing: არაა დაყენებული
contact_unavailable: მიუწ.
documentation: დოკუმენტაცია
extended_description_html: |
<h3>კარგი ადგილი წესებისთვის</h3>
<p>განვრცობილი აღწერილობა ჯერ არ შექმნილა.</p>
features:
humane_approach_body: სხვა ქსელების შეცდომების გათვალისწინებით, მასტოდონი მიზნად ისახავს ეტიკური დიზაინის არჩევნების გაკეთებას, დაუპირისპირდეს სოციალური მედიის არასწორ მოხმარებას.
humane_approach_title: უფრო ადამიანური მიდგომა
not_a_product_body: მასტოდონი არ არის კომერციული ქსელი. არაა რეკლამა, არაა მაინინგი, არაა შემოღობილი ბაღები. არაა ცენტრალური ავტორიტეტი.
not_a_product_title: შენ ხარ პერსონა და არა პროდუქტი
real_conversation_body: 500 ნიშნის განკარგულებით, მარცვლოვანი კონტენტის და მედია გაფრთხილებების მხარდაჭერით, შეგიძლიათ გამოხატოთ ისე როგორც გსურთ.
real_conversation_title: შექმნილია ნამდვილი საუბრისთვის
within_reach_body: დეველოპერისთვის-მეგობრული აპი ექოსისტემის წყალობით, მრავალი აპლიკაცია აი-ოსისთვის, ანდროიდისთვის და სხვა პლატფორმებისთვის, საშალებას მოგცემთ ნებისმიერი ადგილიდან იქონიოთ კავშირი თქვენს მეგობრებთან.
within_reach_title: მუდამ წვდომის ქვეშ
generic_description: "%{domain} ერთი სერვერია ქსელში"
hosted_on: მასტოდონს მასპინძლობს %{domain}
learn_more: გაიგე მეტი
other_instances: ინსტანციების სია
privacy_policy: კონფიდენციალურობის პოლიტიკა
source_code: კოდი
status_count_after: სტატუსები
status_count_before: ვინც უავტორა
terms: მომსახურების პირობები
user_count_after: მომხმარებლისთვის
user_count_before: სახლი
what_is_mastodon: რა არის მასტოდონი?
accounts:
choices_html: "%{name}-ის არჩევნები:"
follow: გაყევი
followers: მიმდევრები
following: მიჰყვება
joined: გაწევრიანდა %{date}
media: მედია
moved_html: "%{name} გადავიდა %{new_profile_link}:"
network_hidden: ეს ინფორმაცია ხელმიუწვდომელია
nothing_here: აქ არაფერია!
people_followed_by: ხალხი ვისაც %{name} მიჰყვება
people_who_follow: ხალხი ვინც მიჰყვება %{name}-ს
pin_errors:
following: იმ ადამიანს, ვინც მოგწონთ, უკვე უნდა მიჰყვებოდეთ
posts: ტუტები
posts_with_replies: ტუტები და პასუხები
reserved_username: მომხმარებელი რეზერვირებულია
roles:
admin: ადმინისტრატორი
bot: ბოტი
moderator: მოდერატორი
unfollow: ნუღარ მიჰყვები
admin:
account_moderation_notes:
create: დატოვეთ ჩანაწერი
created_msg: მოდერაციის ჩანაწერი წარმატებით შეიქმნა!
delete: გაუქმება
destroyed_msg: მოდერაციის ჩანაწერი წარმატებით გაუქმდა!
accounts:
are_you_sure: დარწმუნებული ხარ?
avatar: ავატარი
by_domain: დომენი
change_email:
changed_msg: ანგარიშის ელ-ფოსტა წარმატებით შეიცვალა!
current_email: მიმდინარე ელ-ფოსტა
label: ელ-ფოსტის შეცვლა
new_email: ახალი ელ-ფოსტა
submit: ელ-ფოსტის შეცვლა
title: შეცვალეთ ელ-ფოსტა მომხმარებლისთვის %{username}
confirm: დადასტურება
confirmed: დადასტურებულია
confirming: დასტურდება
demote: დაქვეითება
disable: გამორთვა
disable_two_factor_authentication: გამორთე 2FA
disabled: გამორთულია
display_name: დისპლეი სახელი
domain: დომენი
edit: შეცვლა
email: ელ-ფოსტა
email_status: ელ-ფოსტის სტატუსი
enable: ჩართვა
enabled: ჩართულია
feed_url: ლენტის ურლ
followers: მიმდევრები
followers_url: მიმდევრების ურლ
follows: დადევნებები
inbox_url: ინბოქსის ურლ
ip: აი-პი
location:
all: ყველა
local: ლოკალური
remote: დისტანციური
title: ადგილმდებარეობა
login_status: ლოგინის სტატუსი
media_attachments: თან-დართული მედია
memorialize: აქციე მემორანდუმად
moderation:
all: ყველა
silenced: გაჩუმებული
suspended: შეჩერებული
title: მოდერაცია
moderation_notes: მოდერაციის ჩანაწერები
most_recent_activity: უახლესი აქტივობა
most_recent_ip: უახლესი აი-პი
not_subscribed: გამოუწერელი
order:
alphabetic: ანბანური
most_recent: უახლესი
title: წესრიგი
outbox_url: აუთბოქსის ურლ
perform_full_suspension: მოახდინეთ სრული შეჩერება
profile_url: პროფილის ურლ
promote: დაწინაურება
protocol: პროტოკოლი
public: საჯარო
push_subscription_expires: ფუშ გამოწერა უქმდება
redownload: განაახლე ავატარი
remove_avatar: გააუქმე ავატარი
resend_confirmation:
already_confirmed: ეს მომხმარებელი უკვე დამოწმებულია
send: დამოწმების ინსტრუქციების გადაგზავნა
success: დამოწმების ინსტრუქციები წარმატებით გაიგზავნა!
reset: გადატვირთვა
reset_password: პაროლის გადატვირთვა
resubscribe: ხელახალი გამოწერა
role: უფლებები
roles:
admin: ადმინისტრატორი
moderator: მოდერატორი
staff: სტაფი
user: მომხმარებელი
salmon_url: სალმონის ურლ
search: ძებნა
shared_inbox_url: გაზიარებული ინბოქსის ურლ
show:
created_reports: ამ ანგარიშის მიერ შექმნილი რეპორტები
report: რეპორტი
targeted_reports: ამ ანგარიშზე მიღებული რეპორტები
silence: სიჩუმე
statuses: სტატუსები
subscribe: გამოწერა
title: ანგარიშები
unconfirmed_email: დაუმოწმებელი ელ-ფოსტა
undo_silenced: გაჩუმების მოშორება
undo_suspension: შეჩერების მოშორება
unsubscribe: გამოწერის შეწყვეტა
username: მომხმარებლის სახელი
web: ვები
action_logs:
actions:
assigned_to_self_report: "%{name}-მა დანიშნა რეპორტი %{target} საკუთარ თავზე"
change_email_user: "%{name}-მა შეცვალა %{target} მომხმარებლის ელ-ფოსტის მისამართი"
confirm_user: "%{name}-მა დაამოწმა %{target} მომხმარებლის ელ-ფოსტის მისამართი"
create_custom_emoji: "%{name}-მა ატვირთა ახალი ემოჯი %{target}"
create_domain_block: "%{name}-მა დაბლოკა დომენი %{target}"
create_email_domain_block: "%{name}-მა შავ სიაში მოაქცია დომენი %{target}"
demote_user: "%{name}-მა დააქვეითა მომხმარებელი %{target}"
destroy_domain_block: "%{name}-მა ბლოკი მოხსნა დომენს %{target}"
destroy_email_domain_block: "%{name} თეთრ სიაში მოაქცია დომენი %{target}"
destroy_status: "%{name}-მა გააუქმა სტატუსი %{target}-ზე"
disable_2fa_user: "%{name} გათიშა მეორე ფაქტორის მოთხოვნილება მომხმარებელზე %{target}"
disable_custom_emoji: "%{name}-მა გათისა ემოჯი %{target}"
disable_user: "%{name}-მა გათიშა ლოგინი მომხმარებლისთვის %{target}"
enable_custom_emoji: "%{name}-მა ჩართო ემოჯი %{target}"
enable_user: "%{name}-მა ჩართო ლოგინი მომხმარებლისთვის %{target}"
memorialize_account: "%{name}-მა აქცია ანგარიში %{target} მემორანდუმის გვერდად"
promote_user: "%{name}-მა დააწინაურა მომხმარებელი %{target}"
remove_avatar_user: "%{name}-მა გააუქმა %{target} მომხმარებლის ავატარი"
reopen_report: "%{name}-მა ხელახლა გახსნა რეპორტი %{target}"
reset_password_user: "%{name} გადატვირთა მომხმარებლის %{target} პაროლი"
resolve_report: "%{name}-მა მოაგვარა %{target} მომხმარებლის რეპორტი"
silence_account: "%{name}-მა გააჩუმა %{target} ანგარიში"
suspend_account: "%{name} შეაჩერა %{target} ანგარიში"
unassigned_report: "%{name}-მა მოაშორა რეპორტი %{target}"
unsilence_account: "%{name}-მა მოაშორა გაჩუმება %{target} ანგარიშს"
unsuspend_account: "%{name}-მა მოაშორა შეჩერება %{target} ანგარიშს"
update_custom_emoji: "%{name}-მა განაახლა ემოჯი %{target}"
update_status: "%{name}-მა განაახლა სტატუსი %{target}-ით"
deleted_status: "(გაუქმებული სტატუსი)"
title: აუდიტის ლოგი
custom_emojis:
by_domain: დომენი
copied_msg: ემოჯის ლოკალური ასლი წარმატებით შეიქმნა
copy: კოპირება
copy_failed_msg: ამ ემოჯის ლოკალური ასლი ვერ შეიქმნა
created_msg: ემოჯი წარმატებით შეიქმნა!
delete: გაუქმება
destroyed_msg: ემოჯი წარმატებით გაუქმდა!
disable: გათიშვა
disabled_msg: ეს ემოჯი წარმატებით გაითიშა
emoji: ემოჯი
enable: ჩართვა
enabled_msg: წარმატებით ჩაირთო ეს ემოჯი
image_hint: PNG 50კბმდე
listed: ჩამოთვლილი
new:
title: ახალი პერსონალიზირებული ემოჯის დამატება
overwrite: გადაწერა
shortcode: მოკლე-კოდი
shortcode_hint: მინ. 2 ნიშანი, მხოლოდ ალფანუმერიკული ნიშნები და "ქვედა-ტირეები"
title: პერსონალიზირებული ემოჯიები
unlisted: ჩამოუთვლელი
update_failed_msg: ემოჯის განახლება ვერ მოხერხდა
updated_msg: ემოჯი წარმატებით განახლდა!
upload: ატვირთვა
dashboard:
backlog: დაუსრულებელი საქმეები
config: კონფიგურაცია
feature_deletions: ანგარიშის გაუქმებები
feature_invites: მოწვევის ბმულები
feature_registrations: რეგისტრაციები
feature_relay: ფედერაციის რილეი
features: ფუნქციები
hidden_service: ფედერაცია დამალულ სერვისებთან
open_reports: ღია რეპორტები
recent_users: ახალი მომხმარებლები
search: სრული-ტექსტის ძიება
single_user_mode: ერთ-მომხმარებლიანი რეჟიმი
software: პროგრამა
space: მოცულობის მოხმარება
title: დაფა
total_users: სულ მომხმარებლები
trends: ტრენდები
week_interactions: ამ კვირის ინტერაქციები
week_users_active: აქტიური ამ კვირას
week_users_new: ამ კვირის მომხმარებლები
domain_blocks:
add_new: ახლის დამატება
created_msg: დომენის ბლოკი ახლა პროცესირების ქვეშაა
destroyed_msg: დომენის ბლოკი გაუქმდა
domain: დომენი
new:
create: ბლოკის შექმნა
hint: დომენის ბლოკი არ შეაჩერებს ანგარიშების ჩაწერას მონაცემთა ბაზაში, მაგრამ ეს ამ ანგარიშებზე რეტროაქტიულად და ავტომატურად გაატარებს სპეციფიურ მოდერაციის მეთოდებს.
severity:
desc_html: "<strong>გაჩუმება</strong> გახდის ანგარიშის პოსტებს უჩინარს ყველასთვის, ვინც მას არ მიჰყვება. <strong>შეჩერება</strong> გააუქმებს ანგარიშის მთელ კონტენტს, მედიას და პროფილის მონაცემს. გამოიყენეთ <strong>არც ერთი</strong> თუ გსურთ უბრალოდ უარყოთ ფაილები."
noop: არც ერთი
silence: გაჩუმება
suspend: შეჩერება
title: ახალი დომენის ბლოკი
reject_media: მედია ფაილების უარყოფა
reject_media_hint: შლის ლოკალურად შენახულ მედია ფაილებს და უარყოფს სამომავლო გადმოტვირთებს. შეუსაბამო შეჩერებებისთვის
severities:
noop: არც ერთი
silence: გაჩუმება
suspend: შეჩერება
severity: სიმძიმე
show:
affected_accounts:
one: გავლენა იქონია მონაცემთა ბაზაში ერთ ანგარიშზე
other: გავლენა იქონიო მონაცემთა ბაზაში %{count} ანგარიშზე
retroactive:
silence: ამ დომენში ყველა არსებულ ანგარიშზე გაჩუმების მოშორება
suspend: ამ დომენში ყველა არსებულ ანგარიშზე შეჩერების მოშორება
title: უკუაქციეთ დომენის ბლოკი %{domain} დომენზე
undo: უკუქცევა
title: დომენის ბლოკები
undo: უკუქცევა
email_domain_blocks:
add_new: ახლის დამატება
created_msg: ელ-ფოსტის დომენი წარმატებით დაემატა შავ სიას
delete: გაუქმება
destroyed_msg: ელ-ფოსტის დომენი წარმატებით ამოიშალა შავი სიიდან
domain: დომენი
new:
create: დომენის დამატება
title: ელ-ფოსტის ახალი შენატანი შავ სიაში
title: ელ-ფოსტის შავი სია
instances:
account_count: ცნობილი ანგარიშები
domain_name: დომენი
reset: გადატვირთვა
search: ძებნა
title: ცნობილი ინსტანციები
invites:
filter:
all: ყველა
available: ხელმისაწვდომი
expired: ვადაგასული
title: ფილტრი
title: მოწვევები
relays:
add_new: ახელი რილეი
description_html: "<strong>ფედერაციის რილეი</strong> შუამავალი სერვერია, რომელიც ცვლის საჯარო ტუტების დიდ ოდენობას იმ სერვერებს შორის, რომლებიც გამოიწერენ და მასზე გამოაქვეყნებენ. <strong>ეს მცირე და საშუალო სერვერებს ეხმარება აღმოაჩინონ კონტენტი ფედივერსისგან</strong>, რომელიც სხვა შემთხვევაში მომხარებლებს აიძულებდა მექნიკურ რეჟიმში გაჰყოლოდნენ ხალხს სხვა დისტანციურ სერვერებზე."
enable_hint: ამოქმდების შემდეგ, თქვენი სერვერი გამოიწერს ყველა საჯარო ტუტს ამ რილეიდან და დაიწყებს სერვერის ღია ტუტების იქ გაგზავნას.
inbox_url: რილეი ურლ
setup: რილეი კავშირის დამყარება
status: სტატუსი
title: რილეი სია
report_notes:
created_msg: რეპორტის ჩანაწერი წარმატებით შეიქმნა!
destroyed_msg: რეპორტის ჩანაწერი წარმატებით გაუქმდა!
reports:
account:
note: ჩანაწერი
report: რეპორტი
action_taken_by: მოქმედება შეასრულა
are_you_sure: დარწმუნებული ხარ?
assign_to_self: დანიშნე ჩემზე
assigned: დაინიშნა მოდერატორი
comment:
none: არაფერი
created_at: რეპორტის დრო
id: იდ
mark_as_resolved: მონიშნე გადაწყვეტილად
mark_as_unresolved: მონიშნე გადაუწყვეტლად
notes:
create: ჩანაწერის დამატება
create_and_resolve: გადაწყვეტა ჩანაწერით
create_and_unresolve: ხელახალი გახსნა ჩანაწერით
delete: გაუქმება
placeholder: აღწერეთ თუ რა ნაბიჯები უნდა გადაიდგას, ან სხვა დაკავშირებული განახლებები...
reopen: რეპორტის ხელახალი გახსნა
report: 'რეპორტი #%{id}'
report_contents: მოცულობები
reported_account: დარეპორტებული ანგარიში
reported_by: დაარეპორტა
resolved: გადაწყვეტილი
resolved_msg: რეპორტი წარმატებით გადაწყდა!
silence_account: ანგარიშის გაჩუმება
status: სტატუსი
suspend_account: ანგარიშის შეჩერება
target: მიზანი
title: რეპორტები
unassign: გადაყენება
unresolved: გადაუწყვეტელი
updated_at: განახების დრო
view: ჩვენება
settings:
activity_api_enabled:
desc_html: ლოკალურად გამოქვეყნებული სტატუსების, აქტიური მომხმარებლების და ყოველკვირეული რეგისტრაციების მთვლელი
title: გამოაქვეყნე აგრეგატი სტატისტიკები მომხმარებლის აქტივობაზე
bootstrap_timeline_accounts:
desc_html: გამოჰყავი მომხმარებლები მძიმით. იმუშავებს მხოლოდ ლოკალური და "ბლოკ-მოხსნილ" ანგარიშები. საწყისი როდესაც ცარიელია ყველა ლოკალური ადმინი.
title: საწყისი მიდევნებები ახლა მომხმარებლებზე
contact_information:
email: ბიზნეს ელ-ფოსტა
username: საკონტაქტო მომხმარებლის სახელი
hero:
desc_html: წინა გვერდზე გამოჩენილი. მინ. 600/100პიქს. რეკომენდირებული. როდესაც არაა დაყენებული, ჩნდება ინსტანციის პიქტოგრამა
title: გმირი სურათი
peers_api_enabled:
desc_html: დომენების სახელები რომლებსაც შეხვდა ეს ინსტანცია ფედივერსში
title: გამოაქვეყნე აღმოჩენილი ინსტანციების სია
preview_sensitive_media:
desc_html: ბმულის პრევიუები სხვა ვებ-საიტებზე გამოაჩენენ პიქტოგრამას, მაშინაც კი თუ მედია მონიშნულია მგრძნობიარედ
title: გამოაჩინე მგრძნობიარე მედია ოუფენ-გრეფ პრევიუებში
registrations:
closed_message:
desc_html: გამოჩნდება წინა გვერდზე, როდესაც რეგისტრაციები დახურულია. შეგიძლიათ გამოიყენოთ ჰტმლ ტეგები
title: დახურული რეგისტრაციის წერილი
deletion:
desc_html: უფლება მიეცით ყველას, გააუქმონ თავიანთი ანგარიში
title: ღია ანგარიშის გაუქმება
min_invite_role:
disabled: არავინ
title: ნება დაერთოს მოწვეევებს
open:
desc_html: უფლება მიეცით ყველას, გახსნან ანგარიში
title: ღია რეგისტრაცია
show_known_fediverse_at_about_page:
desc_html: ჩართვისას, ეს გამოაჩენს ტუტებს ყველა ცნობილი ფედივერსისგან პრევიუზე. სხვა შემთხვევაში, გამოაჩენს მხოლოდ ლოკალურ ტუტებს.
title: გამოჩნდეს ცნობილი ვედივერსი თაიმლაინ პრევიუში
show_staff_badge:
desc_html: გამოჩნდეს სტაფის ნიშანი მომხმარებლის გვერდზე
title: სტაფის ნიშნის გამოჩენა
site_description:
desc_html: საშესავლო პარაგრაფი წინა გვერდზე. აღწერეთ თუ რა ხდის ამ მასტოდონის სერვერს განსაკუთრებულს და სხვა მნიშვნელოვანი. შეგიძლიათ გამოიყენოთ ჰტმლ ტეგები, კერძოდ <code>&lt;a&gt;</code> და <code>&lt;em&gt;</code>.
title: ინსტანციის აღწერილობა
site_description_extended:
desc_html: კარგი ადგილი მოქცევის კოდექსისთვის, წესები, სახელმძღვანელოები და სხვა რაც გამოარჩევს თქვენს ინსტანციას. შეგიძლიათ გამოიყენოთ ჰტმლ ტეგები
title: პერსონალიზირებული განვრცობილი ინფორმაცია
site_short_description:
desc_html: გამოჩნდება გვერდით ბარში და მეტა ტეგებში. აღწერეთ თუ რა არის მასტოდონი და რა ხდის ამ სერვერს უნიკალურს ერთ პარაგრაფში. თუ ცარიელია, გამოჩნდება ინსტანციის აღწერილობა.
title: აჩვენეთ ინსტანციის აღწერილობა
site_terms:
desc_html: შეგიძლიათ დაწეროთ საკუთარი კონფიდენციალურობის პოლიტიკა, მომსახურების პირობები ან სხვა იურიდიული დოკუმენტი. შეგიძლიათ გამოიყენოთ ჰტმლ ტეგები
title: პერსონალიზირებული მომსახურების პირობები
site_title: ინსტანციის სახელი
thumbnail:
desc_html: გამოიყენება პრევიუებისთვის ოუფენ-გრეფში და აპი-ში. 1200/630პიქს. რეკომენდირებული
title: ინსტანციის პიქტოგრამა
timeline_preview:
desc_html: აჩვენეთ საჯარო თაიმლაინი ლენდინგ გვერდზე
title: თაიმლაინ პრევიუ
title: საიტის პარამეტრები
statuses:
back_to_account: უკან ანგარიშის გვერდისკენ
batch:
delete: გაუქმება
nsfw_off: მონიშნე არა-მგრძნობიარედ
nsfw_on: მონიშნე მგრძნობიარედ
failed_to_execute: ვერ გაეშვა
media:
title: მედია
no_media: არაა მედია
no_status_selected: სატუსები არ შეცვლილა, რადგან არცერთი არ მონიშნულა
title: ანგარიშის სტატუსები
with_media: მედიით
subscriptions:
callback_url: ქოლბექ ურლ
confirmed: დამოწმდა
expires_in: ვადა გასდის
last_delivery: ბოლო მიღება
title: ვებ-საბი
topic: სათაური
title: ადმინისტრაცია
admin_mailer:
new_report:
body: "%{reporter}-მა დაარეპორტა %{target}"
body_remote: ვიღაცამ %{domain}-იდან დაარეპორტა %{target}
subject: ახალი რეპორტი %{instance} (#%{id})-ზე
application_mailer:
notification_preferences: შეცვალეთ ელ-ფოსტის პრეფერნსიები
salutation: "%{name},"
settings: 'შეცვალეთ ელ-ფოსტის პრეფერენსიები: %{link}'
view: 'ჩვენება:'
view_profile: პროფილის ჩვენება
view_status: სტატუსის ჩვენება
applications:
created: აპლიკაცია წარმატებით შეიქმნა
destroyed: აპლიკაცია წარმატებით გაუქმდა
invalid_url: მოწოდებული ურლ არასწორია
regenerate_token: წვდომის ტოკენის რეგენერაცია
token_regenerated: წვდომის ტოკენის რეგენერაცია მოხერხდა
warning: იყავით ძალიან ფრთხილად ამ მონაცემთან. არასდროს გააზიაროთ ეს!
your_token: თქვენი წვდომის ტოკენი
auth:
agreement_html: რეგისტრაციით თქვენ ეთანხმებით <a href="%{rules_path}">ინსტანციის წესებს</a> და <a href="%{terms_path}">ჩვენ მომსახურების პირობებს</a>.
change_password: პაროლი
confirm_email: ელ-ფოსტის დამოწმება
delete_account: ანგარიშის გაუქმება
delete_account_html: თუ გსურთ გააუქმოთ თქვენი ანგარიში, შეგიძლიათ <a href="%{path}">გააგრძელოთ აქ</a>. საჭირო იქნება დამოწმება.
didnt_get_confirmation: არ მოგსვლიათ დამოწმების ინსტრუქციები?
forgot_password: დაგავიწყდათ პაროლი?
invalid_reset_password_token: პაროლის გადატვირთვის ტოკენი არასწორია ან ვადაგასული. გთხოვთ მოითხოვეთ ახალი.
login: შესვლა
logout: გასვლა
migrate_account: სხვა ანგარიშზე გადასვლა
migrate_account_html: თუ გსურთ ამ ანგარიშის რედირექტის ხვაზე, შეგიძლიათ <a href="%{path}">გაუწიოთ კონფიგურაცია აქ</a>.
or: ან
or_log_in_with: ან გამოიყენეთ
providers:
cas: ქეს
saml: სამლ
register: რეგისტრაცია
register_elsewhere: რეგისტრაცია სხვა სერვერზე
resend_confirmation: დამოწმების ინსტრუქციების ხელახალი გამოგზავნა
reset_password: პაროლის გადატვირთვა
security: უსაფრთხოება
set_new_password: ახალი პაროლის დაყენება
authorize_follow:
already_following: უკვე მიჰყვებით ამ ანგარიშს
error: სამწუხაროთ, დისტანციური სერვერის წაკითხვამ გამოიწვია შეცდომა
follow: გაყევი
follow_request: 'დადევნების მოთხონვა გაეგზავნა:'
following: 'წარმატება! ახლა მიჰყვებით:'
post_follow:
close: ან შეგიძლიათ დახუროთ ეს ფანჯარა.
return: მომხმარებლის პროფილის ჩვენება
web: ვებზე გადასვლა
title: გაყევი %{acct}-ს
datetime:
distance_in_words:
about_x_hours: "%{count}სთ"
about_x_months: "%{count}თვე"
about_x_years: "%{count}წელი"
almost_x_years: "%{count}წელი"
half_a_minute: ამ წამს
less_than_x_minutes: "%{count}წთ"
less_than_x_seconds: ამ წამს
over_x_years: "%{count}წელი"
x_days: "%{count}დღე"
x_minutes: "%{count}წთ"
x_months: "%{count}თვე"
x_seconds: "%{count}წმ"
deletes:
bad_password_msg: კარგად სცადეთ, ჰაკერებო! არასწორი პაროლი
confirm_password: იდენტობის დასამოწმებლად შეიყვანეთ მიმდინარე პაროლი
description_html: ეს <strong>სამუდამოდ, დაუბრუნებლად</strong> გააუქმებს კონტენტს თქვენი ანგარიშიდან და მოახდენს მის დეაქტივაციას. მომხმარებლის სახელი კი, სამომავლო იმპერსონაციების შესაჩერებლად, გახდება რეზერვირებული
proceed: ანგარიშის გაუქმება
success_msg: თქვენი ანგარიში წარმატებით გაუქმდა
warning_html: მოცულობის გაუქმება გარანტირებულია მხოლოდ ამ ინსტანციაზე. კონტენტი რომელიც ფართო მასშტაბით გაზიარდა უფრო დატოვებს კვალს. ოფლაინ სერვერები და სერვერები, რომლებმაც შეწყვიტეს თქვენი განახლებების გამოწერა არ განაახლებენ მონაცემთა ბაზებს.
warning_title: წვდომა გავრცელებულ კონტენტზე
errors:
'403': ამ გვერდის ხილვის უფლება არ გაქვთ.
'404': გვერდი რომელსაც ეძებთ არ არსებობს.
'410': გვერდი რომელსაც ეძებდით აღარ არსებობს.
'422':
content: უსაფრთხოების ვერიფიკაცია ვერ მოხერხდა. ბლოკავთ ქუქის?
title: უსაფრთხოების ვერიფიკაცია არ შედგა
'429': დარტყმა
'500':
content: ბოდიში, ჩვენ მხარეს რაღაც არია.
title: გვერდი არაა სწორი
noscript_html: მასტოდონ ვებ-აპლიკაციის გამოყენებისთვის, გთხოვთ ჩართოთ ჯავასკრიპტი. სხვა შემთხვევაში, მასტოდონის თქვენი პატფორმისთვის სცადეთ გამოიყენოთ ერთ-ერთი <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">მშობლიური აპლიკაცია</a>.
exports:
archive_takeout:
date: თარიღი
download: ჩამოტვირთეთ თქვენი არქივი
hint_html: შეგიძლიათ მოითხოვოთ თქვენი აქივი <strong>ტუტებისა და ატვირთული მედიისა</strong>. ექსპორტირებული მონაცემები იქნება ექთივითი-ფაბ ფორმატში, წაკითხვადი ნებისმიერი თავსებადი პროგრამით. არქივის მოთხოვნა შეგიძლიათ 7 დღეში ერთხელ.
in_progress: მიმდინარეობს თქვენი არქივის შედგენა...
request: თქვენი არქივის მოთხოვნა
size: ზომა
blocks: თქვენ ბლოკავთ
csv: ცსვ
follows: თქვენ მიჰყვებით
mutes: თქვენ აჩუმებთ
storage: მედია საცავი
filters:
contexts:
home: სახლის თაიმლაინი
notifications: შეტყობინებები
public: საჯარო თაიმლაინი
thread: საუბრები
edit:
title: ფილტრის ცვლილება
errors:
invalid_context: მოწოდებულია არასწორი ან ცარიელი კონტექსტი
invalid_irreversible: დაუბრუნებელი ფილტრაცია მუშაობს მხოლოდ სახლის ან ნოტიფიკაციის კონტექსტში
index:
delete: გაუქმება
title: ფილტრები
new:
title: ახალი ფილტრის დამატება
followers:
domain: დომენი
explanation_html: თუ გსურთ უზრუნველყოთ თქვენი სტატუსების კონფიდენციალურობა, უნდა იცოდეთ თუ ვინ მოგყვებათ. <strong>კერძო სტატუსები მიეწოდება ყველა ინსტანციას, სადაც გყავთ მიმდევრები</strong>. შესაძლოა გსურდეთ განიხილოთ ისინი და ამოშალოთ მიმდევრები თუ არ ენდობით თქვენი კონფიდენციალურობის პატივისცემას სტაფისა თუ პროგრამისგან იმ ინსტანციებში.
followers_count: მიმდევრების რაოდენობა
lock_link: თქვენი ანგარიშის ჩაკეტვა
purge: მიმდევრებიდან ამოშლა
success:
one: მიმდევრების სოფტ-ბლოკირების პროცესი ერთი დომენზე...
other: მიმდევრების სოფტ-ბლოკირების პროცესი %{count} დომენზე...
true_privacy_html: გთხოვთ გაითვალისწინეთ, <strong>ჭეშმარიტი კონფიდენციალურობა მიღწევადია მხოლოდ ენდ-თუ-ენდ შიფრაციით</strong>.
unlocked_warning_html: ყველას შეუძლია გამოგყვეთ, რომ უცბად იხილოს თქვენი სტატუსები. %{lock_link} რომ შეძლოთ განიხილოთ და უარყოთ მიმდევრები.
unlocked_warning_title: თქვენი ანგარიში არაა ჩაკეტილი
footer:
developers: დეველოპერები
more: მეტი…
resources: რესურსები
generic:
changes_saved_msg: ცვლილებები წარმატებით დამახსოვრდა!
save_changes: ცვლილებების შენახვა
validation_errors:
one: რაღაც ჯერ არაა მთლად კარგად! გთხოვთ განიხილოთ ქვემოთ მოცემული შეცდომები
other: რაღაც ჯერ არაა მთლად კარგად! გთხოვთ განიხილოთ ქვემოთ მოცემული %{count} შეცდომა
imports:
preface: შეგიძლიათ დააიმპორტოთ მონაცემები, რომლებიც დააექსპორტეთ სხვა სერვერიდან, მაგალითად ადამიანების სია, რომლებსაც მიჰყვებით ან ბლოკავთ.
success: თქვენი მონაცემები წარმატებით აიტვირთა და მათი პროცესირება მოხდება გარკვეულ დროში
types:
blocking: ბლოკირების სია
following: დადევნების სია
muting: გაჩუმების სია
upload: ატვირთვა
in_memoriam_html: მემორანდუმში.
invites:
delete: დეაქტივაცია
expired: ვადა გაუვიდა
expires_in:
'1800': 30 წუთში
'21600': 6 საათში
'3600': 1 საათში
'43200': 12 საათში
'604800': 1 კვირაში
'86400': 1 დღეში
expires_in_prompt: არასდროს
generate: გენერირება
invited_by: 'თქვენ მოგიწვიათ:'
max_uses:
one: 1 მოხმარება
other: "%{count} მოხმარება"
max_uses_prompt: ლიმიტის გარეშე
prompt: ამ ინსტანციაზე წვდომის მისაცემად, დააგენერირეთ და გააზიარეთ ბმულები სხვებთან
table:
expires_at: ვადა გასდის
uses: მოხმარება
title: მოიწვიეთ ხალხი
lists:
errors:
limit: მიაღწიეთ სიების მაქსიმალურ ოდენობას
media_attachments:
validations:
images_and_video: ვიდეოს დართვა სტატუსზე, რომელიც უკვე მოიცავს სურათებს, ვერ მოხერხდება
too_many: თან ვერ დაურთავთ 4 ფაილზე მეტს
migrations:
acct: username@domain ახალი ანგარიშის
currently_redirecting: 'თქვენი პროფილი გამართულია მოახდინოს გადამისამართება მისამართზე:'
proceed: შენახვა
updated_msg: თქვენი ანგარიშის მიგრაციის პარამეტრები წარმატეებით დამახსოვრდა!
moderation:
title: მოდერაცია
notification_mailer:
digest:
action: ყველა შეტყობინების ჩვენება
body: 'აქ მოკლე შინაარსია წერილების, რომლებიც გამოგეპარათ წინა სტუმრობის შემდეგ: %{since}'
mention: "%{name}-მა დაგასახელათ:"
new_followers_summary:
one: ასევე, არყოფნისას შეგეძინათ ერთი ახალი მიმდევარი! იეი!
other: ასევე, არყოფნისას შეგეძინათ %{count} ახალი მიმდევარი! შესანიშნავია!
subject:
one: "1 ახალი შეტყობინება თქვენი ბოლო სტუმრობის შემდეგ \U0001F418"
other: "%{count} ახალი შეტყობინება თქვენი ბოლო სტუმრობის შემდეგ \U0001F418"
title: თქვენს არყოფნაში...
favourite:
body: 'თქვენი სტატუსი ფავორიტი გახადა %{name}-მა:'
subject: "%{name}-მა თქვენი სტატუსი გახადა ფავორიტი"
title: ახალი ფავორიტი
follow:
body: "%{name} ახლა მოგყვებათ!"
subject: "%{name} ახლა მოგყვებათ"
title: ახალი მიმდევარი
follow_request:
action: დადევნების მოთხოვნების მენეჯმენტი
body: "%{name}-მა მოითხოვა გამოგყვეთ"
subject: 'მიმდევარი მოლოდინში: %{name}'
title: ახალი დადევნების მოთხოვნა
mention:
action: პასუხი
body: 'თქვენ %{name}-მა გასახელათ:'
subject: თქვენ გასახელათ %{name}-მა
title: ახალი სახელობა
reblog:
body: 'თქვენი სტატუსი გაზარდა %{name}-მა:'
subject: "%{name}-მა გაზარდა თქვენი სტატუსი"
title: ახალი ბუსტი
number:
human:
decimal_units:
format: "%n%u"
units:
billion: ბილ.
million: მილ.
quadrillion: კუად.
thousand: ათას.
trillion: ტრილ.
unit: ''
pagination:
newer: უფრო ახალი
next: შემდეგი
older: ძველი
prev: წინა
truncate: "&hellip;"
preferences:
languages: ენები
other: სხვა
publishing: გამოქვეყნება
web: ვები
remote_follow:
acct: შეიყვანეთ თქვენი username@domain საიდანაც გსურთ გაჰყვეთ
missing_resource: საჭირო გადამისამართების ურლ თქვენი ანგარიშისთვის ვერ მოიძებნა
no_account_html: არ გაქვთ ანგარიში? შეგიძლიათ <a href='%{sign_up_path}' target='_blank'>დარეგისტრირდეთ აქ</a>
proceed: გააგრძელეთ გასაყოლად
prompt: 'თქვენ გაჰყვებით:'
remote_unfollow:
error: შეცდომა
title: სათაური
unfollowed: დადევნების შეწყვეტა
sessions:
activity: ბოლო აქტივობა
browser: ბრაუზერი
browsers:
alipay: ალიფეი
blackberry: ბლექბერი
chrome: ქრომი
edge: მაიკროსოფთ ედჯი
electron: ელექტრონი
firefox: ფაირფოქსი
generic: ამოუცნობი ბრაუზერი
ie: ინტერნეტ ექფლორერი
micro_messenger: მიკრო-მესინჯერი
nokia: ნოკია ს40 ოვი ბრაუზერი
opera: ოპერა
otter: ოტერი
phantom_js: ფანტომჯეიესი
qq: ქქ ბრაუზერი
safari: საფარი
uc_browser: იუსიბიბრაუზერი
weibo: ვეიბო
current_session: მიმდინარე სესია
description: "%{browser} %{platform}-ზე"
explanation: ეს ვებ-ბრაუზერებია, რომლებიც ამჟამად აუტენტიფიცირებულ არიან თქვენს მასტოდონ ანგარიშთან.
ip: აი-პი
platforms:
adobe_air: ედობ ეარი
android: ანდროიდი
blackberry: ბლექბერი
chrome_os: ქრომო-ოსი
firefox_os: ფაირფოქს-ოსი
ios: აი-ოსი
linux: ლინუქსი
mac: მაკი
other: ამოუცნობი პლატფორმა
windows: ვინდოუსი
windows_mobile: ვინდოუს მობაილი
windows_phone: ვინდოუს ფოუნი
revoke: გაუქმება
revoke_success: სესია წარმატებით გაუქმდა
title: სესიები
settings:
authorized_apps: ავტორიზირებული აპლიკაციები
back: უკან მასტოდონისკენ
delete: ანგარიშის გაუქმება
development: დეველოპმენტი
edit_profile: პროფილის ცვლილება
export: მონაცემის ექსპორტი
followers: ავტორიზირებული მიმდევრები
import: იმპორტი
migrate: ანგარიშის მიგრაცია
notifications: შეტყობინებები
preferences: პრეფერენციები
settings: პარამეტრები
two_factor_authentication: მეორე-ფაქტორის აუტენტიფიკაცია
your_apps: თქვენი აპლიკაციები
statuses:
attached:
description: 'თან დართული: %{attached}'
image:
one: "%{count} სურათი"
other: "%{count} სურათები"
video:
one: "%{count} ვიდეო"
other: "%{count} ვიდეოები"
boosted_from_html: გაიზარდა %{acct_link}-იდან
content_warning: 'გაფრთხილება კონტენტზე: %{warning}'
disallowed_hashtags:
one: 'მოიცავდა აკრძალულ ჰეშტეგს: %{tags}'
other: 'მოიცავს აკრძალულ ჰეშტეგს: %{tags}'
language_detection: ავტომატურად დადგინდეს ენა
open_in_web: ვებში გახნსა
over_character_limit: ნიშნების ლიმიტი გადასცდა %{max}-ს
pin_errors:
limit: ტუტების მაქსიმალური რაოდენობა უკვე აპინეთ
ownership: სხვისი ტუტი ვერ აიპინება
private: არა-საჯარო ტუტი ვერ აიპინება
reblog: ბუსტი ვერ აიპინება
show_more: მეტის ჩვენება
title: '%{name}: "%{quote}"'
visibilities:
private: მხოლოდ-მიმდევრები
private_long: აჩვენე მხოლოდ მიმდევრებს
public: საჯარო
public_long: ხედავს ყველა
unlisted: ჩამოუთვლელი
unlisted_long: ხედავს ყველა, მაგრამ არ ჩანს საჯარო თაიმლაინებში
stream_entries:
pinned: აპინული ტუტი
reblogged: გაზრდილი
sensitive_content: მგრძნობიარე კონტენტი
terms:
body_html: |
<h2>კონფიდენციალურობის პოლიტიკა</h2>
<h3 id="collect">რა ინფორმაციას ვაგროვებთ?</h3>
<ul>
<li><em>ძირითადი ანგარიშის ინფორმაცია</em>: თუ დარეგისტრირდებით ამ სერვერზე, შესაძლოა მოგთხოვოთ მომხმარებლის სახელი, ელ-ფოსტის მისამართი და პაროლი. შესაძლებელია, ასევე შეიყვანოთ დამატებითი პროფილის ინორმაცია, როგორიცაა დისპლეის სახელი და ბიოგრაფია, ასევე ატვირთოთ პროფილის და დასათაურების სურათი. მომხმარებლის სახელი, დისპლეის სახელი, ბიოგრაფია, პროფილის სურათი, დასათაურების სურათი ყოველთვის ღიადაა ჩამოთვლილი.</li>
<li><em>პოსტები, დადევნებები და სხვა საჯარო ინფორმაცია</em>: ადამიანების სია, რომლებსაც მიჰყვებით საჯაროდაა ჩამოთვლილი, იგივე ეხება თქვენს მიდევრებსაც. როდესაც აგზავნით წერილს, თარიღი, დრო და აპლიკაცია თუ საიდანაც განათავსეთ წერილი ინახება. წერილები შესაძლოა შეიცავდნენ მედია ფაილებს, როგორებიცაა სურათები და ვიდეოები. ღია და ჩამოუთვლელი პოსტები ხელმისაწვდომია საჯაროდ. როდესაც ათავსებთ პოსტს თქვენს პროფილზე, ის ასევე საჟაროდ წვდომადი ხდება. თქვენი პოსტები ეგზავნებათ თქვენს მიმდევრებს, ზოგიერთ შემთხვევაში ეს ნიშნავს, რომ ისინი იგზავნება სხვა სერვერებზე და მათი ასლები იქვე ინახება. როდესაც აუქმებთ პოსტს, ეს მოქმედება ეგზავნებათ თქვენს მიმდევრებს. რე-ბლოგირების ან ფავორიტად ქცევის ქმედებები ასევე საქვეყნოა.</li>
<li><em>პირდაპირი და პოსტები მხოლოდ-მიმდევრებისთვის</em>: ყველა პოსტი ინახება და მათი პროცესირება ხდება სერვერზე. პოსტები რომლებიც განეკუთვნება მხოლოდ მიმდევრებს მიეწოდებათ მათ, მომხმარებლები, რომლებიც დასახელებულია პოსტებში და პირდაპირი პოსტები ეგზავნებათ მხოლოდ ჩამოთვლილ მომხმარებლებს. ზოგიერთ შემთხვევაში, ეს ნიშნავს, რომ გადაგზავნა ხდება გარე სერვერებზე და ასლებიც იქ ინახება. ჩვენ დიდ ძალისხმევას ვუწევთ წვდომის ლიმიტს მხოლოდ აუტორიზირებული ადამიანებისთვის, თუმცა სხვა სერვერებმა შეიძლება ეს არ აწარმოონ. აქედან გამომდინარე, მნიშვნელოვანია განიხილოთ სერვერები, საიდანაც მოდიან თქვენი მიმდევრები. შეგიძლიათ ჩართოთ ან გამორთოთ პარამეტრი, დაადასტუროთ ან უარყოთ ახალი მიმდევარი. <em>გთხოვთ გაითვალისწინოთ, რომ სერვერის ოპერაციები და სხვა მიმღები სერვერები შესაძლოა კითხულობდნენ ამგვარ წერილებს</em>, მიმღებებს შეუძლიათ შექმნან სქრინშოთი, დააკოპირონ ან ხელახლა გააზიარონ ისინი. <em>არ გააზიაროთ საშიში ინფორმაცია მასტოდონით.</em></li>
<li><em>აი-პიები და სხვა მეტა-მონაცემები</em>: როდესაც გაივლით აუტენტიფიკაციას, ჩვენ ვინახავთ აი-პი მისამართს საიდანაც შემოხვედით, ასევე ბრაუზერის აპლიკაციას. ყველა ავტორიზირებული სესია თქვენთვის განსახილველად და გასაუქმებლად ხელმისაწვდომია პარამეტრებში. ბოლო შენახული აი-პი მისამართი ინახება მაქსიმუმ 12 თვით. ჩვენ ასევე შეიძლება გაგვაჩნდეს სერვერის ლოგი, რომელიც ინახავს თითოეული მოთხოვნის IP მისამართს.</li>
</ul>
<hr class="spacer" />
<h3 id="use">რაში ვიყენებთ ინფორმაციას?</h3>
<p>ნებისმიერი სხვა ინფორმაცია, რომელსაც ვაგროვებთ თქვენგან შესაძლოა გამოყენებულ იქნას შემდეგი გზებით:</p>
<ul>
<li>რომ უზრუნველვყოთ მასტოდონის მთავარი ფუნქციონალი. შეგიძლიათ ინტერაქცია გაუწიოთ მხოლოდ სხვის კონტენტს და შექმნათ პოსტები მაშინ როდესაც ავტორიზებული ხართ. მაგალითად, შესაძლოა გაჰყვეთ სხვა ადამიანებს, რათა იხილოთ მათი ჯამური პოსტები საკუთარ პერსონალიზებულ სახლის თაიმლაინზე.</li>
<li>რომ შევუწყვოთ ხელი საზოგადოების მოდერაციას, მაგალითად შევადაროთ თქვენი აი-პი მისამართი სხვა ცნობილ მისამართებს, რათა ამოვიცნოთ ბანის გადაუხდელობა ან სხვა დარღვევები.</li>
<li>ელ-ფოსტის მისამართი რომელსაც გვაწვდით, შესაძლოა გამოვიყენოთ თქვენთვის ინფორმაციის გამოსაგძავნად, შეგატყობინოთ სხვა ადამიანების ინტერაქციაზე თქვენს კონტენტთან ან თქვენთვის გამოგზავნილ წერილებზე, ასევე რომ გიპასუხოთ მოთხოვნებზე და/ან სხვა საკითხებზე.</li>
</ul>
<hr class="spacer" />
<h3 id="protect">როგორ ვიცავთ თქვენს ინფორმაციას?</h3>
<p>მიღებული გვაქვს სხვადასხვა ზომა, შევინარჩუნოთ თქვენი პირადი ინფორმაციის უსაფრთხოება, რომელსაც აგზავნით, შეგყავთ ან კითხულობთ. ამ ყველაფერთან ერთად თქვენი ბრაუზერის სესია, ტრეფიკი თქვენს აპლიკაციასა და აპის შორის დაცულია სსლ-ით, თქვენი პაროლი იშიფრება ძლიერი ალგორითმით. შეგიძლიათ ჩართოთ მეორე-ფაქტორის აუტენტიფიკაცია, რათა გააღმაოთ თქვენი ანგარიშის თავდაცვა.</p>
<hr class="spacer" />
<h3 id="data-retention">რა არის ჩვენი მონაცემის უარყოფის პოლიტიკა?</h3>
<p>ჩვენ არ დავიშურებთ ძალისხმევას რომ:</p>
<ul>
<li>შევინარჩუნოთ სერვერის ლოგები, რომლებიც მოიცავენ ყველა მოთხოვნის აი-პი მისამართს, თუმცა ესეთი ლოგები არ ინახება 90 დღეზე მეტ ხანს.</li>
<li>შევინარჩუნოთ რეგისტრირებული მომხმარებლების აი-პი მისამართები მაქსიმუმ 12 თვით.</li>
</ul>
<p>შეგიძლიათ მოითხოვოთ და ჩამოტვირთოთ თქვენი კონტენტის არქივი, რომელიც მოიცავს თქვენს პოსტებს, მედია ფაილებს, პროფილის და დასათაურების სურათს.</p>
<p>შეგიძლიათ დაუბრუნებლად გააუქმოთ თქვენი ანგარიში ნებისმიერ დროს.</p>
<hr class="spacer"/>
<h3 id="cookies">ვიყენებთ თუ არა ქუქის?</h3>
<p>დიახ. ქუქიები წარმოადგენენ პატარა ფაილებს, რომელთაც, საიტი ან სერვის-პროვაიდერი, ათავსებს თქვენი კომპიუტერის მყარ დისკზე, ვებ-ბრაუზერის (თუ ნებას რთავთ) მეშვეობით. ქუქიები საშუალებას აძლევს საიტს ამოიცნონ თქვენი ბრაუზზერი და თუ გაქვთ რეგისტრირებული ანგარიში მისი ასოციაცია მოახდინონ თქვენს ანგარიშთან.</p>
<p>ჩვენ ვიყენებთ ქუქის, ვიცოდეთ და შევინახოთ თქვენი პრეფერენსიები სამომავლო სტუმრობებისთვის.</p>
<hr class="spacer" />
<h3 id="disclose">ვამჟღავნებთ თუ არა ინფორმაციას გარე მხარეებისთვის?</h3>
<p>ჩვენ არ ვყიდით, ვვაჭრობთ ან გადაქვაქ თქვენთვის პირადად იდენტიფიცირებადი ინფორმაცია სხვა მხარეებისთვის. ეს არ მოიცავს სანდო მხარეებს, რომლებიც გვეხმარება საიტის ოპერირებაში, ჩვენი საქმიანობის ჩატარებაში, ან თქვენთვის მომსახურების გაწევაში, წინაპირობით კონფიდენციალურად შეინახონ თქვენი ინფორმაცია. ჩვენ შესაძლოა გამოვაქვეყნოთ თქვენი ინფორმაცია, რომელიც შესაბამისად შეიძლება ჩავთვალოთ კანონმდებლობასთან შეთავსებისთვის, აღვასრულოთ პოლიტიკა ან დავიცვათ ჩვენი ან სხვისი უფლებები, კუთვნილება ან უსაფრთხოება.</p>
<p>თქვენი საჯარო ინფორმაცია შესაძლოა ჩამოტვირთულ იქნას სხვა სერვერების მიერ ქსელში. თქვენი ღია და მიმდევრებზე გათვლილი პოსტები მიეწოდება სერვერებს სადაც თქვენი მიმდევრები მოღვაწეობენ, იმ შემთხვევაში თუ მიმღებები მომდინარეობენ სხვა სერვერიდან, პირდაპირი წერილები მიეწოდებათ მიმღებების სერვერებს.</p>
<p>როდესაც უფლებას მისცემთ აპლიკაციას გამოიყენოს თქვენი ანგარიში, უფლებებისგან გამომდინარე, მან შესაძლოა მოიპოვოს თქვენი საჯარო ინფორმაცია, თქვენი დადევნების სიები, თქვენი მიმდევრები, თქვენი სიები, ყველა პოსტი და თქვენი ფავორიტები. აპლიკაციები ვერასდროს იქონიებენ წვდომას თქვენი ელ-ფოსტის მისამართზე ან პაროლზე.</p>
<hr class="spacer" />
<h3 id="children">საიტის მოხმარებს ბავშვების მიერ</h3>
<p>თუ ეს სერვერი მდებარეობს ეუ-ში ან ეეა-ში: ჩვენი საიტი, პროდუქტები და სერვისები მიმართულია ადამიანებისთვის, რომელთაც შეუსრულდათ 16 წელი. თუ თქვენი ასაკი 16 წელიწადზე ნაკლებია, ჯიდიფიარის (<a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation">ზოგადი მონაცემების დაცვის რეგულაცია/a>) მოთხოვნის მიხედვით არ გამოიყენოთ ეს საიტი.</p>
<p>თუ ეს სერვერი მდებარეობს ა.შ.შ.-ში: ჩვენი საიტი პროდუქტი და სერვისები მიმართულია ადამიანებისთვის, რომელთაც შეუსრულდათ 13 წელი. თუ თქვენი ასაკი 13 წელიწადზე ნაკლებია, კოპპას (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">ბავშვთა ონლაინ კონფიდენციალურობის დაცვის აქტი</a>) მოთხოვნების მიხედვით არ გამოიყენოთ ეს საიტი.</p>
<p>იურიდიული მოთხოვნილებები შეიძლება განსხვავდებოდეს, თუ ეს სერვერი იმყოფება სხვა იურისდიქციის ქვეშ.</p>
<hr class="spacer" />
<h3 id="changes">ცვლილებები კონფიდენციალურობის პოლიტიკაში</h3>
<p>თუ გადავწყვეტთ შევცვალოთ კონფიდენციალურობის პოლიტიკა, გამოვაქვეყნებთ ამ გვერდზე.</p>
<p>ეს დოკუმენტი არის ცც-ბაი-სა. ეს ბოლოს განახლდა 2018 წლის, 17 აგვისტოს.</p>
<p>საწყისად ადაპტირებულია <a href="https://github.com/discourse/discourse">გამჟღავნების კონფიდენციალური პოლიტიკისგან</a>.</p>
title: "%{instance} მომსახურების პირობები და კონფიდენციალურობის პოლიტიკა"
themes:
contrast: მაღალი კონტრასტი
default: მასტოდონი
mastodon-light: მასტოდონი (ღია)
time:
formats:
default: "%b %d, %Y, %H:%M"
month: "%b %Y"
two_factor_authentication:
code_hint: დასამოწმებლად შეიყვანეთ თქვენი აუტენტიფიკატორ აპლიკაციისგან გენერირებული კოდი
description_html: თუ ჩართავთ <strong>მეორე-ფაქტორის აუტენტიფიკაციას</strong>, შესვლისას აუცილებელი იქნება ფლობდეთ ტელეფონს, რომელიც დააგენერირებს შესვლის ტოკენებს.
disable: გათიშვა
enable: ჩართვა
enabled: მეორე-ფაქტორის აუტენტიფიკაცია ჩართულია
enabled_success: მეორე-ფაქტორის აუტენტიფიკაცია წარმატებით ჩაირთო
generate_recovery_codes: აღდგენის კოდების გენერაცია
instructions_html: "<strong>დაასკანირეთ ეს ქრ კოდი გუგლ აუტენტიფიკატორში ან მსგავს ტოტპ აპლიკაციაში თქვენს ტელეფონზე</strong>. ამიერიდან, ეს აპლიკაცია დააგენერირებს ტოკენებს მაშინ როდესაც დაგჭირდებათ ავტორიზაცია."
lost_recovery_codes: აღდგენის კოდები უფლებას გაძლევთ მიიღოთ ხელმეორე წვდომა თქვენი ანგარიშისადმი თუ დაკარგავთ ტელეფონს. თუ დაკარგეთ აღდგენის კოდები, მათ რეგენერაცია შეგიძლიათ აქ. ძველი აღდგენის კოდები აღარ იქნება ვალიდური.
manual_instructions: 'თუ ვერ ასკანირებთ ქრ კოდს და საჭიროებთ მის მექანიკურ რეჟიმში შეყვანას, აქ არის ჩვეულებრივი ტექსტური საიდუმლო:'
recovery_codes: გაუწიეთ აღდგენის კოდებს რეზერვაცია
recovery_codes_regenerated: აღგენის კოდების რეგენერაცია წარმატებით შესრულდა
recovery_instructions_html: თუ როდესმე დაკარგავთ წვდომას თქვენს ტელეფონთან, შეგიძლიათ ქვემოთ მოცემული აღდგენის კოდები გამოიყენოთ, რათა მოიპოვოთ ხელმეორე წვდომა თქვენი ანგარიშისადმი. <strong>იქონიეთ აღდგენის კოდები დაცულად</strong>. მაგალითისთვის, შეგიძლიათ ამობეჭდოთ და შეინახოთ სხვა საბუთებთან ერთად.
setup: დაყენება
wrong_code: შეყვანილი კოდი არ იყო სწორი! სწორია სერვერის და მოწყობილობის დრო?
user_mailer:
backup_ready:
explanation: თქვენ მოითხოვეთ თქვენი მასტოდონის ანგარიშის სრული რეზერვაცია. ის ახლა უკვე მზადაა გადმოსაწერად!
subject: თქვენი არქივი გადმოსაწერად მზადაა
title: არქივის მიღება
welcome:
edit_profile_action: პროფილის მოწყობა
edit_profile_step: შეგიძლიათ მოაწყოთ თქვენი პროფილი ავატარის ატვირთვით, დასათაურების სურათით, თქვენი დისპლეი სახელის შეცვლით და სხვა. თუ გსურთ გაუწიოთ ახალ მიმდევრებს რევიუ, სანამ რეალურად გამოგყვებიან, შეგიძლიათ ჩაკეტოთ თქვენი ანგარიში.
explanation: აქ რამდენიმე რჩევაა დასაწყისისთვის
final_action: დაიწყე პოსტვა
final_step: 'დაიწყე პოსტვა! თქვენი ღია წერილები შესაძლოა ნახონ სხვებმა მიმდევრების გარეშეც კი, მაგალითად თქვენს ლოკალურ თაიმლაინზე ან ჰეშტეგებში. შეგიძლიათ წარადგინოთ თქვენი თავი #introductions ჰეშტეგით.'
full_handle: თქვენი სრული სახელური
full_handle_hint: ეს არის ის რასაც ეტყვით თქვენს მეგობრებს, რათა მოგწერონ ან გამოგყვნენ სხვა ინსტანციიდან.
review_preferences_action: შეცვალეთ პრეფერენსიები
review_preferences_step: დარწმუნდით რომ აყენებთ თქვენს პრეფერენსიებს, მაგალითად რა ელ-ფოსტის წერილების მიღება გსურთ, ან კონფიდენციალურობის რა დონე გსურთ ჰქონდეთ თქვენს პოსტებს საწყისად. თუ არ გაღიზიანებთ მოძრაობა, შეგიძლიათ ჩართოთ გიფის ავტო-დაკვრა.
subject: კეთილი იყოს თქვენი მობრძანება მასტოდონში
tip_bridge_html: თუ მოდიხართ ტვიტერიდან, შეგიძლიათ იპოვოთ მეგობრები მასტოდონში <a href="%{bridge_url}">ხიდის აპლიკაციით</a>. თუმცა, ეს მუშაობს მხოლოდ მაშინ თუ მათაც მოიხმარეს ხიდის აპლიკაცია!
tip_federated_timeline: ფედერალური თაიმლაინი მასტოდონის ქსელის ცეცხლოვანი ხედია. ის მოიცავს მხოლოდ იმ ადამიანებს, რომელთაგანაც გამოიწერეს თქვენმა მეზობლებმა, ასე რომ ეს არაა სრული.
tip_following: თქვენ საწყისად მიჰყვებით თქვენი სერვერის ადმინისტრატორ(ებ)ს. უფრო საინტერესო ადამიანების მოსაძებნად იხილეთ ლოკალური და ფედერალური თაიმლაინები.
tip_local_timeline: ლოკალური თაიმლაინი ცეცხლოვანი ხედია ადამიანებისთვის %{instance}-ზე. ისინი არიან თქვენი უსიტყვო მეზობლები!
tip_mobile_webapp: თუ თქვენი მობილური ბრაუზერი გთავაზობთ მასტოდონის სახლის-ეკრანზე დამატებას, შეძლებთ ფუშ შეტყობინებების მიღებას. ეს მრავალმხრივ მოქმედებს როგორც მშობლიური აპლიკაცია!
tips: რჩევები
title: კეთილი იყოს თქვენი მობრძანება, %{name}!
users:
invalid_email: ელ-ფოსტის მისამართი არაა მართებული
invalid_otp_token: არასწორი მეორე ფაქტორის კოდი
otp_lost_help_html: თუ დაკარგეთ წვდომა ორივეზე, შესაძლოა დაუკავშირდეთ %{email}-ს
seamless_external_login: შესული ხართ გარე სერვისით, აქედან გამომდინარე პაროლი და ელ-ფოსტის მისამართი არაა ხელმისაწვდომი.
signed_in_as: 'შესული ხართ როგორც:'

View File

@ -0,0 +1,99 @@
---
ka:
simple_form:
hints:
defaults:
autofollow: ადამიანები რომლებიც დარეგისტრირდებიან მოწვევით, ავტომატურად გამოგყვებიან
avatar: პნგ, გიფ ან ჯპგ. მაქს. %{size}. ზომა დაპატარავდება %{dimensions}პიქს.-ზე
bot: ეს ანგარიში უმთავრესად ასრულებს ავტომატურ მოქმედებებს და შესაძლოა არ იყოს მონიტორინგის ქვეშ
context: ერთ ან მრავალი კონტექსტი სადაც ფილტრი უნდა შესრულდეს
digest: იგზავნება მხოლოდ ხანგრძლივი უაქტივობის პერიოდის შემდეგ და არყოფნისას თუ მიიღეთ ერთი წერილი მაინც
display_name:
one: დარჩა <span class="name-counter">ერთი</span> ნიშანი
other: დარჩა <span class="name-counter">%{count}</span> ნიშანი
fields: პროფილზე ტაბულის სახით შესაძლოა საჩვენებლად გაგაჩნდეთ მაქს. 4 პუნქტი
header: პნგ, გიფ ან ჯპგ. მაქს. %{size}. ზომა დაპატარავდება %{dimensions}პიქს.-ზე
inbox_url: ურლ დააკოირეთ გამოყენებისთვის სასურველი რილეის წინა გვერდიდან
irreversible: გაფილტრული ტუტები გაუქმდება აღუდგენლად, იმ შემთხვევაშიც კი თუ ფილტრი სამომავლოდ გაუქმდება
locale: მომხმარებლის ინტერფეისის, ელ-ფოსტის წერილების და ფუშ შეტყობინებების ენა
locked: საჭიროებს თქვენ მიერ მიმდევრების ხელით დადასტურებას
note:
one: დარჩა <span class="note-counter">ერთი</span> ნიშანი
other: დარჩა <span class="note-counter">%{count}</span> ნიშანი
phrase: დამთხვევა მოხდება დიდი და პატარა ასოების ან კონტენტის გაფრთხილების გათვალისწინების გარეშე
scopes: რომელი აპიებისადმი ექნება აპლიკაციას ცვდომა. თუ არიჩევთ უმთავრეს ფარგლებს, არ დაგჭირდებათ ინდივიდუალურების ამორჩევა.
setting_default_language: თქვენი ტუტების ენა შეიძლება დადგინდეს ავტომატურად, მაგრამ ეს არაა ყოველთვის ზუსტი
setting_hide_network: ვის მიყვებით და ვინ მოგყვებათ არ გამოჩნდება აქ
setting_noindex: გავლენას ახდენს თქვენს ღია პროფილისა და სტატუსის გვერდებზე
setting_theme: გავლენას ახდენს თუ როგორ გამოიყურება მასტოდონი, როდესაც შესული ხართ რომელიმე მოწყობილობიდან.
whole_word: როდესაც სიტყვა ან ფრაზა მხოლოდ ალფა-ნუმერიკულია, ის დაფიქსირდება თუ ემთხვევა სრულ სიტყვას
imports:
data: ცსვ ფაილის ექსპორტი მოხდა მასტოდონის სხვა ინსტანციიდან
sessions:
otp: 'შეიყვანეთ მეორე ფაქტორის კოდი, რომელიც დააგერირა თქვენმა ტელეფონმა ან მოიხმარეთ შემდეგი აღდგენის კოდებიდან ერთ-ერთი:'
user:
chosen_languages: როდესაც მოინიშნება, ღია თაიმლაინზე გამოჩნდება ტუტები მხოლოდ არჩეულ ენებზე
labels:
account:
fields:
name: ლეიბლი
value: მოცულობა
defaults:
autofollow: მოიწვიეთ რომ გამოჰყვნენ თქვენს ანგარიშს
avatar: ავატარი
bot: ეს ბოტის ანგარიშია
chosen_languages: ენების ფილტრი
confirm_new_password: დაადასტურეთ ახალი პაროლი
confirm_password: დაადასტურეთ პაროლი
context: კონტექსტის ფილტრი
current_password: მიმდინარე პაროლი
data: მონაცემები
display_name: დისპლეის სახელი
email: ელ-ფოსტის მისამართი
expires_in: ვადის გასვლის დრო
fields: პროფილის მეტა-მონაცემი
header: დასათაურება
inbox_url: რილეი ინბოქსის ურლ
irreversible: გაუქმდეს დამალვის მაგივრად
locale: ინტერფეისის ენა
locked: ანგარიშის ჩაკეტვა
max_uses: მოხმარების მაქს. ოდენობა
new_password: ახალი პაროლი
note: ბიო.
otp_attempt: მეორე-ფაქტორის კოდი
password: პაროლი
phrase: სიტყვა ან ფრაზა
setting_auto_play_gif: ანიმაციური გიფების ავტო-დაკვრა
setting_boost_modal: ბუსტამე მოხდეს დამოწმება
setting_default_language: პოსტინგის ენა
setting_default_privacy: პოსტის კონფიდენციალურობა
setting_default_sensitive: ყოველთვის მოინიშნოს მედია მგრძნობიარედ
setting_delete_modal: ტუტის გაუქმებამდე გამოჩნდეს დადასტურების ფანჯარა
setting_display_sensitive_media: ყოველთვის გამოჩნდეს მგრძნობიარე მედია
setting_hide_network: თქვენი ქსელის დამალვა
setting_noindex: საძოები სისტემების ინდექსაციის შეჩერება
setting_reduce_motion: მოძრაობის შემცირება ანიმაციებში
setting_system_font_ui: მოხდეს სისტემის საწყისი ფონტის მოხმარება
setting_theme: საიტის თემა
setting_unfollow_modal: გამოჩნდეს დადასტურების ფანჯარა, სანამ შეყვეტთ ვინმეს დადევნებას
severity: სიმძიმე
type: იმპორტის სახეობა
username: მომხმარებლის სახელი
username_or_email: მომხმარებლის სახელი ან ელ-ფოსტა
whole_word: მთელი სიტყვა
interactions:
must_be_follower: დაიბლოკოს შეტყობინებები არა მიმდევრებისგან
must_be_following: დაიბლოკოს შეტყობინებები ადამიანებისგან ვისაც არ მიჰყვებით
must_be_following_dm: დაიბლოკოს პირადი წერილები ადამიანბისგან ვისაც არ მიჰყვებით
notification_emails:
digest: გამოიგზავნოს დაიჯესტ წერილები
favourite: გამოიგზავნოს წერილი როდესაც ვინმე ფავორიტად აქცევს თქვენს სტატუსს
follow: გამოიგზავნოს წერილი როდესაც ვინმე გამოგყვებათ
follow_request: გამოიგზავნოს წერილი როდესაც ვინმე მოგთხოვთ გაჰყვეთ
mention: გამოიგზავნოს წერილი როდესაც ვინმე გასახელებთ
reblog: გამოიგზავნოს წერილი როდესაც ვინმე გაზრდის თქვენს სტატუსს
'no': არა
required:
mark: "*"
text: აუცილებელი
'yes': კი

View File

@ -74,6 +74,9 @@ Rails.application.routes.draw do
get '/@:account_username/:id', to: 'statuses#show', as: :short_account_status get '/@:account_username/:id', to: 'statuses#show', as: :short_account_status
get '/@:account_username/:id/embed', to: 'statuses#embed', as: :embed_short_account_status get '/@:account_username/:id/embed', to: 'statuses#embed', as: :embed_short_account_status
get '/interact/:id', to: 'remote_interaction#new', as: :remote_interaction
post '/interact/:id', to: 'remote_interaction#create'
namespace :settings do namespace :settings do
resource :profile, only: [:show, :update] resource :profile, only: [:show, :update]
@ -123,7 +126,7 @@ Rails.application.routes.draw do
# Remote follow # Remote follow
resource :remote_unfollow, only: [:create] resource :remote_unfollow, only: [:create]
resource :authorize_follow, only: [:show, :create] resource :authorize_interaction, only: [:show, :create]
resource :share, only: [:show, :create] resource :share, only: [:show, :create]
namespace :admin do namespace :admin do

View File

@ -3,15 +3,18 @@ class CopyStatusStats < ActiveRecord::Migration[5.2]
def up def up
safety_assured do safety_assured do
Status.where.not(id: StatusStat.select('status_id')).select('id').find_in_batches do |statuses|
execute <<-SQL.squish execute <<-SQL.squish
INSERT INTO status_stats (status_id, reblogs_count, favourites_count, created_at, updated_at) INSERT INTO status_stats (status_id, reblogs_count, favourites_count, created_at, updated_at)
SELECT id, reblogs_count, favourites_count, created_at, updated_at SELECT id, reblogs_count, favourites_count, created_at, updated_at
FROM statuses FROM statuses
WHERE id IN (#{statuses.map(&:id).join(', ')})
ON CONFLICT (status_id) DO UPDATE ON CONFLICT (status_id) DO UPDATE
SET reblogs_count = EXCLUDED.reblogs_count, favourites_count = EXCLUDED.favourites_count SET reblogs_count = EXCLUDED.reblogs_count, favourites_count = EXCLUDED.favourites_count
SQL SQL
end end
end end
end
def down def down
# Nothing # Nothing

View File

@ -2,7 +2,7 @@
require 'rails_helper' require 'rails_helper'
describe AuthorizeFollowsController do describe AuthorizeInteractionsController do
render_views render_views
describe 'GET #show' do describe 'GET #show' do
@ -39,19 +39,19 @@ describe AuthorizeFollowsController do
expect(service).to have_received(:call).with('missing@hostname') expect(service).to have_received(:call).with('missing@hostname')
end end
it 'sets account from url' do it 'sets resource from url' do
account = Account.new account = Account.new
service = double service = double
allow(FetchRemoteAccountService).to receive(:new).and_return(service) allow(ResolveURLService).to receive(:new).and_return(service)
allow(service).to receive(:call).with('http://example.com').and_return(account) allow(service).to receive(:call).with('http://example.com').and_return(account)
get :show, params: { acct: 'http://example.com' } get :show, params: { acct: 'http://example.com' }
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(assigns(:account)).to eq account expect(assigns(:resource)).to eq account
end end
it 'sets account from acct uri' do it 'sets resource from acct uri' do
account = Account.new account = Account.new
service = double service = double
allow(ResolveAccountService).to receive(:new).and_return(service) allow(ResolveAccountService).to receive(:new).and_return(service)
@ -60,7 +60,7 @@ describe AuthorizeFollowsController do
get :show, params: { acct: 'acct:found@hostname' } get :show, params: { acct: 'acct:found@hostname' }
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(assigns(:account)).to eq account expect(assigns(:resource)).to eq account
end end
end end
end end
@ -75,8 +75,8 @@ describe AuthorizeFollowsController do
end end
describe 'when signed in' do describe 'when signed in' do
let(:user) { Fabricate(:user) } let!(:user) { Fabricate(:user) }
let(:account) { Fabricate(:account, user: user) } let!(:account) { user.account }
before do before do
sign_in(user) sign_in(user)
@ -84,25 +84,26 @@ describe AuthorizeFollowsController do
it 'shows error when account not found' do it 'shows error when account not found' do
service = double service = double
allow(FollowService).to receive(:new).and_return(service)
allow(service).to receive(:call).with(account, 'user@hostname').and_return(nil) allow(ResolveAccountService).to receive(:new).and_return(service)
allow(service).to receive(:call).with('user@hostname').and_return(nil)
post :create, params: { acct: 'acct:user@hostname' } post :create, params: { acct: 'acct:user@hostname' }
expect(service).to have_received(:call).with(account, 'user@hostname')
expect(response).to render_template(:error) expect(response).to render_template(:error)
end end
it 'follows account when found' do it 'follows account when found' do
target_account = Fabricate(:account) target_account = Fabricate(:account)
result_account = double(target_account: target_account)
service = double service = double
allow(FollowService).to receive(:new).and_return(service)
allow(service).to receive(:call).with(account, 'user@hostname').and_return(result_account) allow(ResolveAccountService).to receive(:new).and_return(service)
allow(service).to receive(:call).with('user@hostname').and_return(target_account)
post :create, params: { acct: 'acct:user@hostname' } post :create, params: { acct: 'acct:user@hostname' }
expect(service).to have_received(:call).with(account, 'user@hostname') expect(service).to have_received(:call).with('user@hostname')
expect(account.following?(target_account)).to be true
expect(response).to render_template(:success) expect(response).to render_template(:success)
end end
end end

View File

@ -13,7 +13,7 @@ RSpec.describe IntentsController, type: :controller do
context 'when host is follow' do context 'when host is follow' do
let(:uri) { 'web+mastodon://follow?uri=test' } let(:uri) { 'web+mastodon://follow?uri=test' }
it { is_expected.to redirect_to authorize_follow_path(acct: 'test') } it { is_expected.to redirect_to authorize_interaction_path(uri: 'test') }
end end
context 'when host is share' do context 'when host is share' do

View File

@ -182,6 +182,27 @@ RSpec.describe Status, type: :model do
reblog.destroy reblog.destroy
expect(subject.reblogs_count).to eq 0 expect(subject.reblogs_count).to eq 0
end end
it 'does not fail when original is deleted before reblog' do
reblog = Fabricate(:status, account: bob, reblog: subject)
expect(subject.reblogs_count).to eq 1
expect { subject.destroy }.to_not raise_error
expect(Status.find_by(id: reblog.id)).to be_nil
end
end
describe '#replies_count' do
it 'is the number of replies' do
reply = Fabricate(:status, account: bob, thread: subject)
expect(subject.replies_count).to eq 1
end
it 'is decremented when reply is removed' do
reply = Fabricate(:status, account: bob, thread: subject)
expect(subject.replies_count).to eq 1
reply.destroy
expect(subject.replies_count).to eq 0
end
end end
describe '#favourites_count' do describe '#favourites_count' do