diff options
author | Starfall <us@starfall.systems> | 2022-02-13 22:15:26 -0600 |
---|---|---|
committer | Starfall <us@starfall.systems> | 2022-02-13 22:15:26 -0600 |
commit | c0341f06be5310a00b85a5d48fa80891d47c6710 (patch) | |
tree | 907ef7f787f8bd446a6d9be1448a8bcff74e5a08 /app | |
parent | 169688aa9f2a69ac3d36332c833e9cad43b5f7a5 (diff) | |
parent | 6f78c66fe01921a4e7e01aa6e2386a5fce7f3afd (diff) |
Merge remote-tracking branch 'glitch/main'
Not at all sure where the admin UI is going to display English language names now but OK.
Diffstat (limited to 'app')
219 files changed, 5423 insertions, 2171 deletions
diff --git a/app/controllers/activitypub/replies_controller.rb b/app/controllers/activitypub/replies_controller.rb index fde6c861f..4ff7cfa08 100644 --- a/app/controllers/activitypub/replies_controller.rb +++ b/app/controllers/activitypub/replies_controller.rb @@ -63,15 +63,29 @@ class ActivityPub::RepliesController < ActivityPub::BaseController end def next_page - only_other_accounts = !(@replies&.last&.account_id == @account.id && @replies.size == DESCENDANTS_LIMIT) - - account_status_replies_url( - @account, - @status, - page: true, - min_id: only_other_accounts && !only_other_accounts? ? nil : @replies&.last&.id, - only_other_accounts: only_other_accounts - ) + if only_other_accounts? + # Only consider remote accounts + return nil if @replies.size < DESCENDANTS_LIMIT + + account_status_replies_url( + @account, + @status, + page: true, + min_id: @replies&.last&.id, + only_other_accounts: true + ) + else + # For now, we're serving only self-replies, but next page might be other accounts + next_only_other_accounts = @replies&.last&.account_id != @account.id || @replies.size < DESCENDANTS_LIMIT + + account_status_replies_url( + @account, + @status, + page: true, + min_id: next_only_other_accounts ? nil : @replies&.last&.id, + only_other_accounts: next_only_other_accounts + ) + end end def page_params diff --git a/app/controllers/admin/reports/actions_controller.rb b/app/controllers/admin/reports/actions_controller.rb new file mode 100644 index 000000000..05a4fb63d --- /dev/null +++ b/app/controllers/admin/reports/actions_controller.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +class Admin::Reports::ActionsController < Admin::BaseController + before_action :set_report + + def create + authorize @report, :show? + + case action_from_button + when 'delete' + status_batch_action = Admin::StatusBatchAction.new( + type: action_from_button, + status_ids: @report.status_ids, + current_account: current_account, + report_id: @report.id, + send_email_notification: !@report.spam? + ) + + status_batch_action.save! + when 'silence', 'suspend' + account_action = Admin::AccountAction.new( + type: action_from_button, + report_id: @report.id, + target_account: @report.target_account, + current_account: current_account, + send_email_notification: !@report.spam? + ) + + account_action.save! + end + + redirect_to admin_reports_path + end + + private + + def set_report + @report = Report.find(params[:report_id]) + end + + def action_from_button + if params[:delete] + 'delete' + elsif params[:silence] + 'silence' + elsif params[:suspend] + 'suspend' + end + end +end diff --git a/app/controllers/admin/statuses_controller.rb b/app/controllers/admin/statuses_controller.rb index 8d039b281..817c0caa9 100644 --- a/app/controllers/admin/statuses_controller.rb +++ b/app/controllers/admin/statuses_controller.rb @@ -29,8 +29,9 @@ module Admin end def after_create_redirect_path - if @status_batch_action.report_id.present? - admin_report_path(@status_batch_action.report_id) + report_id = @status_batch_action&.report_id || params[:report_id] + if report_id.present? + admin_report_path(report_id) else admin_account_statuses_path(params[:account_id], current_params) end @@ -48,6 +49,10 @@ module Admin params.slice(*Admin::StatusFilter::KEYS).permit(*Admin::StatusFilter::KEYS) end + def current_params + params.slice(:media, :page).permit(:media, :page) + end + def action_from_button if params[:report] 'report' diff --git a/app/controllers/api/v1/media_controller.rb b/app/controllers/api/v1/media_controller.rb index a2a919a3e..72094790f 100644 --- a/app/controllers/api/v1/media_controller.rb +++ b/app/controllers/api/v1/media_controller.rb @@ -20,7 +20,7 @@ class Api::V1::MediaController < Api::BaseController end def update - @media_attachment.update!(media_attachment_params) + @media_attachment.update!(updateable_media_attachment_params) render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: status_code_for_media_attachment end @@ -42,6 +42,10 @@ class Api::V1::MediaController < Api::BaseController params.permit(:file, :thumbnail, :description, :focus) end + def updateable_media_attachment_params + params.permit(:thumbnail, :description, :focus) + end + def file_type_error { error: 'File type of uploaded media could not be verified' } end diff --git a/app/controllers/api/v1/reports_controller.rb b/app/controllers/api/v1/reports_controller.rb index e10083d45..052d70cc8 100644 --- a/app/controllers/api/v1/reports_controller.rb +++ b/app/controllers/api/v1/reports_controller.rb @@ -33,6 +33,6 @@ class Api::V1::ReportsController < Api::BaseController end def report_params - params.permit(:account_id, :comment, :forward, status_ids: []) + params.permit(:account_id, :comment, :category, :forward, status_ids: [], rule_ids: []) end end diff --git a/app/controllers/api/v1/statuses/histories_controller.rb b/app/controllers/api/v1/statuses/histories_controller.rb index c2c1fac5d..7fe73a6f5 100644 --- a/app/controllers/api/v1/statuses/histories_controller.rb +++ b/app/controllers/api/v1/statuses/histories_controller.rb @@ -7,7 +7,7 @@ class Api::V1::Statuses::HistoriesController < Api::BaseController before_action :set_status def show - render json: @status.edits, each_serializer: REST::StatusEditSerializer + render json: @status.edits.includes(:account, status: [:account]), each_serializer: REST::StatusEditSerializer end private diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index b1390ae48..eaac8e563 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -3,8 +3,8 @@ class Api::V1::StatusesController < Api::BaseController include Authorization - before_action -> { authorize_if_got_token! :read, :'read:statuses' }, except: [:create, :destroy] - before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:create, :destroy] + before_action -> { authorize_if_got_token! :read, :'read:statuses' }, except: [:create, :update, :destroy] + before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:create, :update, :destroy] before_action :require_user!, except: [:show, :context] before_action :set_status, only: [:show, :context] before_action :set_thread, only: [:create] @@ -35,25 +35,46 @@ class Api::V1::StatusesController < Api::BaseController end def create - @status = PostStatusService.new.call(current_user.account, - text: status_params[:status], - thread: @thread, - media_ids: status_params[:media_ids], - sensitive: status_params[:sensitive], - spoiler_text: status_params[:spoiler_text], - visibility: status_params[:visibility], - scheduled_at: status_params[:scheduled_at], - application: doorkeeper_token.application, - poll: status_params[:poll], - content_type: status_params[:content_type], - idempotency: request.headers['Idempotency-Key'], - with_rate_limit: true) + @status = PostStatusService.new.call( + current_user.account, + text: status_params[:status], + thread: @thread, + media_ids: status_params[:media_ids], + sensitive: status_params[:sensitive], + spoiler_text: status_params[:spoiler_text], + visibility: status_params[:visibility], + language: status_params[:language], + scheduled_at: status_params[:scheduled_at], + application: doorkeeper_token.application, + poll: status_params[:poll], + content_type: status_params[:content_type], + idempotency: request.headers['Idempotency-Key'], + with_rate_limit: true + ) render json: @status, serializer: @status.is_a?(ScheduledStatus) ? REST::ScheduledStatusSerializer : REST::StatusSerializer end + def update + @status = Status.where(account: current_account).find(params[:id]) + authorize @status, :update? + + UpdateStatusService.new.call( + @status, + current_account.id, + text: status_params[:status], + media_ids: status_params[:media_ids], + sensitive: status_params[:sensitive], + spoiler_text: status_params[:spoiler_text], + poll: status_params[:poll], + content_type: status_params[:content_type] + ) + + render json: @status, serializer: REST::StatusSerializer + end + def destroy - @status = Status.where(account_id: current_user.account).find(params[:id]) + @status = Status.where(account: current_account).find(params[:id]) authorize @status, :destroy? @status.discard @@ -85,6 +106,7 @@ class Api::V1::StatusesController < Api::BaseController :sensitive, :spoiler_text, :visibility, + :language, :scheduled_at, :content_type, media_ids: [], diff --git a/app/controllers/api/web/push_subscriptions_controller.rb b/app/controllers/api/web/push_subscriptions_controller.rb index bed57fc54..db2512e5f 100644 --- a/app/controllers/api/web/push_subscriptions_controller.rb +++ b/app/controllers/api/web/push_subscriptions_controller.rb @@ -26,6 +26,7 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController mention: alerts_enabled, poll: alerts_enabled, status: alerts_enabled, + update: alerts_enabled, }, } @@ -61,6 +62,15 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController end def data_params - @data_params ||= params.require(:data).permit(:policy, alerts: [:follow, :follow_request, :favourite, :reblog, :mention, :poll, :status]) + @data_params ||= params.require(:data).permit(:policy, alerts: [ + :follow, + :follow_request, + :favourite, + :reblog, + :mention, + :poll, + :status, + :update, + ]) end end diff --git a/app/controllers/concerns/localized.rb b/app/controllers/concerns/localized.rb index fe1142f34..f7b62f09c 100644 --- a/app/controllers/concerns/localized.rb +++ b/app/controllers/concerns/localized.rb @@ -7,27 +7,24 @@ module Localized around_action :set_locale end - def set_locale - locale = current_user.locale if respond_to?(:user_signed_in?) && user_signed_in? - locale ||= session[:locale] ||= default_locale - locale = default_locale unless I18n.available_locales.include?(locale.to_sym) - - I18n.with_locale(locale) do - yield - end + def set_locale(&block) + I18n.with_locale(requested_locale || I18n.default_locale, &block) end private - def default_locale - if ENV['DEFAULT_LOCALE'].present? - I18n.default_locale - else - request_locale || I18n.default_locale - end + def requested_locale + requested_locale_name = available_locale_or_nil(params[:locale]) + requested_locale_name ||= available_locale_or_nil(current_user.locale) if respond_to?(:user_signed_in?) && user_signed_in? + requested_locale_name ||= http_accept_language if ENV['DEFAULT_LOCALE'].blank? + requested_locale_name + end + + def http_accept_language + HttpAcceptLanguage::Parser.new(request.headers.fetch('Accept-Language')).language_region_compatible_from(I18n.available_locales) if request.headers.key?('Accept-Language') end - def request_locale - http_accept_language.language_region_compatible_from(I18n.available_locales) + def available_locale_or_nil(locale_name) + locale_name.to_sym if locale_name.present? && I18n.available_locales.include?(locale_name.to_sym) end end diff --git a/app/controllers/concerns/theming_concern.rb b/app/controllers/concerns/theming_concern.rb index 425554072..f993a81d7 100644 --- a/app/controllers/concerns/theming_concern.rb +++ b/app/controllers/concerns/theming_concern.rb @@ -20,7 +20,7 @@ module ThemingConcern end def valid_pack_data?(data, pack_name) - data['pack'].is_a?(Hash) && [String, Hash].any? { |c| data['pack'][pack_name].is_a?(c) } + data['pack'].is_a?(Hash) && data['pack'][pack_name].present? end def nil_pack(data) diff --git a/app/helpers/languages_helper.rb b/app/helpers/languages_helper.rb index 2eba433a3..1e075c3fb 100644 --- a/app/helpers/languages_helper.rb +++ b/app/helpers/languages_helper.rb @@ -1,95 +1,251 @@ # frozen_string_literal: true module LanguagesHelper - HUMAN_LOCALES = { - af: 'Afrikaans', - ar: 'العربية', - ast: 'Asturianu', - bg: 'Български', - bn: 'বাংলা', - br: 'Breton', - ca: 'Català', - co: 'Corsu', - cs: 'Čeština', - cy: 'Cymraeg', - da: 'Dansk', - de: 'Deutsch', - el: 'Ελληνικά', - en: 'English', - 'en-cafe': 'English (Plural Cafe)', - eo: 'Esperanto', + ISO_639_1 = { + aa: ['Afar', 'Afaraf'].freeze, + ab: ['Abkhaz', 'аҧсуа бызшәа'].freeze, + ae: ['Avestan', 'avesta'].freeze, + af: ['Afrikaans', 'Afrikaans'].freeze, + ak: ['Akan', 'Akan'].freeze, + am: ['Amharic', 'አማርኛ'].freeze, + an: ['Aragonese', 'aragonés'].freeze, + ar: ['Arabic', 'اللغة العربية'].freeze, + as: ['Assamese', 'অসমীয়া'].freeze, + av: ['Avaric', 'авар мацӀ'].freeze, + ay: ['Aymara', 'aymar aru'].freeze, + az: ['Azerbaijani', 'azərbaycan dili'].freeze, + ba: ['Bashkir', 'башҡорт теле'].freeze, + be: ['Belarusian', 'беларуская мова'].freeze, + bg: ['Bulgarian', 'български език'].freeze, + bh: ['Bihari', 'भोजपुरी'].freeze, + bi: ['Bislama', 'Bislama'].freeze, + bm: ['Bambara', 'bamanankan'].freeze, + bn: ['Bengali', 'বাংলা'].freeze, + bo: ['Tibetan', 'བོད་ཡིག'].freeze, + br: ['Breton', 'brezhoneg'].freeze, + bs: ['Bosnian', 'bosanski jezik'].freeze, + ca: ['Catalan', 'Català'].freeze, + ce: ['Chechen', 'нохчийн мотт'].freeze, + ch: ['Chamorro', 'Chamoru'].freeze, + co: ['Corsican', 'corsu'].freeze, + cr: ['Cree', 'ᓀᐦᐃᔭᐍᐏᐣ'].freeze, + cs: ['Czech', 'čeština'].freeze, + cu: ['Old Church Slavonic', 'ѩзыкъ словѣньскъ'].freeze, + cv: ['Chuvash', 'чӑваш чӗлхи'].freeze, + cy: ['Welsh', 'Cymraeg'].freeze, + da: ['Danish', 'dansk'].freeze, + de: ['German', 'Deutsch'].freeze, + dv: ['Divehi', 'Dhivehi'].freeze, + dz: ['Dzongkha', 'རྫོང་ཁ'].freeze, + ee: ['Ewe', 'Eʋegbe'].freeze, + el: ['Greek', 'Ελληνικά'].freeze, + en: ['English', 'English'].freeze, + eo: ['Esperanto', 'Esperanto'].freeze, + es: ['Spanish', 'Español'].freeze, + et: ['Estonian', 'eesti'].freeze, + eu: ['Basque', 'euskara'].freeze, + fa: ['Persian', 'فارسی'].freeze, + ff: ['Fula', 'Fulfulde'].freeze, + fi: ['Finnish', 'suomi'].freeze, + fj: ['Fijian', 'Vakaviti'].freeze, + fo: ['Faroese', 'føroyskt'].freeze, + fr: ['French', 'Français'].freeze, + fy: ['Western Frisian', 'Frysk'].freeze, + ga: ['Irish', 'Gaeilge'].freeze, + gd: ['Scottish Gaelic', 'Gàidhlig'].freeze, + gl: ['Galician', 'galego'].freeze, + gu: ['Gujarati', 'ગુજરાતી'].freeze, + gv: ['Manx', 'Gaelg'].freeze, + ha: ['Hausa', 'هَوُسَ'].freeze, + he: ['Hebrew', 'עברית'].freeze, + hi: ['Hindi', 'हिन्दी'].freeze, + ho: ['Hiri Motu', 'Hiri Motu'].freeze, + hr: ['Croatian', 'Hrvatski'].freeze, + ht: ['Haitian', 'Kreyòl ayisyen'].freeze, + hu: ['Hungarian', 'magyar'].freeze, + hy: ['Armenian', 'Հայերեն'].freeze, + hz: ['Herero', 'Otjiherero'].freeze, + ia: ['Interlingua', 'Interlingua'].freeze, + id: ['Indonesian', 'Bahasa Indonesia'].freeze, + ie: ['Interlingue', 'Interlingue'].freeze, + ig: ['Igbo', 'Asụsụ Igbo'].freeze, + ii: ['Nuosu', 'ꆈꌠ꒿ Nuosuhxop'].freeze, + ik: ['Inupiaq', 'Iñupiaq'].freeze, + io: ['Ido', 'Ido'].freeze, + is: ['Icelandic', 'Íslenska'].freeze, + it: ['Italian', 'Italiano'].freeze, + iu: ['Inuktitut', 'ᐃᓄᒃᑎᑐᑦ'].freeze, + ja: ['Japanese', '日本語'].freeze, + jv: ['Javanese', 'basa Jawa'].freeze, + ka: ['Georgian', 'ქართული'].freeze, + kg: ['Kongo', 'Kikongo'].freeze, + ki: ['Kikuyu', 'Gĩkũyũ'].freeze, + kj: ['Kwanyama', 'Kuanyama'].freeze, + kk: ['Kazakh', 'қазақ тілі'].freeze, + kl: ['Kalaallisut', 'kalaallisut'].freeze, + km: ['Khmer', 'ខេមរភាសា'].freeze, + kn: ['Kannada', 'ಕನ್ನಡ'].freeze, + ko: ['Korean', '한국어'].freeze, + kr: ['Kanuri', 'Kanuri'].freeze, + ks: ['Kashmiri', 'कश्मीरी'].freeze, + ku: ['Kurdish', 'Kurdî'].freeze, + kv: ['Komi', 'коми кыв'].freeze, + kw: ['Cornish', 'Kernewek'].freeze, + ky: ['Kyrgyz', 'Кыргызча'].freeze, + la: ['Latin', 'latine'].freeze, + lb: ['Luxembourgish', 'Lëtzebuergesch'].freeze, + lg: ['Ganda', 'Luganda'].freeze, + li: ['Limburgish', 'Limburgs'].freeze, + ln: ['Lingala', 'Lingála'].freeze, + lo: ['Lao', 'ພາສາ'].freeze, + lt: ['Lithuanian', 'lietuvių kalba'].freeze, + lu: ['Luba-Katanga', 'Tshiluba'].freeze, + lv: ['Latvian', 'latviešu valoda'].freeze, + mg: ['Malagasy', 'fiteny malagasy'].freeze, + mh: ['Marshallese', 'Kajin M̧ajeļ'].freeze, + mi: ['Māori', 'te reo Māori'].freeze, + mk: ['Macedonian', 'македонски јазик'].freeze, + ml: ['Malayalam', 'മലയാളം'].freeze, + mn: ['Mongolian', 'Монгол хэл'].freeze, + mr: ['Marathi', 'मराठी'].freeze, + ms: ['Malay', 'Bahasa Malaysia'].freeze, + mt: ['Maltese', 'Malti'].freeze, + my: ['Burmese', 'ဗမာစာ'].freeze, + na: ['Nauru', 'Ekakairũ Naoero'].freeze, + nb: ['Norwegian Bokmål', 'Norsk bokmål'].freeze, + nd: ['Northern Ndebele', 'isiNdebele'].freeze, + ne: ['Nepali', 'नेपाली'].freeze, + ng: ['Ndonga', 'Owambo'].freeze, + nl: ['Dutch', 'Nederlands'].freeze, + nn: ['Norwegian Nynorsk', 'Norsk nynorsk'].freeze, + no: ['Norwegian', 'Norsk'].freeze, + nr: ['Southern Ndebele', 'isiNdebele'].freeze, + nv: ['Navajo', 'Diné bizaad'].freeze, + ny: ['Chichewa', 'chiCheŵa'].freeze, + oc: ['Occitan', 'occitan'].freeze, + oj: ['Ojibwe', 'ᐊᓂᔑᓈᐯᒧᐎᓐ'].freeze, + om: ['Oromo', 'Afaan Oromoo'].freeze, + or: ['Oriya', 'ଓଡ଼ିଆ'].freeze, + os: ['Ossetian', 'ирон æвзаг'].freeze, + pa: ['Panjabi', 'ਪੰਜਾਬੀ'].freeze, + pi: ['Pāli', 'पाऴि'].freeze, + pl: ['Polish', 'Polski'].freeze, + ps: ['Pashto', 'پښتو'].freeze, + pt: ['Portuguese', 'Português'].freeze, + qu: ['Quechua', 'Runa Simi'].freeze, + rm: ['Romansh', 'rumantsch grischun'].freeze, + rn: ['Kirundi', 'Ikirundi'].freeze, + ro: ['Romanian', 'Română'].freeze, + ru: ['Russian', 'Русский'].freeze, + rw: ['Kinyarwanda', 'Ikinyarwanda'].freeze, + sa: ['Sanskrit', 'संस्कृतम्'].freeze, + sc: ['Sardinian', 'sardu'].freeze, + sd: ['Sindhi', 'सिन्धी'].freeze, + se: ['Northern Sami', 'Davvisámegiella'].freeze, + sg: ['Sango', 'yângâ tî sängö'].freeze, + si: ['Sinhala', 'සිංහල'].freeze, + sk: ['Slovak', 'slovenčina'].freeze, + sl: ['Slovenian', 'slovenščina'].freeze, + sn: ['Shona', 'chiShona'].freeze, + so: ['Somali', 'Soomaaliga'].freeze, + sq: ['Albanian', 'Shqip'].freeze, + sr: ['Serbian', 'српски језик'].freeze, + ss: ['Swati', 'SiSwati'].freeze, + st: ['Southern Sotho', 'Sesotho'].freeze, + su: ['Sundanese', 'Basa Sunda'].freeze, + sv: ['Swedish', 'Svenska'].freeze, + sw: ['Swahili', 'Kiswahili'].freeze, + ta: ['Tamil', 'தமிழ்'].freeze, + te: ['Telugu', 'తెలుగు'].freeze, + tg: ['Tajik', 'тоҷикӣ'].freeze, + th: ['Thai', 'ไทย'].freeze, + ti: ['Tigrinya', 'ትግርኛ'].freeze, + tk: ['Turkmen', 'Türkmen'].freeze, + tl: ['Tagalog', 'Wikang Tagalog'].freeze, + tn: ['Tswana', 'Setswana'].freeze, + to: ['Tonga', 'faka Tonga'].freeze, + tr: ['Turkish', 'Türkçe'].freeze, + ts: ['Tsonga', 'Xitsonga'].freeze, + tt: ['Tatar', 'татар теле'].freeze, + tw: ['Twi', 'Twi'].freeze, + ty: ['Tahitian', 'Reo Tahiti'].freeze, + ug: ['Uyghur', 'ئۇيغۇرچە'].freeze, + uk: ['Ukrainian', 'Українська'].freeze, + ur: ['Urdu', 'اردو'].freeze, + uz: ['Uzbek', 'Ўзбек'].freeze, + ve: ['Venda', 'Tshivenḓa'].freeze, + vi: ['Vietnamese', 'Tiếng Việt'].freeze, + vo: ['Volapük', 'Volapük'].freeze, + wa: ['Walloon', 'walon'].freeze, + wo: ['Wolof', 'Wollof'].freeze, + xh: ['Xhosa', 'isiXhosa'].freeze, + yi: ['Yiddish', 'ייִדיש'].freeze, + yo: ['Yoruba', 'Yorùbá'].freeze, + za: ['Zhuang', 'Saɯ cueŋƅ'].freeze, + zh: ['Chinese', '中文'].freeze, + zu: ['Zulu', 'isiZulu'].freeze, + }.freeze + + ISO_639_3 = { + ast: ['Asturian', 'Asturianu'].freeze, + kab: ['Kabyle', 'Taqbaylit'].freeze, + kmr: ['Northern Kurdish', 'Kurmancî'].freeze, + zgh: ['Standard Moroccan Tamazight', 'ⵜⴰⵎⴰⵣⵉⵖⵜ'].freeze, + }.freeze + + CUSTOM = { + 'en-cafe': ['English (Plural Cafe)', 'English (Plural Cafe)'].freeze, + }.freeze + + SUPPORTED_LOCALES = {}.merge(ISO_639_1).merge(ISO_639_3).merge(CUSTOM).freeze + + # For ISO-639-1 and ISO-639-3 language codes, we have their official + # names, but for some translations, we need the names of the + # regional variants specifically + REGIONAL_LOCALE_NAMES = { 'es-AR': 'Español (Argentina)', 'es-MX': 'Español (México)', - es: 'Español', - et: 'Eesti', - eu: 'Euskara', - fa: 'فارسی', - fi: 'Suomi', - fr: 'Français', - ga: 'Gaeilge', - gd: 'Gàidhlig', - gl: 'Galego', - he: 'עברית', - hi: 'हिन्दी', - hr: 'Hrvatski', - hu: 'Magyar', - hy: 'Հայերեն', - id: 'Bahasa Indonesia', - io: 'Ido', - is: 'Íslenska', - it: 'Italiano', - ja: '日本語', - ka: 'ქართული', - kab: 'Taqbaylit', - kk: 'Қазақша', - kmr: 'Kurmancî', - kn: 'ಕನ್ನಡ', - ko: '한국어', - ku: 'سۆرانی', - lt: 'Lietuvių', - lv: 'Latviešu', - mk: 'Македонски', - ml: 'മലയാളം', - mr: 'मराठी', - ms: 'Bahasa Melayu', - nl: 'Nederlands', - nn: 'Nynorsk', - no: 'Norsk', - oc: 'Occitan', - pl: 'Polski', 'pt-BR': 'Português (Brasil)', 'pt-PT': 'Português (Portugal)', - pt: 'Português', - ro: 'Română', - ru: 'Русский', - sa: 'संस्कृतम्', - sc: 'Sardu', - si: 'සිංහල', - sk: 'Slovenčina', - sl: 'Slovenščina', - sq: 'Shqip', 'sr-Latn': 'Srpski (latinica)', - sr: 'Српски', - sv: 'Svenska', - ta: 'தமிழ்', - te: 'తెలుగు', - th: 'ไทย', - tr: 'Türkçe', - uk: 'Українська', - ur: 'اُردُو', - vi: 'Tiếng Việt', - zgh: 'ⵜⴰⵎⴰⵣⵉⵖⵜ', 'zh-CN': '简体中文', 'zh-HK': '繁體中文(香港)', 'zh-TW': '繁體中文(臺灣)', - zh: '中文', }.freeze - def human_locale(locale) - if locale == 'und' + def native_locale_name(locale) + if locale.blank? || locale == 'und' + I18n.t('generic.none') + elsif (supported_locale = SUPPORTED_LOCALES[locale.to_sym]) + supported_locale[1] + elsif (regional_locale = REGIONAL_LOCALE_NAMES[locale.to_sym]) + regional_locale + else + locale + end + end + + def standard_locale_name(locale) + if locale.blank? I18n.t('generic.none') + elsif (supported_locale = SUPPORTED_LOCALES[locale.to_sym]) + supported_locale[0] else - HUMAN_LOCALES[locale.to_sym] || locale + locale end end + + def valid_locale_or_nil(str) + return if str.blank? + + code, = str.to_s.split(/[_-]/) # Strip out the region from e.g. en_US or ja-JP + + return unless valid_locale?(code) + + code + end + + def valid_locale?(locale) + SUPPORTED_LOCALES.key?(locale.to_sym) + end end diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index 23739d1cd..3d5592867 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -2,7 +2,7 @@ module SettingsHelper def filterable_languages - LanguageDetector.instance.language_names.select(&LanguagesHelper::HUMAN_LOCALES.method(:key?)) + LanguagesHelper::SUPPORTED_LOCALES.keys end def hash_to_object(hash) diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js index 261c72b2a..baa98e98f 100644 --- a/app/javascript/flavours/glitch/actions/compose.js +++ b/app/javascript/flavours/glitch/actions/compose.js @@ -75,6 +75,8 @@ export const INIT_MEDIA_EDIT_MODAL = 'INIT_MEDIA_EDIT_MODAL'; export const COMPOSE_CHANGE_MEDIA_DESCRIPTION = 'COMPOSE_CHANGE_MEDIA_DESCRIPTION'; export const COMPOSE_CHANGE_MEDIA_FOCUS = 'COMPOSE_CHANGE_MEDIA_FOCUS'; +export const COMPOSE_SET_STATUS = 'COMPOSE_SET_STATUS'; + const messages = defineMessages({ uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' }, uploadErrorPoll: { id: 'upload_error.poll', defaultMessage: 'File upload not allowed with polls.' }, @@ -88,6 +90,15 @@ export const ensureComposeIsVisible = (getState, routerHistory) => { } }; +export function setComposeToStatus(status, text, spoiler_text) { + return{ + type: COMPOSE_SET_STATUS, + status, + text, + spoiler_text, + }; +}; + export function changeCompose(text) { return { type: COMPOSE_CHANGE, @@ -150,8 +161,9 @@ export function directCompose(account, routerHistory) { export function submitCompose(routerHistory) { return function (dispatch, getState) { - let status = getState().getIn(['compose', 'text'], ''); - let media = getState().getIn(['compose', 'media_attachments']); + let status = getState().getIn(['compose', 'text'], ''); + const media = getState().getIn(['compose', 'media_attachments']); + const statusId = getState().getIn(['compose', 'id'], null); const spoilers = getState().getIn(['compose', 'spoiler']) || getState().getIn(['local_settings', 'always_show_spoilers_field']); let spoilerText = spoilers ? getState().getIn(['compose', 'spoiler_text'], '') : ''; @@ -159,20 +171,25 @@ export function submitCompose(routerHistory) { return; } - dispatch(submitComposeRequest()); if (getState().getIn(['compose', 'advanced_options', 'do_not_federate'])) { status = status + ' 👁️'; } - api(getState).post('/api/v1/statuses', { - status, - content_type: getState().getIn(['compose', 'content_type']), - in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null), - media_ids: media.map(item => item.get('id')), - sensitive: getState().getIn(['compose', 'sensitive']) || (spoilerText.length > 0 && media.size !== 0), - spoiler_text: spoilerText, - visibility: getState().getIn(['compose', 'privacy']), - poll: getState().getIn(['compose', 'poll'], null), - }, { + + dispatch(submitComposeRequest()); + + api(getState).request({ + url: statusId === null ? '/api/v1/statuses' : `/api/v1/statuses/${statusId}`, + method: statusId === null ? 'post' : 'put', + data: { + status, + content_type: getState().getIn(['compose', 'content_type']), + in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null), + media_ids: media.map(item => item.get('id')), + sensitive: getState().getIn(['compose', 'sensitive']) || (spoilerText.length > 0 && media.size !== 0), + spoiler_text: spoilerText, + visibility: getState().getIn(['compose', 'privacy']), + poll: getState().getIn(['compose', 'poll'], null), + }, headers: { 'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']), }, @@ -202,14 +219,16 @@ export function submitCompose(routerHistory) { } }; - insertIfOnline('home'); + if (statusId === null) { + insertIfOnline('home'); + } - if (response.data.in_reply_to_id === null && response.data.visibility === 'public') { + if (statusId === null && response.data.in_reply_to_id === null && response.data.visibility === 'public') { insertIfOnline('community'); if (!response.data.local_only) { insertIfOnline('public'); } - } else if (response.data.visibility === 'direct') { + } else if (statusId === null && response.data.visibility === 'direct') { insertIfOnline('direct'); } }).catch(function (error) { diff --git a/app/javascript/flavours/glitch/actions/history.js b/app/javascript/flavours/glitch/actions/history.js new file mode 100644 index 000000000..c47057261 --- /dev/null +++ b/app/javascript/flavours/glitch/actions/history.js @@ -0,0 +1,37 @@ +import api from 'flavours/glitch/util/api'; +import { importFetchedAccounts } from './importer'; + +export const HISTORY_FETCH_REQUEST = 'HISTORY_FETCH_REQUEST'; +export const HISTORY_FETCH_SUCCESS = 'HISTORY_FETCH_SUCCESS'; +export const HISTORY_FETCH_FAIL = 'HISTORY_FETCH_FAIL'; + +export const fetchHistory = statusId => (dispatch, getState) => { + const loading = getState().getIn(['history', statusId, 'loading']); + + if (loading) { + return; + } + + dispatch(fetchHistoryRequest(statusId)); + + api(getState).get(`/api/v1/statuses/${statusId}/history`).then(({ data }) => { + dispatch(importFetchedAccounts(data.map(x => x.account))); + dispatch(fetchHistorySuccess(statusId, data)); + }).catch(error => dispatch(fetchHistoryFail(error))); +}; + +export const fetchHistoryRequest = statusId => ({ + type: HISTORY_FETCH_REQUEST, + statusId, +}); + +export const fetchHistorySuccess = (statusId, history) => ({ + type: HISTORY_FETCH_SUCCESS, + statusId, + history, +}); + +export const fetchHistoryFail = error => ({ + type: HISTORY_FETCH_FAIL, + error, +}); diff --git a/app/javascript/flavours/glitch/actions/notifications.js b/app/javascript/flavours/glitch/actions/notifications.js index 4b00ea632..40430102c 100644 --- a/app/javascript/flavours/glitch/actions/notifications.js +++ b/app/javascript/flavours/glitch/actions/notifications.js @@ -47,7 +47,6 @@ export const NOTIFICATIONS_UNMOUNT = 'NOTIFICATIONS_UNMOUNT'; export const NOTIFICATIONS_SET_VISIBILITY = 'NOTIFICATIONS_SET_VISIBILITY'; - export const NOTIFICATIONS_MARK_AS_READ = 'NOTIFICATIONS_MARK_AS_READ'; export const NOTIFICATIONS_SET_BROWSER_SUPPORT = 'NOTIFICATIONS_SET_BROWSER_SUPPORT'; @@ -136,7 +135,17 @@ const excludeTypesFromSettings = state => state.getIn(['settings', 'notification const excludeTypesFromFilter = filter => { - const allTypes = ImmutableList(['follow', 'follow_request', 'favourite', 'reblog', 'mention', 'poll']); + const allTypes = ImmutableList([ + 'follow', + 'follow_request', + 'favourite', + 'reblog', + 'mention', + 'poll', + 'status', + 'update', + ]); + return allTypes.filterNot(item => item === filter).toJS(); }; diff --git a/app/javascript/flavours/glitch/actions/statuses.js b/app/javascript/flavours/glitch/actions/statuses.js index 7db357df1..6ffcf181d 100644 --- a/app/javascript/flavours/glitch/actions/statuses.js +++ b/app/javascript/flavours/glitch/actions/statuses.js @@ -2,7 +2,7 @@ import api from 'flavours/glitch/util/api'; import { deleteFromTimelines } from './timelines'; import { importFetchedStatus, importFetchedStatuses } from './importer'; -import { ensureComposeIsVisible } from './compose'; +import { ensureComposeIsVisible, setComposeToStatus } from './compose'; export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST'; export const STATUS_FETCH_SUCCESS = 'STATUS_FETCH_SUCCESS'; @@ -26,6 +26,10 @@ export const STATUS_UNMUTE_FAIL = 'STATUS_UNMUTE_FAIL'; export const REDRAFT = 'REDRAFT'; +export const STATUS_FETCH_SOURCE_REQUEST = 'STATUS_FETCH_SOURCE_REQUEST'; +export const STATUS_FETCH_SOURCE_SUCCESS = 'STATUS_FETCH_SOURCE_SUCCESS'; +export const STATUS_FETCH_SOURCE_FAIL = 'STATUS_FETCH_SOURCE_FAIL'; + export function fetchStatusRequest(id, skipLoading) { return { type: STATUS_FETCH_REQUEST, @@ -81,6 +85,37 @@ export function redraft(status, raw_text, content_type) { }; }; +export const editStatus = (id, routerHistory) => (dispatch, getState) => { + let status = getState().getIn(['statuses', id]); + + if (status.get('poll')) { + status = status.set('poll', getState().getIn(['polls', status.get('poll')])); + } + + dispatch(fetchStatusSourceRequest()); + + api(getState).get(`/api/v1/statuses/${id}/source`).then(response => { + dispatch(fetchStatusSourceSuccess()); + ensureComposeIsVisible(getState, routerHistory); + dispatch(setComposeToStatus(status, response.data.text, response.data.spoiler_text)); + }).catch(error => { + dispatch(fetchStatusSourceFail(error)); + }); +}; + +export const fetchStatusSourceRequest = () => ({ + type: STATUS_FETCH_SOURCE_REQUEST, +}); + +export const fetchStatusSourceSuccess = () => ({ + type: STATUS_FETCH_SOURCE_SUCCESS, +}); + +export const fetchStatusSourceFail = error => ({ + type: STATUS_FETCH_SOURCE_FAIL, + error, +}); + export function deleteStatus(id, routerHistory, withRedraft = false) { return (dispatch, getState) => { let status = getState().getIn(['statuses', id]); diff --git a/app/javascript/flavours/glitch/components/dropdown_menu.js b/app/javascript/flavours/glitch/components/dropdown_menu.js index 023fecb9a..bd6bc4ffd 100644 --- a/app/javascript/flavours/glitch/components/dropdown_menu.js +++ b/app/javascript/flavours/glitch/components/dropdown_menu.js @@ -6,6 +6,8 @@ import Overlay from 'react-overlays/lib/Overlay'; import Motion from 'flavours/glitch/util/optional_motion'; import spring from 'react-motion/lib/spring'; import { supportsPassiveEvents } from 'detect-passive-events'; +import classNames from 'classnames'; +import { CircularProgress } from 'mastodon/components/loading_indicator'; const listenerOptions = supportsPassiveEvents ? { passive: true } : false; let id = 0; @@ -17,13 +19,18 @@ class DropdownMenu extends React.PureComponent { }; static propTypes = { - items: PropTypes.array.isRequired, + items: PropTypes.oneOfType([PropTypes.array, ImmutablePropTypes.list]).isRequired, + loading: PropTypes.bool, + scrollable: PropTypes.bool, onClose: PropTypes.func.isRequired, style: PropTypes.object, placement: PropTypes.string, arrowOffsetLeft: PropTypes.string, arrowOffsetTop: PropTypes.string, openedViaKeyboard: PropTypes.bool, + renderItem: PropTypes.func, + renderHeader: PropTypes.func, + onItemClick: PropTypes.func.isRequired, }; static defaultProps = { @@ -45,9 +52,11 @@ class DropdownMenu extends React.PureComponent { document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('keydown', this.handleKeyDown, false); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); + if (this.focusedItem && this.props.openedViaKeyboard) { this.focusedItem.focus({ preventScroll: true }); } + this.setState({ mounted: true }); } @@ -66,7 +75,7 @@ class DropdownMenu extends React.PureComponent { } handleKeyDown = e => { - const items = Array.from(this.node.getElementsByTagName('a')); + const items = Array.from(this.node.querySelectorAll('a, button')); const index = items.indexOf(document.activeElement); let element = null; @@ -109,30 +118,20 @@ class DropdownMenu extends React.PureComponent { } handleClick = e => { - const i = Number(e.currentTarget.getAttribute('data-index')); - const { action, to } = this.props.items[i]; - - this.props.onClose(); - - if (typeof action === 'function') { - e.preventDefault(); - action(); - } else if (to) { - e.preventDefault(); - this.context.router.history.push(to); - } + const { onItemClick } = this.props; + onItemClick(e); } - renderItem (option, i) { + renderItem = (option, i) => { if (option === null) { return <li key={`sep-${i}`} className='dropdown-menu__separator' />; } - const { text, href = '#' } = option; + const { text, href = '#', target = '_blank', method } = option; return ( <li className='dropdown-menu__item' key={`${text}-${i}`}> - <a href={href} target='_blank' rel='noopener noreferrer' role='button' tabIndex='0' ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onKeyPress={this.handleItemKeyPress} data-index={i}> + <a href={href} target={target} data-method={method} rel='noopener noreferrer' role='button' tabIndex='0' ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onKeyPress={this.handleItemKeyPress} data-index={i}> {text} </a> </li> @@ -140,21 +139,37 @@ class DropdownMenu extends React.PureComponent { } render () { - const { items, style, placement, arrowOffsetLeft, arrowOffsetTop } = this.props; + const { items, style, placement, arrowOffsetLeft, arrowOffsetTop, scrollable, renderHeader, loading } = this.props; const { mounted } = this.state; + let renderItem = this.props.renderItem || this.renderItem; + return ( <Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}> {({ opacity, scaleX, scaleY }) => ( // It should not be transformed when mounting because the resulting // size will be used to determine the coordinate of the menu by // react-overlays - <div className='dropdown-menu' style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} ref={this.setRef}> + <div className={`dropdown-menu ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} ref={this.setRef}> <div className={`dropdown-menu__arrow ${placement}`} style={{ left: arrowOffsetLeft, top: arrowOffsetTop }} /> - <ul> - {items.map((option, i) => this.renderItem(option, i))} - </ul> + <div className={classNames('dropdown-menu__container', { 'dropdown-menu__container--loading': loading })}> + {loading && ( + <CircularProgress size={30} strokeWidth={3.5} /> + )} + + {!loading && renderHeader && ( + <div className='dropdown-menu__container__header'> + {renderHeader(items)} + </div> + )} + + {!loading && ( + <ul className={classNames('dropdown-menu__container__list', { 'dropdown-menu__container__list--scrollable': scrollable })}> + {items.map((option, i) => renderItem(option, i, { onClick: this.handleClick, onKeyPress: this.handleItemKeyPress }))} + </ul> + )} + </div> </div> )} </Motion> @@ -170,11 +185,14 @@ export default class Dropdown extends React.PureComponent { }; static propTypes = { - icon: PropTypes.string.isRequired, - items: PropTypes.array.isRequired, - size: PropTypes.number.isRequired, + children: PropTypes.node, + icon: PropTypes.string, + items: PropTypes.oneOfType([PropTypes.array, ImmutablePropTypes.list]).isRequired, + loading: PropTypes.bool, + size: PropTypes.number, title: PropTypes.string, disabled: PropTypes.bool, + scrollable: PropTypes.bool, status: ImmutablePropTypes.map, isUserTouching: PropTypes.func, onOpen: PropTypes.func.isRequired, @@ -182,6 +200,9 @@ export default class Dropdown extends React.PureComponent { dropdownPlacement: PropTypes.string, openDropdownId: PropTypes.number, openedViaKeyboard: PropTypes.bool, + renderItem: PropTypes.func, + renderHeader: PropTypes.func, + onItemClick: PropTypes.func, }; static defaultProps = { @@ -236,17 +257,22 @@ export default class Dropdown extends React.PureComponent { } } - handleItemClick = (i, e) => { - const { action, to } = this.props.items[i]; + handleItemClick = e => { + const { onItemClick } = this.props; + const i = Number(e.currentTarget.getAttribute('data-index')); + const item = this.props.items[i]; this.handleClose(); - if (typeof action === 'function') { + if (typeof onItemClick === 'function') { + e.preventDefault(); + onItemClick(item, i); + } else if (item && typeof item.action === 'function') { e.preventDefault(); - action(); - } else if (to) { + item.action(); + } else if (item && item.to) { e.preventDefault(); - this.context.router.history.push(to); + this.context.router.history.push(item.to); } } @@ -264,29 +290,67 @@ export default class Dropdown extends React.PureComponent { } } + close = () => { + this.handleClose(); + } + render () { - const { icon, items, size, title, disabled, dropdownPlacement, openDropdownId, openedViaKeyboard } = this.props; + const { + icon, + items, + size, + title, + disabled, + loading, + scrollable, + dropdownPlacement, + openDropdownId, + openedViaKeyboard, + children, + renderItem, + renderHeader, + } = this.props; + const open = this.state.id === openDropdownId; + const button = children ? React.cloneElement(React.Children.only(children), { + ref: this.setTargetRef, + onClick: this.handleClick, + onMouseDown: this.handleMouseDown, + onKeyDown: this.handleButtonKeyDown, + onKeyPress: this.handleKeyPress, + }) : ( + <IconButton + icon={icon} + title={title} + active={open} + disabled={disabled} + size={size} + ref={this.setTargetRef} + onClick={this.handleClick} + onMouseDown={this.handleMouseDown} + onKeyDown={this.handleButtonKeyDown} + onKeyPress={this.handleKeyPress} + /> + ); + return ( - <div> - <IconButton - icon={icon} - title={title} - active={open} - disabled={disabled} - size={size} - ref={this.setTargetRef} - onClick={this.handleClick} - onMouseDown={this.handleMouseDown} - onKeyDown={this.handleButtonKeyDown} - onKeyPress={this.handleKeyPress} - /> + <React.Fragment> + {button} <Overlay show={open} placement={dropdownPlacement} target={this.findTarget}> - <DropdownMenu items={items} onClose={this.handleClose} openedViaKeyboard={openedViaKeyboard} /> + <DropdownMenu + items={items} + loading={loading} + scrollable={scrollable} + onClose={this.handleClose} + openedViaKeyboard={openedViaKeyboard} + renderItem={renderItem} + renderHeader={renderHeader} + onItemClick={this.handleItemClick} + /> </Overlay> - </div> + </React.Fragment> ); } diff --git a/app/javascript/flavours/glitch/components/edited_timestamp/containers/dropdown_menu_container.js b/app/javascript/flavours/glitch/components/edited_timestamp/containers/dropdown_menu_container.js new file mode 100644 index 000000000..8b73663d4 --- /dev/null +++ b/app/javascript/flavours/glitch/components/edited_timestamp/containers/dropdown_menu_container.js @@ -0,0 +1,27 @@ +import { connect } from 'react-redux'; +import { openDropdownMenu, closeDropdownMenu } from 'flavours/glitch/actions/dropdown_menu'; +import { fetchHistory } from 'flavours/glitch/actions/history'; +import DropdownMenu from 'flavours/glitch/components/dropdown_menu'; + +const mapStateToProps = (state, { statusId }) => ({ + dropdownPlacement: state.getIn(['dropdown_menu', 'placement']), + openDropdownId: state.getIn(['dropdown_menu', 'openId']), + openedViaKeyboard: state.getIn(['dropdown_menu', 'keyboard']), + items: state.getIn(['history', statusId, 'items']), + loading: state.getIn(['history', statusId, 'loading']), +}); + +const mapDispatchToProps = (dispatch, { statusId }) => ({ + + onOpen (id, onItemClick, dropdownPlacement, keyboard) { + dispatch(fetchHistory(statusId)); + dispatch(openDropdownMenu(id, dropdownPlacement, keyboard)); + }, + + onClose (id) { + dispatch(closeDropdownMenu(id)); + }, + +}); + +export default connect(mapStateToProps, mapDispatchToProps)(DropdownMenu); diff --git a/app/javascript/flavours/glitch/components/edited_timestamp/index.js b/app/javascript/flavours/glitch/components/edited_timestamp/index.js new file mode 100644 index 000000000..9648133af --- /dev/null +++ b/app/javascript/flavours/glitch/components/edited_timestamp/index.js @@ -0,0 +1,70 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { FormattedMessage, injectIntl } from 'react-intl'; +import Icon from 'flavours/glitch/components/icon'; +import DropdownMenu from './containers/dropdown_menu_container'; +import { connect } from 'react-redux'; +import { openModal } from 'flavours/glitch/actions/modal'; +import RelativeTimestamp from 'flavours/glitch/components/relative_timestamp'; +import InlineAccount from 'flavours/glitch/components/inline_account'; + +const mapDispatchToProps = (dispatch, { statusId }) => ({ + + onItemClick (index) { + dispatch(openModal('COMPARE_HISTORY', { index, statusId })); + }, + +}); + +export default @connect(null, mapDispatchToProps) +@injectIntl +class EditedTimestamp extends React.PureComponent { + + static propTypes = { + statusId: PropTypes.string.isRequired, + timestamp: PropTypes.string.isRequired, + intl: PropTypes.object.isRequired, + onItemClick: PropTypes.func.isRequired, + }; + + handleItemClick = (item, i) => { + const { onItemClick } = this.props; + onItemClick(i); + }; + + renderHeader = items => { + return ( + <FormattedMessage id='status.edited_x_times' defaultMessage='Edited {count, plural, one {{count} time} other {{count} times}}' values={{ count: items.size - 1 }} /> + ); + } + + renderItem = (item, index, { onClick, onKeyPress }) => { + const formattedDate = <RelativeTimestamp timestamp={item.get('created_at')} short={false} />; + const formattedName = <InlineAccount accountId={item.get('account')} />; + + const label = item.get('original') ? ( + <FormattedMessage id='status.history.created' defaultMessage='{name} created {date}' values={{ name: formattedName, date: formattedDate }} /> + ) : ( + <FormattedMessage id='status.history.edited' defaultMessage='{name} edited {date}' values={{ name: formattedName, date: formattedDate }} /> + ); + + return ( + <li className='dropdown-menu__item edited-timestamp__history__item' key={item.get('created_at')}> + <button data-index={index} onClick={onClick} onKeyPress={onKeyPress}>{label}</button> + </li> + ); + } + + render () { + const { timestamp, intl, statusId } = this.props; + + return ( + <DropdownMenu statusId={statusId} renderItem={this.renderItem} scrollable renderHeader={this.renderHeader} onItemClick={this.handleItemClick}> + <button className='dropdown-menu__text-button'> + <FormattedMessage id='status.edited' defaultMessage='Edited {date}' values={{ date: intl.formatDate(timestamp, { hour12: false, month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }) }} /> <Icon id='caret-down' /> + </button> + </DropdownMenu> + ); + } + +} diff --git a/app/javascript/flavours/glitch/components/inline_account.js b/app/javascript/flavours/glitch/components/inline_account.js new file mode 100644 index 000000000..2ef1f52cc --- /dev/null +++ b/app/javascript/flavours/glitch/components/inline_account.js @@ -0,0 +1,34 @@ +import React from 'react'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import { connect } from 'react-redux'; +import { makeGetAccount } from 'flavours/glitch/selectors'; +import Avatar from 'flavours/glitch/components/avatar'; + +const makeMapStateToProps = () => { + const getAccount = makeGetAccount(); + + const mapStateToProps = (state, { accountId }) => ({ + account: getAccount(state, accountId), + }); + + return mapStateToProps; +}; + +export default @connect(makeMapStateToProps) +class InlineAccount extends React.PureComponent { + + static propTypes = { + account: ImmutablePropTypes.map.isRequired, + }; + + render () { + const { account } = this.props; + + return ( + <span className='inline-account'> + <Avatar size={13} account={account} /> <strong>{account.get('username')}</strong> + </span> + ); + } + +} diff --git a/app/javascript/flavours/glitch/components/loading_indicator.js b/app/javascript/flavours/glitch/components/loading_indicator.js index d6a5adb6f..59f721c50 100644 --- a/app/javascript/flavours/glitch/components/loading_indicator.js +++ b/app/javascript/flavours/glitch/components/loading_indicator.js @@ -1,10 +1,31 @@ import React from 'react'; -import { FormattedMessage } from 'react-intl'; +import PropTypes from 'prop-types'; + +export const CircularProgress = ({ size, strokeWidth }) => { + const viewBox = `0 0 ${size} ${size}`; + const radius = (size - strokeWidth) / 2; + + return ( + <svg width={size} heigh={size} viewBox={viewBox} className='circular-progress' role='progressbar'> + <circle + fill='none' + cx={size / 2} + cy={size / 2} + r={radius} + strokeWidth={`${strokeWidth}px`} + /> + </svg> + ); +}; + +CircularProgress.propTypes = { + size: PropTypes.number.isRequired, + strokeWidth: PropTypes.number.isRequired, +}; const LoadingIndicator = () => ( <div className='loading-indicator'> - <div className='loading-indicator__figure' /> - <FormattedMessage id='loading_indicator.label' defaultMessage='Loading...' /> + <CircularProgress size={50} strokeWidth={6} /> </div> ); diff --git a/app/javascript/flavours/glitch/components/relative_timestamp.js b/app/javascript/flavours/glitch/components/relative_timestamp.js index 711181dcd..512480339 100644 --- a/app/javascript/flavours/glitch/components/relative_timestamp.js +++ b/app/javascript/flavours/glitch/components/relative_timestamp.js @@ -5,10 +5,15 @@ import PropTypes from 'prop-types'; const messages = defineMessages({ today: { id: 'relative_time.today', defaultMessage: 'today' }, just_now: { id: 'relative_time.just_now', defaultMessage: 'now' }, + just_now_full: { id: 'relative_time.full.just_now', defaultMessage: 'just now' }, seconds: { id: 'relative_time.seconds', defaultMessage: '{number}s' }, + seconds_full: { id: 'relative_time.full.seconds', defaultMessage: '{number, plural, one {# second} other {# seconds}} ago' }, minutes: { id: 'relative_time.minutes', defaultMessage: '{number}m' }, + minutes_full: { id: 'relative_time.full.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}} ago' }, hours: { id: 'relative_time.hours', defaultMessage: '{number}h' }, + hours_full: { id: 'relative_time.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}} ago' }, days: { id: 'relative_time.days', defaultMessage: '{number}d' }, + days_full: { id: 'relative_time.full.days', defaultMessage: '{number, plural, one {# day} other {# days}} ago' }, moments_remaining: { id: 'time_remaining.moments', defaultMessage: 'Moments remaining' }, seconds_remaining: { id: 'time_remaining.seconds', defaultMessage: '{number, plural, one {# second} other {# seconds}} left' }, minutes_remaining: { id: 'time_remaining.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}} left' }, @@ -66,7 +71,7 @@ const getUnitDelay = units => { } }; -export const timeAgoString = (intl, date, now, year, timeGiven = true) => { +export const timeAgoString = (intl, date, now, year, timeGiven, short) => { const delta = now - date.getTime(); let relativeTime; @@ -74,16 +79,16 @@ export const timeAgoString = (intl, date, now, year, timeGiven = true) => { if (delta < DAY && !timeGiven) { relativeTime = intl.formatMessage(messages.today); } else if (delta < 10 * SECOND) { - relativeTime = intl.formatMessage(messages.just_now); + relativeTime = intl.formatMessage(short ? messages.just_now : messages.just_now_full); } else if (delta < 7 * DAY) { if (delta < MINUTE) { - relativeTime = intl.formatMessage(messages.seconds, { number: Math.floor(delta / SECOND) }); + relativeTime = intl.formatMessage(short ? messages.seconds : messages.seconds_full, { number: Math.floor(delta / SECOND) }); } else if (delta < HOUR) { - relativeTime = intl.formatMessage(messages.minutes, { number: Math.floor(delta / MINUTE) }); + relativeTime = intl.formatMessage(short ? messages.minutes : messages.minutes_full, { number: Math.floor(delta / MINUTE) }); } else if (delta < DAY) { - relativeTime = intl.formatMessage(messages.hours, { number: Math.floor(delta / HOUR) }); + relativeTime = intl.formatMessage(short ? messages.hours : messages.hours_full, { number: Math.floor(delta / HOUR) }); } else { - relativeTime = intl.formatMessage(messages.days, { number: Math.floor(delta / DAY) }); + relativeTime = intl.formatMessage(short ? messages.days : messages.days_full, { number: Math.floor(delta / DAY) }); } } else if (date.getFullYear() === year) { relativeTime = intl.formatDate(date, shortDateFormatOptions); @@ -124,6 +129,7 @@ class RelativeTimestamp extends React.Component { timestamp: PropTypes.string.isRequired, year: PropTypes.number.isRequired, futureDate: PropTypes.bool, + short: PropTypes.bool, }; state = { @@ -132,6 +138,7 @@ class RelativeTimestamp extends React.Component { static defaultProps = { year: (new Date()).getFullYear(), + short: true, }; shouldComponentUpdate (nextProps, nextState) { @@ -176,11 +183,11 @@ class RelativeTimestamp extends React.Component { } render () { - const { timestamp, intl, year, futureDate } = this.props; + const { timestamp, intl, year, futureDate, short } = this.props; const timeGiven = timestamp.includes('T'); const date = new Date(timestamp); - const relativeTime = futureDate ? timeRemainingString(intl, date, this.state.now, timeGiven) : timeAgoString(intl, date, this.state.now, year, timeGiven); + const relativeTime = futureDate ? timeRemainingString(intl, date, this.state.now, timeGiven) : timeAgoString(intl, date, this.state.now, year, timeGiven, short); return ( <time dateTime={timestamp} title={intl.formatDate(date, dateFormatOptions)}> diff --git a/app/javascript/flavours/glitch/components/status_action_bar.js b/app/javascript/flavours/glitch/components/status_action_bar.js index ae67c6116..68d93cd67 100644 --- a/app/javascript/flavours/glitch/components/status_action_bar.js +++ b/app/javascript/flavours/glitch/components/status_action_bar.js @@ -13,6 +13,7 @@ import classNames from 'classnames'; const messages = defineMessages({ delete: { id: 'status.delete', defaultMessage: 'Delete' }, redraft: { id: 'status.redraft', defaultMessage: 'Delete & re-draft' }, + edit: { id: 'status.edit', defaultMessage: 'Edit' }, direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' }, mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' }, mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' }, @@ -126,6 +127,10 @@ class StatusActionBar extends ImmutablePureComponent { this.props.onDelete(this.props.status, this.context.router.history, true); } + handleEditClick = () => { + this.props.onEdit(this.props.status, this.context.router.history); + } + handlePinClick = () => { this.props.onPin(this.props.status); } @@ -225,6 +230,7 @@ class StatusActionBar extends ImmutablePureComponent { } if (writtenByMe) { + // menu.push({ text: intl.formatMessage(messages.edit), action: this.handleEditClick }); menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick }); menu.push({ text: intl.formatMessage(messages.redraft), action: this.handleRedraftClick }); } else { diff --git a/app/javascript/flavours/glitch/components/status_prepend.js b/app/javascript/flavours/glitch/components/status_prepend.js index 5a00f232e..1661ca8f5 100644 --- a/app/javascript/flavours/glitch/components/status_prepend.js +++ b/app/javascript/flavours/glitch/components/status_prepend.js @@ -88,6 +88,14 @@ export default class StatusPrepend extends React.PureComponent { /> ); } + case 'update': + return ( + <FormattedMessage + id='notification.update' + defaultMessage='{name} edited a post' + values={{ name: link }} + /> + ); } return null; } @@ -115,6 +123,9 @@ export default class StatusPrepend extends React.PureComponent { case 'status': iconId = 'bell'; break; + case 'update': + iconId = 'pencil'; + break; }; return !type ? null : ( diff --git a/app/javascript/flavours/glitch/containers/dropdown_menu_container.js b/app/javascript/flavours/glitch/containers/dropdown_menu_container.js index 1c0385b74..0c4a2b50f 100644 --- a/app/javascript/flavours/glitch/containers/dropdown_menu_container.js +++ b/app/javascript/flavours/glitch/containers/dropdown_menu_container.js @@ -14,15 +14,11 @@ const mapDispatchToProps = (dispatch, { status, items, scrollKey }) => ({ onOpen(id, onItemClick, dropdownPlacement, keyboard) { dispatch(isUserTouching() ? openModal('ACTIONS', { status, - actions: items.map( - (item, i) => item ? { - ...item, - name: `${item.text}-${i}`, - onClick: item.action ? ((e) => { return onItemClick(i, e) }) : null, - } : null - ), + actions: items, + onClick: onItemClick, }) : openDropdownMenu(id, dropdownPlacement, keyboard, scrollKey)); }, + onClose(id) { dispatch(closeModal('ACTIONS')); dispatch(closeDropdownMenu(id)); diff --git a/app/javascript/flavours/glitch/containers/status_container.js b/app/javascript/flavours/glitch/containers/status_container.js index bc3c43d85..358b89ab9 100644 --- a/app/javascript/flavours/glitch/containers/status_container.js +++ b/app/javascript/flavours/glitch/containers/status_container.js @@ -17,7 +17,7 @@ import { pin, unpin, } from 'flavours/glitch/actions/interactions'; -import { muteStatus, unmuteStatus, deleteStatus } from 'flavours/glitch/actions/statuses'; +import { muteStatus, unmuteStatus, deleteStatus, editStatus } from 'flavours/glitch/actions/statuses'; import { initMuteModal } from 'flavours/glitch/actions/mutes'; import { initBlockModal } from 'flavours/glitch/actions/blocks'; import { initReport } from 'flavours/glitch/actions/reports'; @@ -169,6 +169,10 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({ } }, + onEdit (status, history) { + dispatch(editStatus(status.get('id'), history)); + }, + onDirect (account, router) { dispatch(directCompose(account, router)); }, diff --git a/app/javascript/flavours/glitch/features/compose/components/compose_form.js b/app/javascript/flavours/glitch/features/compose/components/compose_form.js index 5dfc119c1..c75906ce7 100644 --- a/app/javascript/flavours/glitch/features/compose/components/compose_form.js +++ b/app/javascript/flavours/glitch/features/compose/components/compose_form.js @@ -47,6 +47,7 @@ class ComposeForm extends ImmutablePureComponent { preselectDate: PropTypes.instanceOf(Date), isSubmitting: PropTypes.bool, isChangingUpload: PropTypes.bool, + isEditing: PropTypes.bool, isUploading: PropTypes.bool, onChange: PropTypes.func, onSubmit: PropTypes.func, @@ -293,6 +294,7 @@ class ComposeForm extends ImmutablePureComponent { spoilerText, suggestions, spoilersAlwaysOn, + isEditing, } = this.props; const countText = this.getFulltextForCharacterCounting(); @@ -353,6 +355,7 @@ class ComposeForm extends ImmutablePureComponent { onToggleSpoiler={spoilersAlwaysOn ? null : onChangeSpoilerness} onUpload={onPaste} privacy={privacy} + isEditing={isEditing} sensitive={sensitive || (spoilersAlwaysOn && spoilerText && spoilerText.length > 0)} spoiler={spoilersAlwaysOn ? (spoilerText && spoilerText.length > 0) : spoiler} /> @@ -364,6 +367,7 @@ class ComposeForm extends ImmutablePureComponent { <Publisher countText={countText} disabled={!this.canSubmit()} + isEditing={isEditing} onSecondarySubmit={handleSecondarySubmit} onSubmit={handleSubmit} privacy={privacy} diff --git a/app/javascript/flavours/glitch/features/compose/components/dropdown.js b/app/javascript/flavours/glitch/features/compose/components/dropdown.js index abf7cbba1..9f70d6b79 100644 --- a/app/javascript/flavours/glitch/features/compose/components/dropdown.js +++ b/app/javascript/flavours/glitch/features/compose/components/dropdown.js @@ -21,22 +21,25 @@ export default class ComposerOptionsDropdown extends React.PureComponent { icon: PropTypes.string, items: PropTypes.arrayOf(PropTypes.shape({ icon: PropTypes.string, - meta: PropTypes.node, + meta: PropTypes.string, name: PropTypes.string.isRequired, - on: PropTypes.bool, - text: PropTypes.node, + text: PropTypes.string, })).isRequired, onModalOpen: PropTypes.func, onModalClose: PropTypes.func, title: PropTypes.string, value: PropTypes.string, onChange: PropTypes.func, - noModal: PropTypes.bool, container: PropTypes.func, + renderItemContents: PropTypes.func, + closeOnChange: PropTypes.bool, + }; + + static defaultProps = { + closeOnChange: true, }; state = { - needsModalUpdate: false, open: false, openedViaKeyboard: undefined, placement: 'bottom', @@ -44,10 +47,10 @@ export default class ComposerOptionsDropdown extends React.PureComponent { // Toggles opening and closing the dropdown. handleToggle = ({ target, type }) => { - const { onModalOpen, noModal } = this.props; + const { onModalOpen } = this.props; const { open } = this.state; - if (!noModal && isUserTouching()) { + if (isUserTouching()) { if (this.state.open) { this.props.onModalClose(); } else { @@ -107,9 +110,25 @@ export default class ComposerOptionsDropdown extends React.PureComponent { this.setState({ open: false }); } + handleItemClick = (e) => { + const { + items, + onChange, + onModalClose, + closeOnChange, + } = this.props; + + const i = Number(e.currentTarget.getAttribute('data-index')); + + const { name } = items[i]; + + e.preventDefault(); // Prevents focus from changing + if (closeOnChange) onModalClose(); + onChange(name); + }; + // Creates an action modal object. handleMakeModal = () => { - const component = this; const { items, onChange, @@ -125,6 +144,8 @@ export default class ComposerOptionsDropdown extends React.PureComponent { // The object. return { + renderItemContents: this.props.renderItemContents, + onClick: this.handleItemClick, actions: items.map( ({ name, @@ -133,48 +154,11 @@ export default class ComposerOptionsDropdown extends React.PureComponent { ...rest, active: value && name === value, name, - onClick (e) { - e.preventDefault(); // Prevents focus from changing - onModalClose(); - onChange(name); - }, - onPassiveClick (e) { - e.preventDefault(); // Prevents focus from changing - onChange(name); - component.setState({ needsModalUpdate: true }); - }, }) ), }; } - // If our modal is open and our props update, we need to also update - // the modal. - handleUpdate = () => { - const { onModalOpen } = this.props; - const { needsModalUpdate } = this.state; - - // Gets our modal object. - const modal = this.handleMakeModal(); - - // Reopens the modal with the new object. - if (needsModalUpdate && modal && onModalOpen) { - onModalOpen(modal); - } - } - - // Updates our modal as necessary. - componentDidUpdate (prevProps) { - const { items } = this.props; - const { needsModalUpdate } = this.state; - if (needsModalUpdate && items.find( - (item, i) => item.on !== prevProps.items[i].on - )) { - this.handleUpdate(); - this.setState({ needsModalUpdate: false }); - } - } - // Rendering. render () { const { @@ -186,6 +170,8 @@ export default class ComposerOptionsDropdown extends React.PureComponent { onChange, value, container, + renderItemContents, + closeOnChange, } = this.props; const { open, placement } = this.state; const computedClass = classNames('composer--options--dropdown', { @@ -226,10 +212,12 @@ export default class ComposerOptionsDropdown extends React.PureComponent { > <DropdownMenu items={items} + renderItemContents={renderItemContents} onChange={onChange} onClose={this.handleClose} value={value} openedViaKeyboard={this.state.openedViaKeyboard} + closeOnChange={closeOnChange} /> </Overlay> </div> diff --git a/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js b/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js index bee06e64c..0649fe1ca 100644 --- a/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js +++ b/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js @@ -2,7 +2,6 @@ import PropTypes from 'prop-types'; import React from 'react'; import spring from 'react-motion/lib/spring'; -import Toggle from 'react-toggle'; import ImmutablePureComponent from 'react-immutable-pure-component'; import classNames from 'classnames'; @@ -28,18 +27,20 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent icon: PropTypes.string, meta: PropTypes.node, name: PropTypes.string.isRequired, - on: PropTypes.bool, text: PropTypes.node, })), onChange: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired, style: PropTypes.object, value: PropTypes.string, + renderItemContents: PropTypes.func, openedViaKeyboard: PropTypes.bool, + closeOnChange: PropTypes.bool, }; static defaultProps = { style: {}, + closeOnChange: true, }; state = { @@ -77,16 +78,19 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent document.removeEventListener('touchend', this.handleDocumentClick, withPassive); } - handleClick = (name, e) => { + handleClick = (e) => { + const i = Number(e.currentTarget.getAttribute('data-index')); + const { onChange, onClose, + closeOnChange, items, } = this.props; - const { on } = this.props.items.find(item => item.name === name); + const { name } = this.props.items[i]; e.preventDefault(); // Prevents change in focus on click - if ((on === null || typeof on === 'undefined')) { + if (closeOnChange) { onClose(); } onChange(name); @@ -101,11 +105,9 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent } } - handleKeyDown = (name, e) => { + handleKeyDown = (e) => { + const index = Number(e.currentTarget.getAttribute('data-index')); const { items } = this.props; - const index = items.findIndex(item => { - return (item.name === name); - }); let element = null; switch(e.key) { @@ -139,7 +141,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent if (element) { element.focus(); - this.handleChange(element.getAttribute('data-index')); + this.handleChange(this.props.items[Number(element.getAttribute('data-index'))].name); e.preventDefault(); e.stopPropagation(); } @@ -149,44 +151,40 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent this.focusedItem = c; } - renderItem = (item) => { - const { name, icon, meta, on, text } = item; + renderItem = (item, i) => { + const { name, icon, meta, text } = item; const active = (name === (this.props.value || this.state.value)); - const computedClass = classNames('composer--options--dropdown--content--item', { - active, - lengthy: meta, - 'toggled-off': !on && on !== null && typeof on !== 'undefined', - 'toggled-on': on, - 'with-icon': icon, - }); + const computedClass = classNames('composer--options--dropdown--content--item', { active }); + + let contents = this.props.renderItemContents && this.props.renderItemContents(item, i); - let prefix = null; + if (!contents) { + contents = ( + <React.Fragment> + {icon && <Icon className='icon' fixedWidth id={icon} />} - if (on !== null && typeof on !== 'undefined') { - prefix = <Toggle checked={on} onChange={this.handleClick.bind(this, name)} />; - } else if (icon) { - prefix = <Icon className='icon' fixedWidth id={icon} /> + <div className='content'> + <strong>{text}</strong> + {meta} + </div> + </React.Fragment> + ); } return ( <div className={computedClass} - onClick={this.handleClick.bind(this, name)} - onKeyDown={this.handleKeyDown.bind(this, name)} + onClick={this.handleClick} + onKeyDown={this.handleKeyDown} role='option' tabIndex='0' key={name} - data-index={name} + data-index={i} ref={active ? this.setFocusRef : null} > - {prefix} - - <div className='content'> - <strong>{text}</strong> - {meta} - </div> + {contents} </div> ); } @@ -229,7 +227,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent transform: mounted ? `scale(${scaleX}, ${scaleY})` : null, }} > - {!!items && items.map(item => this.renderItem(item))} + {!!items && items.map((item, i) => this.renderItem(item, i))} </div> )} </Motion> diff --git a/app/javascript/flavours/glitch/features/compose/components/header.js b/app/javascript/flavours/glitch/features/compose/components/header.js index c6e4cc36b..95add2027 100644 --- a/app/javascript/flavours/glitch/features/compose/components/header.js +++ b/app/javascript/flavours/glitch/features/compose/components/header.js @@ -119,7 +119,7 @@ class Header extends ImmutablePureComponent { <a aria-label={intl.formatMessage(messages.settings)} onClick={onSettingsClick} - href='#' + href='/settings/preferences' title={intl.formatMessage(messages.settings)} ><Icon id='cogs' /></a> <a diff --git a/app/javascript/flavours/glitch/features/compose/components/options.js b/app/javascript/flavours/glitch/features/compose/components/options.js index f9212bbae..3a31e214d 100644 --- a/app/javascript/flavours/glitch/features/compose/components/options.js +++ b/app/javascript/flavours/glitch/features/compose/components/options.js @@ -2,8 +2,10 @@ import PropTypes from 'prop-types'; import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; +import { defineMessages, injectIntl } from 'react-intl'; import spring from 'react-motion/lib/spring'; +import Toggle from 'react-toggle'; +import { connect } from 'react-redux'; // Components. import IconButton from 'flavours/glitch/components/icon_button'; @@ -80,6 +82,36 @@ const messages = defineMessages({ }, }); +@connect((state, { name }) => ({ checked: state.getIn(['compose', 'advanced_options', name]) })) +class ToggleOption extends ImmutablePureComponent { + + static propTypes = { + name: PropTypes.string.isRequired, + checked: PropTypes.bool, + onChangeAdvancedOption: PropTypes.func.isRequired, + }; + + handleChange = () => { + this.props.onChangeAdvancedOption(this.props.name); + }; + + render() { + const { meta, text, checked } = this.props; + + return ( + <React.Fragment> + <Toggle checked={checked} onChange={this.handleChange} /> + + <div className='content'> + <strong>{text}</strong> + {meta} + </div> + </React.Fragment> + ); + } + +} + export default @injectIntl class ComposerOptions extends ImmutablePureComponent { @@ -106,6 +138,7 @@ class ComposerOptions extends ImmutablePureComponent { resetFileKey: PropTypes.number, spoiler: PropTypes.bool, showContentTypeChoice: PropTypes.bool, + isEditing: PropTypes.bool, }; // Handles file selection. @@ -141,6 +174,13 @@ class ComposerOptions extends ImmutablePureComponent { this.fileElement = fileElement; } + renderToggleItemContents = (item) => { + const { onChangeAdvancedOption } = this.props; + const { name, meta, text } = item; + + return <ToggleOption name={name} text={text} meta={meta} onChangeAdvancedOption={onChangeAdvancedOption} />; + }; + // Rendering. render () { const { @@ -152,7 +192,6 @@ class ComposerOptions extends ImmutablePureComponent { hasMedia, allowPoll, hasPoll, - intl, onChangeAdvancedOption, onChangeContentType, onChangeVisibility, @@ -164,23 +203,25 @@ class ComposerOptions extends ImmutablePureComponent { resetFileKey, spoiler, showContentTypeChoice, + isEditing, + intl: { formatMessage }, } = this.props; const contentTypeItems = { plain: { icon: 'file-text', name: 'text/plain', - text: <FormattedMessage {...messages.plain} />, + text: formatMessage(messages.plain), }, html: { icon: 'code', name: 'text/html', - text: <FormattedMessage {...messages.html} />, + text: formatMessage(messages.html), }, markdown: { icon: 'arrow-circle-down', name: 'text/markdown', - text: <FormattedMessage {...messages.markdown} />, + text: formatMessage(messages.markdown), }, }; @@ -204,18 +245,18 @@ class ComposerOptions extends ImmutablePureComponent { { icon: 'cloud-upload', name: 'upload', - text: <FormattedMessage {...messages.upload} />, + text: formatMessage(messages.upload), }, { icon: 'paint-brush', name: 'doodle', - text: <FormattedMessage {...messages.doodle} />, + text: formatMessage(messages.doodle), }, ]} onChange={this.handleClickAttach} onModalClose={onModalClose} onModalOpen={onModalOpen} - title={intl.formatMessage(messages.attach)} + title={formatMessage(messages.attach)} /> {!!pollLimits && ( <IconButton @@ -229,12 +270,12 @@ class ComposerOptions extends ImmutablePureComponent { height: null, lineHeight: null, }} - title={intl.formatMessage(hasPoll ? messages.remove_poll : messages.add_poll)} + title={formatMessage(hasPoll ? messages.remove_poll : messages.add_poll)} /> )} <hr /> <PrivacyDropdown - disabled={disabled} + disabled={disabled || isEditing} onChange={onChangeVisibility} onModalClose={onModalClose} onModalOpen={onModalOpen} @@ -252,7 +293,7 @@ class ComposerOptions extends ImmutablePureComponent { onChange={onChangeContentType} onModalClose={onModalClose} onModalOpen={onModalOpen} - title={intl.formatMessage(messages.content_type)} + title={formatMessage(messages.content_type)} value={contentType} /> )} @@ -262,31 +303,31 @@ class ComposerOptions extends ImmutablePureComponent { ariaControls='glitch.composer.spoiler.input' label='CW' onClick={onToggleSpoiler} - title={intl.formatMessage(messages.spoiler)} + title={formatMessage(messages.spoiler)} /> )} <Dropdown active={advancedOptions && advancedOptions.some(value => !!value)} - disabled={disabled} + disabled={disabled || isEditing} icon='ellipsis-h' items={advancedOptions ? [ { - meta: <FormattedMessage {...messages.local_only_long} />, + meta: formatMessage(messages.local_only_long), name: 'do_not_federate', - on: advancedOptions.get('do_not_federate'), - text: <FormattedMessage {...messages.local_only_short} />, + text: formatMessage(messages.local_only_short), }, { - meta: <FormattedMessage {...messages.threaded_mode_long} />, + meta: formatMessage(messages.threaded_mode_long), name: 'threaded_mode', - on: advancedOptions.get('threaded_mode'), - text: <FormattedMessage {...messages.threaded_mode_short} />, + text: formatMessage(messages.threaded_mode_short), }, ] : null} onChange={onChangeAdvancedOption} + renderItemContents={this.renderToggleItemContents} onModalClose={onModalClose} onModalOpen={onModalOpen} - title={intl.formatMessage(messages.advanced_options_icon_title)} + title={formatMessage(messages.advanced_options_icon_title)} + closeOnChange={false} /> </div> ); diff --git a/app/javascript/flavours/glitch/features/compose/components/privacy_dropdown.js b/app/javascript/flavours/glitch/features/compose/components/privacy_dropdown.js index 39f7c7bd1..c8e783d22 100644 --- a/app/javascript/flavours/glitch/features/compose/components/privacy_dropdown.js +++ b/app/javascript/flavours/glitch/features/compose/components/privacy_dropdown.js @@ -1,46 +1,19 @@ import PropTypes from 'prop-types'; import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; +import { defineMessages, injectIntl } from 'react-intl'; import Dropdown from './dropdown'; const messages = defineMessages({ - change_privacy: { - defaultMessage: 'Adjust status privacy', - id: 'privacy.change', - }, - direct_long: { - defaultMessage: 'Visible for mentioned users only', - id: 'privacy.direct.long', - }, - direct_short: { - defaultMessage: 'Direct', - id: 'privacy.direct.short', - }, - private_long: { - defaultMessage: 'Visible for followers only', - id: 'privacy.private.long', - }, - private_short: { - defaultMessage: 'Followers-only', - id: 'privacy.private.short', - }, - public_long: { - defaultMessage: 'Visible for all, shown in public timelines', - id: 'privacy.public.long', - }, - public_short: { - defaultMessage: 'Public', - id: 'privacy.public.short', - }, - unlisted_long: { - defaultMessage: 'Visible for all, but not in public timelines', - id: 'privacy.unlisted.long', - }, - unlisted_short: { - defaultMessage: 'Unlisted', - id: 'privacy.unlisted.short', - }, + public_short: { id: 'privacy.public.short', defaultMessage: 'Public' }, + public_long: { id: 'privacy.public.long', defaultMessage: 'Visible for all, shown in public timelines' }, + unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' }, + unlisted_long: { id: 'privacy.unlisted.long', defaultMessage: 'Visible for all, but not in public timelines' }, + private_short: { id: 'privacy.private.short', defaultMessage: 'Followers-only' }, + private_long: { id: 'privacy.private.long', defaultMessage: 'Visible for followers only' }, + direct_short: { id: 'privacy.direct.short', defaultMessage: 'Direct' }, + direct_long: { id: 'privacy.direct.long', defaultMessage: 'Visible for mentioned users only' }, + change_privacy: { id: 'privacy.change', defaultMessage: 'Adjust status privacy' }, }); export default @injectIntl @@ -53,40 +26,40 @@ class PrivacyDropdown extends React.PureComponent { value: PropTypes.string.isRequired, onChange: PropTypes.func.isRequired, noDirect: PropTypes.bool, - noModal: PropTypes.bool, container: PropTypes.func, + disabled: PropTypes.bool, intl: PropTypes.object.isRequired, }; render () { - const { value, onChange, onModalOpen, onModalClose, disabled, noDirect, noModal, container, intl } = this.props; + const { value, onChange, onModalOpen, onModalClose, disabled, noDirect, container, intl: { formatMessage } } = this.props; // We predefine our privacy items so that we can easily pick the // dropdown icon later. const privacyItems = { direct: { icon: 'envelope', - meta: <FormattedMessage {...messages.direct_long} />, + meta: formatMessage(messages.direct_long), name: 'direct', - text: <FormattedMessage {...messages.direct_short} />, + text: formatMessage(messages.direct_short), }, private: { icon: 'lock', - meta: <FormattedMessage {...messages.private_long} />, + meta: formatMessage(messages.private_long), name: 'private', - text: <FormattedMessage {...messages.private_short} />, + text: formatMessage(messages.private_short), }, public: { icon: 'globe', - meta: <FormattedMessage {...messages.public_long} />, + meta: formatMessage(messages.public_long), name: 'public', - text: <FormattedMessage {...messages.public_short} />, + text: formatMessage(messages.public_short), }, unlisted: { icon: 'unlock', - meta: <FormattedMessage {...messages.unlisted_long} />, + meta: formatMessage(messages.unlisted_long), name: 'unlisted', - text: <FormattedMessage {...messages.unlisted_short} />, + text: formatMessage(messages.unlisted_short), }, }; @@ -104,9 +77,8 @@ class PrivacyDropdown extends React.PureComponent { onChange={onChange} onModalClose={onModalClose} onModalOpen={onModalOpen} - title={intl.formatMessage(messages.change_privacy)} + title={formatMessage(messages.change_privacy)} container={container} - noModal={noModal} value={value} /> ); diff --git a/app/javascript/flavours/glitch/features/compose/components/publisher.js b/app/javascript/flavours/glitch/features/compose/components/publisher.js index 1531dcaa9..9a8c0f510 100644 --- a/app/javascript/flavours/glitch/features/compose/components/publisher.js +++ b/app/javascript/flavours/glitch/features/compose/components/publisher.js @@ -2,7 +2,7 @@ import classNames from 'classnames'; import PropTypes from 'prop-types'; import React from 'react'; -import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; +import { defineMessages, injectIntl } from 'react-intl'; import { length } from 'stringz'; import ImmutablePureComponent from 'react-immutable-pure-component'; @@ -23,6 +23,7 @@ const messages = defineMessages({ defaultMessage: '{publish}!', id: 'compose_form.publish_loud', }, + saveChanges: { id: 'compose_form.save_changes', defaultMessage: 'Save changes' }, }); export default @injectIntl @@ -36,6 +37,7 @@ class Publisher extends ImmutablePureComponent { onSubmit: PropTypes.func, privacy: PropTypes.oneOf(['direct', 'private', 'unlisted', 'public']), sideArm: PropTypes.oneOf(['none', 'direct', 'private', 'unlisted', 'public']), + isEditing: PropTypes.bool, }; handleSubmit = () => { @@ -43,7 +45,7 @@ class Publisher extends ImmutablePureComponent { }; render () { - const { countText, disabled, intl, onSecondarySubmit, privacy, sideArm } = this.props; + const { countText, disabled, intl, onSecondarySubmit, privacy, sideArm, isEditing } = this.props; const diff = maxChars - length(countText || ''); const computedClass = classNames('composer--publisher', { @@ -51,63 +53,37 @@ class Publisher extends ImmutablePureComponent { over: diff < 0, }); + const privacyIcons = { direct: 'envelope', private: 'lock', public: 'globe', unlisted: 'unlock' }; + + let publishText; + if (isEditing) { + publishText = intl.formatMessage(messages.saveChanges); + } else if (privacy === 'private' || privacy === 'direct') { + const iconId = privacyIcons[privacy]; + publishText = ( + <span> + <Icon id={iconId} /> {intl.formatMessage(messages.publish)} + </span> + ); + } else { + publishText = privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish); + } + return ( <div className={computedClass}> - {sideArm && sideArm !== 'none' ? ( + {sideArm && !isEditing && sideArm !== 'none' ? ( <Button className='side_arm' disabled={disabled} onClick={onSecondarySubmit} style={{ padding: null }} - text={ - <span> - <Icon - id={{ - public: 'globe', - unlisted: 'unlock', - private: 'lock', - direct: 'envelope', - }[sideArm]} - /> - </span> - } + text={<Icon id={privacyIcons[sideArm]} />} title={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage({ id: `privacy.${sideArm}.short` })}`} /> ) : null} <Button className='primary' - text={function () { - switch (true) { - case !!sideArm && sideArm !== 'none': - case privacy === 'direct': - case privacy === 'private': - return ( - <span> - <Icon - id={{ - direct: 'envelope', - private: 'lock', - public: 'globe', - unlisted: 'unlock', - }[privacy]} - /> - {' '} - <FormattedMessage {...messages.publish} /> - </span> - ); - case privacy === 'public': - return ( - <span> - <FormattedMessage - {...messages.publishLoud} - values={{ publish: <FormattedMessage {...messages.publish} /> }} - /> - </span> - ); - default: - return <span><FormattedMessage {...messages.publish} /></span>; - } - }()} + text={publishText} title={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage({ id: `privacy.${privacy}.short` })}`} onClick={this.handleSubmit} disabled={disabled} diff --git a/app/javascript/flavours/glitch/features/compose/components/upload.js b/app/javascript/flavours/glitch/features/compose/components/upload.js index 425b0fe5e..338bfca37 100644 --- a/app/javascript/flavours/glitch/features/compose/components/upload.js +++ b/app/javascript/flavours/glitch/features/compose/components/upload.js @@ -19,6 +19,7 @@ export default class Upload extends ImmutablePureComponent { media: ImmutablePropTypes.map.isRequired, onUndo: PropTypes.func.isRequired, onOpenFocalPoint: PropTypes.func.isRequired, + isEditingStatus: PropTypes.func.isRequired, }; handleUndoClick = e => { @@ -32,7 +33,7 @@ export default class Upload extends ImmutablePureComponent { } render () { - const { intl, media } = this.props; + const { intl, media, isEditingStatus } = this.props; const focusX = media.getIn(['meta', 'focus', 'x']); const focusY = media.getIn(['meta', 'focus', 'y']); const x = ((focusX / 2) + .5) * 100; @@ -45,7 +46,7 @@ export default class Upload extends ImmutablePureComponent { <div style={{ transform: `scale(${scale})`, backgroundImage: `url(${media.get('preview_url')})`, backgroundPosition: `${x}% ${y}%` }}> <div className={classNames('composer--upload_form--actions', { active: true })}> <button className='icon-button' onClick={this.handleUndoClick}><Icon id='times' /> <FormattedMessage id='upload_form.undo' defaultMessage='Delete' /></button> - <button className='icon-button' onClick={this.handleFocalPointClick}><Icon id='pencil' /> <FormattedMessage id='upload_form.edit' defaultMessage='Edit' /></button> + {!isEditingStatus && (<button className='icon-button' onClick={this.handleFocalPointClick}><Icon id='pencil' /> <FormattedMessage id='upload_form.edit' defaultMessage='Edit' /></button>)} </div> </div> )} diff --git a/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js b/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js index 8eff8a36b..a037bbbcc 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js @@ -51,6 +51,7 @@ function mapStateToProps (state) { focusDate: state.getIn(['compose', 'focusDate']), caretPosition: state.getIn(['compose', 'caretPosition']), isSubmitting: state.getIn(['compose', 'is_submitting']), + isEditing: state.getIn(['compose', 'id']) !== null, isChangingUpload: state.getIn(['compose', 'is_changing_upload']), isUploading: state.getIn(['compose', 'is_uploading']), layout: state.getIn(['local_settings', 'layout']), diff --git a/app/javascript/flavours/glitch/features/compose/containers/reply_indicator_container.js b/app/javascript/flavours/glitch/features/compose/containers/reply_indicator_container.js index 395a9aa5b..dd6899be4 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/reply_indicator_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/reply_indicator_container.js @@ -1,14 +1,24 @@ import { connect } from 'react-redux'; import { cancelReplyCompose } from 'flavours/glitch/actions/compose'; -import { makeGetStatus } from 'flavours/glitch/selectors'; import ReplyIndicator from '../components/reply_indicator'; -function makeMapStateToProps (state) { - const inReplyTo = state.getIn(['compose', 'in_reply_to']); +const makeMapStateToProps = () => { + const mapStateToProps = state => { + let statusId = state.getIn(['compose', 'id'], null); + let editing = true; - return { - status: inReplyTo ? state.getIn(['statuses', inReplyTo]) : null, + if (statusId === null) { + statusId = state.getIn(['compose', 'in_reply_to']); + editing = false; + } + + return { + status: state.getIn(['statuses', statusId]), + editing, + }; }; + + return mapStateToProps; }; const mapDispatchToProps = dispatch => ({ diff --git a/app/javascript/flavours/glitch/features/compose/containers/upload_container.js b/app/javascript/flavours/glitch/features/compose/containers/upload_container.js index f3ca4ce7b..d6256fe96 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/upload_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/upload_container.js @@ -5,6 +5,7 @@ import { submitCompose } from 'flavours/glitch/actions/compose'; const mapStateToProps = (state, { id }) => ({ media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id), + isEditingStatus: state.getIn(['compose', 'id']) !== null, }); const mapDispatchToProps = dispatch => ({ diff --git a/app/javascript/flavours/glitch/features/notifications/components/column_settings.js b/app/javascript/flavours/glitch/features/notifications/components/column_settings.js index 95250c6ed..569ba4db0 100644 --- a/app/javascript/flavours/glitch/features/notifications/components/column_settings.js +++ b/app/javascript/flavours/glitch/features/notifications/components/column_settings.js @@ -154,6 +154,17 @@ export default class ColumnSettings extends React.PureComponent { <PillBarButton prefix='notifications' settings={settings} settingPath={['sounds', 'status']} onChange={onChange} label={soundStr} /> </div> </div> + + <div role='group' aria-labelledby='notifications-update'> + <span id='notifications-status' className='column-settings__section'><FormattedMessage id='notifications.column_settings.update' defaultMessage='Edits:' /></span> + + <div className='column-settings__pillbar'> + <PillBarButton disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'update']} onChange={onChange} label={alertStr} /> + {showPushSettings && <PillBarButton prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'update']} onChange={this.onPushChange} label={pushStr} />} + <PillBarButton prefix='notifications' settings={settings} settingPath={['shows', 'update']} onChange={onChange} label={showStr} /> + <PillBarButton prefix='notifications' settings={settings} settingPath={['sounds', 'update']} onChange={onChange} label={soundStr} /> + </div> + </div> </div> ); } diff --git a/app/javascript/flavours/glitch/features/notifications/components/notification.js b/app/javascript/flavours/glitch/features/notifications/components/notification.js index e1d9fbd0a..1cf205898 100644 --- a/app/javascript/flavours/glitch/features/notifications/components/notification.js +++ b/app/javascript/flavours/glitch/features/notifications/components/notification.js @@ -171,6 +171,28 @@ export default class Notification extends ImmutablePureComponent { unread={this.props.unread} /> ); + case 'update': + return ( + <StatusContainer + containerId={notification.get('id')} + hidden={hidden} + id={notification.get('status')} + account={notification.get('account')} + prepend='update' + muted + notification={notification} + onMoveDown={onMoveDown} + onMoveUp={onMoveUp} + onMention={onMention} + getScrollPosition={getScrollPosition} + updateScrollBottom={updateScrollBottom} + cachedMediaWidth={this.props.cachedMediaWidth} + cacheMediaWidth={this.props.cacheMediaWidth} + onUnmount={this.props.onUnmount} + withDismiss + unread={this.props.unread} + /> + ); default: return null; } diff --git a/app/javascript/flavours/glitch/features/status/components/action_bar.js b/app/javascript/flavours/glitch/features/status/components/action_bar.js index eb4583026..a67a045da 100644 --- a/app/javascript/flavours/glitch/features/status/components/action_bar.js +++ b/app/javascript/flavours/glitch/features/status/components/action_bar.js @@ -11,6 +11,7 @@ import classNames from 'classnames'; const messages = defineMessages({ delete: { id: 'status.delete', defaultMessage: 'Delete' }, redraft: { id: 'status.redraft', defaultMessage: 'Delete & re-draft' }, + edit: { id: 'status.edit', defaultMessage: 'Edit' }, direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' }, mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' }, reply: { id: 'status.reply', defaultMessage: 'Reply' }, @@ -52,6 +53,7 @@ class ActionBar extends React.PureComponent { onMuteConversation: PropTypes.func, onBlock: PropTypes.func, onDelete: PropTypes.func.isRequired, + onEdit: PropTypes.func.isRequired, onDirect: PropTypes.func.isRequired, onMention: PropTypes.func.isRequired, onReport: PropTypes.func, @@ -84,6 +86,10 @@ class ActionBar extends React.PureComponent { this.props.onDelete(this.props.status, this.context.router.history, true); } + handleEditClick = () => { + this.props.onEdit(this.props.status, this.context.router.history); + } + handleDirectClick = () => { this.props.onDirect(this.props.status.get('account'), this.context.router.history); } @@ -166,6 +172,7 @@ class ActionBar extends React.PureComponent { menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick }); menu.push(null); + // menu.push({ text: intl.formatMessage(messages.edit), action: this.handleEditClick }); menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick }); menu.push({ text: intl.formatMessage(messages.redraft), action: this.handleRedraftClick }); } else { diff --git a/app/javascript/flavours/glitch/features/status/components/detailed_status.js b/app/javascript/flavours/glitch/features/status/components/detailed_status.js index 4b3a6aaaa..528d2eb73 100644 --- a/app/javascript/flavours/glitch/features/status/components/detailed_status.js +++ b/app/javascript/flavours/glitch/features/status/components/detailed_status.js @@ -7,7 +7,7 @@ import StatusContent from 'flavours/glitch/components/status_content'; import MediaGallery from 'flavours/glitch/components/media_gallery'; import AttachmentList from 'flavours/glitch/components/attachment_list'; import { Link } from 'react-router-dom'; -import { injectIntl, FormattedDate, FormattedMessage } from 'react-intl'; +import { injectIntl, FormattedDate } from 'react-intl'; import Card from './card'; import ImmutablePureComponent from 'react-immutable-pure-component'; import Video from 'flavours/glitch/features/video'; @@ -19,6 +19,7 @@ import PollContainer from 'flavours/glitch/containers/poll_container'; import Icon from 'flavours/glitch/components/icon'; import AnimatedNumber from 'flavours/glitch/components/animated_number'; import PictureInPicturePlaceholder from 'flavours/glitch/components/picture_in_picture_placeholder'; +import EditedTimestamp from 'flavours/glitch/components/edited_timestamp'; export default @injectIntl class DetailedStatus extends ImmutablePureComponent { @@ -265,7 +266,7 @@ class DetailedStatus extends ImmutablePureComponent { edited = ( <React.Fragment> <React.Fragment> · </React.Fragment> - <FormattedMessage id='status.edited' defaultMessage='Edited {date}' values={{ date: intl.formatDate(status.get('edited_at'), { hour12: false, month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }) }} /> + <EditedTimestamp statusId={status.get('id')} timestamp={status.get('edited_at')} /> </React.Fragment> ); } diff --git a/app/javascript/flavours/glitch/features/status/index.js b/app/javascript/flavours/glitch/features/status/index.js index 12ea407ad..653fabeae 100644 --- a/app/javascript/flavours/glitch/features/status/index.js +++ b/app/javascript/flavours/glitch/features/status/index.js @@ -26,7 +26,7 @@ import { directCompose, } from 'flavours/glitch/actions/compose'; import { changeLocalSetting } from 'flavours/glitch/actions/local_settings'; -import { muteStatus, unmuteStatus, deleteStatus } from 'flavours/glitch/actions/statuses'; +import { muteStatus, unmuteStatus, deleteStatus, editStatus } from 'flavours/glitch/actions/statuses'; import { initMuteModal } from 'flavours/glitch/actions/mutes'; import { initBlockModal } from 'flavours/glitch/actions/blocks'; import { initReport } from 'flavours/glitch/actions/reports'; @@ -307,6 +307,10 @@ class Status extends ImmutablePureComponent { } } + handleEditClick = (status, history) => { + this.props.dispatch(editStatus(status.get('id'), history)); + } + handleDirectClick = (account, router) => { this.props.dispatch(directCompose(account, router)); } @@ -585,6 +589,7 @@ class Status extends ImmutablePureComponent { onReblog={this.handleReblogClick} onBookmark={this.handleBookmarkClick} onDelete={this.handleDeleteClick} + onEdit={this.handleEditClick} onDirect={this.handleDirectClick} onMention={this.handleMentionClick} onMute={this.handleMuteClick} diff --git a/app/javascript/flavours/glitch/features/ui/components/actions_modal.js b/app/javascript/flavours/glitch/features/ui/components/actions_modal.js index 24169036c..aae2e4426 100644 --- a/app/javascript/flavours/glitch/features/ui/components/actions_modal.js +++ b/app/javascript/flavours/glitch/features/ui/components/actions_modal.js @@ -7,24 +7,22 @@ import Avatar from 'flavours/glitch/components/avatar'; import RelativeTimestamp from 'flavours/glitch/components/relative_timestamp'; import DisplayName from 'flavours/glitch/components/display_name'; import classNames from 'classnames'; -import Icon from 'flavours/glitch/components/icon'; -import Link from 'flavours/glitch/components/link'; -import Toggle from 'react-toggle'; +import IconButton from 'flavours/glitch/components/icon_button'; export default class ActionsModal extends ImmutablePureComponent { static propTypes = { status: ImmutablePropTypes.map, + onClick: PropTypes.func, actions: PropTypes.arrayOf(PropTypes.shape({ active: PropTypes.bool, href: PropTypes.string, icon: PropTypes.string, - meta: PropTypes.node, + meta: PropTypes.string, name: PropTypes.string, - on: PropTypes.bool, - onPassiveClick: PropTypes.func, - text: PropTypes.node, + text: PropTypes.string, })), + renderItemContents: PropTypes.func, }; renderAction = (action, i) => { @@ -32,57 +30,26 @@ export default class ActionsModal extends ImmutablePureComponent { return <li key={`sep-${i}`} className='dropdown-menu__separator' />; } - const { - active, - href, - icon, - meta, - name, - on, - onClick, - onPassiveClick, - text, - } = action; + const { icon = null, text, meta = null, active = false, href = '#' } = action; + let contents = this.props.renderItemContents && this.props.renderItemContents(action, i); - return ( - <li key={name || i}> - <Link - className={classNames('link', { active })} - href={href} - onClick={on !== null && typeof on !== 'undefined' && onPassiveClick || onClick} - role={onClick ? 'button' : null} - > - {function () { + if (!contents) { + contents = ( + <React.Fragment> + {icon && <IconButton title={text} icon={icon} role='presentation' tabIndex='-1' inverted />} + <div> + <div className={classNames({ 'actions-modal__item-label': !!meta })}>{text}</div> + <div>{meta}</div> + </div> + </React.Fragment> + ); + } - // We render a `<Toggle>` if we were provided an `on` - // property, and otherwise show an `<Icon>` if available. - switch (true) { - case on !== null && typeof on !== 'undefined': - return ( - <Toggle - checked={on} - onChange={onPassiveClick || onClick} - /> - ); - case !!icon: - return ( - <Icon - className='icon' - fixedWidth - id={icon} - /> - ); - default: - return null; - } - }()} - {meta ? ( - <div> - <strong>{text}</strong> - {meta} - </div> - ) : <div>{text}</div>} - </Link> + return ( + <li key={`${text}-${i}`}> + <a href={href} target='_blank' rel='noopener noreferrer' onClick={this.props.onClick} data-index={i} className={classNames('link', { active })}> + {contents} + </a> </li> ); } diff --git a/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.js b/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.js new file mode 100644 index 000000000..198443221 --- /dev/null +++ b/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.js @@ -0,0 +1,79 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import { connect } from 'react-redux'; +import { FormattedMessage } from 'react-intl'; +import { closeModal } from 'flavours/glitch/actions/modal'; +import emojify from 'flavours/glitch/util/emoji'; +import escapeTextContentForBrowser from 'escape-html'; +import InlineAccount from 'flavours/glitch/components/inline_account'; +import IconButton from 'flavours/glitch/components/icon_button'; +import RelativeTimestamp from 'flavours/glitch/components/relative_timestamp'; + +const mapStateToProps = (state, { statusId }) => ({ + versions: state.getIn(['history', statusId, 'items']), +}); + +const mapDispatchToProps = dispatch => ({ + + onClose() { + dispatch(closeModal()); + }, + +}); + +export default @connect(mapStateToProps, mapDispatchToProps) +class CompareHistoryModal extends React.PureComponent { + + static propTypes = { + onClose: PropTypes.func.isRequired, + index: PropTypes.number.isRequired, + statusId: PropTypes.string.isRequired, + versions: ImmutablePropTypes.list.isRequired, + }; + + render () { + const { index, versions, onClose } = this.props; + const currentVersion = versions.get(index); + + const emojiMap = currentVersion.get('emojis').reduce((obj, emoji) => { + obj[`:${emoji.get('shortcode')}:`] = emoji.toJS(); + return obj; + }, {}); + + const content = { __html: emojify(currentVersion.get('content'), emojiMap) }; + const spoilerContent = { __html: emojify(escapeTextContentForBrowser(currentVersion.get('spoiler_text')), emojiMap) }; + + const formattedDate = <RelativeTimestamp timestamp={currentVersion.get('created_at')} short={false} />; + const formattedName = <InlineAccount accountId={currentVersion.get('account')} />; + + const label = currentVersion.get('original') ? ( + <FormattedMessage id='status.history.created' defaultMessage='{name} created {date}' values={{ name: formattedName, date: formattedDate }} /> + ) : ( + <FormattedMessage id='status.history.edited' defaultMessage='{name} edited {date}' values={{ name: formattedName, date: formattedDate }} /> + ); + + return ( + <div className='modal-root__modal compare-history-modal'> + <div className='report-modal__target'> + <IconButton className='report-modal__close' icon='times' onClick={onClose} size={20} /> + {label} + </div> + + <div className='compare-history-modal__container'> + <div className='status__content'> + {currentVersion.get('spoiler_text').length > 0 && ( + <React.Fragment> + <div className='translate' dangerouslySetInnerHTML={spoilerContent} /> + <hr /> + </React.Fragment> + )} + + <div className='status__content__text status__content__text--visible translate' dangerouslySetInnerHTML={content} /> + </div> + </div> + </div> + ); + } + +} diff --git a/app/javascript/flavours/glitch/features/ui/components/modal_root.js b/app/javascript/flavours/glitch/features/ui/components/modal_root.js index 62bb167a0..1e065c171 100644 --- a/app/javascript/flavours/glitch/features/ui/components/modal_root.js +++ b/app/javascript/flavours/glitch/features/ui/components/modal_root.js @@ -24,6 +24,7 @@ import { ListEditor, ListAdder, PinnedAccountsEditor, + CompareHistoryModal, } from 'flavours/glitch/util/async-components'; const MODAL_COMPONENTS = { @@ -42,9 +43,10 @@ const MODAL_COMPONENTS = { 'ACTIONS': () => Promise.resolve({ default: ActionsModal }), 'EMBED': EmbedModal, 'LIST_EDITOR': ListEditor, - 'LIST_ADDER':ListAdder, 'FOCAL_POINT': () => Promise.resolve({ default: FocalPointModal }), + 'LIST_ADDER': ListAdder, 'PINNED_ACCOUNTS_EDITOR': PinnedAccountsEditor, + 'COMPARE_HISTORY': CompareHistoryModal, }; export default class ModalRoot extends React.PureComponent { diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js index d2ea0a924..f97c799e7 100644 --- a/app/javascript/flavours/glitch/reducers/compose.js +++ b/app/javascript/flavours/glitch/reducers/compose.js @@ -46,6 +46,7 @@ import { INIT_MEDIA_EDIT_MODAL, COMPOSE_CHANGE_MEDIA_DESCRIPTION, COMPOSE_CHANGE_MEDIA_FOCUS, + COMPOSE_SET_STATUS, } from 'flavours/glitch/actions/compose'; import { TIMELINE_DELETE } from 'flavours/glitch/actions/timelines'; import { STORE_HYDRATE } from 'flavours/glitch/actions/store'; @@ -75,6 +76,7 @@ const initialState = ImmutableMap({ spoiler: false, spoiler_text: '', privacy: null, + id: null, content_type: defaultContentType || 'text/plain', text: '', focusDate: null, @@ -160,6 +162,7 @@ function apiStatusToTextHashtags (state, status) { function clearAll(state) { return state.withMutations(map => { + map.set('id', null); map.set('text', ''); if (defaultContentType) map.set('content_type', defaultContentType); map.set('spoiler', false); @@ -400,6 +403,7 @@ export default function compose(state = initialState, action) { .set('elefriend', (state.get('elefriend') + 1) % totalElefriends); case COMPOSE_REPLY: return state.withMutations(map => { + map.set('id', null); map.set('in_reply_to', action.status.get('id')); map.set('text', statusToTextMentions(state, action.status)); map.set('privacy', privacyPreference(action.status.get('visibility'), state.get('default_privacy'))); @@ -434,6 +438,7 @@ export default function compose(state = initialState, action) { map.set('spoiler', false); map.set('spoiler_text', ''); map.set('privacy', state.get('default_privacy')); + map.set('id', null); map.set('poll', null); map.update( 'advanced_options', @@ -573,6 +578,34 @@ export default function compose(state = initialState, action) { })); } }); + case COMPOSE_SET_STATUS: + return state.withMutations(map => { + map.set('id', action.status.get('id')); + map.set('text', action.text); + map.set('in_reply_to', action.status.get('in_reply_to_id')); + map.set('privacy', action.status.get('visibility')); + map.set('media_attachments', action.status.get('media_attachments')); + map.set('focusDate', new Date()); + map.set('caretPosition', null); + map.set('idempotencyKey', uuid()); + map.set('sensitive', action.status.get('sensitive')); + + if (action.spoiler_text.length > 0) { + map.set('spoiler', true); + map.set('spoiler_text', action.spoiler_text); + } else { + map.set('spoiler', false); + map.set('spoiler_text', ''); + } + + if (action.status.get('poll')) { + map.set('poll', ImmutableMap({ + options: action.status.getIn(['poll', 'options']).map(x => x.get('title')), + multiple: action.status.getIn(['poll', 'multiple']), + expires_in: expiresInFromExpiresAt(action.status.getIn(['poll', 'expires_at'])), + })); + } + }); case COMPOSE_POLL_ADD: return state.set('poll', initialPoll); case COMPOSE_POLL_REMOVE: diff --git a/app/javascript/flavours/glitch/reducers/history.js b/app/javascript/flavours/glitch/reducers/history.js new file mode 100644 index 000000000..04f5f2fd1 --- /dev/null +++ b/app/javascript/flavours/glitch/reducers/history.js @@ -0,0 +1,28 @@ +import { HISTORY_FETCH_REQUEST, HISTORY_FETCH_SUCCESS, HISTORY_FETCH_FAIL } from 'flavours/glitch/actions/history'; +import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable'; + +const initialHistory = ImmutableMap({ + loading: false, + items: ImmutableList(), +}); + +const initialState = ImmutableMap(); + +export default function history(state = initialState, action) { + switch(action.type) { + case HISTORY_FETCH_REQUEST: + return state.update(action.statusId, initialHistory, history => history.withMutations(map => { + map.set('loading', true); + map.set('items', ImmutableList()); + })); + case HISTORY_FETCH_SUCCESS: + return state.update(action.statusId, initialHistory, history => history.withMutations(map => { + map.set('loading', false); + map.set('items', fromJS(action.history.map((x, i) => ({ ...x, account: x.account.id, original: i === 0 })).reverse())); + })); + case HISTORY_FETCH_FAIL: + return state.update(action.statusId, initialHistory, history => history.set('loading', false)); + default: + return state; + } +} diff --git a/app/javascript/flavours/glitch/reducers/index.js b/app/javascript/flavours/glitch/reducers/index.js index 7d7fe6fd3..d9123b103 100644 --- a/app/javascript/flavours/glitch/reducers/index.js +++ b/app/javascript/flavours/glitch/reducers/index.js @@ -41,6 +41,7 @@ import markers from './markers'; import account_notes from './account_notes'; import picture_in_picture from './picture_in_picture'; import accounts_map from './accounts_map'; +import history from './history'; const reducers = { announcements, @@ -85,6 +86,7 @@ const reducers = { markers, account_notes, picture_in_picture, + history, }; export default combineReducers(reducers); diff --git a/app/javascript/flavours/glitch/reducers/settings.js b/app/javascript/flavours/glitch/reducers/settings.js index a53d34a83..48587ce64 100644 --- a/app/javascript/flavours/glitch/reducers/settings.js +++ b/app/javascript/flavours/glitch/reducers/settings.js @@ -40,6 +40,7 @@ const initialState = ImmutableMap({ mention: false, poll: false, status: false, + update: false, }), quickFilter: ImmutableMap({ @@ -59,6 +60,7 @@ const initialState = ImmutableMap({ mention: true, poll: true, status: true, + update: true, }), sounds: ImmutableMap({ @@ -69,6 +71,7 @@ const initialState = ImmutableMap({ mention: true, poll: true, status: true, + update: true, }), }), diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index 92061585a..66ce92ce2 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -1203,6 +1203,10 @@ a.sparkline { } } } + + @media screen and (max-width: 930px) { + grid-template-columns: minmax(0, 1fr); + } } .account-card { @@ -1410,8 +1414,9 @@ a.sparkline { } &__button { + box-sizing: border-box; flex: 0 0 auto; - width: 100px; + width: 200px; padding: 15px; padding-right: 0; @@ -1427,4 +1432,38 @@ a.sparkline { color: $dark-text-color; } } + + @media screen and (max-width: 800px) { + border: 0; + + &__item { + flex-direction: column; + border: 0; + + &__button { + width: 100%; + padding: 15px 0; + } + + &__description { + padding: 0; + padding-bottom: 15px; + } + } + } +} + +.section-skip-link { + float: right; + + a { + color: $ui-highlight-color; + text-decoration: none; + + &:hover, + &:focus, + &:active { + text-decoration: underline; + } + } } diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss index 2656890d7..656d8f25d 100644 --- a/app/javascript/flavours/glitch/styles/components/index.scss +++ b/app/javascript/flavours/glitch/styles/components/index.scss @@ -500,8 +500,47 @@ box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4); z-index: 9999; - ul { - list-style: none; + &__text-button { + display: inline; + color: inherit; + background: transparent; + border: 0; + margin: 0; + padding: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; + + &:focus { + outline: 1px dotted; + } + } + + &__container { + &__header { + border-bottom: 1px solid darken($ui-secondary-color, 8%); + padding: 4px 14px; + padding-bottom: 8px; + font-size: 13px; + line-height: 18px; + color: $inverted-text-color; + } + + &__list { + list-style: none; + + &--scrollable { + max-height: 300px; + overflow-y: scroll; + } + } + + &--loading { + display: flex; + align-items: center; + justify-content: center; + padding: 30px 45px; + } } } @@ -541,18 +580,29 @@ } .dropdown-menu__item { - a { - font-size: 13px; - line-height: 18px; + font-size: 13px; + line-height: 18px; + display: block; + color: $inverted-text-color; + + a, + button { + font-family: inherit; + font-size: inherit; + line-height: inherit; display: block; + width: 100%; padding: 4px 14px; + border: 0; + margin: 0; box-sizing: border-box; text-decoration: none; background: $ui-secondary-color; - color: $inverted-text-color; + color: inherit; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; + text-align: inherit; &:focus, &:hover, @@ -564,6 +614,42 @@ } } +.dropdown-menu__item--text { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + padding: 4px 14px; +} + +.dropdown-menu__item.edited-timestamp__history__item { + border-bottom: 1px solid darken($ui-secondary-color, 8%); + + &:last-child { + border-bottom: 0; + } + + &.dropdown-menu__item--text, + a, + button { + padding: 8px 14px; + } +} + +.inline-account { + display: inline-flex; + align-items: center; + vertical-align: top; + + .account__avatar { + margin-right: 5px; + border-radius: 50%; + } + + strong { + font-weight: 600; + } +} + .dropdown--active .dropdown__content { display: block; line-height: 18px; @@ -1229,36 +1315,48 @@ button.icon-button.active i.fa-retweet { top: 50%; left: 50%; transform: translate(-50%, -50%); + display: flex; + align-items: center; + justify-content: center; +} - span { - display: block; - float: left; - transform: translateX(-50%); - margin: 82px 0 0 50%; - white-space: nowrap; +.circular-progress { + color: lighten($ui-base-color, 26%); + animation: 1.4s linear 0s infinite normal none running simple-rotate; + + circle { + stroke: currentColor; + stroke-dasharray: 80px, 200px; + stroke-dashoffset: 0; + animation: circular-progress 1.4s ease-in-out infinite; } } -.loading-indicator__figure { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 42px; - height: 42px; - box-sizing: border-box; - background-color: transparent; - border: 0 solid lighten($ui-base-color, 26%); - border-width: 6px; - border-radius: 50%; -} +@keyframes circular-progress { + 0% { + stroke-dasharray: 1px, 200px; + stroke-dashoffset: 0; + } + + 50% { + stroke-dasharray: 100px, 200px; + stroke-dashoffset: -15px; + } -.no-reduce-motion .loading-indicator span { - animation: loader-label 1.15s infinite cubic-bezier(0.215, 0.610, 0.355, 1.000); + 100% { + stroke-dasharray: 100px, 200px; + stroke-dashoffset: -125px; + } } -.no-reduce-motion .loading-indicator__figure { - animation: loader-figure 1.15s infinite cubic-bezier(0.215, 0.610, 0.355, 1.000); +@keyframes simple-rotate { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } } @keyframes spring-rotate-in { @@ -1305,40 +1403,6 @@ button.icon-button.active i.fa-retweet { } } -@keyframes loader-figure { - 0% { - width: 0; - height: 0; - background-color: lighten($ui-base-color, 26%); - } - - 29% { - background-color: lighten($ui-base-color, 26%); - } - - 30% { - width: 42px; - height: 42px; - background-color: transparent; - border-width: 21px; - opacity: 1; - } - - 100% { - width: 42px; - height: 42px; - border-width: 0; - opacity: 0; - background-color: transparent; - } -} - -@keyframes loader-label { - 0% { opacity: 0.25; } - 30% { opacity: 1; } - 100% { opacity: 0.25; } -} - .spoiler-button { top: 0; left: 0; @@ -1508,6 +1572,41 @@ button.icon-button.active i.fa-retweet { filter: none; } +.compare-history-modal { + .report-modal__target { + border-bottom: 1px solid $ui-secondary-color; + } + + &__container { + padding: 30px; + pointer-events: all; + } + + .status__content { + color: $inverted-text-color; + font-size: 19px; + line-height: 24px; + + .emojione { + width: 24px; + height: 24px; + margin: -1px 0 0; + } + + a { + color: $highlight-text-color; + } + + hr { + height: 0.25rem; + padding: 0; + background-color: $ui-secondary-color; + border: 0; + margin: 20px 0; + } + } +} + .loading-bar { background-color: $ui-highlight-color; height: 3px; diff --git a/app/javascript/flavours/glitch/styles/components/modal.scss b/app/javascript/flavours/glitch/styles/components/modal.scss index cb776e88f..fb2445a17 100644 --- a/app/javascript/flavours/glitch/styles/components/modal.scss +++ b/app/javascript/flavours/glitch/styles/components/modal.scss @@ -420,7 +420,8 @@ .report-modal, .actions-modal, .mute-modal, -.block-modal { +.block-modal, +.compare-history-modal { background: lighten($ui-secondary-color, 8%); color: $inverted-text-color; border-radius: 8px; diff --git a/app/javascript/flavours/glitch/theme.yml b/app/javascript/flavours/glitch/theme.yml index ee2b699b2..f3c7fac7e 100644 --- a/app/javascript/flavours/glitch/theme.yml +++ b/app/javascript/flavours/glitch/theme.yml @@ -1,7 +1,9 @@ # (REQUIRED) The location of the pack files. pack: about: packs/about.js - admin: packs/admin.js + admin: + - packs/admin.js + - packs/public.js auth: packs/public.js common: filename: packs/common.js diff --git a/app/javascript/flavours/glitch/util/async-components.js b/app/javascript/flavours/glitch/util/async-components.js index a6c6ab0ab..8c9630eea 100644 --- a/app/javascript/flavours/glitch/util/async-components.js +++ b/app/javascript/flavours/glitch/util/async-components.js @@ -173,3 +173,7 @@ export function Directory () { export function FollowRecommendations () { return import(/* webpackChunkName: "features/glitch/async/follow_recommendations" */'flavours/glitch/features/follow_recommendations'); } + +export function CompareHistoryModal () { + return import(/*webpackChunkName: "flavours/glitch/async/compare_history_modal" */'flavours/glitch/features/ui/components/compare_history_modal'); +} diff --git a/app/javascript/flavours/vanilla/theme.yml b/app/javascript/flavours/vanilla/theme.yml index 3263fd7d4..9173d4ec9 100644 --- a/app/javascript/flavours/vanilla/theme.yml +++ b/app/javascript/flavours/vanilla/theme.yml @@ -1,7 +1,9 @@ # (REQUIRED) The location of the pack files inside `pack_directory`. pack: about: about.js - admin: admin.js + admin: + - admin.js + - public.js auth: public.js common: filename: common.js diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index 7c3bbcbd8..f3129f8d9 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -70,6 +70,8 @@ export const INIT_MEDIA_EDIT_MODAL = 'INIT_MEDIA_EDIT_MODAL'; export const COMPOSE_CHANGE_MEDIA_DESCRIPTION = 'COMPOSE_CHANGE_MEDIA_DESCRIPTION'; export const COMPOSE_CHANGE_MEDIA_FOCUS = 'COMPOSE_CHANGE_MEDIA_FOCUS'; +export const COMPOSE_SET_STATUS = 'COMPOSE_SET_STATUS'; + const messages = defineMessages({ uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' }, uploadErrorPoll: { id: 'upload_error.poll', defaultMessage: 'File upload not allowed with polls.' }, @@ -83,6 +85,15 @@ export const ensureComposeIsVisible = (getState, routerHistory) => { } }; +export function setComposeToStatus(status, text, spoiler_text) { + return{ + type: COMPOSE_SET_STATUS, + status, + text, + spoiler_text, + }; +}; + export function changeCompose(text) { return { type: COMPOSE_CHANGE, @@ -137,8 +148,9 @@ export function directCompose(account, routerHistory) { export function submitCompose(routerHistory) { return function (dispatch, getState) { - const status = getState().getIn(['compose', 'text'], ''); - const media = getState().getIn(['compose', 'media_attachments']); + const status = getState().getIn(['compose', 'text'], ''); + const media = getState().getIn(['compose', 'media_attachments']); + const statusId = getState().getIn(['compose', 'id'], null); if ((!status || !status.length) && media.size === 0) { return; @@ -146,15 +158,18 @@ export function submitCompose(routerHistory) { dispatch(submitComposeRequest()); - api(getState).post('/api/v1/statuses', { - status, - in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null), - media_ids: media.map(item => item.get('id')), - sensitive: getState().getIn(['compose', 'sensitive']), - spoiler_text: getState().getIn(['compose', 'spoiler']) ? getState().getIn(['compose', 'spoiler_text'], '') : '', - visibility: getState().getIn(['compose', 'privacy']), - poll: getState().getIn(['compose', 'poll'], null), - }, { + api(getState).request({ + url: statusId === null ? '/api/v1/statuses' : `/api/v1/statuses/${statusId}`, + method: statusId === null ? 'post' : 'put', + data: { + status, + in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null), + media_ids: media.map(item => item.get('id')), + sensitive: getState().getIn(['compose', 'sensitive']), + spoiler_text: getState().getIn(['compose', 'spoiler']) ? getState().getIn(['compose', 'spoiler_text'], '') : '', + visibility: getState().getIn(['compose', 'privacy']), + poll: getState().getIn(['compose', 'poll'], null), + }, headers: { 'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']), }, @@ -176,11 +191,11 @@ export function submitCompose(routerHistory) { } }; - if (response.data.visibility !== 'direct') { + if (statusId === null && response.data.visibility !== 'direct') { insertIfOnline('home'); } - if (response.data.in_reply_to_id === null && response.data.visibility === 'public') { + if (statusId === null && response.data.in_reply_to_id === null && response.data.visibility === 'public') { insertIfOnline('community'); if (!response.data.local_only) { insertIfOnline('public'); diff --git a/app/javascript/mastodon/actions/history.js b/app/javascript/mastodon/actions/history.js new file mode 100644 index 000000000..c142aaf61 --- /dev/null +++ b/app/javascript/mastodon/actions/history.js @@ -0,0 +1,37 @@ +import api from '../api'; +import { importFetchedAccounts } from './importer'; + +export const HISTORY_FETCH_REQUEST = 'HISTORY_FETCH_REQUEST'; +export const HISTORY_FETCH_SUCCESS = 'HISTORY_FETCH_SUCCESS'; +export const HISTORY_FETCH_FAIL = 'HISTORY_FETCH_FAIL'; + +export const fetchHistory = statusId => (dispatch, getState) => { + const loading = getState().getIn(['history', statusId, 'loading']); + + if (loading) { + return; + } + + dispatch(fetchHistoryRequest(statusId)); + + api(getState).get(`/api/v1/statuses/${statusId}/history`).then(({ data }) => { + dispatch(importFetchedAccounts(data.map(x => x.account))); + dispatch(fetchHistorySuccess(statusId, data)); + }).catch(error => dispatch(fetchHistoryFail(error))); +}; + +export const fetchHistoryRequest = statusId => ({ + type: HISTORY_FETCH_REQUEST, + statusId, +}); + +export const fetchHistorySuccess = (statusId, history) => ({ + type: HISTORY_FETCH_SUCCESS, + statusId, + history, +}); + +export const fetchHistoryFail = error => ({ + type: HISTORY_FETCH_FAIL, + error, +}); diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js index 663cf21e3..9370811e0 100644 --- a/app/javascript/mastodon/actions/notifications.js +++ b/app/javascript/mastodon/actions/notifications.js @@ -34,7 +34,6 @@ export const NOTIFICATIONS_LOAD_PENDING = 'NOTIFICATIONS_LOAD_PENDING'; export const NOTIFICATIONS_MOUNT = 'NOTIFICATIONS_MOUNT'; export const NOTIFICATIONS_UNMOUNT = 'NOTIFICATIONS_UNMOUNT'; - export const NOTIFICATIONS_MARK_AS_READ = 'NOTIFICATIONS_MARK_AS_READ'; export const NOTIFICATIONS_SET_BROWSER_SUPPORT = 'NOTIFICATIONS_SET_BROWSER_SUPPORT'; @@ -124,7 +123,17 @@ export function updateNotifications(notification, intlMessages, intlLocale) { const excludeTypesFromSettings = state => state.getIn(['settings', 'notifications', 'shows']).filter(enabled => !enabled).keySeq().toJS(); const excludeTypesFromFilter = filter => { - const allTypes = ImmutableList(['follow', 'follow_request', 'favourite', 'reblog', 'mention', 'poll']); + const allTypes = ImmutableList([ + 'follow', + 'follow_request', + 'favourite', + 'reblog', + 'mention', + 'poll', + 'status', + 'update', + ]); + return allTypes.filterNot(item => item === filter).toJS(); }; diff --git a/app/javascript/mastodon/actions/statuses.js b/app/javascript/mastodon/actions/statuses.js index 20d71362e..adc24eabf 100644 --- a/app/javascript/mastodon/actions/statuses.js +++ b/app/javascript/mastodon/actions/statuses.js @@ -2,7 +2,7 @@ import api from '../api'; import { deleteFromTimelines } from './timelines'; import { importFetchedStatus, importFetchedStatuses, importFetchedAccount } from './importer'; -import { ensureComposeIsVisible } from './compose'; +import { ensureComposeIsVisible, setComposeToStatus } from './compose'; export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST'; export const STATUS_FETCH_SUCCESS = 'STATUS_FETCH_SUCCESS'; @@ -30,6 +30,10 @@ export const STATUS_COLLAPSE = 'STATUS_COLLAPSE'; export const REDRAFT = 'REDRAFT'; +export const STATUS_FETCH_SOURCE_REQUEST = 'STATUS_FETCH_SOURCE_REQUEST'; +export const STATUS_FETCH_SOURCE_SUCCESS = 'STATUS_FETCH_SOURCE_SUCCESS'; +export const STATUS_FETCH_SOURCE_FAIL = 'STATUS_FETCH_SOURCE_FAIL'; + export function fetchStatusRequest(id, skipLoading) { return { type: STATUS_FETCH_REQUEST, @@ -84,6 +88,37 @@ export function redraft(status, raw_text) { }; }; +export const editStatus = (id, routerHistory) => (dispatch, getState) => { + let status = getState().getIn(['statuses', id]); + + if (status.get('poll')) { + status = status.set('poll', getState().getIn(['polls', status.get('poll')])); + } + + dispatch(fetchStatusSourceRequest()); + + api(getState).get(`/api/v1/statuses/${id}/source`).then(response => { + dispatch(fetchStatusSourceSuccess()); + ensureComposeIsVisible(getState, routerHistory); + dispatch(setComposeToStatus(status, response.data.text, response.data.spoiler_text)); + }).catch(error => { + dispatch(fetchStatusSourceFail(error)); + }); +}; + +export const fetchStatusSourceRequest = () => ({ + type: STATUS_FETCH_SOURCE_REQUEST, +}); + +export const fetchStatusSourceSuccess = () => ({ + type: STATUS_FETCH_SOURCE_SUCCESS, +}); + +export const fetchStatusSourceFail = error => ({ + type: STATUS_FETCH_SOURCE_FAIL, + error, +}); + export function deleteStatus(id, routerHistory, withRedraft = false) { return (dispatch, getState) => { let status = getState().getIn(['statuses', id]); diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js index 7d0588901..4b4ad8355 100644 --- a/app/javascript/mastodon/components/dropdown_menu.js +++ b/app/javascript/mastodon/components/dropdown_menu.js @@ -6,6 +6,8 @@ import Overlay from 'react-overlays/lib/Overlay'; import Motion from '../features/ui/util/optional_motion'; import spring from 'react-motion/lib/spring'; import { supportsPassiveEvents } from 'detect-passive-events'; +import classNames from 'classnames'; +import { CircularProgress } from 'mastodon/components/loading_indicator'; const listenerOptions = supportsPassiveEvents ? { passive: true } : false; let id = 0; @@ -17,13 +19,18 @@ class DropdownMenu extends React.PureComponent { }; static propTypes = { - items: PropTypes.array.isRequired, + items: PropTypes.oneOfType([PropTypes.array, ImmutablePropTypes.list]).isRequired, + loading: PropTypes.bool, + scrollable: PropTypes.bool, onClose: PropTypes.func.isRequired, style: PropTypes.object, placement: PropTypes.string, arrowOffsetLeft: PropTypes.string, arrowOffsetTop: PropTypes.string, openedViaKeyboard: PropTypes.bool, + renderItem: PropTypes.func, + renderHeader: PropTypes.func, + onItemClick: PropTypes.func.isRequired, }; static defaultProps = { @@ -45,9 +52,11 @@ class DropdownMenu extends React.PureComponent { document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('keydown', this.handleKeyDown, false); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); + if (this.focusedItem && this.props.openedViaKeyboard) { this.focusedItem.focus({ preventScroll: true }); } + this.setState({ mounted: true }); } @@ -66,7 +75,7 @@ class DropdownMenu extends React.PureComponent { } handleKeyDown = e => { - const items = Array.from(this.node.getElementsByTagName('a')); + const items = Array.from(this.node.querySelectorAll('a, button')); const index = items.indexOf(document.activeElement); let element = null; @@ -109,21 +118,11 @@ class DropdownMenu extends React.PureComponent { } handleClick = e => { - const i = Number(e.currentTarget.getAttribute('data-index')); - const { action, to } = this.props.items[i]; - - this.props.onClose(); - - if (typeof action === 'function') { - e.preventDefault(); - action(e); - } else if (to) { - e.preventDefault(); - this.context.router.history.push(to); - } + const { onItemClick } = this.props; + onItemClick(e); } - renderItem (option, i) { + renderItem = (option, i) => { if (option === null) { return <li key={`sep-${i}`} className='dropdown-menu__separator' />; } @@ -140,9 +139,11 @@ class DropdownMenu extends React.PureComponent { } render () { - const { items, style, placement, arrowOffsetLeft, arrowOffsetTop } = this.props; + const { items, style, placement, arrowOffsetLeft, arrowOffsetTop, scrollable, renderHeader, loading } = this.props; const { mounted } = this.state; + let renderItem = this.props.renderItem || this.renderItem; + return ( <Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}> {({ opacity, scaleX, scaleY }) => ( @@ -152,9 +153,23 @@ class DropdownMenu extends React.PureComponent { <div className={`dropdown-menu ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} ref={this.setRef}> <div className={`dropdown-menu__arrow ${placement}`} style={{ left: arrowOffsetLeft, top: arrowOffsetTop }} /> - <ul> - {items.map((option, i) => this.renderItem(option, i))} - </ul> + <div className={classNames('dropdown-menu__container', { 'dropdown-menu__container--loading': loading })}> + {loading && ( + <CircularProgress size={30} strokeWidth={3.5} /> + )} + + {!loading && renderHeader && ( + <div className='dropdown-menu__container__header'> + {renderHeader(items)} + </div> + )} + + {!loading && ( + <ul className={classNames('dropdown-menu__container__list', { 'dropdown-menu__container__list--scrollable': scrollable })}> + {items.map((option, i) => renderItem(option, i, { onClick: this.handleClick, onKeyPress: this.handleItemKeyPress }))} + </ul> + )} + </div> </div> )} </Motion> @@ -170,11 +185,14 @@ export default class Dropdown extends React.PureComponent { }; static propTypes = { - icon: PropTypes.string.isRequired, - items: PropTypes.array.isRequired, - size: PropTypes.number.isRequired, + children: PropTypes.node, + icon: PropTypes.string, + items: PropTypes.oneOfType([PropTypes.array, ImmutablePropTypes.list]).isRequired, + loading: PropTypes.bool, + size: PropTypes.number, title: PropTypes.string, disabled: PropTypes.bool, + scrollable: PropTypes.bool, status: ImmutablePropTypes.map, isUserTouching: PropTypes.func, onOpen: PropTypes.func.isRequired, @@ -182,6 +200,9 @@ export default class Dropdown extends React.PureComponent { dropdownPlacement: PropTypes.string, openDropdownId: PropTypes.number, openedViaKeyboard: PropTypes.bool, + renderItem: PropTypes.func, + renderHeader: PropTypes.func, + onItemClick: PropTypes.func, }; static defaultProps = { @@ -237,17 +258,21 @@ export default class Dropdown extends React.PureComponent { } handleItemClick = e => { + const { onItemClick } = this.props; const i = Number(e.currentTarget.getAttribute('data-index')); - const { action, to } = this.props.items[i]; + const item = this.props.items[i]; this.handleClose(); - if (typeof action === 'function') { + if (typeof onItemClick === 'function') { + e.preventDefault(); + onItemClick(item, i); + } else if (item && typeof item.action === 'function') { e.preventDefault(); - action(); - } else if (to) { + item.action(); + } else if (item && item.to) { e.preventDefault(); - this.context.router.history.push(to); + this.context.router.history.push(item.to); } } @@ -265,29 +290,67 @@ export default class Dropdown extends React.PureComponent { } } + close = () => { + this.handleClose(); + } + render () { - const { icon, items, size, title, disabled, dropdownPlacement, openDropdownId, openedViaKeyboard } = this.props; + const { + icon, + items, + size, + title, + disabled, + loading, + scrollable, + dropdownPlacement, + openDropdownId, + openedViaKeyboard, + children, + renderItem, + renderHeader, + } = this.props; + const open = this.state.id === openDropdownId; + const button = children ? React.cloneElement(React.Children.only(children), { + ref: this.setTargetRef, + onClick: this.handleClick, + onMouseDown: this.handleMouseDown, + onKeyDown: this.handleButtonKeyDown, + onKeyPress: this.handleKeyPress, + }) : ( + <IconButton + icon={icon} + title={title} + active={open} + disabled={disabled} + size={size} + ref={this.setTargetRef} + onClick={this.handleClick} + onMouseDown={this.handleMouseDown} + onKeyDown={this.handleButtonKeyDown} + onKeyPress={this.handleKeyPress} + /> + ); + return ( - <div> - <IconButton - icon={icon} - title={title} - active={open} - disabled={disabled} - size={size} - ref={this.setTargetRef} - onClick={this.handleClick} - onMouseDown={this.handleMouseDown} - onKeyDown={this.handleButtonKeyDown} - onKeyPress={this.handleKeyPress} - /> + <React.Fragment> + {button} <Overlay show={open} placement={dropdownPlacement} target={this.findTarget}> - <DropdownMenu items={items} onClose={this.handleClose} openedViaKeyboard={openedViaKeyboard} /> + <DropdownMenu + items={items} + loading={loading} + scrollable={scrollable} + onClose={this.handleClose} + openedViaKeyboard={openedViaKeyboard} + renderItem={renderItem} + renderHeader={renderHeader} + onItemClick={this.handleItemClick} + /> </Overlay> - </div> + </React.Fragment> ); } diff --git a/app/javascript/mastodon/components/edited_timestamp/containers/dropdown_menu_container.js b/app/javascript/mastodon/components/edited_timestamp/containers/dropdown_menu_container.js new file mode 100644 index 000000000..e30c18372 --- /dev/null +++ b/app/javascript/mastodon/components/edited_timestamp/containers/dropdown_menu_container.js @@ -0,0 +1,27 @@ +import { connect } from 'react-redux'; +import { openDropdownMenu, closeDropdownMenu } from 'mastodon/actions/dropdown_menu'; +import { fetchHistory } from 'mastodon/actions/history'; +import DropdownMenu from 'mastodon/components/dropdown_menu'; + +const mapStateToProps = (state, { statusId }) => ({ + dropdownPlacement: state.getIn(['dropdown_menu', 'placement']), + openDropdownId: state.getIn(['dropdown_menu', 'openId']), + openedViaKeyboard: state.getIn(['dropdown_menu', 'keyboard']), + items: state.getIn(['history', statusId, 'items']), + loading: state.getIn(['history', statusId, 'loading']), +}); + +const mapDispatchToProps = (dispatch, { statusId }) => ({ + + onOpen (id, onItemClick, dropdownPlacement, keyboard) { + dispatch(fetchHistory(statusId)); + dispatch(openDropdownMenu(id, dropdownPlacement, keyboard)); + }, + + onClose (id) { + dispatch(closeDropdownMenu(id)); + }, + +}); + +export default connect(mapStateToProps, mapDispatchToProps)(DropdownMenu); diff --git a/app/javascript/mastodon/components/edited_timestamp/index.js b/app/javascript/mastodon/components/edited_timestamp/index.js new file mode 100644 index 000000000..bebf93886 --- /dev/null +++ b/app/javascript/mastodon/components/edited_timestamp/index.js @@ -0,0 +1,70 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { FormattedMessage, injectIntl } from 'react-intl'; +import Icon from 'mastodon/components/icon'; +import DropdownMenu from './containers/dropdown_menu_container'; +import { connect } from 'react-redux'; +import { openModal } from 'mastodon/actions/modal'; +import RelativeTimestamp from 'mastodon/components/relative_timestamp'; +import InlineAccount from 'mastodon/components/inline_account'; + +const mapDispatchToProps = (dispatch, { statusId }) => ({ + + onItemClick (index) { + dispatch(openModal('COMPARE_HISTORY', { index, statusId })); + }, + +}); + +export default @connect(null, mapDispatchToProps) +@injectIntl +class EditedTimestamp extends React.PureComponent { + + static propTypes = { + statusId: PropTypes.string.isRequired, + timestamp: PropTypes.string.isRequired, + intl: PropTypes.object.isRequired, + onItemClick: PropTypes.func.isRequired, + }; + + handleItemClick = (item, i) => { + const { onItemClick } = this.props; + onItemClick(i); + }; + + renderHeader = items => { + return ( + <FormattedMessage id='status.edited_x_times' defaultMessage='Edited {count, plural, one {{count} time} other {{count} times}}' values={{ count: items.size - 1 }} /> + ); + } + + renderItem = (item, index, { onClick, onKeyPress }) => { + const formattedDate = <RelativeTimestamp timestamp={item.get('created_at')} short={false} />; + const formattedName = <InlineAccount accountId={item.get('account')} />; + + const label = item.get('original') ? ( + <FormattedMessage id='status.history.created' defaultMessage='{name} created {date}' values={{ name: formattedName, date: formattedDate }} /> + ) : ( + <FormattedMessage id='status.history.edited' defaultMessage='{name} edited {date}' values={{ name: formattedName, date: formattedDate }} /> + ); + + return ( + <li className='dropdown-menu__item edited-timestamp__history__item' key={item.get('created_at')}> + <button data-index={index} onClick={onClick} onKeyPress={onKeyPress}>{label}</button> + </li> + ); + } + + render () { + const { timestamp, intl, statusId } = this.props; + + return ( + <DropdownMenu statusId={statusId} renderItem={this.renderItem} scrollable renderHeader={this.renderHeader} onItemClick={this.handleItemClick}> + <button className='dropdown-menu__text-button'> + <FormattedMessage id='status.edited' defaultMessage='Edited {date}' values={{ date: intl.formatDate(timestamp, { hour12: false, month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }) }} /> <Icon id='caret-down' /> + </button> + </DropdownMenu> + ); + } + +} diff --git a/app/javascript/mastodon/components/inline_account.js b/app/javascript/mastodon/components/inline_account.js new file mode 100644 index 000000000..a1b495590 --- /dev/null +++ b/app/javascript/mastodon/components/inline_account.js @@ -0,0 +1,34 @@ +import React from 'react'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import { connect } from 'react-redux'; +import { makeGetAccount } from 'mastodon/selectors'; +import Avatar from 'mastodon/components/avatar'; + +const makeMapStateToProps = () => { + const getAccount = makeGetAccount(); + + const mapStateToProps = (state, { accountId }) => ({ + account: getAccount(state, accountId), + }); + + return mapStateToProps; +}; + +export default @connect(makeMapStateToProps) +class InlineAccount extends React.PureComponent { + + static propTypes = { + account: ImmutablePropTypes.map.isRequired, + }; + + render () { + const { account } = this.props; + + return ( + <span className='inline-account'> + <Avatar size={13} account={account} /> <strong>{account.get('username')}</strong> + </span> + ); + } + +} diff --git a/app/javascript/mastodon/components/loading_indicator.js b/app/javascript/mastodon/components/loading_indicator.js index d6a5adb6f..59f721c50 100644 --- a/app/javascript/mastodon/components/loading_indicator.js +++ b/app/javascript/mastodon/components/loading_indicator.js @@ -1,10 +1,31 @@ import React from 'react'; -import { FormattedMessage } from 'react-intl'; +import PropTypes from 'prop-types'; + +export const CircularProgress = ({ size, strokeWidth }) => { + const viewBox = `0 0 ${size} ${size}`; + const radius = (size - strokeWidth) / 2; + + return ( + <svg width={size} heigh={size} viewBox={viewBox} className='circular-progress' role='progressbar'> + <circle + fill='none' + cx={size / 2} + cy={size / 2} + r={radius} + strokeWidth={`${strokeWidth}px`} + /> + </svg> + ); +}; + +CircularProgress.propTypes = { + size: PropTypes.number.isRequired, + strokeWidth: PropTypes.number.isRequired, +}; const LoadingIndicator = () => ( <div className='loading-indicator'> - <div className='loading-indicator__figure' /> - <FormattedMessage id='loading_indicator.label' defaultMessage='Loading...' /> + <CircularProgress size={50} strokeWidth={6} /> </div> ); diff --git a/app/javascript/mastodon/components/relative_timestamp.js b/app/javascript/mastodon/components/relative_timestamp.js index 711181dcd..512480339 100644 --- a/app/javascript/mastodon/components/relative_timestamp.js +++ b/app/javascript/mastodon/components/relative_timestamp.js @@ -5,10 +5,15 @@ import PropTypes from 'prop-types'; const messages = defineMessages({ today: { id: 'relative_time.today', defaultMessage: 'today' }, just_now: { id: 'relative_time.just_now', defaultMessage: 'now' }, + just_now_full: { id: 'relative_time.full.just_now', defaultMessage: 'just now' }, seconds: { id: 'relative_time.seconds', defaultMessage: '{number}s' }, + seconds_full: { id: 'relative_time.full.seconds', defaultMessage: '{number, plural, one {# second} other {# seconds}} ago' }, minutes: { id: 'relative_time.minutes', defaultMessage: '{number}m' }, + minutes_full: { id: 'relative_time.full.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}} ago' }, hours: { id: 'relative_time.hours', defaultMessage: '{number}h' }, + hours_full: { id: 'relative_time.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}} ago' }, days: { id: 'relative_time.days', defaultMessage: '{number}d' }, + days_full: { id: 'relative_time.full.days', defaultMessage: '{number, plural, one {# day} other {# days}} ago' }, moments_remaining: { id: 'time_remaining.moments', defaultMessage: 'Moments remaining' }, seconds_remaining: { id: 'time_remaining.seconds', defaultMessage: '{number, plural, one {# second} other {# seconds}} left' }, minutes_remaining: { id: 'time_remaining.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}} left' }, @@ -66,7 +71,7 @@ const getUnitDelay = units => { } }; -export const timeAgoString = (intl, date, now, year, timeGiven = true) => { +export const timeAgoString = (intl, date, now, year, timeGiven, short) => { const delta = now - date.getTime(); let relativeTime; @@ -74,16 +79,16 @@ export const timeAgoString = (intl, date, now, year, timeGiven = true) => { if (delta < DAY && !timeGiven) { relativeTime = intl.formatMessage(messages.today); } else if (delta < 10 * SECOND) { - relativeTime = intl.formatMessage(messages.just_now); + relativeTime = intl.formatMessage(short ? messages.just_now : messages.just_now_full); } else if (delta < 7 * DAY) { if (delta < MINUTE) { - relativeTime = intl.formatMessage(messages.seconds, { number: Math.floor(delta / SECOND) }); + relativeTime = intl.formatMessage(short ? messages.seconds : messages.seconds_full, { number: Math.floor(delta / SECOND) }); } else if (delta < HOUR) { - relativeTime = intl.formatMessage(messages.minutes, { number: Math.floor(delta / MINUTE) }); + relativeTime = intl.formatMessage(short ? messages.minutes : messages.minutes_full, { number: Math.floor(delta / MINUTE) }); } else if (delta < DAY) { - relativeTime = intl.formatMessage(messages.hours, { number: Math.floor(delta / HOUR) }); + relativeTime = intl.formatMessage(short ? messages.hours : messages.hours_full, { number: Math.floor(delta / HOUR) }); } else { - relativeTime = intl.formatMessage(messages.days, { number: Math.floor(delta / DAY) }); + relativeTime = intl.formatMessage(short ? messages.days : messages.days_full, { number: Math.floor(delta / DAY) }); } } else if (date.getFullYear() === year) { relativeTime = intl.formatDate(date, shortDateFormatOptions); @@ -124,6 +129,7 @@ class RelativeTimestamp extends React.Component { timestamp: PropTypes.string.isRequired, year: PropTypes.number.isRequired, futureDate: PropTypes.bool, + short: PropTypes.bool, }; state = { @@ -132,6 +138,7 @@ class RelativeTimestamp extends React.Component { static defaultProps = { year: (new Date()).getFullYear(), + short: true, }; shouldComponentUpdate (nextProps, nextState) { @@ -176,11 +183,11 @@ class RelativeTimestamp extends React.Component { } render () { - const { timestamp, intl, year, futureDate } = this.props; + const { timestamp, intl, year, futureDate, short } = this.props; const timeGiven = timestamp.includes('T'); const date = new Date(timestamp); - const relativeTime = futureDate ? timeRemainingString(intl, date, this.state.now, timeGiven) : timeAgoString(intl, date, this.state.now, year, timeGiven); + const relativeTime = futureDate ? timeRemainingString(intl, date, this.state.now, timeGiven) : timeAgoString(intl, date, this.state.now, year, timeGiven, short); return ( <time dateTime={timestamp} title={intl.formatDate(date, dateFormatOptions)}> diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.js index 4e19cc0e4..e3a7d763f 100644 --- a/app/javascript/mastodon/components/status_action_bar.js +++ b/app/javascript/mastodon/components/status_action_bar.js @@ -12,6 +12,7 @@ import classNames from 'classnames'; const messages = defineMessages({ delete: { id: 'status.delete', defaultMessage: 'Delete' }, redraft: { id: 'status.redraft', defaultMessage: 'Delete & re-draft' }, + edit: { id: 'status.edit', defaultMessage: 'Edit' }, direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' }, mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' }, mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' }, @@ -137,6 +138,10 @@ class StatusActionBar extends ImmutablePureComponent { this.props.onDelete(this.props.status, this.context.router.history, true); } + handleEditClick = () => { + this.props.onEdit(this.props.status, this.context.router.history); + } + handlePinClick = () => { this.props.onPin(this.props.status); } @@ -255,6 +260,7 @@ class StatusActionBar extends ImmutablePureComponent { } if (writtenByMe) { + // menu.push({ text: intl.formatMessage(messages.edit), action: this.handleEditClick }); menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick }); menu.push({ text: intl.formatMessage(messages.redraft), action: this.handleRedraftClick }); } else { diff --git a/app/javascript/mastodon/containers/status_container.js b/app/javascript/mastodon/containers/status_container.js index 9abdec138..ef0aca13a 100644 --- a/app/javascript/mastodon/containers/status_container.js +++ b/app/javascript/mastodon/containers/status_container.js @@ -24,6 +24,7 @@ import { hideStatus, revealStatus, toggleStatusCollapse, + editStatus, } from '../actions/statuses'; import { unmuteAccount, @@ -142,6 +143,10 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ } }, + onEdit (status, history) { + dispatch(editStatus(status.get('id'), history)); + }, + onDirect (account, router) { dispatch(directCompose(account, router)); }, diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js index 647d0fba2..26232247d 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.js +++ b/app/javascript/mastodon/features/compose/components/compose_form.js @@ -29,6 +29,7 @@ const messages = defineMessages({ spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Write your warning here' }, publish: { id: 'compose_form.publish', defaultMessage: 'Toot' }, publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' }, + saveChanges: { id: 'compose_form.save_changes', defaultMessage: 'Save changes' }, }); export default @injectIntl @@ -50,6 +51,7 @@ class ComposeForm extends ImmutablePureComponent { preselectDate: PropTypes.instanceOf(Date), isSubmitting: PropTypes.bool, isChangingUpload: PropTypes.bool, + isEditing: PropTypes.bool, isUploading: PropTypes.bool, onChange: PropTypes.func.isRequired, onSubmit: PropTypes.func.isRequired, @@ -200,7 +202,9 @@ class ComposeForm extends ImmutablePureComponent { const disabled = this.props.isSubmitting; let publishText = ''; - if (this.props.privacy === 'private' || this.props.privacy === 'direct') { + if (this.props.isEditing) { + publishText = intl.formatMessage(messages.saveChanges); + } else if (this.props.privacy === 'private' || this.props.privacy === 'direct') { publishText = <span className='compose-form__publish-private'><Icon id='lock' /> {intl.formatMessage(messages.publish)}</span>; } else { publishText = this.props.privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish); @@ -256,7 +260,7 @@ class ComposeForm extends ImmutablePureComponent { <div className='compose-form__buttons'> <UploadButtonContainer /> <PollButtonContainer /> - <PrivacyDropdownContainer /> + <PrivacyDropdownContainer disabled={this.props.isEditing} /> <SpoilerButtonContainer /> </div> <div className='character-counter__wrapper'><CharacterCounter max={maxChars} text={this.getFulltextForCharacterCounting()} /></div> diff --git a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js index df59f46b3..599467cdb 100644 --- a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js +++ b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js @@ -159,6 +159,7 @@ class PrivacyDropdown extends React.PureComponent { onChange: PropTypes.func.isRequired, noDirect: PropTypes.bool, container: PropTypes.func, + disabled: PropTypes.bool, intl: PropTypes.object.isRequired, }; @@ -247,7 +248,7 @@ class PrivacyDropdown extends React.PureComponent { } render () { - const { value, container, intl } = this.props; + const { value, container, disabled, intl } = this.props; const { open, placement } = this.state; const valueOption = this.options.find(item => item.value === value); @@ -267,6 +268,7 @@ class PrivacyDropdown extends React.PureComponent { onMouseDown={this.handleMouseDown} onKeyDown={this.handleButtonKeyDown} style={{ height: null, lineHeight: '27px' }} + disabled={disabled} /> </div> diff --git a/app/javascript/mastodon/features/compose/components/upload.js b/app/javascript/mastodon/features/compose/components/upload.js index b9f0fbe3a..1289d6b94 100644 --- a/app/javascript/mastodon/features/compose/components/upload.js +++ b/app/javascript/mastodon/features/compose/components/upload.js @@ -18,6 +18,7 @@ export default class Upload extends ImmutablePureComponent { media: ImmutablePropTypes.map.isRequired, onUndo: PropTypes.func.isRequired, onOpenFocalPoint: PropTypes.func.isRequired, + isEditingStatus: PropTypes.func.isRequired, }; handleUndoClick = e => { @@ -31,7 +32,7 @@ export default class Upload extends ImmutablePureComponent { } render () { - const { media } = this.props; + const { media, isEditingStatus } = this.props; const focusX = media.getIn(['meta', 'focus', 'x']); const focusY = media.getIn(['meta', 'focus', 'y']); const x = ((focusX / 2) + .5) * 100; @@ -44,7 +45,7 @@ export default class Upload extends ImmutablePureComponent { <div className='compose-form__upload-thumbnail' style={{ transform: `scale(${scale})`, backgroundImage: `url(${media.get('preview_url')})`, backgroundPosition: `${x}% ${y}%` }}> <div className={classNames('compose-form__upload__actions', { active: true })}> <button className='icon-button' onClick={this.handleUndoClick}><Icon id='times' /> <FormattedMessage id='upload_form.undo' defaultMessage='Delete' /></button> - <button className='icon-button' onClick={this.handleFocalPointClick}><Icon id='pencil' /> <FormattedMessage id='upload_form.edit' defaultMessage='Edit' /></button> + {!isEditingStatus && (<button className='icon-button' onClick={this.handleFocalPointClick}><Icon id='pencil' /> <FormattedMessage id='upload_form.edit' defaultMessage='Edit' /></button>)} </div> </div> )} diff --git a/app/javascript/mastodon/features/compose/containers/compose_form_container.js b/app/javascript/mastodon/features/compose/containers/compose_form_container.js index c44850294..1be7633cc 100644 --- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js +++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js @@ -21,6 +21,7 @@ const mapStateToProps = state => ({ caretPosition: state.getIn(['compose', 'caretPosition']), preselectDate: state.getIn(['compose', 'preselectDate']), isSubmitting: state.getIn(['compose', 'is_submitting']), + isEditing: state.getIn(['compose', 'id']) !== null, isChangingUpload: state.getIn(['compose', 'is_changing_upload']), isUploading: state.getIn(['compose', 'is_uploading']), showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']), diff --git a/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js b/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js index 5eb1eb72a..a1302b2d4 100644 --- a/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js +++ b/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js @@ -6,9 +6,20 @@ import ReplyIndicator from '../components/reply_indicator'; const makeMapStateToProps = () => { const getStatus = makeGetStatus(); - const mapStateToProps = state => ({ - status: getStatus(state, { id: state.getIn(['compose', 'in_reply_to']) }), - }); + const mapStateToProps = state => { + let statusId = state.getIn(['compose', 'id'], null); + let editing = true; + + if (statusId === null) { + statusId = state.getIn(['compose', 'in_reply_to']); + editing = false; + } + + return { + status: getStatus(state, { id: statusId }), + editing, + }; + }; return mapStateToProps; }; diff --git a/app/javascript/mastodon/features/compose/containers/upload_container.js b/app/javascript/mastodon/features/compose/containers/upload_container.js index 05cd2ecc1..1108aec30 100644 --- a/app/javascript/mastodon/features/compose/containers/upload_container.js +++ b/app/javascript/mastodon/features/compose/containers/upload_container.js @@ -5,6 +5,7 @@ import { submitCompose } from '../../../actions/compose'; const mapStateToProps = (state, { id }) => ({ media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id), + isEditingStatus: state.getIn(['compose', 'id']) !== null, }); const mapDispatchToProps = dispatch => ({ diff --git a/app/javascript/mastodon/features/notifications/components/column_settings.js b/app/javascript/mastodon/features/notifications/components/column_settings.js index 005f5afda..ada8b6e4a 100644 --- a/app/javascript/mastodon/features/notifications/components/column_settings.js +++ b/app/javascript/mastodon/features/notifications/components/column_settings.js @@ -153,6 +153,17 @@ export default class ColumnSettings extends React.PureComponent { <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'status']} onChange={onChange} label={soundStr} /> </div> </div> + + <div role='group' aria-labelledby='notifications-update'> + <span id='notifications-status' className='column-settings__section'><FormattedMessage id='notifications.column_settings.update' defaultMessage='Edits:' /></span> + + <div className='column-settings__row'> + <SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'update']} onChange={onChange} label={alertStr} /> + {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'update']} onChange={this.onPushChange} label={pushStr} />} + <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'update']} onChange={onChange} label={showStr} /> + <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'update']} onChange={onChange} label={soundStr} /> + </div> + </div> </div> ); } diff --git a/app/javascript/mastodon/features/notifications/components/notification.js b/app/javascript/mastodon/features/notifications/components/notification.js index f9f8a87f2..cd471852b 100644 --- a/app/javascript/mastodon/features/notifications/components/notification.js +++ b/app/javascript/mastodon/features/notifications/components/notification.js @@ -19,6 +19,7 @@ const messages = defineMessages({ poll: { id: 'notification.poll', defaultMessage: 'A poll you have voted in has ended' }, reblog: { id: 'notification.reblog', defaultMessage: '{name} boosted your status' }, status: { id: 'notification.status', defaultMessage: '{name} just posted' }, + update: { id: 'notification.update', defaultMessage: '{name} edited a post' }, }); const notificationForScreenReader = (intl, message, timestamp) => { @@ -273,6 +274,38 @@ class Notification extends ImmutablePureComponent { ); } + renderUpdate (notification, link) { + const { intl, unread } = this.props; + + return ( + <HotKeys handlers={this.getHandlers()}> + <div className={classNames('notification notification-update focusable', { unread })} tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage(messages.update, { name: notification.getIn(['account', 'acct']) }), notification.get('created_at'))}> + <div className='notification__message'> + <div className='notification__favourite-icon-wrapper'> + <Icon id='pencil' fixedWidth /> + </div> + + <span title={notification.get('created_at')}> + <FormattedMessage id='notification.update' defaultMessage='{name} edited a post' values={{ name: link }} /> + </span> + </div> + + <StatusContainer + id={notification.get('status')} + account={notification.get('account')} + muted + withDismiss + hidden={this.props.hidden} + getScrollPosition={this.props.getScrollPosition} + updateScrollBottom={this.props.updateScrollBottom} + cachedMediaWidth={this.props.cachedMediaWidth} + cacheMediaWidth={this.props.cacheMediaWidth} + /> + </div> + </HotKeys> + ); + } + renderPoll (notification, account) { const { intl, unread } = this.props; const ownPoll = me === account.get('id'); @@ -330,6 +363,8 @@ class Notification extends ImmutablePureComponent { return this.renderReblog(notification, link); case 'status': return this.renderStatus(notification, link); + case 'update': + return this.renderUpdate(notification, link); case 'poll': return this.renderPoll(notification, account); } diff --git a/app/javascript/mastodon/features/status/components/action_bar.js b/app/javascript/mastodon/features/status/components/action_bar.js index a15a4d567..3f3ec0e71 100644 --- a/app/javascript/mastodon/features/status/components/action_bar.js +++ b/app/javascript/mastodon/features/status/components/action_bar.js @@ -11,6 +11,7 @@ import classNames from 'classnames'; const messages = defineMessages({ delete: { id: 'status.delete', defaultMessage: 'Delete' }, redraft: { id: 'status.redraft', defaultMessage: 'Delete & re-draft' }, + edit: { id: 'status.edit', defaultMessage: 'Edit' }, direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' }, mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' }, reply: { id: 'status.reply', defaultMessage: 'Reply' }, @@ -59,6 +60,7 @@ class ActionBar extends React.PureComponent { onFavourite: PropTypes.func.isRequired, onBookmark: PropTypes.func.isRequired, onDelete: PropTypes.func.isRequired, + onEdit: PropTypes.func.isRequired, onDirect: PropTypes.func.isRequired, onMention: PropTypes.func.isRequired, onMute: PropTypes.func, @@ -98,6 +100,10 @@ class ActionBar extends React.PureComponent { this.props.onDelete(this.props.status, this.context.router.history, true); } + handleEditClick = () => { + this.props.onEdit(this.props.status, this.context.router.history); + } + handleDirectClick = () => { this.props.onDirect(this.props.status.get('account'), this.context.router.history); } @@ -209,6 +215,7 @@ class ActionBar extends React.PureComponent { menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick }); menu.push(null); + // menu.push({ text: intl.formatMessage(messages.edit), action: this.handleEditClick }); menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick }); menu.push({ text: intl.formatMessage(messages.redraft), action: this.handleRedraftClick }); } else { diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js index ee4a6b989..c99e01f73 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.js +++ b/app/javascript/mastodon/features/status/components/detailed_status.js @@ -6,7 +6,7 @@ import DisplayName from '../../../components/display_name'; import StatusContent from '../../../components/status_content'; import MediaGallery from '../../../components/media_gallery'; import { Link } from 'react-router-dom'; -import { injectIntl, defineMessages, FormattedDate, FormattedMessage } from 'react-intl'; +import { injectIntl, defineMessages, FormattedDate } from 'react-intl'; import Card from './card'; import ImmutablePureComponent from 'react-immutable-pure-component'; import Video from '../../video'; @@ -16,6 +16,7 @@ import classNames from 'classnames'; import Icon from 'mastodon/components/icon'; import AnimatedNumber from 'mastodon/components/animated_number'; import PictureInPicturePlaceholder from 'mastodon/components/picture_in_picture_placeholder'; +import EditedTimestamp from 'mastodon/components/edited_timestamp'; const messages = defineMessages({ public_short: { id: 'privacy.public.short', defaultMessage: 'Public' }, @@ -242,7 +243,7 @@ class DetailedStatus extends ImmutablePureComponent { edited = ( <React.Fragment> <React.Fragment> · </React.Fragment> - <FormattedMessage id='status.edited' defaultMessage='Edited {date}' values={{ date: intl.formatDate(status.get('edited_at'), { hour12: false, month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }) }} /> + <EditedTimestamp statusId={status.get('id')} timestamp={status.get('edited_at')} /> </React.Fragment> ); } diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js index f342a3641..4d7f24834 100644 --- a/app/javascript/mastodon/features/status/index.js +++ b/app/javascript/mastodon/features/status/index.js @@ -29,6 +29,7 @@ import { muteStatus, unmuteStatus, deleteStatus, + editStatus, hideStatus, revealStatus, } from '../../actions/statuses'; @@ -273,6 +274,10 @@ class Status extends ImmutablePureComponent { } } + handleEditClick = (status, history) => { + this.props.dispatch(editStatus(status.get('id'), history)); + } + handleDirectClick = (account, router) => { this.props.dispatch(directCompose(account, router)); } @@ -567,6 +572,7 @@ class Status extends ImmutablePureComponent { onReblog={this.handleReblogClick} onBookmark={this.handleBookmarkClick} onDelete={this.handleDeleteClick} + onEdit={this.handleEditClick} onDirect={this.handleDirectClick} onMention={this.handleMentionClick} onMute={this.handleMuteClick} diff --git a/app/javascript/mastodon/features/ui/components/compare_history_modal.js b/app/javascript/mastodon/features/ui/components/compare_history_modal.js new file mode 100644 index 000000000..40cfba335 --- /dev/null +++ b/app/javascript/mastodon/features/ui/components/compare_history_modal.js @@ -0,0 +1,79 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import { connect } from 'react-redux'; +import { FormattedMessage } from 'react-intl'; +import { closeModal } from 'mastodon/actions/modal'; +import emojify from 'mastodon/features/emoji/emoji'; +import escapeTextContentForBrowser from 'escape-html'; +import InlineAccount from 'mastodon/components/inline_account'; +import IconButton from 'mastodon/components/icon_button'; +import RelativeTimestamp from 'mastodon/components/relative_timestamp'; + +const mapStateToProps = (state, { statusId }) => ({ + versions: state.getIn(['history', statusId, 'items']), +}); + +const mapDispatchToProps = dispatch => ({ + + onClose() { + dispatch(closeModal()); + }, + +}); + +export default @connect(mapStateToProps, mapDispatchToProps) +class CompareHistoryModal extends React.PureComponent { + + static propTypes = { + onClose: PropTypes.func.isRequired, + index: PropTypes.number.isRequired, + statusId: PropTypes.string.isRequired, + versions: ImmutablePropTypes.list.isRequired, + }; + + render () { + const { index, versions, onClose } = this.props; + const currentVersion = versions.get(index); + + const emojiMap = currentVersion.get('emojis').reduce((obj, emoji) => { + obj[`:${emoji.get('shortcode')}:`] = emoji.toJS(); + return obj; + }, {}); + + const content = { __html: emojify(currentVersion.get('content'), emojiMap) }; + const spoilerContent = { __html: emojify(escapeTextContentForBrowser(currentVersion.get('spoiler_text')), emojiMap) }; + + const formattedDate = <RelativeTimestamp timestamp={currentVersion.get('created_at')} short={false} />; + const formattedName = <InlineAccount accountId={currentVersion.get('account')} />; + + const label = currentVersion.get('original') ? ( + <FormattedMessage id='status.history.created' defaultMessage='{name} created {date}' values={{ name: formattedName, date: formattedDate }} /> + ) : ( + <FormattedMessage id='status.history.edited' defaultMessage='{name} edited {date}' values={{ name: formattedName, date: formattedDate }} /> + ); + + return ( + <div className='modal-root__modal compare-history-modal'> + <div className='report-modal__target'> + <IconButton className='report-modal__close' icon='times' onClick={onClose} size={20} /> + {label} + </div> + + <div className='compare-history-modal__container'> + <div className='status__content'> + {currentVersion.get('spoiler_text').length > 0 && ( + <React.Fragment> + <div className='translate' dangerouslySetInnerHTML={spoilerContent} /> + <hr /> + </React.Fragment> + )} + + <div className='status__content__text status__content__text--visible translate' dangerouslySetInnerHTML={content} /> + </div> + </div> + </div> + ); + } + +} diff --git a/app/javascript/mastodon/features/ui/components/modal_root.js b/app/javascript/mastodon/features/ui/components/modal_root.js index 377cccda5..7b14fe5ca 100644 --- a/app/javascript/mastodon/features/ui/components/modal_root.js +++ b/app/javascript/mastodon/features/ui/components/modal_root.js @@ -19,7 +19,8 @@ import { EmbedModal, ListEditor, ListAdder, -} from '../../../features/ui/util/async-components'; + CompareHistoryModal, +} from 'mastodon/features/ui/util/async-components'; const MODAL_COMPONENTS = { 'MEDIA': () => Promise.resolve({ default: MediaModal }), @@ -34,7 +35,8 @@ const MODAL_COMPONENTS = { 'EMBED': EmbedModal, 'LIST_EDITOR': ListEditor, 'FOCAL_POINT': () => Promise.resolve({ default: FocalPointModal }), - 'LIST_ADDER':ListAdder, + 'LIST_ADDER': ListAdder, + 'COMPARE_HISTORY': CompareHistoryModal, }; export default class ModalRoot extends React.PureComponent { diff --git a/app/javascript/mastodon/features/ui/util/async-components.js b/app/javascript/mastodon/features/ui/util/async-components.js index aa90b226a..5349bd656 100644 --- a/app/javascript/mastodon/features/ui/util/async-components.js +++ b/app/javascript/mastodon/features/ui/util/async-components.js @@ -157,3 +157,7 @@ export function Directory () { export function FollowRecommendations () { return import(/* webpackChunkName: "features/follow_recommendations" */'../../follow_recommendations'); } + +export function CompareHistoryModal () { + return import(/*webpackChunkName: "modals/compare_history_modal" */'../components/compare_history_modal'); +} diff --git a/app/javascript/mastodon/locales/af.json b/app/javascript/mastodon/locales/af.json index eca4765c4..2675da68c 100644 --- a/app/javascript/mastodon/locales/af.json +++ b/app/javascript/mastodon/locales/af.json @@ -47,7 +47,8 @@ "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Show in column", "notifications.column_settings.sound": "Play sound", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "Cancel", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Load more", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index 0992394a2..d244ab5fc 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -33,8 +33,8 @@ "account.mute_notifications": "كَتم الإشعارات من @{name}", "account.muted": "مَكتوم", "account.never_active": "أبدًا", - "account.posts": "تبويقات", - "account.posts_with_replies": "التَّبويقات والرُدود", + "account.posts": "منشورات", + "account.posts_with_replies": "المنشورات والرُدود", "account.report": "الإبلاغ عن @{name}", "account.requested": "في اِنتظر القُبول. اِنقُر لإلغاء طلب المُتابعة", "account.share": "مُشاركة الملف الشخصي لـ @{name}", @@ -46,19 +46,20 @@ "account.unfollow": "إلغاء المُتابعة", "account.unmute": "إلغاء الكَتم عن @{name}", "account.unmute_notifications": "إلغاء كَتم الإشعارات عن @{name}", - "account_note.placeholder": "اِنقُر لإضافة مُلاحظة", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "account_note.placeholder": "اضغط لإضافة مُلاحظة", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "المعدل", + "admin.dashboard.retention.cohort": "شهر التسجيل", + "admin.dashboard.retention.cohort_size": "المستخدمون الجدد", "alert.rate_limited.message": "يُرجى إعادة المحاولة بعد {retry_time, time, medium}.", "alert.rate_limited.title": "المُعَدَّل مَحدود", "alert.unexpected.message": "لقد طرأ خطأ غير متوقّع.", "alert.unexpected.title": "المعذرة!", "announcement.announcement": "إعلان", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(غير معالَج)", "autosuggest_hashtag.per_week": "{count} في الأسبوع", - "boost_modal.combo": "يُمكنك الضّغط على {combo} لتخطي هذا في المرة المُقبِلَة", + "boost_modal.combo": "يُمكنك الضّغط على {combo} لتخطي هذا في المرة المُقبلة", "bundle_column_error.body": "لقد حدث خطأ ما أثناء تحميل هذا العنصر.", "bundle_column_error.retry": "إعادة المُحاولة", "bundle_column_error.title": "خطأ في الشبكة", @@ -66,18 +67,18 @@ "bundle_modal_error.message": "لقد حدث خطأ ما أثناء تحميل هذا العنصر.", "bundle_modal_error.retry": "إعادة المُحاولة", "column.blocks": "المُستَخدِمون المَحظورون", - "column.bookmarks": "العَلاماتُ المَرجعيَّة", - "column.community": "الخَطُّ الزَّمَنِيُّ المَحَلِّيّ", - "column.direct": "الرَّسَائِلُ المُبَاشِرَة", - "column.directory": "تَصَفُّحُ المَلَفَّاتِ الشَّخصِيَّة", + "column.bookmarks": "الفواصل المرجعية", + "column.community": "الخيط الزمني المحلي", + "column.direct": "الرسائل المباشرة", + "column.directory": "تَصَفُّحُ المَلفات الشخصية", "column.domain_blocks": "النِّطاقَاتُ المَحظُورَة", "column.favourites": "المُفَضَّلَة", "column.follow_requests": "طَلَبَاتُ المُتَابَعَة", - "column.home": "الرَّئِيسَة", - "column.lists": "القَوائِم", + "column.home": "الرئيسية", + "column.lists": "القوائم", "column.mutes": "المُستَخدِمون المَكتومون", "column.notifications": "الإشعارَات", - "column.pins": "التَّبويقاتُ المُثَبَّتَة", + "column.pins": "المنشورات المُثَبَّتَة", "column.public": "الخَطُّ الزَّمَنِيُّ المُوَحَّد", "column_back_button.label": "العودة", "column_header.hide_settings": "إخفاء الإعدادات", @@ -86,13 +87,13 @@ "column_header.pin": "تثبيت", "column_header.show_settings": "إظهار الإعدادات", "column_header.unpin": "إلغاء التَّثبيت", - "column_subheading.settings": "الإعدَادَات", + "column_subheading.settings": "الإعدادات", "community.column_settings.local_only": "المحلي فقط", "community.column_settings.media_only": "الوسائط فقط", "community.column_settings.remote_only": "عن بُعد فقط", "compose_form.direct_message_warning": "سوف تُرسَل هذه التَّبويقة فقط للمُستَخدِمين المَذكورين.", "compose_form.direct_message_warning_learn_more": "تَعَلَّم المَزيد", - "compose_form.hashtag_warning": "لن تُدرَج هذه التبويقة تحت أي وسم بما أنَّها غير مُدرَجة. فقط التبويقات العامة يُمكن البحث عنها بواسطة الوسم.", + "compose_form.hashtag_warning": "لن يُدرَج هذا المنشور تحت أي وسم بما أنَّه غير مُدرَج. فقط المنشورات العامة يُمكن البحث عنها بواسطة الوسم.", "compose_form.lock_disclaimer": "حسابُك غير {locked}. يُمكن لأي شخص مُتابعتك لرؤية (منشورات المتابعين فقط).", "compose_form.lock_disclaimer.lock": "مُقفَل", "compose_form.placeholder": "فِيمَ تُفكِّر؟", @@ -104,10 +105,11 @@ "compose_form.poll.switch_to_single": "تغيِير الاستطلاع للسماح باِخيار واحد فقط", "compose_form.publish": "تبويق", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {الإشارة إلى الوَسط كمُحتوى حسّاس} two{الإشارة إلى الوسطان كمُحتويان حسّاسان} other {الإشارة إلى الوسائط كمُحتويات حسّاسة}}", "compose_form.sensitive.marked": "{count, plural, one {تمَّ الإشارة إلى الوسط كمُحتوى حسّاس} two{تمَّ الإشارة إلى الوسطان كمُحتويان حسّاسان} other {تمَّ الإشارة إلى الوسائط كمُحتويات حسّاسة}}", "compose_form.sensitive.unmarked": "{count, plural, one {لم تَتِمّ الإشارة إلى الوسط كمُحتوى حسّاس} two{لم تَتِمّ الإشارة إلى الوسطان كمُحتويان حسّاسان} other {لم تَتِمّ الإشارة إلى الوسائط كمُحتويات حسّاسة}}", - "compose_form.spoiler.marked": "إنّ النص مخفي وراء تحذير", + "compose_form.spoiler.marked": "إزالة تحذير المحتوى", "compose_form.spoiler.unmarked": "إنَّ النص غير مخفي", "compose_form.spoiler_placeholder": "اُكتُب تحذيركَ هُنا", "confirmation_modal.cancel": "إلغاء", @@ -118,8 +120,8 @@ "confirmations.delete.message": "هل أنتَ مُتأكدٌ أنك تُريدُ حَذفَ هذا المنشور؟", "confirmations.delete_list.confirm": "حذف", "confirmations.delete_list.message": "هل أنتَ مُتأكدٌ أنكَ تُريدُ حَذفَ هذِهِ القائمةَ بشكلٍ دائم؟", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "تجاهل", + "confirmations.discard_edit_media.message": "لديك تغييرات غير محفوظة لوصف الوسائط أو معاينتها، تجاهلها على أي حال؟", "confirmations.domain_block.confirm": "حظر اِسم النِّطاق بشكلٍ كامل", "confirmations.domain_block.message": "متأكد من أنك تود حظر اسم النطاق {domain} بالكامل ؟ في غالب الأحيان يُستَحسَن كتم أو حظر بعض الحسابات بدلا من حظر نطاق بالكامل.\nلن تتمكن مِن رؤية محتوى هذا النطاق لا على خيوطك العمومية و لا في إشعاراتك. سوف يتم كذلك إزالة كافة متابعيك المنتمين إلى هذا النطاق.", "confirmations.logout.confirm": "خروج", @@ -158,21 +160,21 @@ "emoji_button.symbols": "رموز", "emoji_button.travel": "الأماكن والسفر", "empty_column.account_suspended": "حساب معلق", - "empty_column.account_timeline": "ليس هناك تبويقات!", + "empty_column.account_timeline": "لا توجد منشورات هنا!", "empty_column.account_unavailable": "الملف التعريفي غير متوفر", "empty_column.blocks": "لم تقم بحظر أي مستخدِم بعد.", - "empty_column.bookmarked_statuses": "ليس لديك أية تبويقات في الفواصل المرجعية بعد. عندما ستقوم بإضافة البعض منها، ستظهر هنا.", + "empty_column.bookmarked_statuses": "ليس لديك أية منشورات في الفواصل المرجعية بعد. عندما ستقوم بإضافة البعض منها، ستظهر هنا.", "empty_column.community": "الخط العام المحلي فارغ. أكتب شيئا ما للعامة كبداية!", "empty_column.direct": "لم تتلق أية رسالة خاصة مباشِرة بعد. سوف يتم عرض الرسائل المباشرة هنا إن قمت بإرسال واحدة أو تلقيت البعض منها.", "empty_column.domain_blocks": "ليس هناك نطاقات مخفية بعد.", - "empty_column.favourited_statuses": "ليس لديك أية تبويقات مفضلة بعد. عندما ستقوم بالإعجاب بواحد، سيظهر هنا.", - "empty_column.favourites": "لم يقم أي أحد بالإعجاب بهذا التبويق بعد. عندما يقوم أحدهم بذلك سوف يظهر هنا.", + "empty_column.favourited_statuses": "ليس لديك أية منشورات مفضلة بعد. عندما ستقوم بالإعجاب بواحدة، ستظهر هنا.", + "empty_column.favourites": "لم يقم أي أحد بالإعجاب بهذا المنشور بعد. عندما يقوم أحدهم بذلك سوف يظهر هنا.", "empty_column.follow_recommendations": "يبدو أنه لا يمكن إنشاء أي اقتراحات لك. يمكنك البحث عن أشخاص قد تعرفهم أو استكشاف الوسوم الرائجة.", "empty_column.follow_requests": "ليس عندك أي طلب للمتابعة بعد. سوف تظهر طلباتك هنا إن قمت بتلقي البعض منها.", "empty_column.hashtag": "ليس هناك بعدُ أي محتوى ذو علاقة بهذا الوسم.", "empty_column.home": "إنّ الخيط الزمني لصفحتك الرئيسية فارغ. قم بزيارة {public} أو استخدم حقل البحث لكي تكتشف مستخدمين آخرين.", "empty_column.home.suggestions": "شاهد بعض الاقتراحات", - "empty_column.list": "هذه القائمة فارغة مؤقتا و لكن سوف تمتلئ تدريجيا عندما يبدأ الأعضاء المُنتَمين إليها بنشر تبويقات.", + "empty_column.list": "هذه القائمة فارغة مؤقتا و لكن سوف تمتلئ تدريجيا عندما يبدأ الأعضاء المُنتَمين إليها بنشر منشورات.", "empty_column.lists": "ليس عندك أية قائمة بعد. سوف تظهر قائمتك هنا إن قمت بإنشاء واحدة.", "empty_column.mutes": "لم تقم بكتم أي مستخدم بعد.", "empty_column.notifications": "لم تتلق أي إشعار بعدُ. تفاعل مع المستخدمين الآخرين لإنشاء محادثة.", @@ -185,7 +187,7 @@ "errors.unexpected_crash.report_issue": "الإبلاغ عن خلل", "follow_recommendations.done": "تم", "follow_recommendations.heading": "تابع الأشخاص الذين ترغب في رؤية منشوراتهم! إليك بعض الاقتراحات.", - "follow_recommendations.lead": "ستظهر المنشورات من الأشخاص الذين تُتابعتهم بترتيب تسلسلي زمني على صفحتك الرئيسية. لا تخف إذا ارتكبت أي أخطاء، تستطيع إلغاء متابعة أي شخص في أي وقت تريد!", + "follow_recommendations.lead": "ستظهر منشورات الأشخاص الذين تُتابعتهم بترتيب تسلسلي زمني على صفحتك الرئيسية. لا تخف إذا ارتكبت أي أخطاء، تستطيع إلغاء متابعة أي شخص في أي وقت تريد!", "follow_request.authorize": "ترخيص", "follow_request.reject": "رفض", "follow_requests.unlocked_explanation": "على الرغم من أن حسابك غير مقفل، فإن موظفين الـ{domain} ظنوا أنك قد ترغب في مراجعة طلبات المتابعة من هذه الحسابات يدوياً.", @@ -237,7 +239,7 @@ "keyboard_shortcuts.my_profile": "لفتح ملفك التعريفي", "keyboard_shortcuts.notifications": "لفتح عمود الإشعارات", "keyboard_shortcuts.open_media": "لفتح الوسائط", - "keyboard_shortcuts.pinned": "لفتح قائمة التبويقات المدبسة", + "keyboard_shortcuts.pinned": "لفتح قائمة المنشورات المثبتة", "keyboard_shortcuts.profile": "لفتح الملف التعريفي للناشر", "keyboard_shortcuts.reply": "للردّ", "keyboard_shortcuts.requests": "لفتح قائمة طلبات المتابعة", @@ -294,7 +296,7 @@ "navigation_bar.logout": "خروج", "navigation_bar.mutes": "الحسابات المكتومة", "navigation_bar.personal": "شخصي", - "navigation_bar.pins": "التبويقات المثبتة", + "navigation_bar.pins": "المنشورات المُثَبَّتَة", "navigation_bar.preferences": "التفضيلات", "navigation_bar.public_timeline": "الخيط العام الموحد", "navigation_bar.security": "الأمان", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "المُفَضَّلة:", "notifications.column_settings.filter_bar.advanced": "اعرض كافة الفئات", "notifications.column_settings.filter_bar.category": "شريط الفلترة السريعة", - "notifications.column_settings.filter_bar.show": "اظهِره", + "notifications.column_settings.filter_bar.show_bar": "إظهار شريط التصفية", "notifications.column_settings.follow": "متابعُون جُدُد:", "notifications.column_settings.follow_request": "الطلبات الجديد لِمتابَعتك:", "notifications.column_settings.mention": "الإشارات:", @@ -321,8 +323,9 @@ "notifications.column_settings.reblog": "الترقيّات:", "notifications.column_settings.show": "اعرِضها في عمود", "notifications.column_settings.sound": "أصدر صوتا", - "notifications.column_settings.status": "تبويقات جديدة:", - "notifications.column_settings.unread_markers.category": "علامات إشعار غير مقروءة", + "notifications.column_settings.status": "منشورات جديدة:", + "notifications.column_settings.unread_notifications.category": "إشعارات غير مقروءة", + "notifications.column_settings.unread_notifications.highlight": "علّم الإشعارات غير المقرؤة", "notifications.filter.all": "الكل", "notifications.filter.boosts": "الترقيات", "notifications.filter.favourites": "المفضلة", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# صوت} other {# أصوات}}", "poll.vote": "صَوّت", "poll.voted": "لقد صوّتت على هذه الإجابة", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# صوت} other {# أصوات}}", "poll_button.add_poll": "إضافة استطلاع للرأي", "poll_button.remove_poll": "إزالة استطلاع الرأي", "privacy.change": "اضبط خصوصية المنشور", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "جارٍ التحميل…", "regeneration_indicator.sublabel": "جارٍ تجهيز تغذية صفحتك الرئيسية!", "relative_time.days": "{number}ي", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}سا", "relative_time.just_now": "الآن", "relative_time.minutes": "{number}د", "relative_time.seconds": "{number}ثا", "relative_time.today": "اليوم", "reply_indicator.cancel": "إلغاء", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "التحويل إلى {target}", "report.forward_hint": "هذا الحساب ينتمي إلى خادوم آخَر. هل تودّ إرسال نسخة مجهولة مِن التقرير إلى هنالك أيضًا؟", "report.hint": "سوف يتم إرسال التقرير إلى المُشرِفين على خادومكم. بإمكانكم الإدلاء بشرح عن سبب الإبلاغ عن الحساب أسفله:", @@ -383,8 +394,8 @@ "search_popout.tips.user": "مستخدِم", "search_results.accounts": "أشخاص", "search_results.hashtags": "الوُسوم", - "search_results.statuses": "التبويقات", - "search_results.statuses_fts_disabled": "البحث في التبويقات عن طريق المحتوى ليس مفعل في خادم ماستدون هذا.", + "search_results.statuses": "المنشورات", + "search_results.statuses_fts_disabled": "البحث عن المنشورات عن طريق المحتوى ليس مفعل في خادم ماستدون هذا.", "search_results.total": "{count, number} {count, plural, zero {} one {نتيجة} two {نتيجتين} few {نتائج} many {نتائج} other {نتائج}}", "status.admin_account": "افتح الواجهة الإدارية لـ @{name}", "status.admin_status": "افتح هذا المنشور على واجهة الإشراف", @@ -396,9 +407,14 @@ "status.delete": "احذف", "status.detailed_status": "تفاصيل المحادثة", "status.direct": "رسالة خاصة إلى @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "إدماج", "status.favourite": "أضف إلى المفضلة", "status.filtered": "مُصفّى", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "حمّل المزيد", "status.media_hidden": "الصورة مستترة", "status.mention": "أذكُر @{name}", @@ -443,7 +459,7 @@ "timeline_hint.remote_resource_not_displayed": "{resource} من الخوادم الأخرى لا يتم عرضها.", "timeline_hint.resources.followers": "المتابِعون", "timeline_hint.resources.follows": "المتابَعون", - "timeline_hint.resources.statuses": "التبويقات القديمة", + "timeline_hint.resources.statuses": "المنشورات القديمة", "trends.counter_by_accounts": "{count,plural,zero{} one{{counter} شخص} two{{counter} شخصين} few{{counter} أشخاص } many{{counter} شخص} other{{counter} شخص}}", "trends.trending_now": "المتداولة الآن", "ui.beforeunload": "سوف تفقد مسودتك إن تركت ماستدون.", @@ -462,7 +478,7 @@ "upload_form.video_description": "وصف للمعاقين بصريا أو لِذي قِصر السمع", "upload_modal.analyzing_picture": "جارٍ فحص الصورة…", "upload_modal.apply": "طبّق", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "جارٍ التطبيق…", "upload_modal.choose_image": "اختر صورة", "upload_modal.description_placeholder": "نصٌّ حكيمٌ لهُ سِرٌّ قاطِعٌ وَذُو شَأنٍ عَظيمٍ مكتوبٌ على ثوبٍ أخضرَ ومُغلفٌ بجلدٍ أزرق", "upload_modal.detect_text": "اكتشف النص مِن الصورة", diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json index 89a13246c..d4c4f84b0 100644 --- a/app/javascript/mastodon/locales/ast.json +++ b/app/javascript/mastodon/locales/ast.json @@ -47,16 +47,17 @@ "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", - "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "admin.dashboard.retention.cohort_size": "Usuarios nuevos", + "alert.rate_limited.message": "Volvi tentalo dempués de la hora: {retry_time, time, medium}.", "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Asocedió un fallu inesperáu.", "alert.unexpected.title": "¡Meca!", "announcement.announcement": "Anunciu", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(ensin procesar)", "autosuggest_hashtag.per_week": "{count} per selmana", "boost_modal.combo": "Pues primir {combo} pa saltar esto la próxima vegada", "bundle_column_error.body": "Asocedió daqué malo mentanto se cargaba esti componente.", @@ -91,7 +92,7 @@ "community.column_settings.media_only": "Namái multimedia", "community.column_settings.remote_only": "Remote only", "compose_form.direct_message_warning": "Esti barritu namái va unviase a los usuarios mentaos.", - "compose_form.direct_message_warning_learn_more": "Learn more", + "compose_form.direct_message_warning_learn_more": "Saber más", "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.", "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.", "compose_form.lock_disclaimer.lock": "locked", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Barritar", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -163,7 +165,7 @@ "empty_column.blocks": "Entá nun bloquiesti a nunengún usuariu.", "empty_column.bookmarked_statuses": "Entá nun tienes nengún barritu en Marcadores. Cuando amiestes unu, va amosase equí.", "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!", - "empty_column.direct": "Entá nun tienes nunengún mensaxe direutu. Cuando unvies o recibas dalgún, va apaecer equí.", + "empty_column.direct": "Entá nun tienes nuengún mensaxe direutu. Cuando unvies o recibas dalgún, va apaecer equí.", "empty_column.domain_blocks": "Entá nun hai dominios anubríos.", "empty_column.favourited_statuses": "Entá nun tienes nengún barritu en Favoritos. Cuando amiestes unu, va amosase equí.", "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.", @@ -177,7 +179,7 @@ "empty_column.mutes": "Entá nun silenciesti a nunengún usuariu.", "empty_column.notifications": "Entá nun tienes nunengún avisu. Interactúa con otros p'aniciar la conversación.", "empty_column.public": "¡Equí nun hai nada! Escribi daqué público o sigui a usuarios d'otros sirvidores pa rellenar esto", - "error.unexpected_crash.explanation": "Pola mor d'un fallu nel códigu o un problema de compatibilidá del restolador, esta páxina nun pudo amosase correutamente.", + "error.unexpected_crash.explanation": "Pola mor d'un fallu nel códigu o un problema de compatibilidá del restolador, esta páxina nun se pudo amosar correutamente.", "error.unexpected_crash.explanation_addons": "This page could not be displayed correctly. This error is likely caused by a browser add-on or automatic translation tools.", "error.unexpected_crash.next_steps": "Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favoritos:", "notifications.column_settings.filter_bar.advanced": "Amosar toles estayes", "notifications.column_settings.filter_bar.category": "Barra de peñera rápida", - "notifications.column_settings.filter_bar.show": "Amosar", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Siguidores nuevos:", "notifications.column_settings.follow_request": "Solicitúes de siguimientu nueves:", "notifications.column_settings.mention": "Menciones:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Amosar en columna", "notifications.column_settings.sound": "Reproducir un soníu", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Too", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -336,8 +339,8 @@ "notifications.permission_denied": "Desktop notifications are unavailable due to previously denied browser permissions request", "notifications.permission_denied_alert": "Desktop notifications can't be enabled, as browser permission has been denied before", "notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.", - "notifications_permission_banner.enable": "Enable desktop notifications", - "notifications_permission_banner.how_to_control": "To receive notifications when Mastodon isn't open, enable desktop notifications. You can control precisely which types of interactions generate desktop notifications through the {icon} button above once they're enabled.", + "notifications_permission_banner.enable": "Activar los avisos d'escritoriu", + "notifications_permission_banner.how_to_control": "Pa recibir avisos cuando Mastodon nun tea abiertu, activa los avisos del escritoriu. Pues controlar al milímetru qué tipu d'interaiciones xeneren avisos namás que s'activen, pente'l botón {icon} d'arriba.", "notifications_permission_banner.title": "Never miss a thing", "picture_in_picture.restore": "Put it back", "poll.closed": "Acabó", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Cargando…", "regeneration_indicator.sublabel": "¡Tamos tresnando'l feed d'Aniciu!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "agora", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "güei", "reply_indicator.cancel": "Encaboxar", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "L'informe va unviase a los llendadores del to sirvidor. Embaxo, pues desplicar por qué informes d'esta cuenta:", @@ -396,9 +407,14 @@ "status.delete": "Desaniciar", "status.detailed_status": "Detailed conversation view", "status.direct": "Unviar un mensaxe direutu a @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Empotrar", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Cargar más", "status.media_hidden": "Multimedia anubrida", "status.mention": "Mentar a @{name}", @@ -408,7 +424,7 @@ "status.open": "Espander esti estáu", "status.pin": "Fixar nel perfil", "status.pinned": "Barritu fixáu", - "status.read_more": "Read more", + "status.read_more": "Lleer más", "status.reblog": "Compartir", "status.reblog_private": "Compartir cola audiencia orixinal", "status.reblogged_by": "{name} compartió", @@ -437,7 +453,7 @@ "tabs_bar.search": "Search", "time_remaining.days": "{number, plural, one {Queda # día} other {Queden # díes}}", "time_remaining.hours": "{number, plural, one {# hora restante} other {# hores restantes}}", - "time_remaining.minutes": "{number, plural, one {# minutu restante} other {# minutos restantes}}", + "time_remaining.minutes": "{number, plural, one {Queda # minutu} other {Queden # minutos}}", "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# segundu restante} other {# segundos restantes}}", "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.", @@ -465,7 +481,7 @@ "upload_modal.applying": "Applying…", "upload_modal.choose_image": "Choose image", "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Deteutar el testu de la semeya", + "upload_modal.detect_text": "Detectar el testu de la semeya", "upload_modal.edit_media": "Edición", "upload_modal.hint": "Calca o arrastra'l círculu de la previsualización pa escoyer el puntu d'enfoque que va amosase siempres en toles miniatures.", "upload_modal.preparing_ocr": "Preparing OCR…", @@ -477,8 +493,8 @@ "video.expand": "Espander el videu", "video.fullscreen": "Pantalla completa", "video.hide": "Anubrir el videu", - "video.mute": "Silenciar el soníu", + "video.mute": "Desactivar el soníu", "video.pause": "Posar", "video.play": "Reproducir", - "video.unmute": "Unmute sound" + "video.unmute": "Activar el soníu" } diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index 8e3848f54..02e37c4c7 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.json @@ -47,7 +47,8 @@ "account.unmute": "Раззаглушаване на @{name}", "account.unmute_notifications": "Раззаглушаване на известия от @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Промяна на анкетата, за да се позволи един възможен избор", "compose_form.publish": "Раздумай", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Маркиране на мултимедията като деликатна} other {Маркиране на мултимедиите като деликатни}}", "compose_form.sensitive.marked": "{count, plural, one {Мултимедията е маркирана като деликатна} other {Мултимедиите са маркирани като деликатни}}", "compose_form.sensitive.unmarked": "{count, plural, one {Мултимедията не е маркирана като деликатна} other {Мултимедиите не са маркирани като деликатни}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Предпочитани:", "notifications.column_settings.filter_bar.advanced": "Показване на всички категории", "notifications.column_settings.filter_bar.category": "Лента за бърз филтър", - "notifications.column_settings.filter_bar.show": "Показване", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Нови последователи:", "notifications.column_settings.follow_request": "Нови заявки за последване:", "notifications.column_settings.mention": "Споменавания:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Покажи в колона", "notifications.column_settings.sound": "Пускане на звук", "notifications.column_settings.status": "Нови публикации:", - "notifications.column_settings.unread_markers.category": "отметки за непрочетени известия", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Всичко", "notifications.filter.boosts": "Споделяния", "notifications.filter.favourites": "Любими", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Зареждане…", "regeneration_indicator.sublabel": "Вашата начална емисия се подготвя!", "relative_time.days": "{number}д", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}ч", "relative_time.just_now": "сега", "relative_time.minutes": "{number}м", "relative_time.seconds": "{number}с", "relative_time.today": "днес", "reply_indicator.cancel": "Отказ", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Препращане към {target}", "report.forward_hint": "Акаунтът е от друг сървър. Изпращане на анонимно копие на доклада и там?", "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Изтриване", "status.detailed_status": "Подробен изглед на разговор", "status.direct": "Директно съобщение към @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Вграждане", "status.favourite": "Предпочитани", "status.filtered": "Филтрирано", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Зареждане на още", "status.media_hidden": "Мултимедията е скрита", "status.mention": "Споменаване", diff --git a/app/javascript/mastodon/locales/bn.json b/app/javascript/mastodon/locales/bn.json index f28e8b110..ec034b002 100644 --- a/app/javascript/mastodon/locales/bn.json +++ b/app/javascript/mastodon/locales/bn.json @@ -47,7 +47,8 @@ "account.unmute": "@{name} র কার্যকলাপ আবার দেখুন", "account.unmute_notifications": "@{name} র প্রজ্ঞাপন দেখুন", "account_note.placeholder": "নোট যোগ করতে ক্লিক করুন", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "একটি একক পছন্দের অনুমতি দেওয়ার জন্য পোল পরিবর্তন করুন", "compose_form.publish": "টুট", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "এই ছবি বা ভিডিওটি সংবেদনশীল হিসেবে চিহ্নিত করতে", "compose_form.sensitive.marked": "এই ছবি বা ভিডিওটি সংবেদনশীল হিসেবে চিহ্নিত করা হয়েছে", "compose_form.sensitive.unmarked": "এই ছবি বা ভিডিওটি সংবেদনশীল হিসেবে চিহ্নিত করা হয়নি", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "পছন্দের:", "notifications.column_settings.filter_bar.advanced": "সব শ্রেণীগুলো দেখানো", "notifications.column_settings.filter_bar.category": "সংক্ষিপ্ত ছাঁকনি অংশ", - "notifications.column_settings.filter_bar.show": "দেখানো", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "নতুন অনুসরণকারীরা:", "notifications.column_settings.follow_request": "অনুসরণের অনুরোধগুলি:", "notifications.column_settings.mention": "প্রজ্ঞাপনগুলো:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "কলামে দেখানো", "notifications.column_settings.sound": "শব্দ বাজানো", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "সব", "notifications.filter.boosts": "সমর্থনগুলো", "notifications.filter.favourites": "পছন্দের গুলো", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "আসছে…", "regeneration_indicator.sublabel": "আপনার বাড়ির-সময়রেখা প্রস্তূত করা হচ্ছে!", "relative_time.days": "{number} দিন", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number} ঘন্টা", "relative_time.just_now": "এখন", "relative_time.minutes": "{number}মিঃ", "relative_time.seconds": "{number} সেকেন্ড", "relative_time.today": "আজ", "reply_indicator.cancel": "বাতিল করতে", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "এটা আরো পাঠান {target} তে", "report.forward_hint": "এই নিবন্ধনটি অন্য একটি সার্ভারে। অপ্রকাশিতনামাভাবে রিপোর্টের কপি সেখানেও কি পাঠাতে চান ?", "report.hint": "রিপোর্টটি আপনার সার্ভারের পরিচালকের কাছে পাঠানো হবে। রিপোর্ট পাঠানোর কারণ নিচে বিস্তারিত লিখতে পারেন:", @@ -396,9 +407,14 @@ "status.delete": "মুছে ফেলতে", "status.detailed_status": "বিস্তারিত কথোপকথনের হিসেবে দেখতে", "status.direct": "@{name} কে সরাসরি লেখা পাঠাতে", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "এমবেড করতে", "status.favourite": "পছন্দের করতে", "status.filtered": "ছাঁকনিদিত", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "আরো দেখুন", "status.media_hidden": "মিডিয়া লুকানো আছে", "status.mention": "@{name}কে উল্লেখ করতে", diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json index 06fc32095..f13b7dfd7 100644 --- a/app/javascript/mastodon/locales/br.json +++ b/app/javascript/mastodon/locales/br.json @@ -6,9 +6,9 @@ "account.block": "Berzañ @{name}", "account.block_domain": "Berzañ pep tra eus {domain}", "account.blocked": "Stanket", - "account.browse_more_on_origin_server": "Browse more on the original profile", + "account.browse_more_on_origin_server": "Furchal muioc'h war ar profil kentañ", "account.cancel_follow_request": "Nullañ ar bedadenn heuliañ", - "account.direct": "Kas ur gemennadenn da @{name}", + "account.direct": "Kas ur gemennadenn prevez da @{name}", "account.disable_notifications": "Paouez d'am c'hemenn pa vez toudet gant @{name}", "account.domain_blocked": "Domani berzet", "account.edit_profile": "Aozañ ar profil", @@ -25,7 +25,7 @@ "account.joined": "Amañ abaoe {date}", "account.last_status": "Oberiantiz zivezhañ", "account.link_verified_on": "Gwiriet eo bet perc'hennidigezh al liamm d'an deiziad-mañ : {date}", - "account.locked_info": "Prennet eo ar gon-mañ. Dibab a ra ar perc'henn ar re a c'hall heuliañ anezhi pe anezhañ.", + "account.locked_info": "Prennet eo ar gont-mañ. Dibab a ra ar perc'henn ar re a c'hall heuliañ anezhi pe anezhañ.", "account.media": "Media", "account.mention": "Menegiñ @{name}", "account.moved_to": "Dilojet en·he deus {name} da :", @@ -39,7 +39,7 @@ "account.requested": "O c'hortoz an asant. Klikit evit nullañ ar goulenn heuliañ", "account.share": "Skignañ profil @{name}", "account.show_reblogs": "Diskouez skignadennoù @{name}", - "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}", + "account.statuses_counter": "{count, plural, one {{counter} Toud} other {{counter} Toud}}", "account.unblock": "Diverzañ @{name}", "account.unblock_domain": "Diverzañ an domani {domain}", "account.unendorse": "Paouez da lakaat war-wel war ar profil", @@ -47,16 +47,17 @@ "account.unmute": "Diguzhat @{name}", "account.unmute_notifications": "Diguzhat kemennoù a @{name}", "account_note.placeholder": "Klikit evit ouzhpenniñ un notenn", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Keidenn", + "admin.dashboard.retention.cohort": "Miz an enrolladur", + "admin.dashboard.retention.cohort_size": "Implijerien.erezed nevez", "alert.rate_limited.message": "Klaskit en-dro a-benn {retry_time, time, medium}.", "alert.rate_limited.title": "Feur bevennet", "alert.unexpected.message": "Ur fazi dic'hortozet zo degouezhet.", "alert.unexpected.title": "Hopala!", "announcement.announcement": "Kemenn", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(ket meret)", "autosuggest_hashtag.per_week": "{count} bep sizhun", "boost_modal.combo": "Ar wezh kentañ e c'halliot gwaskañ war {combo} evit tremen hebiou", "bundle_column_error.body": "Degouezhet ez eus bet ur fazi en ur gargañ an elfenn-mañ.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Kemmañ ar sontadeg evit aotren un dibab hepken", "compose_form.publish": "Toudañ", "compose_form.publish_loud": "{publish} !", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Merkañ ar media evel kizidik", "compose_form.sensitive.marked": "Merket eo ar media evel kizidik", "compose_form.sensitive.unmarked": "N'eo ket merket ar media evel kizidik", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Ha sur oc'h e fell deoc'h dilemel an toud-mañ ?", "confirmations.delete_list.confirm": "Dilemel", "confirmations.delete_list.message": "Ha sur eo hoc'h eus c'hoant da zilemel ar roll-mañ da vat ?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Nac'hañ", + "confirmations.discard_edit_media.message": "Bez ez eus kemmoù n'int ket enrollet e deskrivadur ar media pe ar rakwel, nullañ anezho evelato?", "confirmations.domain_block.confirm": "Berzañ an domani a-bezh", "confirmations.domain_block.message": "Ha sur oc'h e fell deoc'h berzañ an {domain} a-bezh? Peurvuiañ eo trawalc'h berzañ pe mudañ un nebeud implijer·ezed·ien. Ne welot danvez ebet o tont eus an domani-mañ. Dilamet e vo ar c'houmanantoù war an domani-mañ.", "confirmations.logout.confirm": "Digevreañ", @@ -157,7 +159,7 @@ "emoji_button.search_results": "Disoc'hoù an enklask", "emoji_button.symbols": "Arouezioù", "emoji_button.travel": "Lec'hioù ha Beajoù", - "empty_column.account_suspended": "Account suspended", + "empty_column.account_suspended": "Kont ehanet", "empty_column.account_timeline": "Toud ebet amañ!", "empty_column.account_unavailable": "Profil dihegerz", "empty_column.blocks": "N'eus ket bet berzet implijer·ez ganeoc'h c'hoazh.", @@ -167,28 +169,28 @@ "empty_column.domain_blocks": "N'eus domani kuzh ebet c'hoazh.", "empty_column.favourited_statuses": "N'ho peus toud muiañ-karet ebet c'hoazh. Pa vo lakaet unan ganeoc'h e vo diskouezet amañ.", "empty_column.favourites": "Den ebet n'eus lakaet an toud-mañ en e reoù muiañ-karet. Pa vo graet gant unan bennak e vo diskouezet amañ.", - "empty_column.follow_recommendations": "Looks like no suggestions could be generated for you. You can try using search to look for people you might know or explore trending hashtags.", + "empty_column.follow_recommendations": "Seblant a ra ne vez ket genelet damvenegoù evidoc'h. Gallout a rit implijout un enklask evit klask tud hag a vefe anavezet ganeoc'h pe ergerzhout gerioù-klik diouzh ar c'hiz.", "empty_column.follow_requests": "N'ho peus goulenn heuliañ ebet c'hoazh. Pa resevot reoù e vo diskouezet amañ.", "empty_column.hashtag": "N'eus netra er ger-klik-mañ c'hoazh.", "empty_column.home": "Goullo eo ho red-amzer degemer! Kit da weladenniñ {public} pe implijit ar c'hlask evit kregiñ ganti ha kejañ gant implijer·ien·ezed all.", - "empty_column.home.suggestions": "See some suggestions", + "empty_column.home.suggestions": "Gwellout damvenegoù", "empty_column.list": "Goullo eo ar roll-mañ evit ar poent. Pa vo toudet gant e izili e vo diskouezet amañ.", "empty_column.lists": "N'ho peus roll ebet c'hoazh. Pa vo krouet unan ganeoc'h e vo diskouezet amañ.", "empty_column.mutes": "N'ho peus kuzhet implijer ebet c'hoazh.", "empty_column.notifications": "N'ho peus kemenn ebet c'hoazh. Grit gant implijer·ezed·ien all evit loc'hañ ar gomz.", "empty_column.public": "N'eus netra amañ! Skrivit un dra bennak foran pe heuilhit implijer·ien·ezed eus dafariadoù all evit leuniañ", "error.unexpected_crash.explanation": "Abalamour d'ur beug en hor c'hod pe d'ur gudenn geverlec'hded n'hallomp ket skrammañ ar bajenn-mañ en un doare dereat.", - "error.unexpected_crash.explanation_addons": "This page could not be displayed correctly. This error is likely caused by a browser add-on or automatic translation tools.", + "error.unexpected_crash.explanation_addons": "Ar bajenn-mañ ne c'hell ket bezañ skrammet mat. Ar fazi-se a zo kaoz d'un astenn pe d'un ostilh troidigezh emgefreek war ho merdeer.", "error.unexpected_crash.next_steps": "Klaskit azbevaat ar bajenn. Ma n'a ket en-dro e c'hallit klask ober gant Mastodon dre ur merdeer disheñvel pe dre an arload genidik.", - "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", + "error.unexpected_crash.next_steps_addons": "Klaskit azbevaat ar bajenn. Ma n'ez a ket en-dro e c'hallit klask ober gant Mastodon dre ur merdeer disheñvel pe dre an arload genidik.", "errors.unexpected_crash.copy_stacktrace": "Eilañ ar roudoù diveugañ er golver", "errors.unexpected_crash.report_issue": "Danevellañ ur fazi", "follow_recommendations.done": "Graet", - "follow_recommendations.heading": "Follow people you'd like to see posts from! Here are some suggestions.", - "follow_recommendations.lead": "Posts from people you follow will show up in chronological order on your home feed. Don't be afraid to make mistakes, you can unfollow people just as easily any time!", + "follow_recommendations.heading": "Heuliit tud e plijfe deoc'h lenn toudoù! Setu un tamm alioù.", + "follow_recommendations.lead": "Toudoù eus tud heuliet ganeoc'h a zeuio war wel en un urzh amzeroniezhel war ho red degemer. N'ho peus ket aon ober fazioù, gallout a rit paouez heuliañ tud ken aes n'eus forzh pegoulz!", "follow_request.authorize": "Aotren", "follow_request.reject": "Nac'hañ", - "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.", + "follow_requests.unlocked_explanation": "Daoust ma n'eo ket ho kont prennet, skipailh {domain} a soñj e fellfe deoc'h gwiriekaat pedadennoù heuliañ deus ar c'hontoù-se diwar-zorn.", "generic.saved": "Enrollet", "getting_started.developers": "Diorroerien", "getting_started.directory": "Roll ar profiloù", @@ -215,43 +217,43 @@ "intervals.full.days": "{number, plural, one {# devezh} other{# a zevezhioù}}", "intervals.full.hours": "{number, plural, one {# eurvezh} other{# eurvezh}}", "intervals.full.minutes": "{number, plural, one {# munut} other{# a vunutoù}}", - "keyboard_shortcuts.back": "to navigate back", - "keyboard_shortcuts.blocked": "to open blocked users list", + "keyboard_shortcuts.back": "Distreiñ", + "keyboard_shortcuts.blocked": "Digeriñ roll an implijer.ezed.rien stanket", "keyboard_shortcuts.boost": "da skignañ", - "keyboard_shortcuts.column": "to focus a status in one of the columns", - "keyboard_shortcuts.compose": "to focus the compose textarea", + "keyboard_shortcuts.column": "Fokus ar bann", + "keyboard_shortcuts.compose": "Fokus an takad testenn", "keyboard_shortcuts.description": "Deskrivadur", - "keyboard_shortcuts.direct": "to open direct messages column", - "keyboard_shortcuts.down": "to move down in the list", + "keyboard_shortcuts.direct": "Digeriñ bann ar c'hemennadennoù prevez", + "keyboard_shortcuts.down": "Diskennañ er roll", "keyboard_shortcuts.enter": "evit digeriñ un toud", - "keyboard_shortcuts.favourite": "to favourite", - "keyboard_shortcuts.favourites": "to open favourites list", - "keyboard_shortcuts.federated": "to open federated timeline", - "keyboard_shortcuts.heading": "Keyboard Shortcuts", - "keyboard_shortcuts.home": "to open home timeline", + "keyboard_shortcuts.favourite": "Lakaat an toud evel muiañ-karet", + "keyboard_shortcuts.favourites": "Digeriñ roll an toudoù muiañ-karet", + "keyboard_shortcuts.federated": "Digeriñ ar red-amzer kevreet", + "keyboard_shortcuts.heading": "Berradennoù klavier", + "keyboard_shortcuts.home": "Digeriñ ho red-amzer degemer", "keyboard_shortcuts.hotkey": "Berradur", - "keyboard_shortcuts.legend": "to display this legend", - "keyboard_shortcuts.local": "to open local timeline", - "keyboard_shortcuts.mention": "to mention author", - "keyboard_shortcuts.muted": "to open muted users list", - "keyboard_shortcuts.my_profile": "to open your profile", - "keyboard_shortcuts.notifications": "to open notifications column", - "keyboard_shortcuts.open_media": "to open media", - "keyboard_shortcuts.pinned": "to open pinned toots list", - "keyboard_shortcuts.profile": "to open author's profile", + "keyboard_shortcuts.legend": "Skrammañ ar skrid-se", + "keyboard_shortcuts.local": "Digeriñ red-amzer lec'hel", + "keyboard_shortcuts.mention": "Menegiñ an aozer.ez", + "keyboard_shortcuts.muted": "Digeriñ roll an implijer.ezed.ien kuzhet", + "keyboard_shortcuts.my_profile": "Digeriñ ho profil", + "keyboard_shortcuts.notifications": "Digeriñ bann kemennoù", + "keyboard_shortcuts.open_media": "Digeriñ ar media", + "keyboard_shortcuts.pinned": "Digeriñ roll an toudoù spilhennet", + "keyboard_shortcuts.profile": "Digeriñ profil an aozer.ez", "keyboard_shortcuts.reply": "da respont", - "keyboard_shortcuts.requests": "to open follow requests list", - "keyboard_shortcuts.search": "to focus search", - "keyboard_shortcuts.spoilers": "to show/hide CW field", - "keyboard_shortcuts.start": "to open \"get started\" column", - "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW", + "keyboard_shortcuts.requests": "Digeriñ roll goulennoù heuliañ", + "keyboard_shortcuts.search": "Fokus barenn klask", + "keyboard_shortcuts.spoilers": "da guzhat/ziguzhat tachenn CW", + "keyboard_shortcuts.start": "Digeriñ bann \"Kregiñ\"", + "keyboard_shortcuts.toggle_hidden": "da guzhat/ziguzhat an desten a-dreñv CW", "keyboard_shortcuts.toggle_sensitivity": "da guzhat/ziguzhat ur media", "keyboard_shortcuts.toot": "da gregiñ gant un toud nevez-flamm", - "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search", - "keyboard_shortcuts.up": "to move up in the list", + "keyboard_shortcuts.unfocus": "Difokus an dachenn testenn/klask", + "keyboard_shortcuts.up": "Pignat er roll", "lightbox.close": "Serriñ", - "lightbox.compress": "Compress image view box", - "lightbox.expand": "Expand image view box", + "lightbox.compress": "Bihanaat boest hewel ar skeudenn", + "lightbox.expand": "Ledanaat boest hewel ar skeudenn", "lightbox.next": "Da-heul", "lightbox.previous": "A-raok", "lists.account.add": "Ouzhpennañ d'al listenn", @@ -261,20 +263,20 @@ "lists.edit.submit": "Cheñch an titl", "lists.new.create": "Ouzhpennañ ul listenn", "lists.new.title_placeholder": "Titl nevez al listenn", - "lists.replies_policy.followed": "Any followed user", + "lists.replies_policy.followed": "Pep implijer.ez heuliet", "lists.replies_policy.list": "Izili ar roll", "lists.replies_policy.none": "Den ebet", "lists.replies_policy.title": "Diskouez ar respontoù:", "lists.search": "Klask e-touez tud heuliet ganeoc'h", "lists.subheading": "Ho listennoù", - "load_pending": "{count, plural, one {# new item} other {# new items}}", + "load_pending": "{count, plural, one {# dra nevez} other {# dra nevez}}", "loading_indicator.label": "O kargañ...", - "media_gallery.toggle_visible": "Toggle visibility", + "media_gallery.toggle_visible": "{number, plural, one {Kuzhat ar skeudenn} other {Kuzhat ar skeudenn}}", "missing_indicator.label": "Digavet", - "missing_indicator.sublabel": "This resource could not be found", + "missing_indicator.sublabel": "An danvez-se ne vez ket kavet", "mute_modal.duration": "Padelezh", "mute_modal.hide_notifications": "Kuzhat kemenadennoù eus an implijer-se ?", - "mute_modal.indefinite": "Indefinite", + "mute_modal.indefinite": "Amstrizh", "navigation_bar.apps": "Arloadoù pellgomz", "navigation_bar.blocks": "Implijer·ezed·ien berzet", "navigation_bar.bookmarks": "Sinedoù", @@ -287,7 +289,7 @@ "navigation_bar.favourites": "Ar re vuiañ-karet", "navigation_bar.filters": "Gerioù kuzhet", "navigation_bar.follow_requests": "Pedadoù heuliañ", - "navigation_bar.follows_and_followers": "Follows and followers", + "navigation_bar.follows_and_followers": "Heuliadennoù ha heulier·ezed·ien", "navigation_bar.info": "Diwar-benn an dafariad-mañ", "navigation_bar.keyboard_shortcuts": "Berradurioù", "navigation_bar.lists": "Listennoù", @@ -298,55 +300,56 @@ "navigation_bar.preferences": "Gwellvezioù", "navigation_bar.public_timeline": "Red-amzer kevreet", "navigation_bar.security": "Diogelroez", - "notification.favourite": "{name} favourited your status", + "notification.favourite": "{name} en/he deus lakaet ho toud en e/he muiañ-karet", "notification.follow": "heuliañ a ra {name} ac'hanoc'h", - "notification.follow_request": "{name} has requested to follow you", + "notification.follow_request": "{name} en/he deus goulennet da heuliañ ac'hanoc'h", "notification.mention": "{name} en/he deus meneget ac'hanoc'h", "notification.own_poll": "Echu eo ho sontadeg", "notification.poll": "Ur sontadeg ho deus mouezhet warnañ a zo echuet", - "notification.reblog": "{name} boosted your status", - "notification.status": "{name} just posted", + "notification.reblog": "{name} skignet ho toud", + "notification.status": "{name} en/he deus toudet", "notifications.clear": "Skarzhañ ar c'hemennoù", - "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?", + "notifications.clear_confirmation": "Ha sur oc'h e fell deoc'h skarzhañ ho kemennoù penn-da-benn?", "notifications.column_settings.alert": "Kemennoù war ar burev", "notifications.column_settings.favourite": "Ar re vuiañ-karet:", "notifications.column_settings.filter_bar.advanced": "Skrammañ an-holl rummadoù", "notifications.column_settings.filter_bar.category": "Barrenn siloù prim", - "notifications.column_settings.filter_bar.show": "Diskouez", + "notifications.column_settings.filter_bar.show_bar": "Diskouezh barrenn siloù", "notifications.column_settings.follow": "Heulierien nevez:", - "notifications.column_settings.follow_request": "New follow requests:", + "notifications.column_settings.follow_request": "Pedadoù heuliañ nevez :", "notifications.column_settings.mention": "Menegoù:", "notifications.column_settings.poll": "Disoc'hoù ar sontadeg:", - "notifications.column_settings.push": "Push notifications", + "notifications.column_settings.push": "Kemennoù push", "notifications.column_settings.reblog": "Skignadennoù:", "notifications.column_settings.show": "Diskouez er bann", "notifications.column_settings.sound": "Seniñ", - "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.status": "Toudoù nevez:", + "notifications.column_settings.unread_notifications.category": "Kemennoù n'int ket lennet", + "notifications.column_settings.unread_notifications.highlight": "Usskediñ kemennoù nevez", "notifications.filter.all": "Pep tra", "notifications.filter.boosts": "Skignadennoù", "notifications.filter.favourites": "Muiañ-karet", "notifications.filter.follows": "Heuliañ", "notifications.filter.mentions": "Menegoù", "notifications.filter.polls": "Disoc'hoù ar sontadegoù", - "notifications.filter.statuses": "Updates from people you follow", - "notifications.grant_permission": "Grant permission.", + "notifications.filter.statuses": "Hizivadurioù eus tud heuliet ganeoc'h", + "notifications.grant_permission": "Reiñ aotre.", "notifications.group": "{count} a gemennoù", - "notifications.mark_as_read": "Mark every notification as read", - "notifications.permission_denied": "Desktop notifications are unavailable due to previously denied browser permissions request", - "notifications.permission_denied_alert": "Desktop notifications can't be enabled, as browser permission has been denied before", - "notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.", - "notifications_permission_banner.enable": "Enable desktop notifications", - "notifications_permission_banner.how_to_control": "To receive notifications when Mastodon isn't open, enable desktop notifications. You can control precisely which types of interactions generate desktop notifications through the {icon} button above once they're enabled.", - "notifications_permission_banner.title": "Never miss a thing", - "picture_in_picture.restore": "Put it back", + "notifications.mark_as_read": "Merkañ an holl kemennoù evel bezañ lennet", + "notifications.permission_denied": "Kemennoù war ar burev n'int ket hegerz rak pedadenn aotren ar merdeer a zo bet nullet araok", + "notifications.permission_denied_alert": "Kemennoù wa ar burev na c'hellont ket bezañ lezelet, rak aotre ar merdeer a zo bet nac'het a-raok", + "notifications.permission_required": "Kemennoù war ar burev n'int ket hegerz abalamour d'an aotre rekis n'eo ket bet roet.", + "notifications_permission_banner.enable": "Lezel kemennoù war ar burev", + "notifications_permission_banner.how_to_control": "Evit reseviñ kemennoù pa ne vez ket digoret Mastodon, lezelit kemennoù war ar burev. Gallout a rit kontrollañ peseurt eskemmoù a c'henel kemennoù war ar burev gant ar {icon} nozelenn a-us kentre ma'z int lezelet.", + "notifications_permission_banner.title": "Na vankit netra morse", + "picture_in_picture.restore": "Adlakaat", "poll.closed": "Serret", "poll.refresh": "Azbevaat", - "poll.total_people": "{count, plural, one {# person} other {# people}}", - "poll.total_votes": "{count, plural, one {# vote} other {# votes}}", + "poll.total_people": "{count, plural, one {# den} other {# a zen}}", + "poll.total_votes": "{count, plural, one {# votadenn} other {# votadenn}}", "poll.vote": "Mouezhiañ", "poll.voted": "Mouezhiet ho peus evit ar respont-mañ", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural,one {#votadenn} other {# votadenn}}", "poll_button.add_poll": "Ouzhpennañ ur sontadeg", "poll_button.remove_poll": "Dilemel ar sontadeg", "privacy.change": "Kemmañ gwelidigezh ar statud", @@ -362,43 +365,56 @@ "regeneration_indicator.label": "O kargañ…", "regeneration_indicator.sublabel": "War brientiñ emañ ho red degemer!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}e", "relative_time.just_now": "bremañ", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}eil", "relative_time.today": "hiziv", "reply_indicator.cancel": "Nullañ", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Treuzkas da: {target}", - "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", - "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", + "report.forward_hint": "War ur servijer all emañ ar c'hont-se. Kas dezhañ un adskrid disanv eus an danevell ivez?", + "report.hint": "Ar danevell a vo bet kaset da evezhidi ho servijer. Gallout a rit displegañ perak emaoc'h oc'h aroueziañ ar c'hont a-is:", "report.placeholder": "Askelennoù ouzhpenn", "report.submit": "Kinnig", - "report.target": "Report {target}", + "report.target": "O tisklêriañ {target}", "search.placeholder": "Klask", - "search_popout.search_format": "Advanced search format", - "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.", + "search_popout.search_format": "Framm klask araokaet", + "search_popout.tips.full_text": "Testenn simpl a adkas toudoù skrivet ganeoc'h, merket ganeoc'h evel miuañ-karet, toudoù skignet, pe e-lec'h oc'h bet meneget, met ivez anvioù skrammañ, anvioù implijer ha gêrioù-klik hag a glot.", "search_popout.tips.hashtag": "ger-klik", - "search_popout.tips.status": "statud", - "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags", + "search_popout.tips.status": "toud", + "search_popout.tips.text": "Testenn simpl a adkas anvioù skrammañ, anvioù implijer ha gêrioù-klik hag a glot", "search_popout.tips.user": "implijer·ez", "search_results.accounts": "Tud", "search_results.hashtags": "Gerioù-klik", "search_results.statuses": "a doudoù", - "search_results.statuses_fts_disabled": "Searching toots by their content is not enabled on this Mastodon server.", - "search_results.total": "{count, number} {count, plural, one {result} other {results}}", - "status.admin_account": "Open moderation interface for @{name}", - "status.admin_status": "Open this status in the moderation interface", + "search_results.statuses_fts_disabled": "Klask toudoù dre oc'h endalc'h n'eo ket aotreet war ar servijer-mañ.", + "search_results.total": "{count, number} {count, plural, one {disoc'h} other {a zisoc'h}}", + "status.admin_account": "Digeriñ etrefas evezherezh evit @{name}", + "status.admin_status": "Digeriñ an toud e-barzh an etrefas evezherezh", "status.block": "Berzañ @{name}", "status.bookmark": "Ouzhpennañ d'ar sinedoù", - "status.cancel_reblog_private": "Unboost", - "status.cannot_reblog": "This post cannot be boosted", + "status.cancel_reblog_private": "Nac'hañ ar skignadenn", + "status.cannot_reblog": "An toud-se ne c'hall ket bezañ skignet", "status.copy": "Eilañ liamm an toud", "status.delete": "Dilemel", - "status.detailed_status": "Detailed conversation view", - "status.direct": "Kas ur c'hemennad da @{name}", + "status.detailed_status": "Gwel kaozeadenn munudek", + "status.direct": "Kas ur c'hemennad prevez da @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Enframmañ", "status.favourite": "Muiañ-karet", "status.filtered": "Silet", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Kargañ muioc'h", "status.media_hidden": "Media kuzhet", "status.mention": "Menegiñ @{name}", @@ -410,75 +426,75 @@ "status.pinned": "Toud spilhennet", "status.read_more": "Lenn muioc'h", "status.reblog": "Skignañ", - "status.reblog_private": "Boost with original visibility", - "status.reblogged_by": "{name} boosted", - "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.", - "status.redraft": "Delete & re-draft", + "status.reblog_private": "Skignañ gant ar weledenn gentañ", + "status.reblogged_by": "{name} en/he deus skignet", + "status.reblogs.empty": "Den ebet n'eus skignet an toud-mañ c'hoazh. Pa vo graet gant unan bennak e vo diskouezet amañ.", + "status.redraft": "Diverkañ ha skrivañ en-dro", "status.remove_bookmark": "Dilemel ar sined", "status.reply": "Respont", "status.replyAll": "Respont d'ar gaozeadenn", "status.report": "Disklêriañ @{name}", - "status.sensitive_warning": "Sensitive content", + "status.sensitive_warning": "Dalc'had kizidik", "status.share": "Rannañ", "status.show_less": "Diskouez nebeutoc'h", - "status.show_less_all": "Show less for all", + "status.show_less_all": "Diskouez nebeutoc'h evit an holl", "status.show_more": "Diskouez muioc'h", "status.show_more_all": "Diskouez miuoc'h evit an holl", "status.show_thread": "Diskouez ar gaozeadenn", "status.uncached_media_warning": "Dihegerz", "status.unmute_conversation": "Diguzhat ar gaozeadenn", "status.unpin": "Dispilhennañ eus ar profil", - "suggestions.dismiss": "Dismiss suggestion", + "suggestions.dismiss": "Dilezel damvenegoù", "suggestions.header": "Marteze e vefec'h dedenet gant…", "tabs_bar.federated_timeline": "Kevredet", "tabs_bar.home": "Degemer", "tabs_bar.local_timeline": "Lec'hel", "tabs_bar.notifications": "Kemennoù", "tabs_bar.search": "Klask", - "time_remaining.days": "{number, plural,one {# devezh} other {# a zevezhioù}} a chom", + "time_remaining.days": "{number, plural,one {# devezh} other {# a zevezh}} a chom", "time_remaining.hours": "{number, plural, one {# eurvezh} other{# eurvezh}} a chom", - "time_remaining.minutes": "{number, plural, one {# munut} other{# a vunutoù}} a chom", - "time_remaining.moments": "Moments remaining", + "time_remaining.minutes": "{number, plural, one {# munut} other{# a vunut}} a chom", + "time_remaining.moments": "Pennadoù a-zilerc'h", "time_remaining.seconds": "{number, plural, one {# eilenn} other{# eilenn}} a chom", - "timeline_hint.remote_resource_not_displayed": "{resource} eus servijerien all n'int ket diskouezet.", + "timeline_hint.remote_resource_not_displayed": "{resource} eus servijerien all n'int ket skrammet.", "timeline_hint.resources.followers": "Heulier·ezed·ien", "timeline_hint.resources.follows": "Heuliañ", "timeline_hint.resources.statuses": "Toudoù koshoc'h", "trends.counter_by_accounts": "{count, plural, one {{counter} den} other {{counter} a zud}} a zo o komz", "trends.trending_now": "Luskad ar mare", "ui.beforeunload": "Kollet e vo ho prell ma kuitit Mastodon.", - "units.short.billion": "{count}B", - "units.short.million": "{count}M", - "units.short.thousand": "{count}K", - "upload_area.title": "Drag & drop to upload", + "units.short.billion": "{count}miliard", + "units.short.million": "{count}milion", + "units.short.thousand": "{count}mil", + "upload_area.title": "Tennañ ha leuskel evit pellgargañ", "upload_button.label": "Ouzhpennañ ur media", - "upload_error.limit": "File upload limit exceeded.", - "upload_error.poll": "File upload not allowed with polls.", + "upload_error.limit": "Bevenn evit pellgargañ restroù a zo distremenet.", + "upload_error.poll": "Pellgargañ restroù n'eo ket aotreet gant sontadegoù.", "upload_form.audio_description": "Diskrivañ evit tud a zo kollet o c'hlev", "upload_form.description": "Diskrivañ evit tud a zo kollet o gweled", "upload_form.edit": "Aozañ", "upload_form.thumbnail": "Kemmañ ar velvenn", "upload_form.undo": "Dilemel", "upload_form.video_description": "Diskrivañ evit tud a zo kollet o gweled pe o c'hlev", - "upload_modal.analyzing_picture": "Analyzing picture…", + "upload_modal.analyzing_picture": "O tielfennañ ar skeudenn…", "upload_modal.apply": "Arloañ", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Oc'h arloañ…", "upload_modal.choose_image": "Dibab ur skeudenn", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", + "upload_modal.description_placeholder": "Ul louarn gell mibin a zo o lammat a-zioc'h ar c'hi lezirek", "upload_modal.detect_text": "Dinoiñ testenn diouzh ar skeudenn", "upload_modal.edit_media": "Embann ar media", - "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preparing_ocr": "Preparing OCR…", + "upload_modal.hint": "Klikit pe tennit ar c'helc'h war ar rakwel evit dibab al lerc'h kengreizel a vo gwelet atav war an holl melvennoù.", + "upload_modal.preparing_ocr": "Oc'h aozañ OCR…", "upload_modal.preview_label": "Rakwel ({ratio})", "upload_progress.label": "O pellgargañ...", "video.close": "Serriñ ar video", "video.download": "Pellgargañ ar restr", "video.exit_fullscreen": "Kuitaat ar mod skramm leun", - "video.expand": "Expand video", + "video.expand": "Ledanaat ar video", "video.fullscreen": "Skramm a-bezh", "video.hide": "Kuzhat ar video", "video.mute": "Paouez gant ar son", - "video.pause": "Pause", + "video.pause": "Paouez", "video.play": "Lenn", "video.unmute": "Lakaat ar son en-dro" } diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index 9434dbcc3..0ab88e2cd 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -47,16 +47,17 @@ "account.unmute": "Treure silenci de @{name}", "account.unmute_notifications": "Activar notificacions de @{name}", "account_note.placeholder": "Fes clic per afegir una nota", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Mitjana", + "admin.dashboard.retention.cohort": "Registres mes", + "admin.dashboard.retention.cohort_size": "Nous usuaris", "alert.rate_limited.message": "Si us plau torna-ho a provar després de {retry_time, time, medium}.", "alert.rate_limited.title": "Límit de freqüència", "alert.unexpected.message": "S'ha produït un error inesperat.", "alert.unexpected.title": "Vaja!", "announcement.announcement": "Anunci", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(sense processar)", "autosuggest_hashtag.per_week": "{count} per setmana", "boost_modal.combo": "Pots prémer {combo} per saltar-te això el proper cop", "bundle_column_error.body": "S'ha produït un error en carregar aquest component.", @@ -96,14 +97,15 @@ "compose_form.lock_disclaimer": "El teu compte no està bloquejat {locked}. Tothom pot seguir-te i veure els teus missatges a seguidors.", "compose_form.lock_disclaimer.lock": "bloquejat", "compose_form.placeholder": "En què penses?", - "compose_form.poll.add_option": "Afegeix una opció", + "compose_form.poll.add_option": "Afegir una opció", "compose_form.poll.duration": "Durada de l'enquesta", "compose_form.poll.option_placeholder": "Opció {number}", "compose_form.poll.remove_option": "Elimina aquesta opció", "compose_form.poll.switch_to_multiple": "Canvia l’enquesta per a permetre diverses opcions", "compose_form.poll.switch_to_single": "Canvia l’enquesta per a permetre una única opció", - "compose_form.publish": "Tut", + "compose_form.publish": "Publicar", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Marcar mèdia com a sensible", "compose_form.sensitive.marked": "Mèdia marcat com a sensible", "compose_form.sensitive.unmarked": "Mèdia no està marcat com a sensible", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Estàs segur que vols suprimir aquest tut?", "confirmations.delete_list.confirm": "Suprimeix", "confirmations.delete_list.message": "Estàs segur que vols suprimir permanentment aquesta llista?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Descarta", + "confirmations.discard_edit_media.message": "Tens canvis no desats de la descripciò de mèdia o previsualització, els vols descartar?", "confirmations.domain_block.confirm": "Amaga tot el domini", "confirmations.domain_block.message": "Estàs segur, realment segur que vols bloquejar totalment {domain}? En la majoria dels casos bloquejar o silenciar uns pocs objectius és suficient i preferible. No veuràs contingut d’aquest domini en cap de les línies de temps ni en les notificacions. Els teus seguidors d’aquest domini seran eliminats.", "confirmations.logout.confirm": "Tancar sessió", @@ -244,7 +246,7 @@ "keyboard_shortcuts.search": "per a centrar la cerca", "keyboard_shortcuts.spoilers": "mostrar/amagar el camp CW", "keyboard_shortcuts.start": "per a obrir la columna \"Començar\"", - "keyboard_shortcuts.toggle_hidden": "per a mostrar o amagar text sota CW", + "keyboard_shortcuts.toggle_hidden": "Mostrar/ocultar el text marcat com a sensible", "keyboard_shortcuts.toggle_sensitivity": "per a mostrar o amagar contingut multimèdia", "keyboard_shortcuts.toot": "per a començar un tut nou de trinca", "keyboard_shortcuts.unfocus": "descentrar l'àrea de composició de text/cerca", @@ -281,14 +283,14 @@ "navigation_bar.community_timeline": "Línia de temps Local", "navigation_bar.compose": "Redacta un nou tut", "navigation_bar.direct": "Missatges directes", - "navigation_bar.discover": "Descobreix", + "navigation_bar.discover": "Descobrir", "navigation_bar.domain_blocks": "Dominis ocults", "navigation_bar.edit_profile": "Editar perfil", "navigation_bar.favourites": "Preferits", "navigation_bar.filters": "Paraules silenciades", "navigation_bar.follow_requests": "Sol·licituds de seguiment", "navigation_bar.follows_and_followers": "Seguits i seguidors", - "navigation_bar.info": "Sobre aquest servidor", + "navigation_bar.info": "Quant a aquest servidor", "navigation_bar.keyboard_shortcuts": "Dreceres de teclat", "navigation_bar.lists": "Llistes", "navigation_bar.logout": "Tancar sessió", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Preferits:", "notifications.column_settings.filter_bar.advanced": "Mostra totes les categories", "notifications.column_settings.filter_bar.category": "Barra ràpida de filtres", - "notifications.column_settings.filter_bar.show": "Mostra", + "notifications.column_settings.filter_bar.show_bar": "Mostra la barra de filtres", "notifications.column_settings.follow": "Nous seguidors:", "notifications.column_settings.follow_request": "Nova sol·licitud de seguiment:", "notifications.column_settings.mention": "Mencions:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Mostra en la columna", "notifications.column_settings.sound": "Reproduir so", "notifications.column_settings.status": "Nous tuts:", - "notifications.column_settings.unread_markers.category": "Marcadors de notificacions no llegides", + "notifications.column_settings.unread_notifications.category": "Notificacions no llegides", + "notifications.column_settings.unread_notifications.highlight": "Destaca notificacions no llegides", "notifications.filter.all": "Tots", "notifications.filter.boosts": "Impulsos", "notifications.filter.favourites": "Favorits", @@ -346,10 +349,10 @@ "poll.total_votes": "{count, plural, one {# vot} other {# vots}}", "poll.vote": "Vota", "poll.voted": "Vas votar per aquesta resposta", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", - "poll_button.add_poll": "Afegeix una enquesta", + "poll.votes": "{votes, plural, one {# vot} other {# vots}}", + "poll_button.add_poll": "Afegir una enquesta", "poll_button.remove_poll": "Elimina l'enquesta", - "privacy.change": "Ajusta l'estat de privacitat", + "privacy.change": "Ajustar l'estat de privacitat", "privacy.direct.long": "Publicar només per als usuaris esmentats", "privacy.direct.short": "Directe", "privacy.private.long": "Publicar només a seguidors", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Carregant…", "regeneration_indicator.sublabel": "S'està preparant la línia de temps Inici!", "relative_time.days": "fa {number} dies", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "fa {number} hores", "relative_time.just_now": "ara", "relative_time.minutes": "fa {number} minuts", "relative_time.seconds": "fa {number} segons", "relative_time.today": "avui", "reply_indicator.cancel": "Cancel·lar", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Reenvia a {target}", "report.forward_hint": "Aquest compte és d'un altre servidor. Enviar-hi també una copia anònima del informe?", "report.hint": "El informe s'enviarà als moderadors del teu servidor. Pots explicar perquè vols informar d'aquest compte aquí:", @@ -396,9 +407,14 @@ "status.delete": "Esborrar", "status.detailed_status": "Visualització detallada de la conversa", "status.direct": "Missatge directe @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Incrustar", "status.favourite": "Favorit", "status.filtered": "Filtrat", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Carrega més", "status.media_hidden": "Multimèdia amagat", "status.mention": "Esmentar @{name}", @@ -430,7 +446,7 @@ "status.unpin": "Deslliga del perfil", "suggestions.dismiss": "Descartar suggeriment", "suggestions.header": "És possible que estiguis interessat en…", - "tabs_bar.federated_timeline": "Federada", + "tabs_bar.federated_timeline": "Federat", "tabs_bar.home": "Inici", "tabs_bar.local_timeline": "Local", "tabs_bar.notifications": "Notificacions", @@ -462,7 +478,7 @@ "upload_form.video_description": "Descriu per a les persones amb pèrdua auditiva o deficiència visual", "upload_modal.analyzing_picture": "Analitzant imatge…", "upload_modal.apply": "Aplica", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Aplicant…", "upload_modal.choose_image": "Tria imatge", "upload_modal.description_placeholder": "Jove xef, porti whisky amb quinze glaçons d’hidrogen, coi!", "upload_modal.detect_text": "Detecta el text de l'imatge", diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json index b8ac9281d..d3fade546 100644 --- a/app/javascript/mastodon/locales/co.json +++ b/app/javascript/mastodon/locales/co.json @@ -47,7 +47,8 @@ "account.unmute": "Ùn piattà più @{name}", "account.unmute_notifications": "Ùn piattà più nutificazione da @{name}", "account_note.placeholder": "Senza cummentariu", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -56,7 +57,7 @@ "alert.unexpected.message": "Un prublemu inaspettatu hè accadutu.", "alert.unexpected.title": "Uups!", "announcement.announcement": "Annunziu", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(micca trattata)", "autosuggest_hashtag.per_week": "{count} per settimana", "boost_modal.combo": "Pudete appughjà nant'à {combo} per saltà quessa a prussima volta", "bundle_column_error.body": "C'hè statu un prublemu caricandu st'elementu.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Cambià u scandagliu per ùn accittà ch'una scelta", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Indicà u media cum'è sensibile} other {Indicà i media cum'è sensibili}}", "compose_form.sensitive.marked": "{count, plural, one {Media indicatu cum'è sensibile} other {Media indicati cum'è sensibili}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media micca indicatu cum'è sensibile} other {Media micca indicati cum'è sensibili}}", @@ -118,7 +120,7 @@ "confirmations.delete.message": "Site sicuru·a che vulete sguassà stu statutu?", "confirmations.delete_list.confirm": "Toglie", "confirmations.delete_list.message": "Site sicuru·a che vulete toglie sta lista?", - "confirmations.discard_edit_media.confirm": "Discard", + "confirmations.discard_edit_media.confirm": "Scartà", "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", "confirmations.domain_block.confirm": "Piattà tuttu u duminiu", "confirmations.domain_block.message": "Site veramente sicuru·a che vulete piattà tuttu à {domain}? Saria forse abbastanza di bluccà ò piattà alcuni conti da quallà. Ùn viderete più nunda da quallà indè e linee pubbliche o e nutificazione. I vostri abbunati da stu duminiu saranu tolti.", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favuriti:", "notifications.column_settings.filter_bar.advanced": "Affissà tutte e categurie", "notifications.column_settings.filter_bar.category": "Barra di ricerca pronta", - "notifications.column_settings.filter_bar.show": "Mustrà", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Abbunati novi:", "notifications.column_settings.follow_request": "Nove dumande d'abbunamentu:", "notifications.column_settings.mention": "Minzione:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Mustrà indè a colonna", "notifications.column_settings.sound": "Sunà", "notifications.column_settings.status": "Statuti novi:", - "notifications.column_settings.unread_markers.category": "Marcatori di nutificazione micca lette", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Tuttu", "notifications.filter.boosts": "Spartere", "notifications.filter.favourites": "Favuriti", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# votu} other {# voti}}", "poll.vote": "Vutà", "poll.voted": "Avete vutatu per sta risposta", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# votu} other {# voti}}", "poll_button.add_poll": "Aghjunghje", "poll_button.remove_poll": "Toglie u scandagliu", "privacy.change": "Mudificà a cunfidenzialità di u statutu", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Caricamentu…", "regeneration_indicator.sublabel": "Priparazione di a vostra pagina d'accolta!", "relative_time.days": "{number}ghj", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}o", "relative_time.just_now": "avà", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "oghji", "reply_indicator.cancel": "Annullà", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Trasferisce à {target}", "report.forward_hint": "U contu hè nant'à un'altru servore. Vulete ancu mandà una copia anonima di u signalamentu quallà?", "report.hint": "U signalamentu sarà mandatu à i muderatori di u servore. Pudete spiegà perchè avete palisatu stu contu quì sottu:", @@ -396,9 +407,14 @@ "status.delete": "Toglie", "status.detailed_status": "Vista in ditagliu di a cunversazione", "status.direct": "Mandà un missaghju @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Integrà", "status.favourite": "Aghjunghje à i favuriti", "status.filtered": "Filtratu", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Vede di più", "status.media_hidden": "Media piattata", "status.mention": "Mintuvà @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Discrizzione per i ciochi o cechi", "upload_modal.analyzing_picture": "Analisi di u ritrattu…", "upload_modal.apply": "Affettà", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Appiegazione…", "upload_modal.choose_image": "Cambià ritrattu", "upload_modal.description_placeholder": "Chì tempi brevi ziu, quandu solfeghji", "upload_modal.detect_text": "Ditettà testu da u ritrattu", diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index 636fbd4ea..2b31d32c3 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -12,7 +12,7 @@ "account.disable_notifications": "Zrušit upozorňování na příspěvky @{name}", "account.domain_blocked": "Doména blokována", "account.edit_profile": "Upravit profil", - "account.enable_notifications": "Oznámit mě na příspěvky @{name}", + "account.enable_notifications": "Oznamovat mi příspěvky @{name}", "account.endorse": "Zvýraznit na profilu", "account.follow": "Sledovat", "account.followers": "Sledující", @@ -47,16 +47,17 @@ "account.unmute": "Zrušit skrytí @{name}", "account.unmute_notifications": "Zrušit skrytí oznámení od @{name}", "account_note.placeholder": "Klikněte pro přidání poznámky", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Průměr", + "admin.dashboard.retention.cohort": "Měsíc registrace", + "admin.dashboard.retention.cohort_size": "Noví uživatelé", "alert.rate_limited.message": "Zkuste to prosím znovu za {retry_time, time, medium}.", "alert.rate_limited.title": "Spojení omezena", "alert.unexpected.message": "Objevila se neočekávaná chyba.", "alert.unexpected.title": "Jejda!", "announcement.announcement": "Oznámení", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(nezpracováno)", "autosuggest_hashtag.per_week": "{count} za týden", "boost_modal.combo": "Příště můžete pro přeskočení stisknout {combo}", "bundle_column_error.body": "Při načítání této komponenty se něco pokazilo.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Povolit u ankety výběr jediné možnosti", "compose_form.publish": "Odeslat", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Označit média za citlivá} few {Označit média za citlivá} many {Označit média za citlivá} other {Označit média za citlivá}}", "compose_form.sensitive.marked": "{count, plural, one {Média jsou označena za citlivá} few {Média jsou označena za citlivá} many {Média jsou označena za citlivá} other {Média jsou označena za citlivá}}", "compose_form.sensitive.unmarked": "{count, plural, one {Média nejsou označena za citlivá} few {Média nejsou označena za citlivá} many {Média nejsou označena za citlivá} other {Média nejsou označena za citlivá}}", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Opravdu chcete smazat tento příspěvek?", "confirmations.delete_list.confirm": "Smazat", "confirmations.delete_list.message": "Opravdu chcete tento seznam navždy smazat?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Zahodit", + "confirmations.discard_edit_media.message": "Máte neuložené změny popisku médií nebo náhledu, přesto je zahodit?", "confirmations.domain_block.confirm": "Blokovat celou doménu", "confirmations.domain_block.message": "Opravdu chcete blokovat celou doménu {domain}? Ve většině případů stačí zablokovat nebo skrýt pár konkrétních uživatelů, což také doporučujeme. Z této domény neuvidíte obsah v žádné veřejné časové ose ani v oznámeních. Vaši sledující z této domény budou odstraněni.", "confirmations.logout.confirm": "Odhlásit", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Oblíbení:", "notifications.column_settings.filter_bar.advanced": "Zobrazit všechny kategorie", "notifications.column_settings.filter_bar.category": "Panel rychlého filtrování", - "notifications.column_settings.filter_bar.show": "Zobrazit", + "notifications.column_settings.filter_bar.show_bar": "Zobrazit panel filtrů", "notifications.column_settings.follow": "Noví sledující:", "notifications.column_settings.follow_request": "Nové žádosti o sledování:", "notifications.column_settings.mention": "Zmínky:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Zobrazit ve sloupci", "notifications.column_settings.sound": "Přehrát zvuk", "notifications.column_settings.status": "Nové příspěvky:", - "notifications.column_settings.unread_markers.category": "Značky nepřečtených oznámení", + "notifications.column_settings.unread_notifications.category": "Nepřečtená oznámení", + "notifications.column_settings.unread_notifications.highlight": "Zvýraznit nepřečtená oznámení", "notifications.filter.all": "Vše", "notifications.filter.boosts": "Boosty", "notifications.filter.favourites": "Oblíbení", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# hlas} few {# hlasy} many {# hlasů} other {# hlasů}}", "poll.vote": "Hlasovat", "poll.voted": "Pro tuto odpověď jste hlasovali", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# hlas} few {# hlasy} many {# hlasů} other {# hlasů}}", "poll_button.add_poll": "Přidat anketu", "poll_button.remove_poll": "Odstranit anketu", "privacy.change": "Změnit soukromí příspěvku", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Načítání…", "regeneration_indicator.sublabel": "Váš domovský kanál se připravuje!", "relative_time.days": "{number} d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number} h", "relative_time.just_now": "teď", "relative_time.minutes": "{number} m", "relative_time.seconds": "{number} s", "relative_time.today": "dnes", "reply_indicator.cancel": "Zrušit", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Přeposlat na {target}", "report.forward_hint": "Tento účet je z jiného serveru. Chcete na něj také poslat anonymizovanou kopii hlášení?", "report.hint": "Hlášení bude zasláno moderátorům vašeho serveru. Níže můžete uvést, proč tento účet nahlašujete:", @@ -396,9 +407,14 @@ "status.delete": "Smazat", "status.detailed_status": "Podrobné zobrazení konverzace", "status.direct": "Poslat @{name} přímou zprávu", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Vložit na web", "status.favourite": "Oblíbit", "status.filtered": "Filtrováno", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Zobrazit více", "status.media_hidden": "Média skryta", "status.mention": "Zmínit @{name}", @@ -461,8 +477,8 @@ "upload_form.undo": "Smazat", "upload_form.video_description": "Popis pro sluchově či zrakově postižené", "upload_modal.analyzing_picture": "Analyzuji obrázek…", - "upload_modal.apply": "Použít", - "upload_modal.applying": "Applying…", + "upload_modal.apply": "Aplikovat", + "upload_modal.applying": "Aplikuji…", "upload_modal.choose_image": "Vybrat obrázek", "upload_modal.description_placeholder": "Příliš žluťoučký kůň úpěl ďábelské ódy", "upload_modal.detect_text": "Detekovat text z obrázku", diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index 2f8c09014..a6379568c 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -47,7 +47,8 @@ "account.unmute": "Dad-dawelu @{name}", "account.unmute_notifications": "Dad-dawelu hysbysiadau o @{name}", "account_note.placeholder": "Clicio i ychwanegu nodyn", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Newid pleidlais i gyfyngu i un dewis", "compose_form.publish": "Tŵt", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Marcio cyfryngau fel eu bod yn sensitif", "compose_form.sensitive.marked": "Cyfryngau wedi'u marcio'n sensitif", "compose_form.sensitive.unmarked": "Nid yw'r cyfryngau wedi'u marcio'n sensitif", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Ffefrynnau:", "notifications.column_settings.filter_bar.advanced": "Dangos pob categori", "notifications.column_settings.filter_bar.category": "Bar hidlo", - "notifications.column_settings.filter_bar.show": "Dangos", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Dilynwyr newydd:", "notifications.column_settings.follow_request": "Ceisiadau dilyn newydd:", "notifications.column_settings.mention": "Crybwylliadau:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Dangos yn y golofn", "notifications.column_settings.sound": "Chwarae sain", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Pob", "notifications.filter.boosts": "Hybiadau", "notifications.filter.favourites": "Ffefrynnau", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Llwytho…", "regeneration_indicator.sublabel": "Mae eich ffrwd cartref yn cael ei baratoi!", "relative_time.days": "{number}dydd", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}awr", "relative_time.just_now": "nawr", "relative_time.minutes": "{number}munud", "relative_time.seconds": "{number}eiliad", "relative_time.today": "heddiw", "reply_indicator.cancel": "Canslo", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Ymlaen i {target}", "report.forward_hint": "Mae'r cyfrif o weinydd arall. Anfon copi anhysbys o'r adroddiad yno hefyd?", "report.hint": "Bydd yr adroddiad yn cael ei anfon i arolygydd eich achos. Mae modd darparu esboniad o pam yr ydych yn cwyno am y cyfrif hwn isod:", @@ -396,9 +407,14 @@ "status.delete": "Dileu", "status.detailed_status": "Golwg manwl o'r sgwrs", "status.direct": "Neges breifat @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Plannu", "status.favourite": "Hoffi", "status.filtered": "Wedi'i hidlo", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Llwythwch mwy", "status.media_hidden": "Cyfryngau wedi'u cuddio", "status.mention": "Crybwyll @{name}", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index 9db5da3eb..56c1daa13 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -1,75 +1,76 @@ { - "account.account_note_header": "Notat", + "account.account_note_header": "Note", "account.add_or_remove_from_list": "Tilføj eller fjern fra lister", "account.badges.bot": "Bot", "account.badges.group": "Gruppe", "account.block": "Blokér @{name}", "account.block_domain": "Blokér domænet {domain}", "account.blocked": "Blokeret", - "account.browse_more_on_origin_server": "Gennemse mere på den oprindelige profil", - "account.cancel_follow_request": "Annullér følgeranmodning", + "account.browse_more_on_origin_server": "Se mere på den oprindelige profil", + "account.cancel_follow_request": "Annullér følgeanmodning", "account.direct": "Direkte besked til @{name}", "account.disable_notifications": "Advisér mig ikke længere, når @{name} poster", "account.domain_blocked": "Domæne blokeret", - "account.edit_profile": "Redigere profil", - "account.enable_notifications": "Advisér mig, når @{name} poster", + "account.edit_profile": "Redigér profil", + "account.enable_notifications": "Giv besked når @{name} udgiver nyt", "account.endorse": "Fremhæv på profil", "account.follow": "Følg", "account.followers": "Følgere", - "account.followers.empty": "Ingen følger denne bruger endnu.", + "account.followers.empty": "Ingen følger brugeren endnu.", "account.followers_counter": "{count, plural, one {{counter} Følger} other {{counter} Følgere}}", - "account.following_counter": "{count, plural, one {{counter} Følger} other {{counter} Følgere}}", - "account.follows.empty": "Denne bruger følger endnu ikke nogen.", + "account.following_counter": "{count, plural, one {{counter} Følges} other {{counter} Følges}}", + "account.follows.empty": "Denne bruger følger ikke nogen endnu.", "account.follows_you": "Følger dig", - "account.hide_reblogs": "Skjul fremhævelserne fra @{name}", + "account.hide_reblogs": "Skjul fremhævelser fra @{name}", "account.joined": "Tilmeldt {date}", "account.last_status": "Senest aktiv", "account.link_verified_on": "Ejerskab af dette link blev tjekket {date}", "account.locked_info": "Denne kontos fortrolighedsstatus er sat til låst. Ejeren bedømmer manuelt, hvem der kan følge vedkommende.", - "account.media": "Medie", + "account.media": "Medier", "account.mention": "Nævn @{name}", "account.moved_to": "{name} er flyttet til:", - "account.mute": "Tavsgør @{name}", - "account.mute_notifications": "Tavsgør notifikationer fra @{name}", - "account.muted": "Tavsgjort", + "account.mute": "Skjul @{name}", + "account.mute_notifications": "Skjul notifikationer fra @{name}", + "account.muted": "Tystnet", "account.never_active": "Aldrig", - "account.posts": "Trut", - "account.posts_with_replies": "Trut og svar", + "account.posts": "Indlæg", + "account.posts_with_replies": "Indlæg og svar", "account.report": "Anmeld @{name}", "account.requested": "Afventer godkendelse. Tryk for at annullere følgeanmodning", "account.share": "Del @{name}s profil", - "account.show_reblogs": "Vis fremhævelserne fra @{name}", - "account.statuses_counter": "{count, plural, one {{counter} Trut} other {{counter} Trut}}", + "account.show_reblogs": "Vis fremhævelser fra @{name}", + "account.statuses_counter": "{count, plural, one {{counter} Indlæg} other {{counter} Indlæg}}", "account.unblock": "Fjern blokeringen af @{name}", "account.unblock_domain": "Afblokér domænet {domain}", - "account.unendorse": "Fremhæv ikke på profil", + "account.unendorse": "Fjern visning på din profil", "account.unfollow": "Følg ikke længere", "account.unmute": "Fjern tavsgjort for @{name}", - "account.unmute_notifications": "Fjern tavsgjort for notifikationer fra @{name}", + "account.unmute_notifications": "Slå notifikationer om @{name} til igen", "account_note.placeholder": "Klik for at tilføje notat", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Gennemsnitlig", + "admin.dashboard.retention.cohort": "Tilmeldingsmåned", + "admin.dashboard.retention.cohort_size": "Nye brugere", "alert.rate_limited.message": "Forsøg igen efter {retry_time, time, medium}.", - "alert.rate_limited.title": "Gradsbegrænset", - "alert.unexpected.message": "En uventet fejl opstod.", + "alert.rate_limited.title": "Hastighedsbegrænset", + "alert.unexpected.message": "Der skete en uventet fejl.", "alert.unexpected.title": "Ups!", "announcement.announcement": "Bekendtgørelse", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(ubearbejdet)", "autosuggest_hashtag.per_week": "{count} pr. uge", - "boost_modal.combo": "Du kan trykke på {combo} for at overspringe dette næste gang", + "boost_modal.combo": "Du kan trykke på {combo} for at springe over næste gang", "bundle_column_error.body": "Noget gik galt under indlæsningen af denne komponent.", - "bundle_column_error.retry": "Forsøg igen", + "bundle_column_error.retry": "Prøv igen", "bundle_column_error.title": "Netværksfejl", "bundle_modal_error.close": "Luk", "bundle_modal_error.message": "Noget gik galt under indlæsningen af denne komponent.", - "bundle_modal_error.retry": "Forsøg igen", + "bundle_modal_error.retry": "Prøv igen", "column.blocks": "Blokerede brugere", "column.bookmarks": "Bogmærker", "column.community": "Lokal tidslinje", "column.direct": "Direkte beskeder", - "column.directory": "Gennemse profiler", + "column.directory": "Se profiler", "column.domain_blocks": "Blokerede domæner", "column.favourites": "Favoritter", "column.follow_requests": "Følg-anmodninger", @@ -77,8 +78,8 @@ "column.lists": "Lister", "column.mutes": "Tavsgjorte brugere", "column.notifications": "Notifikationer", - "column.pins": "Fastgjorte trut", - "column.public": "Forenede tidslinje", + "column.pins": "Fastgjorte indlæg", + "column.public": "Fælles tidslinje", "column_back_button.label": "Tilbage", "column_header.hide_settings": "Skjul indstillinger", "column_header.moveLeft_settings": "Flyt kolonne til venstre", @@ -88,71 +89,72 @@ "column_header.unpin": "Løsgør", "column_subheading.settings": "Indstillinger", "community.column_settings.local_only": "Kun lokalt", - "community.column_settings.media_only": "Kun medie", - "community.column_settings.remote_only": "Kun fjernt", - "compose_form.direct_message_warning": "Dette trut sendes kun til de nævnte brugere.", + "community.column_settings.media_only": "Kun medier", + "community.column_settings.remote_only": "Kun udefra", + "compose_form.direct_message_warning": "Indlægget bliver kun sendt til de nævnte brugere.", "compose_form.direct_message_warning_learn_more": "Få mere at vide", "compose_form.hashtag_warning": "Dette trut vises ikke under noget hashtag, da det ikke er listet. Kun offentlige trut kan søges via hashtags.", - "compose_form.lock_disclaimer": "Din konto er ikke {locked}. Alle kan følge dig for at se dine kun-følger poster.", + "compose_form.lock_disclaimer": "Din konto er ikke {locked}. Alle kan følge dig, så de også kan se de indlæg, der kun er til følgere.", "compose_form.lock_disclaimer.lock": "låst", - "compose_form.placeholder": "Hvad tænker du på?", + "compose_form.placeholder": "Hvad vil du gerne fortælle om?", "compose_form.poll.add_option": "Tilføj valgmulighed", - "compose_form.poll.duration": "Afstemningsvarighed", + "compose_form.poll.duration": "Afstemningens varighed", "compose_form.poll.option_placeholder": "Valgmulighed {number}", - "compose_form.poll.remove_option": "Fjern denne valgmulighed", + "compose_form.poll.remove_option": "Fjern valgmulighed", "compose_form.poll.switch_to_multiple": "Ændr afstemning til flervalgstype", "compose_form.poll.switch_to_single": "Ændr afstemning til enkeltvalgstype", - "compose_form.publish": "Toot", + "compose_form.publish": "Udgiv", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Markér medie som følsomt} other {Markér medier som følsomme}}", "compose_form.sensitive.marked": "{count, plural, one {Medie er markeret som sensitivt} other {Medier er markerede som sensitive}}", - "compose_form.sensitive.unmarked": "Intet medie market som sensitivt", - "compose_form.spoiler.marked": "Tekst skjult bag advarsel", - "compose_form.spoiler.unmarked": "Teksten er ikke skjult", + "compose_form.sensitive.unmarked": "{count, plural, one {Medie er ikke market som sensitivt} other {Medier er ikke markerede som sensitive}}", + "compose_form.spoiler.marked": "Fjern advarsel", + "compose_form.spoiler.unmarked": "Skjul bag advarsel", "compose_form.spoiler_placeholder": "Skriv din advarsel hér", "confirmation_modal.cancel": "Afbryd", "confirmations.block.block_and_report": "Blokér og Anmeld", "confirmations.block.confirm": "Blokér", - "confirmations.block.message": "Sikker på, at du vil blokere {name}?", + "confirmations.block.message": "Er du sikker på, du vil blokere {name}?", "confirmations.delete.confirm": "Slet", - "confirmations.delete.message": "Sikker på, at du vil slette dette trut?", + "confirmations.delete.message": "Er du sikker på, at du vil slette indlægget?", "confirmations.delete_list.confirm": "Slet", "confirmations.delete_list.message": "Sikker på, at du vil slette denne liste permanent?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", - "confirmations.domain_block.confirm": "Skjul hele domænet", - "confirmations.domain_block.message": "Helt sikker på, at du vil blokere hele {domain}-domænet? Oftest vil få, specifikke blokeringer eller tavsgørelser være nok og at fortrække. Du vil ikke se indhold fra domænet på offentlige tidslinjer eller i dine notifikationer. Dine følgere fra domænet fjernes.", + "confirmations.discard_edit_media.confirm": "Kassér", + "confirmations.discard_edit_media.message": "Der er ugemte ændringer i mediebeskrivelsen eller forhåndsvisningen, kassér dem alligevel?", + "confirmations.domain_block.confirm": "Blokér hele domænet", + "confirmations.domain_block.message": "Er du helt sikker på, at du vil blokere hele {domain}-domænet? Oftest vil det være at foretrække istedet målrettet at blokere eller skjule nogle få brugere. Hvis du blokerer domænet, vil du ikke se indhold fra domænet på offentlige tidslinjer eller i dine notifikationer. Dine følgere fra domænet fjernes.", "confirmations.logout.confirm": "Log ud", "confirmations.logout.message": "Log ud, sikker?", - "confirmations.mute.confirm": "Tavsgøre", - "confirmations.mute.explanation": "Dette skjuler indlæg fra dem (og om) dem, men det vil lade dem at se dine indlæg og følge dig.", - "confirmations.mute.message": "Sikker på, du vil tavsgøre {name}?", + "confirmations.mute.confirm": "Skjul", + "confirmations.mute.explanation": "Dette skjuler indlæg fra (og om) dem, men de kan stadig se dine indlæg og følge dig.", + "confirmations.mute.message": "Er du sikker på, du vil skjule {name}?", "confirmations.redraft.confirm": "Slet og omskriv", - "confirmations.redraft.message": "Sikker på, at du vil slette dette trut og omskrive det? Favoritter og fremhævelser går tabt og svar til det oprindelige indlæg afassocieres.", - "confirmations.reply.confirm": "Besvar", - "confirmations.reply.message": "Besvarelse nu vil overskrive den besked, du er ved at skrive. Fortsæt alligevel?", + "confirmations.redraft.message": "Er du sikker på, at du vil slette og omskrive indlægget? Favoritter og fremhævelser går tabt og svar til det oprindelige indlæg afassocieres.", + "confirmations.reply.confirm": "Svar", + "confirmations.reply.message": "At svare nu vil overskrive den besked, du er ved at skrive. Fortsæt alligevel?", "confirmations.unfollow.confirm": "Følg ikke længere", - "confirmations.unfollow.message": "Sikker på, at du ikke længere vil følge {name}?", - "conversation.delete": "Slet konversation", + "confirmations.unfollow.message": "Er du sikker på, at du ikke vil følge {name}?", + "conversation.delete": "Slet samtale", "conversation.mark_as_read": "Markér som læst", - "conversation.open": "Vis konversation", + "conversation.open": "Vis samtale", "conversation.with": "Med {names}", - "directory.federated": "Fra kendt fedivers", + "directory.federated": "Fra kendt Fællesvers", "directory.local": "Kun fra {domain}", "directory.new_arrivals": "Nye ankomster", - "directory.recently_active": "Senest aktiv", - "embed.instructions": "Indlejr dette trut på din side ved at kopiere koden nedenfor.", + "directory.recently_active": "Aktive for nyligt", + "embed.instructions": "Indlejr indlægget på din side ved at kopiere koden nedenfor.", "embed.preview": "Sådan kommer det til at se ud:", "emoji_button.activity": "Aktivitet", "emoji_button.custom": "Tilpasset", "emoji_button.flags": "Flag", "emoji_button.food": "Mad og drikke", - "emoji_button.label": "Indsæt humørikon", + "emoji_button.label": "Indsæt emoji", "emoji_button.nature": "Natur", - "emoji_button.not_found": "Ingen emojos!! (╯°□°)╯︵ ┻━┻", + "emoji_button.not_found": "Kunne ikke finde tilsvarende emojis", "emoji_button.objects": "Objekter", "emoji_button.people": "Personer", - "emoji_button.recent": "Oftest brugt", + "emoji_button.recent": "De sædvanlige", "emoji_button.search": "Søg...", "emoji_button.search_results": "Søgeresultater", "emoji_button.symbols": "Symboler", @@ -160,32 +162,32 @@ "empty_column.account_suspended": "Konto suspenderet", "empty_column.account_timeline": "Ingen trut her!", "empty_column.account_unavailable": "Profil utilgængelig", - "empty_column.blocks": "Du har ikke blokeret nogle brugere endnu.", - "empty_column.bookmarked_statuses": "Du har ingen bogmærkede trut endnu. Når du bogmærker ét, vil det dukke op hér.", + "empty_column.blocks": "Du har ikke blokeret nogen endnu.", + "empty_column.bookmarked_statuses": "Du har ingen indlæg med bogmærke endnu. Når du sætter et bogmærke, vil det dukke op hér.", "empty_column.community": "Den lokale tidslinje er tom. Skriv noget offentligt for at sætte tingene i gang!", - "empty_column.direct": "Du har endnu ingen direkte beskeder. Når du sender eller modtager en, vil den vises hér.", - "empty_column.domain_blocks": "Der er endnu ingen skjulte domæner.", - "empty_column.favourited_statuses": "Du har endnu ingen favorit-trut. Når du favoriserer ét, vil det blive vist hér.", - "empty_column.favourites": "Ingen har endnu favoriseret dette trut. Når nogen anden gør vil det blive vist hér.", - "empty_column.follow_recommendations": "Ser ud til, at der ikke kunne genereres forslag til dig. Du kan prøve med Søg for at lede efter personer, du måske kender, eller udforske hashtags.", - "empty_column.follow_requests": "Du har endnu ingen følgeranmodninger. Når du modtager én, vil den fremgå hér.", - "empty_column.hashtag": "Intet indhold i dette hashtag endnu.", + "empty_column.direct": "Du har ingen direkte beskeder endnu. Hvis du sender eller modtager en, bliver den vist hér.", + "empty_column.domain_blocks": "Der er ingen skjulte domæner endnu.", + "empty_column.favourited_statuses": "Du har ikke markeret nogle indlæg som favorit. Når du markerer ét, bliver det vist hér.", + "empty_column.favourites": "Ingen har markeret indlægget som favorit endnu. Hvis der er nogen der gør, bliver det vist hér.", + "empty_column.follow_recommendations": "Det ser ud til, at der ikke kunne blive lavet forslag til dig. Du kan prøve med Søg for at finde personer, du kender, eller udforske hashtags.", + "empty_column.follow_requests": "Du har ingen følgeanmodninger endnu. Hvis du modtager en, bliver den vist her.", + "empty_column.hashtag": "Der er ingen indlæg med hashtagget endnu.", "empty_column.home": "Din hjemmetidslinje er tom! Besøg {public} eller brug søgningen for at komme igang og møde andre brugere.", "empty_column.home.suggestions": "Se nogle foreslag", - "empty_column.list": "Der er endnu intet i denne liste. Når medlemmer af denne liste poster nye trut, vil de fremgå hér.", + "empty_column.list": "Der er ikke noget på denne liste endnu. Når medlemmer af listen udgiver nye indlæg vil de fremgå hér.", "empty_column.lists": "Du har endnu ingen lister. Når du opretter én, vil den fremgå hér.", - "empty_column.mutes": "Du har endnu ikke tavsgjort nogle brugere.", - "empty_column.notifications": "Du har endnu ingen notifikationer. Interagér med andre for at starte konversationen.", + "empty_column.mutes": "Du har endnu ikke tystnet nogle brugere.", + "empty_column.notifications": "Du har ingen notifikationer. Hvis andre interagerer med dig, bliver det vist her.", "empty_column.public": "Der er intet hér! Skriv noget offentligt eller følg manuelt brugere fra andre servere for at se indhold", "error.unexpected_crash.explanation": "Grundet en fejl i vores kode, eller en browser-kompatibilitetsfejl, kunne siden ikke vises korrekt.", "error.unexpected_crash.explanation_addons": "Denne side kunne ikke vises korrekt. Fejlen skyldes sandsynligvis en browsertilføjelse eller automatiske oversættelsesværktøjer.", - "error.unexpected_crash.next_steps": "Prøv at opfriske siden. Hjælper dette ikke, kan Mastodon muligvis stadig bruges via en anden browser eller app.", - "error.unexpected_crash.next_steps_addons": "Prøv at deaktivere dem og opfriske siden. Hjælper dette ikke, kan Mastodon muligvis stadig bruges via en anden browser eller app.", + "error.unexpected_crash.next_steps": "Prøv at genindlæs siden. Hvis dette ikke hjælper, så forsøg venligst, at tilgå Mastodon via en anden browser eller app.", + "error.unexpected_crash.next_steps_addons": "Prøv at deaktivere dem og genindlæse siden. Hvis det ikke hjælper, kan Mastodon muligvis stadig bruges via en anden browser eller app.", "errors.unexpected_crash.copy_stacktrace": "Kopiér stacktrace til udklipsholderen", "errors.unexpected_crash.report_issue": "Anmeld problem", "follow_recommendations.done": "Udført", "follow_recommendations.heading": "Følg personer du gerne vil se indlæg fra! Her er nogle forslag.", - "follow_recommendations.lead": "Indlæg, fra personer du følger, vises i kronologisk rækkefølge i dit hjemmefeed. Vær ikke bange for at begå fejl, du kan vælge \"følg ikke\" personer lige så nemt til enhver tid!", + "follow_recommendations.lead": "Indlæg, fra personer du følger, vises i kronologisk rækkefølge i hjemmetidslinjen. Bare prøv dig frem med hvem du følger her. Du kan altid vælge om igen!", "follow_request.authorize": "Godkend", "follow_request.reject": "Afvis", "follow_requests.unlocked_explanation": "Selvom din konto ikke er låst, antog {domain}-personalet, at du måske vil gennemgå dine anmodninger manuelt.", @@ -193,9 +195,9 @@ "getting_started.developers": "Udviklere", "getting_started.directory": "Profilliste", "getting_started.documentation": "Dokumentation", - "getting_started.heading": "Komme i gang", + "getting_started.heading": "Startmenu", "getting_started.invite": "Invitér folk", - "getting_started.open_source_notice": "Mastodon er en open-source software. Du kan bidrage eller anmelde fejl via GitHub {github}.", + "getting_started.open_source_notice": "Mastodon er open-source software. Du kan bidrage eller anmelde fejl via GitHub {github}.", "getting_started.security": "Kontoindstillinger", "getting_started.terms": "Tjenestevilkår", "hashtag.column_header.tag_mode.all": "og {additional}", @@ -203,7 +205,7 @@ "hashtag.column_header.tag_mode.none": "uden {additional}", "hashtag.column_settings.select.no_options_message": "Ingen forslag fundet", "hashtag.column_settings.select.placeholder": "Angiv hashtags…", - "hashtag.column_settings.tag_mode.all": "Alle disse", + "hashtag.column_settings.tag_mode.all": "Allesammen", "hashtag.column_settings.tag_mode.any": "Nogle af disse", "hashtag.column_settings.tag_mode.none": "Ingen af disse", "hashtag.column_settings.tag_toggle": "Inkludér ekstra tags for denne kolonne", @@ -216,17 +218,17 @@ "intervals.full.hours": "{number, plural, one {# time} other {# timer}}", "intervals.full.minutes": "{number, plural, one {# minut} other {# minutter}}", "keyboard_shortcuts.back": "for at navigere tilbage", - "keyboard_shortcuts.blocked": "for at åbne listen over blokerede brugere", - "keyboard_shortcuts.boost": "for at fremhæve", + "keyboard_shortcuts.blocked": "Vis listen over blokerede brugere", + "keyboard_shortcuts.boost": "Fremhæv indlæg", "keyboard_shortcuts.column": "for at fokusere et trut i en af kolonnerne", "keyboard_shortcuts.compose": "for at fokusere på skriveområdet", "keyboard_shortcuts.description": "Beskrivelse", - "keyboard_shortcuts.direct": "for at åbne direkte besked-kolonnen", + "keyboard_shortcuts.direct": "Åben kolonnen med direkte beskeder", "keyboard_shortcuts.down": "for at rykke nedad på listen", - "keyboard_shortcuts.enter": "for at åbne trut", - "keyboard_shortcuts.favourite": "for at favorisere", + "keyboard_shortcuts.enter": "Åben indlæg", + "keyboard_shortcuts.favourite": "Markér som favorit", "keyboard_shortcuts.favourites": "for at åbne favoritlisten", - "keyboard_shortcuts.federated": "for at åbne den forenede tidslinje", + "keyboard_shortcuts.federated": "Åben den fælles tidslinje", "keyboard_shortcuts.heading": "Tastaturgenveje", "keyboard_shortcuts.home": "for at åbne hjemmetidslinjen", "keyboard_shortcuts.hotkey": "Hurtigtast", @@ -237,10 +239,10 @@ "keyboard_shortcuts.my_profile": "for at åbne din profil", "keyboard_shortcuts.notifications": "for at åbne notifikationskolonnen", "keyboard_shortcuts.open_media": "for at åbne medier", - "keyboard_shortcuts.pinned": "for at åbne listen over fastgjorte trut", + "keyboard_shortcuts.pinned": "Åben listen over fastgjorte indlæg", "keyboard_shortcuts.profile": "for at åbne forfatterens profil", "keyboard_shortcuts.reply": "for at besvare", - "keyboard_shortcuts.requests": "for at åbne følganmodningslisten", + "keyboard_shortcuts.requests": "Åben listen over følgeanmodninger", "keyboard_shortcuts.search": "for at fokusere søgningen", "keyboard_shortcuts.spoilers": "for at vise/skjule CW-felt", "keyboard_shortcuts.start": "for at åbne \"komme i gang\"-kolonnen", @@ -273,48 +275,48 @@ "missing_indicator.label": "Ikke fundet", "missing_indicator.sublabel": "Denne ressource kunne ikke findes", "mute_modal.duration": "Varighed", - "mute_modal.hide_notifications": "Skjul notifikationer fra denne bruger?", - "mute_modal.indefinite": "Uendeligt", - "navigation_bar.apps": "Mobil-apps", + "mute_modal.hide_notifications": "Skjul notifikationer fra brugeren?", + "mute_modal.indefinite": "Tidsubegrænset", + "navigation_bar.apps": "Apps til mobilen", "navigation_bar.blocks": "Blokerede brugere", "navigation_bar.bookmarks": "Bogmærker", "navigation_bar.community_timeline": "Lokal tidslinje", - "navigation_bar.compose": "Skriv nyt trut", + "navigation_bar.compose": "Skriv nyt indlæg", "navigation_bar.direct": "Direkte beskeder", "navigation_bar.discover": "Opdag", "navigation_bar.domain_blocks": "Blokerede domæner", "navigation_bar.edit_profile": "Redigér profil", "navigation_bar.favourites": "Favoritter", - "navigation_bar.filters": "Tavsgjorte ord", - "navigation_bar.follow_requests": "Følganmodninger", - "navigation_bar.follows_and_followers": "Følger og følgere", + "navigation_bar.filters": "Tystnede ord", + "navigation_bar.follow_requests": "Følgeanmodninger", + "navigation_bar.follows_and_followers": "Følges og følgere", "navigation_bar.info": "Om denne server", "navigation_bar.keyboard_shortcuts": "Hurtigtaster", "navigation_bar.lists": "Lister", - "navigation_bar.logout": "Log ud", - "navigation_bar.mutes": "Tavsgjorte brugere", + "navigation_bar.logout": "Log af", + "navigation_bar.mutes": "Tystnede brugere", "navigation_bar.personal": "Personlig", - "navigation_bar.pins": "Fastgjorte trut", + "navigation_bar.pins": "Fastgjorte indlæg", "navigation_bar.preferences": "Præferencer", - "navigation_bar.public_timeline": "Forenet tidslinje", + "navigation_bar.public_timeline": "Fælles tidslinje", "navigation_bar.security": "Sikkerhed", "notification.favourite": "{name} favoriserede dit trut", "notification.follow": "{name} fulgte dig", "notification.follow_request": "{name} har anmodet om at følge dig", "notification.mention": "{name} nævnte dig", "notification.own_poll": "Din afstemning er afsluttet", - "notification.poll": "En afstemning, hvori du stemte, er slut", - "notification.reblog": "{name} fremhævede din trut", - "notification.status": "{name} har netop postet", + "notification.poll": "En afstemning, du deltog i, er færdig", + "notification.reblog": "{name} fremhævede dit indlæg", + "notification.status": "{name} har netop udgivet", "notifications.clear": "Ryd notifikationer", - "notifications.clear_confirmation": "Sikker på, at du vil rydde alle dine notifikationer permanent?", + "notifications.clear_confirmation": "Er du sikker på, du vil rydde alle dine notifikationer permanent?", "notifications.column_settings.alert": "Skrivebordsnotifikationer", "notifications.column_settings.favourite": "Favoritter:", "notifications.column_settings.filter_bar.advanced": "Vis alle kategorier", "notifications.column_settings.filter_bar.category": "Hurtigfilterbjælke", - "notifications.column_settings.filter_bar.show": "Vis", + "notifications.column_settings.filter_bar.show_bar": "Vis filterbjælke", "notifications.column_settings.follow": "Nye følgere:", - "notifications.column_settings.follow_request": "Nye følganmodninger:", + "notifications.column_settings.follow_request": "Nye følgeanmodninger:", "notifications.column_settings.mention": "Omtaler:", "notifications.column_settings.poll": "Afstemningsresultater:", "notifications.column_settings.push": "Pushnotifikationer", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Vis i kolonne", "notifications.column_settings.sound": "Afspil lyd", "notifications.column_settings.status": "Nye indlæg:", - "notifications.column_settings.unread_markers.category": "Ulæste notifkationer-markører", + "notifications.column_settings.unread_notifications.category": "Ulæste notifikationer", + "notifications.column_settings.unread_notifications.highlight": "Fremhæv ulæste notifikationer", "notifications.filter.all": "Alle", "notifications.filter.boosts": "Fremhævelser", "notifications.filter.favourites": "Favoritter", @@ -341,36 +344,44 @@ "notifications_permission_banner.title": "Gå aldrig glip af noget", "picture_in_picture.restore": "Sæt det tilbage", "poll.closed": "Lukket", - "poll.refresh": "Opfrisk", + "poll.refresh": "Opdatér", "poll.total_people": "{count, plural, one {# person} other {# personer}}", "poll.total_votes": "{count, plural, one {# stemme} other {# stemmer}}", "poll.vote": "Stem", - "poll.voted": "Du stemte for dette svar", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.voted": "Du stemte på dette svar", + "poll.votes": "{votes, plural, one {# stemme} other {# stemmer}}", "poll_button.add_poll": "Tilføj en afstemning", "poll_button.remove_poll": "Fjern afstemning", - "privacy.change": "Justér trutfortrolighed", + "privacy.change": "Justér fortrolighed", "privacy.direct.long": "Kun synlig for nævnte brugere", "privacy.direct.short": "Direkte", "privacy.private.long": "Kun synlig for følgere", "privacy.private.short": "Kun for følgere", - "privacy.public.long": "Synlig for alle på offentlige tidslinjer", + "privacy.public.long": "Synlig for alle og vises på offentlige tidslinjer", "privacy.public.short": "Offentlig", - "privacy.unlisted.long": "Synlig for alle, men på offentlige tidslinjer", - "privacy.unlisted.short": "Ulistet", - "refresh": "Opfrisk", + "privacy.unlisted.long": "Synlig for alle, men vises ikke på offentlige tidslinjer", + "privacy.unlisted.short": "Diskret", + "refresh": "Genindlæs", "regeneration_indicator.label": "Indlæser…", - "regeneration_indicator.sublabel": "Din hjemmefeed klargøres!", + "regeneration_indicator.sublabel": "Din hjemmetidslinje klargøres!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}t", "relative_time.just_now": "nu", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "i dag", "reply_indicator.cancel": "Afbryd", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Videresend til {target}", - "report.forward_hint": "Kontoen er fra en anden server. Sende en anonymiseret anmeldelseskopi dertil også?", - "report.hint": "Anmeldelsen sendes til din serverordstyrerer. Du kan oplyse nærmere om kontoanmeldelsen nedennfor:", + "report.forward_hint": "Kontoen er fra en anden server. Send en anonymiseret kopi af anmeldelsen dertil også?", + "report.hint": "Anmeldelsen sendes til din serverordstyrer. Du kan oplyse nærmere om kontoanmeldelsen nedenfor:", "report.placeholder": "Yderligere kommentarer", "report.submit": "Indsend", "report.target": "Anmelder {target}", @@ -378,47 +389,52 @@ "search_popout.search_format": "Avanceret søgeformat", "search_popout.tips.full_text": "Simpel tekst returnerer trut, du har skrevet, favoriseret, fremhævede eller som er nævnt i/matcher bruger- og profilnavne samt hashtags.", "search_popout.tips.hashtag": "hashtag", - "search_popout.tips.status": "trut", + "search_popout.tips.status": "indlæg", "search_popout.tips.text": "Simpel tekst returnerer matchende visnings- og brugernavne samt hashtags", "search_popout.tips.user": "bruger", "search_results.accounts": "Personer", "search_results.hashtags": "Hashtags", - "search_results.statuses": "Trut", + "search_results.statuses": "Indlæg", "search_results.statuses_fts_disabled": "På denne Mastodon-server er trutsøgning efter deres indhold ikke aktiveret.", "search_results.total": "{count, number} {count, plural, one {resultat} other {resultater}}", "status.admin_account": "Åbn modereringsbrugerflade for @{name}", "status.admin_status": "Åbn dette trut i modereringsbrugerflade", "status.block": "Blokér @{name}", - "status.bookmark": "Bogmærke", + "status.bookmark": "Tilføj bogmærke", "status.cancel_reblog_private": "Fjern fremhævning", - "status.cannot_reblog": "Dette indlæg kan ikke fremhæves", + "status.cannot_reblog": "Indlægget kan ikke fremhæves", "status.copy": "Kopiér link til trut", "status.delete": "Slet", - "status.detailed_status": "Detaljeret konversationsvisning", + "status.detailed_status": "Detaljeret samtalevisning", "status.direct": "Direkte besked til @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Indlejr", "status.favourite": "Favorit", "status.filtered": "Filtreret", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Indlæs mere", "status.media_hidden": "Medie skjult", "status.mention": "Nævn @{name}", "status.more": "Mere", - "status.mute": "Tavsgør @{name}", - "status.mute_conversation": "Tavsgør konversation", - "status.open": "Udvid dette trut", + "status.mute": "Skjul @{name}", + "status.mute_conversation": "Skjul samtale", + "status.open": "Udvid indlægget", "status.pin": "Fastgør til profil", "status.pinned": "Fastgjort trut", "status.read_more": "Læs mere", "status.reblog": "Fremhæv", "status.reblog_private": "Fremhæv med oprindelig synlighed", "status.reblogged_by": "{name} fremhævet", - "status.reblogs.empty": "Ingen har endnu fremhævet dette trut. Når nogen gør, vil det fremgå hér.", + "status.reblogs.empty": "Ingen har fremhævet indlægget endnu. Når nogen gør, vil det fremgå hér.", "status.redraft": "Slet og omskriv", "status.remove_bookmark": "Fjern bogmærke", "status.reply": "Besvar", - "status.replyAll": "Besvar til tråd", + "status.replyAll": "Svar på tråd", "status.report": "Anmeld @{name}", - "status.sensitive_warning": "Sensitivt indhold", + "status.sensitive_warning": "Følsomt indhold", "status.share": "Del", "status.show_less": "Vis mindre", "status.show_less_all": "Vis mindre for alle", @@ -426,11 +442,11 @@ "status.show_more_all": "Vis mere for alle", "status.show_thread": "Vis tråd", "status.uncached_media_warning": "Utilgængelig", - "status.unmute_conversation": "Genaktivér konversation", + "status.unmute_conversation": "Genaktivér samtale", "status.unpin": "Frigør fra profil", "suggestions.dismiss": "Afvis foreslag", "suggestions.header": "Du er måske interesseret i…", - "tabs_bar.federated_timeline": "Forenede", + "tabs_bar.federated_timeline": "Fælles", "tabs_bar.home": "Hjem", "tabs_bar.local_timeline": "Lokal", "tabs_bar.notifications": "Notifikationer", @@ -438,7 +454,7 @@ "time_remaining.days": "{number, plural, one {# dag} other {# dage}} tilbage", "time_remaining.hours": "{number, plural, one {# time} other {# timer}} tilbage", "time_remaining.minutes": "{number, plural, one {# minut} other {# minutter}} tilbage", - "time_remaining.moments": "Få øjeblikke tilbage", + "time_remaining.moments": "Et øjeblik tilbage", "time_remaining.seconds": "{number, plural, one {# sekund} other {# sekunder}} tilbage", "timeline_hint.remote_resource_not_displayed": "{resource} fra andre servere vises ikke.", "timeline_hint.resources.followers": "Følgere", @@ -446,13 +462,13 @@ "timeline_hint.resources.statuses": "Ældre indlæg", "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} personer}} taler", "trends.trending_now": "Hot lige nu", - "ui.beforeunload": "Dit udkast går tabt, hvis du forlader Mastodon.", - "units.short.billion": "{count}MI", + "ui.beforeunload": "Dit udkast går tabt, hvis du lukker Mastodon.", + "units.short.billion": "{count}G", "units.short.million": "{count}M", - "units.short.thousand": "{count}K", + "units.short.thousand": "{count}k", "upload_area.title": "Træk og slip for at uploade", "upload_button.label": "Tilføj billeder, en video- eller lydfil", - "upload_error.limit": "Filuploadgrænse nået.", + "upload_error.limit": "Grænse for filupload nået.", "upload_error.poll": "Filupload ikke tilladt for afstemninger.", "upload_form.audio_description": "Beskrivelse til hørehæmmede", "upload_form.description": "Beskrivelse til svagtseende", @@ -462,9 +478,9 @@ "upload_form.video_description": "Beskrivelse for hørehæmmede eller synshandicappede personer", "upload_modal.analyzing_picture": "Analyserer billede…", "upload_modal.apply": "Anvend", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Effektuerer…", "upload_modal.choose_image": "Vælg billede", - "upload_modal.description_placeholder": "En hurtig brun ræv hopper over den dovne hund", + "upload_modal.description_placeholder": "Høj bly gom vandt fræk sexquiz på wc", "upload_modal.detect_text": "Detektér tekst i billede", "upload_modal.edit_media": "Redigér medie", "upload_modal.hint": "Klik eller træk cirklen i forhåndsvisningen for at vælge det fokuspunkt, der altid vil være synligt på alle miniaturer.", @@ -477,8 +493,8 @@ "video.expand": "Udvid video", "video.fullscreen": "Fuldskærm", "video.hide": "Skjul video", - "video.mute": "Tavsgør lyd", + "video.mute": "Sluk lyden", "video.pause": "Sæt på pause", "video.play": "Afspil", - "video.unmute": "Fjern lydtavsgørelse" + "video.unmute": "Tænd for lyden" } diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 4e98b7e41..12ac0b253 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -47,16 +47,17 @@ "account.unmute": "@{name} nicht mehr stummschalten", "account.unmute_notifications": "Benachrichtigungen von @{name} einschalten", "account_note.placeholder": "Notiz durch Klicken hinzufügen", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Durchschnitt", + "admin.dashboard.retention.cohort": "Anmeldemonat", + "admin.dashboard.retention.cohort_size": "Neue Benutzer", "alert.rate_limited.message": "Bitte versuche es nach {retry_time, time, medium}.", "alert.rate_limited.title": "Anfragelimit überschritten", "alert.unexpected.message": "Ein unerwarteter Fehler ist aufgetreten.", "alert.unexpected.title": "Hoppla!", "announcement.announcement": "Ankündigung", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(unverarbeitet)", "autosuggest_hashtag.per_week": "{count} pro Woche", "boost_modal.combo": "Drücke {combo}, um dieses Fenster zu überspringen", "bundle_column_error.body": "Etwas ist beim Laden schiefgelaufen.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Umfrage ändern, um eine einzige Wahl zu erlauben", "compose_form.publish": "Tröt", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Medien als NSFW markieren", "compose_form.sensitive.marked": "Medien sind als NSFW markiert", "compose_form.sensitive.unmarked": "Medien sind nicht als NSFW markiert", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Bist du dir sicher, dass du diesen Beitrag löschen möchtest?", "confirmations.delete_list.confirm": "Löschen", "confirmations.delete_list.message": "Bist du dir sicher, dass du diese Liste permanent löschen möchtest?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Verwerfen", + "confirmations.discard_edit_media.message": "Du hast ungespeicherte Änderungen an der Medienbeschreibung oder der Medienvorschau. Trotzdem verwerfen?", "confirmations.domain_block.confirm": "Die ganze Domain blockieren", "confirmations.domain_block.message": "Bist du dir wirklich sicher, dass du die ganze Domain {domain} blockieren willst? In den meisten Fällen reichen ein paar gezielte Blockierungen oder Stummschaltungen aus. Du wirst den Inhalt von dieser Domain nicht in irgendwelchen öffentlichen Timelines oder den Benachrichtigungen finden. Deine Folgenden von dieser Domain werden entfernt.", "confirmations.logout.confirm": "Abmelden", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favorisierungen:", "notifications.column_settings.filter_bar.advanced": "Zeige alle Kategorien an", "notifications.column_settings.filter_bar.category": "Schnellfilterleiste", - "notifications.column_settings.filter_bar.show": "Anzeigen", + "notifications.column_settings.filter_bar.show_bar": "Filterleiste anzeigen", "notifications.column_settings.follow": "Neue Folgende:", "notifications.column_settings.follow_request": "Neue Folgeanfragen:", "notifications.column_settings.mention": "Erwähnungen:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "In der Spalte anzeigen", "notifications.column_settings.sound": "Ton abspielen", "notifications.column_settings.status": "Neue Beiträge:", - "notifications.column_settings.unread_markers.category": "Ungelesene Benachrichtigungsmarkierungen", + "notifications.column_settings.unread_notifications.category": "Ungelesene Benachrichtigungen", + "notifications.column_settings.unread_notifications.highlight": "Ungelesene Benachrichtigungen hervorheben", "notifications.filter.all": "Alle", "notifications.filter.boosts": "Geteilte Beiträge", "notifications.filter.favourites": "Favorisierungen", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# Stimme} other {# Stimmen}}", "poll.vote": "Abstimmen", "poll.voted": "Du hast dafür gestimmt", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# Stimme} other {# Stimmen}}", "poll_button.add_poll": "Eine Umfrage erstellen", "poll_button.remove_poll": "Umfrage entfernen", "privacy.change": "Sichtbarkeit des Beitrags anpassen", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Laden…", "regeneration_indicator.sublabel": "Deine Startseite wird gerade vorbereitet!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "jetzt", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "heute", "reply_indicator.cancel": "Abbrechen", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "An {target} weiterleiten", "report.forward_hint": "Dieses Konto ist von einem anderen Server. Soll eine anonymisierte Kopie des Berichts auch dorthin geschickt werden?", "report.hint": "Der Bericht wird an die Moderatoren des Servers geschickt. Du kannst hier eine Erklärung angeben, warum du dieses Konto meldest:", @@ -396,9 +407,14 @@ "status.delete": "Löschen", "status.detailed_status": "Detaillierte Ansicht der Konversation", "status.direct": "Direktnachricht @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Einbetten", "status.favourite": "Favorisieren", "status.filtered": "Gefiltert", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Weitere laden", "status.media_hidden": "Medien versteckt", "status.mention": "@{name} erwähnen", @@ -462,7 +478,7 @@ "upload_form.video_description": "Beschreibe das Video für Menschen mit einer Hör- oder Sehbehinderung", "upload_modal.analyzing_picture": "Analysiere Bild…", "upload_modal.apply": "Übernehmen", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Anwenden…", "upload_modal.choose_image": "Bild auswählen", "upload_modal.description_placeholder": "Die heiße Zypernsonne quälte Max und Victoria ja böse auf dem Weg bis zur Küste", "upload_modal.detect_text": "Text aus Bild erkennen", diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index 950d73a46..1f6477e44 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -82,6 +82,23 @@ { "descriptors": [ { + "defaultMessage": "Other", + "id": "report.categories.other" + }, + { + "defaultMessage": "Spam", + "id": "report.categories.spam" + }, + { + "defaultMessage": "Content violates one or more server rules", + "id": "report.categories.violation" + } + ], + "path": "app/javascript/mastodon/components/admin/ReportReasonSelector.json" + }, + { + "descriptors": [ + { "defaultMessage": "Loading...", "id": "loading_indicator.label" }, @@ -98,8 +115,12 @@ "id": "admin.dashboard.retention.average" }, { - "defaultMessage": "Retention", - "id": "admin.dashboard.retention" + "defaultMessage": "User retention rate by day after sign-up", + "id": "admin.dashboard.daily_retention" + }, + { + "defaultMessage": "User retention rate by month after sign-up", + "id": "admin.dashboard.monthly_retention" } ], "path": "app/javascript/mastodon/components/admin/Retention.json" @@ -211,6 +232,27 @@ { "descriptors": [ { + "defaultMessage": "Edited {count, plural, one {{count} time} other {{count} times}}", + "id": "status.edited_x_times" + }, + { + "defaultMessage": "{name} created {date}", + "id": "status.history.created" + }, + { + "defaultMessage": "{name} edited {date}", + "id": "status.history.edited" + }, + { + "defaultMessage": "Edited {date}", + "id": "status.edited" + } + ], + "path": "app/javascript/mastodon/components/edited_timestamp/index.json" + }, + { + "descriptors": [ + { "defaultMessage": "This page could not be displayed correctly. This error is likely caused by a browser add-on or automatic translation tools.", "id": "error.unexpected_crash.explanation_addons" }, @@ -382,22 +424,42 @@ "id": "relative_time.just_now" }, { + "defaultMessage": "just now", + "id": "relative_time.full.just_now" + }, + { "defaultMessage": "{number}s", "id": "relative_time.seconds" }, { + "defaultMessage": "{number, plural, one {# second} other {# seconds}} ago", + "id": "relative_time.full.seconds" + }, + { "defaultMessage": "{number}m", "id": "relative_time.minutes" }, { + "defaultMessage": "{number, plural, one {# minute} other {# minutes}} ago", + "id": "relative_time.full.minutes" + }, + { "defaultMessage": "{number}h", "id": "relative_time.hours" }, { + "defaultMessage": "{number, plural, one {# hour} other {# hours}} ago", + "id": "relative_time.full.hours" + }, + { "defaultMessage": "{number}d", "id": "relative_time.days" }, { + "defaultMessage": "{number, plural, one {# day} other {# days}} ago", + "id": "relative_time.full.days" + }, + { "defaultMessage": "Moments remaining", "id": "time_remaining.moments" }, @@ -448,6 +510,10 @@ "id": "status.redraft" }, { + "defaultMessage": "Edit", + "id": "status.edit" + }, + { "defaultMessage": "Direct message @{name}", "id": "status.direct" }, @@ -606,6 +672,10 @@ "id": "privacy.direct.short" }, { + "defaultMessage": "Edited {date}", + "id": "status.edited" + }, + { "defaultMessage": "Filtered", "id": "status.filtered" }, @@ -1106,6 +1176,10 @@ { "defaultMessage": "{publish}!", "id": "compose_form.publish_loud" + }, + { + "defaultMessage": "Save changes", + "id": "compose_form.save_changes" } ], "path": "app/javascript/mastodon/features/compose/components/compose_form.json" @@ -2594,6 +2668,10 @@ "id": "status.redraft" }, { + "defaultMessage": "Edit", + "id": "status.edit" + }, + { "defaultMessage": "Direct message @{name}", "id": "status.direct" }, @@ -2921,6 +2999,19 @@ { "descriptors": [ { + "defaultMessage": "{name} created {date}", + "id": "status.history.created" + }, + { + "defaultMessage": "{name} edited {date}", + "id": "status.history.edited" + } + ], + "path": "app/javascript/mastodon/features/ui/components/compare_history_modal.json" + }, + { + "descriptors": [ + { "defaultMessage": "Cancel", "id": "confirmation_modal.cancel" } diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index 10e08cf97..78d071f66 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -47,16 +47,17 @@ "account.unmute": "Διακοπή αποσιώπησης @{name}", "account.unmute_notifications": "Διακοπή αποσιώπησης ειδοποιήσεων του/της @{name}", "account_note.placeholder": "Κλικ για να βάλεις σημείωση", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.retention.cohort": "Μήνας εγγραφής", + "admin.dashboard.retention.cohort_size": "Νέοι χρήστες", "alert.rate_limited.message": "Παρακαλούμε δοκίμασε ξανά αφού περάσει η {retry_time, time, medium}.", "alert.rate_limited.title": "Περιορισμός συχνότητας", "alert.unexpected.message": "Προέκυψε απροσδόκητο σφάλμα.", "alert.unexpected.title": "Εεπ!", "announcement.announcement": "Ανακοίνωση", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(μη επεξεργασμένο)", "autosuggest_hashtag.per_week": "{count} ανα εβδομάδα", "boost_modal.combo": "Μπορείς να πατήσεις {combo} για να το προσπεράσεις αυτό την επόμενη φορά", "bundle_column_error.body": "Κάτι πήγε στραβά ενώ φορτωνόταν αυτό το στοιχείο.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Ενημέρωση δημοσκόπησης με μοναδική επιλογή", "compose_form.publish": "Τουτ", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Σημείωσε τα πολυμέσα ως ευαίσθητα", "compose_form.sensitive.marked": "Το πολυμέσο έχει σημειωθεί ως ευαίσθητο", "compose_form.sensitive.unmarked": "Το πολυμέσο δεν έχει σημειωθεί ως ευαίσθητο", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Σίγουρα θες να διαγράψεις αυτή τη δημοσίευση;", "confirmations.delete_list.confirm": "Διέγραψε", "confirmations.delete_list.message": "Σίγουρα θες να διαγράψεις οριστικά αυτή τη λίστα;", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Απόρριψη", + "confirmations.discard_edit_media.message": "Έχετε μη αποθηκευμένες αλλαγές στην περιγραφή πολυμέσων ή στην προεπισκόπηση, απορρίψτε τις ούτως ή άλλως;", "confirmations.domain_block.confirm": "Απόκρυψη ολόκληρου του τομέα", "confirmations.domain_block.message": "Σίγουρα θες να μπλοκάρεις ολόκληρο το {domain}; Συνήθως μερικά εστιασμένα μπλοκ ή αποσιωπήσεις επαρκούν και προτιμούνται. Δεν θα βλέπεις περιεχόμενο από αυτό τον κόμβο σε καμία δημόσια ροή, ούτε στις ειδοποιήσεις σου. Όσους ακόλουθους έχεις αυτό αυτό τον κόμβο θα αφαιρεθούν.", "confirmations.logout.confirm": "Αποσύνδεση", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Αγαπημένα:", "notifications.column_settings.filter_bar.advanced": "Εμφάνιση όλων των κατηγοριών", "notifications.column_settings.filter_bar.category": "Μπάρα γρήγορου φίλτρου", - "notifications.column_settings.filter_bar.show": "Εμφάνιση", + "notifications.column_settings.filter_bar.show_bar": "Εμφάνιση μπάρας φίλτρου", "notifications.column_settings.follow": "Νέοι ακόλουθοι:", "notifications.column_settings.follow_request": "Νέο αίτημα παρακολούθησης:", "notifications.column_settings.mention": "Αναφορές:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Εμφάνισε σε στήλη", "notifications.column_settings.sound": "Ηχητική ειδοποίηση", "notifications.column_settings.status": "Νέα τουτ:", - "notifications.column_settings.unread_markers.category": "Δείκτες μη αναγνωσμένων ειδοποιήσεων", + "notifications.column_settings.unread_notifications.category": "Μη αναγνωσμένες ειδοποιήσεις", + "notifications.column_settings.unread_notifications.highlight": "Επισήμανση μη αναγνωσμένων ειδοποιήσεων", "notifications.filter.all": "Όλες", "notifications.filter.boosts": "Προωθήσεις", "notifications.filter.favourites": "Αγαπημένα", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# ψήφος} other {# ψήφοι}}", "poll.vote": "Ψήφισε", "poll.voted": "Ψηφίσατε αυτήν την απάντηση", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# ψήφος} other {# ψήφοι}}", "poll_button.add_poll": "Προσθήκη δημοσκόπησης", "poll_button.remove_poll": "Αφαίρεση δημοσκόπησης", "privacy.change": "Προσαρμογή ιδιωτικότητας δημοσίευσης", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Φορτώνει…", "regeneration_indicator.sublabel": "Η αρχική σου ροή ετοιμάζεται!", "relative_time.days": "{number}η", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}ω", "relative_time.just_now": "τώρα", "relative_time.minutes": "{number}λ", "relative_time.seconds": "{number}δ", "relative_time.today": "σήμερα", "reply_indicator.cancel": "Άκυρο", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Προώθηση προς {target}", "report.forward_hint": "Ο λογαριασμός είναι από διαφορετικό διακομιστή. Να σταλεί ανώνυμο αντίγραφο της καταγγελίας κι εκεί;", "report.hint": "Η καταγγελία θα σταλεί στους διαχειριστές του κόμβου σου. Μπορείς να περιγράψεις γιατί καταγγέλεις αυτόν το λογαριασμό παρακάτω:", @@ -396,9 +407,14 @@ "status.delete": "Διαγραφή", "status.detailed_status": "Προβολή λεπτομερειών συζήτησης", "status.direct": "Προσωπικό μήνυμα προς @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Ενσωμάτωσε", "status.favourite": "Σημείωσε ως αγαπημένο", "status.filtered": "Φιλτραρισμένα", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Φόρτωσε περισσότερα", "status.media_hidden": "Κρυμμένο πολυμέσο", "status.mention": "Ανέφερε τον/την @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Περιγραφή για άτομα με προβλήματα ακοής ή όρασης", "upload_modal.analyzing_picture": "Ανάλυση εικόνας…", "upload_modal.apply": "Εφαρμογή", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Εφαρμογή…", "upload_modal.choose_image": "Επιλογή εικόνας", "upload_modal.description_placeholder": "Λύκος μαύρος και ισχνός του πατέρα του καημός", "upload_modal.detect_text": "Αναγνώριση κειμένου από την εικόνα", diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index ac7d4b53a..9b5676ee3 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -47,7 +47,8 @@ "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", "account_note.placeholder": "Click to add note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -108,6 +109,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -368,12 +370,20 @@ "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "Cancel", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -402,9 +412,14 @@ "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Load more", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index ac1f195b4..c3f7e3acd 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -47,16 +47,17 @@ "account.unmute": "Malsilentigi @{name}", "account.unmute_notifications": "Malsilentigi sciigojn de @{name}", "account_note.placeholder": "Alklaku por aldoni noton", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Averaĝa", + "admin.dashboard.retention.cohort": "Registriĝo monato", + "admin.dashboard.retention.cohort_size": "Novaj uzantoj", "alert.rate_limited.message": "Bonvolu reprovi post {retry_time, time, medium}.", "alert.rate_limited.title": "Mesaĝkvante limigita", "alert.unexpected.message": "Neatendita eraro okazis.", "alert.unexpected.title": "Ups!", "announcement.announcement": "Anonco", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(neprilaborita)", "autosuggest_hashtag.per_week": "{count} semajne", "boost_modal.combo": "Vi povas premi {combo} por preterpasi sekvafoje", "bundle_column_error.body": "Io misfunkciis en la ŝargado de ĉi tiu elemento.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Ŝanĝi la balotenketon por permesi unu solan elekton", "compose_form.publish": "Hup", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Marki la aŭdovidaĵojn kiel tiklaj", "compose_form.sensitive.marked": "Aŭdovidaĵo markita tikla", "compose_form.sensitive.unmarked": "Aŭdovidaĵo ne markita tikla", @@ -118,7 +120,7 @@ "confirmations.delete.message": "Ĉu vi certas, ke vi volas forigi ĉi tiun mesaĝon?", "confirmations.delete_list.confirm": "Forigi", "confirmations.delete_list.message": "Ĉu vi certas, ke vi volas porĉiame forigi ĉi tiun liston?", - "confirmations.discard_edit_media.confirm": "Discard", + "confirmations.discard_edit_media.confirm": "Ne konservi", "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", "confirmations.domain_block.confirm": "Bloki la tutan domajnon", "confirmations.domain_block.message": "Ĉu vi vere, vere certas, ke vi volas tute bloki {domain}? Plej ofte, trafa blokado kaj silentigado sufiĉas kaj preferindas. Vi ne vidos enhavon de tiu domajno en publika templinio aŭ en viaj sciigoj. Viaj sekvantoj de tiu domajno estos forigitaj.", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Stelumoj:", "notifications.column_settings.filter_bar.advanced": "Montri ĉiujn kategoriojn", "notifications.column_settings.filter_bar.category": "Rapida filtra breto", - "notifications.column_settings.filter_bar.show": "Montri", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Novaj sekvantoj:", "notifications.column_settings.follow_request": "Novaj petoj de sekvado:", "notifications.column_settings.mention": "Mencioj:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Montri en kolumno", "notifications.column_settings.sound": "Eligi sonon", "notifications.column_settings.status": "Novaj mesaĝoj:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Nelegitaj sciigoj", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Ĉiuj", "notifications.filter.boosts": "Diskonigoj", "notifications.filter.favourites": "Stelumoj", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# voĉdono} other {# voĉdonoj}}", "poll.vote": "Voĉdoni", "poll.voted": "Vi elektis por ĉi tiu respondo", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# voĉdono} other {# voĉdonoj}}", "poll_button.add_poll": "Aldoni balotenketon", "poll_button.remove_poll": "Forigi balotenketon", "privacy.change": "Agordi mesaĝan privatecon", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Ŝargado…", "regeneration_indicator.sublabel": "Via hejma fluo pretiĝas!", "relative_time.days": "{number}t", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "nun", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "hodiaŭ", "reply_indicator.cancel": "Nuligi", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Plusendi al {target}", "report.forward_hint": "La konto estas en alia servilo. Ĉu sendi sennomigitan kopion de la signalo ankaŭ tien?", "report.hint": "La signalo estos sendita al la kontrolantoj de via servilo. Vi povas doni klarigon pri kial vi signalas ĉi tiun konton sube:", @@ -396,9 +407,14 @@ "status.delete": "Forigi", "status.detailed_status": "Detala konversacia vido", "status.direct": "Rekte mesaĝi @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Enkorpigi", "status.favourite": "Stelumi", "status.filtered": "Filtrita", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Ŝargi pli", "status.media_hidden": "Aŭdovidaĵo kaŝita", "status.mention": "Mencii @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Priskribi por homoj kiuj malfacile aŭdi aŭ vidi", "upload_modal.analyzing_picture": "Bilda analizado…", "upload_modal.apply": "Apliki", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Apliki…", "upload_modal.choose_image": "Elekti bildon", "upload_modal.description_placeholder": "Laŭ Ludoviko Zamenhof bongustas freŝa ĉeĥa manĝaĵo kun spicoj", "upload_modal.detect_text": "Detekti tekston de la bildo", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index 08e9564da..d57be2717 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -47,16 +47,17 @@ "account.unmute": "Dejar de silenciar a @{name}", "account.unmute_notifications": "Dejar de silenciar las notificaciones de @{name}", "account_note.placeholder": "Hacé clic par agregar una nota", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Promedio", + "admin.dashboard.retention.cohort": "Mes de registro", + "admin.dashboard.retention.cohort_size": "Nuevos usuarios", "alert.rate_limited.message": "Por favor, reintentá después de las {retry_time, time, medium}.", "alert.rate_limited.title": "Acción limitada", "alert.unexpected.message": "Ocurrió un error.", "alert.unexpected.title": "¡Epa!", "announcement.announcement": "Anuncio", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "[sin procesar]", "autosuggest_hashtag.per_week": "{count} por semana", "boost_modal.combo": "Podés hacer clic en {combo} para saltar esto la próxima vez", "bundle_column_error.body": "Algo salió mal al cargar este componente.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Cambiar encuesta para permitir una sola opción", "compose_form.publish": "Enviar", "compose_form.publish_loud": "¡{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Marcar medio como sensible", "compose_form.sensitive.marked": "{count, plural, one {El medio está marcado como sensible} other {Los medios están marcados como sensibles}}", "compose_form.sensitive.unmarked": "El medio no está marcado como sensible", @@ -118,8 +120,8 @@ "confirmations.delete.message": "¿Estás seguro que querés eliminar este mensaje?", "confirmations.delete_list.confirm": "Eliminar", "confirmations.delete_list.message": "¿Estás seguro que querés eliminar permanentemente esta lista?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Descartar", + "confirmations.discard_edit_media.message": "Tenés cambios sin guardar en la descripción de medios o en la vista previa, ¿querés descartarlos de todos modos?", "confirmations.domain_block.confirm": "Bloquear dominio entero", "confirmations.domain_block.message": "¿Estás completamente seguro que querés bloquear el {domain} entero? En la mayoría de los casos, unos cuantos bloqueos y silenciados puntuales son suficientes y preferibles. No vas a ver contenido de ese dominio en ninguna de tus líneas temporales o en tus notificaciones. Tus seguidores de ese dominio serán quitados.", "confirmations.logout.confirm": "Cerrar sesión", @@ -267,7 +269,7 @@ "lists.replies_policy.title": "Mostrar respuestas a:", "lists.search": "Buscar entre la gente que seguís", "lists.subheading": "Tus listas", - "load_pending": "{count, plural, one {# nuevo elemento} other {# nuevos elementos}}", + "load_pending": "{count, plural, one {# elemento nuevo} other {# elementos nuevos}}", "loading_indicator.label": "Cargando...", "media_gallery.toggle_visible": "Ocultar {number, plural, one {imagen} other {imágenes}}", "missing_indicator.label": "No se encontró", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favoritos:", "notifications.column_settings.filter_bar.advanced": "Mostrar todas las categorías", "notifications.column_settings.filter_bar.category": "Barra de filtrado rápido", - "notifications.column_settings.filter_bar.show": "Mostrar", + "notifications.column_settings.filter_bar.show_bar": "Mostrar barra de filtros", "notifications.column_settings.follow": "Nuevos seguidores:", "notifications.column_settings.follow_request": "Nuevas solicitudes de seguimiento:", "notifications.column_settings.mention": "Menciones:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Mostrar en columna", "notifications.column_settings.sound": "Reproducir sonido", "notifications.column_settings.status": "Nuevos mensajes:", - "notifications.column_settings.unread_markers.category": "Indicadores de notificaciones no leídas", + "notifications.column_settings.unread_notifications.category": "Notificaciones sin leer", + "notifications.column_settings.unread_notifications.highlight": "Resaltar notificaciones no leídas", "notifications.filter.all": "Todas", "notifications.filter.boosts": "Adhesiones", "notifications.filter.favourites": "Favoritos", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# voto} other {# votos}}", "poll.vote": "Votar", "poll.voted": "Votaste esta opción", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# voto} other {# votos}}", "poll_button.add_poll": "Agregar encuesta", "poll_button.remove_poll": "Quitar encuesta", "privacy.change": "Configurar privacidad del mensaje", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Cargando…", "regeneration_indicator.sublabel": "¡Se está preparando tu línea temporal principal!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "ahora", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "hoy", "reply_indicator.cancel": "Cancelar", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Reenviar a {target}", "report.forward_hint": "La cuenta es de otro servidor. ¿Querés enviar una copia anonimizada del informe también ahí?", "report.hint": "La denuncia se enviará a los moderadores de tu servidor. A continuación, podés proporcionar una explicación de por qué estás denunciando esta cuenta:", @@ -396,9 +407,14 @@ "status.delete": "Eliminar", "status.detailed_status": "Vista de conversación detallada", "status.direct": "Mensaje directo para @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Insertar", "status.favourite": "Marcar como favorito", "status.filtered": "Filtrado", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Cargar más", "status.media_hidden": "Medios ocultos", "status.mention": "Mencionar a @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Agregá una descripción para personas con dificultades auditivas o visuales", "upload_modal.analyzing_picture": "Analizando imagen…", "upload_modal.apply": "Aplicar", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Aplicando…", "upload_modal.choose_image": "Elegir imagen", "upload_modal.description_placeholder": "El veloz murciélago hindú comía feliz cardillo y kiwi. La cigüeña tocaba el saxofón detrás del palenque de paja.", "upload_modal.detect_text": "Detectar texto de la imagen", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index ffd159c02..ba56241ff 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -1,6 +1,6 @@ { "account.account_note_header": "Nota", - "account.add_or_remove_from_list": "Agregar o eliminar de listas", + "account.add_or_remove_from_list": "Agregar o eliminar de las listas", "account.badges.bot": "Bot", "account.badges.group": "Grupo", "account.block": "Bloquear a @{name}", @@ -47,16 +47,17 @@ "account.unmute": "Dejar de silenciar a @{name}", "account.unmute_notifications": "Dejar de silenciar las notificaciones de @{name}", "account_note.placeholder": "Clic para añadir nota", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Promedio", + "admin.dashboard.retention.cohort": "Mes de registro", + "admin.dashboard.retention.cohort_size": "Nuevos usuarios", "alert.rate_limited.message": "Por favor reintente después de {retry_time, time, medium}.", "alert.rate_limited.title": "Tarifa limitada", "alert.unexpected.message": "Hubo un error inesperado.", "alert.unexpected.title": "¡Ups!", "announcement.announcement": "Anuncio", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(sin procesar)", "autosuggest_hashtag.per_week": "{count} por semana", "boost_modal.combo": "Puedes hacer clic en {combo} para saltar este aviso la próxima vez", "bundle_column_error.body": "Algo salió mal al cargar este componente.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Modificar encuesta para permitir una única opción", "compose_form.publish": "Tootear", "compose_form.publish_loud": "¡{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Marcar multimedia como sensible", "compose_form.sensitive.marked": "Material marcado como sensible", "compose_form.sensitive.unmarked": "Material no marcado como sensible", @@ -118,8 +120,8 @@ "confirmations.delete.message": "¿Estás seguro de que quieres borrar este toot?", "confirmations.delete_list.confirm": "Eliminar", "confirmations.delete_list.message": "¿Seguro que quieres borrar esta lista permanentemente?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Descartar", + "confirmations.discard_edit_media.message": "Tienes cambios sin guardar en la descripción o vista previa del archivo, ¿deseas descartarlos de cualquier manera?", "confirmations.domain_block.confirm": "Ocultar dominio entero", "confirmations.domain_block.message": "¿Seguro de que quieres bloquear al dominio {domain} entero? En general unos cuantos bloqueos y silenciados concretos es suficiente y preferible.", "confirmations.logout.confirm": "Cerrar sesión", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favoritos:", "notifications.column_settings.filter_bar.advanced": "Mostrar todas las categorías", "notifications.column_settings.filter_bar.category": "Barra de filtrado rápido", - "notifications.column_settings.filter_bar.show": "Mostrar", + "notifications.column_settings.filter_bar.show_bar": "Mostrar barra de filtros", "notifications.column_settings.follow": "Nuevos seguidores:", "notifications.column_settings.follow_request": "Nuevas solicitudes de seguimiento:", "notifications.column_settings.mention": "Menciones:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Mostrar en columna", "notifications.column_settings.sound": "Reproducir sonido", "notifications.column_settings.status": "Nuevos toots:", - "notifications.column_settings.unread_markers.category": "Indicadores de notificaciones no leídas", + "notifications.column_settings.unread_notifications.category": "Notificaciones sin leer", + "notifications.column_settings.unread_notifications.highlight": "Destacar notificaciones no leídas", "notifications.filter.all": "Todos", "notifications.filter.boosts": "Retoots", "notifications.filter.favourites": "Favoritos", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# voto} other {# votos}}", "poll.vote": "Votar", "poll.voted": "Has votado a favor de esta respuesta", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# voto} other {# votos}}", "poll_button.add_poll": "Añadir una encuesta", "poll_button.remove_poll": "Eliminar encuesta", "privacy.change": "Ajustar privacidad", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Cargando…", "regeneration_indicator.sublabel": "¡Tu historia de inicio se está preparando!", "relative_time.days": "{number} d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number} h", "relative_time.just_now": "ahora", "relative_time.minutes": "{number} m", "relative_time.seconds": "{number} s", "relative_time.today": "hoy", "reply_indicator.cancel": "Cancelar", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Reenviar a {target}", "report.forward_hint": "Esta cuenta es de otro servidor. ¿Enviar una copia anonimizada del informe allí también?", "report.hint": "El informe se enviará a los moderadores de tu instancia. Puedes proporcionar una explicación de por qué informas sobre esta cuenta a continuación:", @@ -396,9 +407,14 @@ "status.delete": "Borrar", "status.detailed_status": "Vista de conversación detallada", "status.direct": "Mensaje directo a @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Incrustado", "status.favourite": "Favorito", "status.filtered": "Filtrado", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Cargar más", "status.media_hidden": "Contenido multimedia oculto", "status.mention": "Mencionar", @@ -462,7 +478,7 @@ "upload_form.video_description": "Describir para personas con problemas auditivos o visuales", "upload_modal.analyzing_picture": "Analizando imagen…", "upload_modal.apply": "Aplicar", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Aplicando…", "upload_modal.choose_image": "Elegir imagen", "upload_modal.description_placeholder": "Un rápido zorro marrón salta sobre el perro perezoso", "upload_modal.detect_text": "Detectar texto de la imagen", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 2b7fb0b6c..0b91f0809 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -47,16 +47,17 @@ "account.unmute": "Dejar de silenciar a @{name}", "account.unmute_notifications": "Dejar de silenciar las notificaciones de @{name}", "account_note.placeholder": "Clic para añadir nota", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Media", + "admin.dashboard.retention.cohort": "Mes de registro", + "admin.dashboard.retention.cohort_size": "Nuevos usuarios", "alert.rate_limited.message": "Por favor reintente después de {retry_time, time, medium}.", "alert.rate_limited.title": "Tarifa limitada", "alert.unexpected.message": "Hubo un error inesperado.", "alert.unexpected.title": "¡Ups!", "announcement.announcement": "Anuncio", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(sin procesar)", "autosuggest_hashtag.per_week": "{count} por semana", "boost_modal.combo": "Puedes hacer clic en {combo} para saltar este aviso la próxima vez", "bundle_column_error.body": "Algo salió mal al cargar este componente.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Modificar encuesta para permitir una única opción", "compose_form.publish": "Tootear", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Marcar material como sensible} other {Marcar material como sensible}}", "compose_form.sensitive.marked": "{count, plural, one {Material marcado como sensible} other {Material marcado como sensible}}", "compose_form.sensitive.unmarked": "{count, plural, one {Material no marcado como sensible} other {Material no marcado como sensible}}", @@ -118,8 +120,8 @@ "confirmations.delete.message": "¿Estás seguro de que quieres borrar esta publicación?", "confirmations.delete_list.confirm": "Eliminar", "confirmations.delete_list.message": "¿Seguro que quieres borrar esta lista permanentemente?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Descartar", + "confirmations.discard_edit_media.message": "Tienes cambios sin guardar en la descripción o vista previa del archivo audiovisual, ¿descartarlos de todos modos?", "confirmations.domain_block.confirm": "Ocultar dominio entero", "confirmations.domain_block.message": "¿Seguro de que quieres bloquear al dominio {domain} entero? En general unos cuantos bloqueos y silenciados concretos es suficiente y preferible.", "confirmations.logout.confirm": "Cerrar sesión", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favoritos:", "notifications.column_settings.filter_bar.advanced": "Mostrar todas las categorías", "notifications.column_settings.filter_bar.category": "Barra de filtrado rápido", - "notifications.column_settings.filter_bar.show": "Mostrar", + "notifications.column_settings.filter_bar.show_bar": "Mostrar barra de filtros", "notifications.column_settings.follow": "Nuevos seguidores:", "notifications.column_settings.follow_request": "Nuevas solicitudes de seguimiento:", "notifications.column_settings.mention": "Menciones:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Mostrar en columna", "notifications.column_settings.sound": "Reproducir sonido", "notifications.column_settings.status": "Nuevas publicaciones:", - "notifications.column_settings.unread_markers.category": "Indicadores de notificaciones no leídas", + "notifications.column_settings.unread_notifications.category": "Notificaciones sin leer", + "notifications.column_settings.unread_notifications.highlight": "Destacar notificaciones no leídas", "notifications.filter.all": "Todos", "notifications.filter.boosts": "Retoots", "notifications.filter.favourites": "Favoritos", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# voto} other {# votos}}", "poll.vote": "Votar", "poll.voted": "Has votado a favor de esta respuesta", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# voto} other {# votos}}", "poll_button.add_poll": "Añadir una encuesta", "poll_button.remove_poll": "Eliminar encuesta", "privacy.change": "Ajustar privacidad", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Cargando…", "regeneration_indicator.sublabel": "¡Tu historia de inicio se está preparando!", "relative_time.days": "{number} d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number} h", "relative_time.just_now": "ahora", "relative_time.minutes": "{number} m", "relative_time.seconds": "{number} s", "relative_time.today": "hoy", "reply_indicator.cancel": "Cancelar", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Reenviar a {target}", "report.forward_hint": "Esta cuenta es de otro servidor. ¿Enviar una copia anonimizada del informe allí también?", "report.hint": "El informe se enviará a los moderadores de tu instancia. Puedes proporcionar una explicación de por qué informas sobre esta cuenta a continuación:", @@ -396,9 +407,14 @@ "status.delete": "Borrar", "status.detailed_status": "Vista de conversación detallada", "status.direct": "Mensaje directo a @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Incrustado", "status.favourite": "Favorito", "status.filtered": "Filtrado", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Cargar más", "status.media_hidden": "Contenido multimedia oculto", "status.mention": "Mencionar", @@ -462,7 +478,7 @@ "upload_form.video_description": "Describir para personas con problemas auditivos o visuales", "upload_modal.analyzing_picture": "Analizando imagen…", "upload_modal.apply": "Aplicar", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Aplicando…", "upload_modal.choose_image": "Elegir imagen", "upload_modal.description_placeholder": "Un rápido zorro marrón salta sobre el perro perezoso", "upload_modal.detect_text": "Detectar texto de la imagen", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index e71e56dee..c1c71a91a 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -47,7 +47,8 @@ "account.unmute": "Ära vaigista @{name}", "account.unmute_notifications": "Ära vaigista teateid kasutajalt @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Muuda küsitlust lubamaks ainult ühte valikut", "compose_form.publish": "Tuut", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Märgista meedia tundlikuks", "compose_form.sensitive.marked": "Meedia on sensitiivseks märgitud", "compose_form.sensitive.unmarked": "Meedia ei ole sensitiivseks märgitud", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Lemmikud:", "notifications.column_settings.filter_bar.advanced": "Kuva kõik kategooriad", "notifications.column_settings.filter_bar.category": "Kiirfiltri riba", - "notifications.column_settings.filter_bar.show": "Kuva", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Uued jälgijad:", "notifications.column_settings.follow_request": "Uued jälgimistaotlused:", "notifications.column_settings.mention": "Mainimised:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Kuva tulbas", "notifications.column_settings.sound": "Mängi heli", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Kõik", "notifications.filter.boosts": "Upitused", "notifications.filter.favourites": "Lemmikud", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Laeb…", "regeneration_indicator.sublabel": "Teie kodu voog on ettevalmistamisel!", "relative_time.days": "{number}p", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}t", "relative_time.just_now": "nüüd", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "täna", "reply_indicator.cancel": "Tühista", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Edasta kasutajale {target}", "report.forward_hint": "See kasutaja on teisest serverist. Kas saadan anonümiseeritud koopia sellest teatest sinna ka?", "report.hint": "See teade saadetakse Teie serveri moderaatoritele. Te saate lisada selgituse selle kohta, miks selle kasutaja kohta teate esitasite, siin:", @@ -396,9 +407,14 @@ "status.delete": "Kustuta", "status.detailed_status": "Detailne vestluskuva", "status.direct": "Otsesõnum @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Sängita", "status.favourite": "Lemmik", "status.filtered": "Filtreeritud", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Lae veel", "status.media_hidden": "Meedia peidetud", "status.mention": "Mainimine @{name}", diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json index b457b7d45..4581dfe95 100644 --- a/app/javascript/mastodon/locales/eu.json +++ b/app/javascript/mastodon/locales/eu.json @@ -47,16 +47,17 @@ "account.unmute": "Desmututu @{name}", "account.unmute_notifications": "Desmututu @{name}(r)en jakinarazpenak", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Batezbestekoa", + "admin.dashboard.retention.cohort": "Izen emate hilean", + "admin.dashboard.retention.cohort_size": "Erabiltzaile berriak", "alert.rate_limited.message": "Saiatu {retry_time, time, medium} barru.", "alert.rate_limited.title": "Abiadura mugatua", "alert.unexpected.message": "Ustekabeko errore bat gertatu da.", "alert.unexpected.title": "Ene!", "announcement.announcement": "Iragarpena", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(prozesatu gabe)", "autosuggest_hashtag.per_week": "{count} asteko", "boost_modal.combo": "{combo} sakatu dezakezu hurrengoan hau saltatzeko", "bundle_column_error.body": "Zerbait okerra gertatu da osagai hau kargatzean.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Aldatu inkesta aukera bakarra onartzeko", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Markatu multimedia hunkigarri gisa", "compose_form.sensitive.marked": "Multimedia edukia hunkigarri gisa markatu da", "compose_form.sensitive.unmarked": "Multimedia edukia ez da hunkigarri gisa markatu", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Ziur bidalketa hau ezabatu nahi duzula?", "confirmations.delete_list.confirm": "Ezabatu", "confirmations.delete_list.message": "Ziur behin betiko ezabatu nahi duzula zerrenda hau?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Baztertu", + "confirmations.discard_edit_media.message": "Multimediaren deskribapen edo aurrebistan gorde gabeko aldaketak daude, baztertu nahi dituzu?", "confirmations.domain_block.confirm": "Ezkutatu domeinu osoa", "confirmations.domain_block.message": "Ziur, erabat ziur, {domain} domeinu osoa blokeatu nahi duzula? Gehienetan gutxi batzuk blokeatu edo mututzearekin nahikoa da. Ez duzu domeinu horretako edukirik ikusiko denbora lerroetan edo jakinarazpenetan. Domeinu horretako zure jarraitzaileak kenduko dira ere.", "confirmations.logout.confirm": "Amaitu saioa", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Gogokoak:", "notifications.column_settings.filter_bar.advanced": "Erakutsi kategoria guztiak", "notifications.column_settings.filter_bar.category": "Iragazki azkarraren barra", - "notifications.column_settings.filter_bar.show": "Erakutsi", + "notifications.column_settings.filter_bar.show_bar": "Erakutsi iragazki-barra", "notifications.column_settings.follow": "Jarraitzaile berriak:", "notifications.column_settings.follow_request": "Jarraitzeko eskaera berriak:", "notifications.column_settings.mention": "Aipamenak:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Erakutsi zutabean", "notifications.column_settings.sound": "Jo soinua", "notifications.column_settings.status": "Bidalketa berriak:", - "notifications.column_settings.unread_markers.category": "Irakurri gabeko jakinarazpenen markatzaileak", + "notifications.column_settings.unread_notifications.category": "Irakurri gabeko jakinarazpenak", + "notifications.column_settings.unread_notifications.highlight": "Nabarmendu irakurri gabeko jakinarazpenak", "notifications.filter.all": "Denak", "notifications.filter.boosts": "Bultzadak", "notifications.filter.favourites": "Gogokoak", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {boto #} other {# boto}}", "poll.vote": "Bozkatu", "poll.voted": "Erantzun honi eman diozu botoa", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {boto #} other {# boto}}", "poll_button.add_poll": "Gehitu inkesta bat", "poll_button.remove_poll": "Kendu inkesta", "privacy.change": "Aldatu bidalketaren pribatutasuna", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Kargatzen…", "regeneration_indicator.sublabel": "Zure hasiera-jarioa prestatzen ari da!", "relative_time.days": "{number}e", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "orain", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "gaur", "reply_indicator.cancel": "Utzi", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Birbidali hona: {target}", "report.forward_hint": "Kontu hau beste zerbitzari batekoa da. Bidali txostenaren kopia anonimo hara ere?", "report.hint": "Txostena zure zerbitzariaren moderatzaileei bidaliko zaie. Kontu hau zergatik salatzen duzun behean azaldu dezakezu:", @@ -396,9 +407,14 @@ "status.delete": "Ezabatu", "status.detailed_status": "Elkarrizketaren ikuspegi xehetsua", "status.direct": "Mezu zuzena @{name}(r)i", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Txertatu", "status.favourite": "Gogokoa", "status.filtered": "Iragazita", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Kargatu gehiago", "status.media_hidden": "Multimedia ezkutatua", "status.mention": "Aipatu @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Deskribatu entzumen galera edo ikusmen urritasuna duten pertsonentzat", "upload_modal.analyzing_picture": "Irudia aztertzen…", "upload_modal.apply": "Aplikatu", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Aplikatzen…", "upload_modal.choose_image": "Aukeratu irudia", "upload_modal.description_placeholder": "Vaudeville itxurako filmean yogi ñaño bat jipoitzen dute Quebec-en whiski truk", "upload_modal.detect_text": "Antzeman testua iruditik", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index c0582da74..f36850dc2 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -1,11 +1,11 @@ { "account.account_note_header": "یادداشت", - "account.add_or_remove_from_list": "افزودن یا برداشتن از فهرستها", - "account.badges.bot": "ربات", + "account.add_or_remove_from_list": "افزودن یا برداشتن از سیاههها", + "account.badges.bot": "روبات", "account.badges.group": "گروه", "account.block": "مسدود کردن @{name}", "account.block_domain": "مسدود کردن دامنهٔ {domain}", - "account.blocked": "مسدود شده", + "account.blocked": "مسدود", "account.browse_more_on_origin_server": "مرور بیشتر روی نمایهٔ اصلی", "account.cancel_follow_request": "لغو درخواست پیگیری", "account.direct": "پیام مستقیم به @{name}", @@ -20,7 +20,7 @@ "account.followers_counter": "{count, plural, one {{counter} پیگیرنده} other {{counter} پیگیرنده}}", "account.following_counter": "{count, plural, one {{counter} پیگرفته} other {{counter} پیگرفته}}", "account.follows.empty": "این کاربر هنوز پیگیر کسی نیست.", - "account.follows_you": "پیگیر شماست", + "account.follows_you": "پی میگیردتان", "account.hide_reblogs": "نهفتن تقویتهای @{name}", "account.joined": "پیوسته از {date}", "account.last_status": "آخرین فعّالیت", @@ -47,23 +47,24 @@ "account.unmute": "ناخموشی @{name}", "account.unmute_notifications": "ناخموشی آگاهیها از @{name}", "account_note.placeholder": "برای افزودن یادداشت کلیک کنید", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "میانگین", + "admin.dashboard.retention.cohort": "ماه ثبتنام", + "admin.dashboard.retention.cohort_size": "کاربران جدید", "alert.rate_limited.message": "لطفاً پس از {retry_time, time, medium} دوباره بیازمایید.", "alert.rate_limited.title": "محدودیت تعداد", "alert.unexpected.message": "خطایی غیرمنتظره رخ داد.", "alert.unexpected.title": "ای وای!", "announcement.announcement": "اعلامیه", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(پردازش نشده)", "autosuggest_hashtag.per_week": "{count} در هفته", "boost_modal.combo": "دکمهٔ {combo} را بزنید تا دیگر این را نبینید", - "bundle_column_error.body": "هنگام بارگزاری این بخش خطایی رخ داد.", + "bundle_column_error.body": "هنگام بار کردن این مولفه، اشتباهی رخ داد.", "bundle_column_error.retry": "تلاش دوباره", "bundle_column_error.title": "خطای شبکه", "bundle_modal_error.close": "بستن", - "bundle_modal_error.message": "هنگام بارگزاری این بخش خطایی رخ داد.", + "bundle_modal_error.message": "هنگام بار کردن این مولفه، اشتباهی رخ داد.", "bundle_modal_error.retry": "تلاش دوباره", "column.blocks": "کاربران مسدود شده", "column.bookmarks": "نشانکها", @@ -74,7 +75,7 @@ "column.favourites": "پسندیدهها", "column.follow_requests": "درخواستهای پیگیری", "column.home": "خانه", - "column.lists": "فهرستها", + "column.lists": "سیاههها", "column.mutes": "کاربران خموش", "column.notifications": "آگاهیها", "column.pins": "فرستههای سنجاقشده", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "تبدیل به نظرسنجی تکگزینهای", "compose_form.publish": "بوق", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {علامتگذاری رسانه به عنوان حساس} other {علامتگذاری رسانهها به عنوان حساس}}", "compose_form.sensitive.marked": "{count, plural, one {رسانه به عنوان حساس علامتگذاری شد} other {رسانهها به عنوان حساس علامتگذاری شدند}}", "compose_form.sensitive.unmarked": "{count, plural, one {رسانه به عنوان حساس علامتگذاری نشد} other {رسانهها به عنوان حساس علامتگذاری نشدند}}", @@ -117,9 +119,9 @@ "confirmations.delete.confirm": "حذف", "confirmations.delete.message": "آیا مطمئنید که میخواهید این فرسته را حذف کنید؟", "confirmations.delete_list.confirm": "حذف", - "confirmations.delete_list.message": "مطمئنید میخواهید این فهرست را برای همیشه حذف کنید؟", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.delete_list.message": "مطمئنید میخواهید این سیاهه را برای همیشه حذف کنید؟", + "confirmations.discard_edit_media.confirm": "دور انداختن", + "confirmations.discard_edit_media.message": "تغییرات ذخیره نشدهای در توضیحات یا پیشنمایش رسانه دارید. همگی نادیده گرفته شوند؟", "confirmations.domain_block.confirm": "مسدود کردن تمام دامنه", "confirmations.domain_block.message": "آیا جدی جدی میخواهید تمام دامنهٔ {domain} را مسدود کنید؟ در بیشتر موارد مسدود کردن یا خموشاندن چند حساب خاص کافی است و توصیه میشود. پس از این کار شما هیچ محتوایی را از این دامنه در خط زمانی عمومی یا آگاهیهایتان نخواهید دید. پیگیرانتان از این دامنه هم برداشته خواهند شد.", "confirmations.logout.confirm": "خروج از حساب", @@ -170,12 +172,12 @@ "empty_column.follow_recommendations": "ظاهرا هیچ پیشنهادی برای شما نمیتوانیم تولید کنیم. میتوانید از امکان جستوجو برای یافتن افرادی که ممکن است بشناسید و یا کاوش میان برچسبهای داغ استفاده کنید.", "empty_column.follow_requests": "شما هنوز هیچ درخواست پیگیریای ندارید. هنگامی که چنین درخواستی بگیرید، اینجا نشان داده خواهد شد.", "empty_column.hashtag": "هنوز هیچ چیزی در این برچسب نیست.", - "empty_column.home": "خط زمانی خانگی شما خالی است! افراد بیشتری را پیگیری کنید تا پُر شود. {suggestions}", + "empty_column.home": "خط زمانی خانگیتان خالی است! برای پر کردنش، افراد بیشتری را پی بگیرید. {suggestions}", "empty_column.home.suggestions": "چند پیشنهاد را ببینید", - "empty_column.list": "در این فهرست هنوز چیزی نیست. هنگامی که اعضای این فهرست چیزی بفرستند، اینجا ظاهر خواهد شد.", - "empty_column.lists": "هنوز هیچ فهرستی ندارید. هنگامی که فهرستی بسازید، اینجا نشان داده خواهد شد.", + "empty_column.list": "هنوز چیزی در این سیاهه نیست. هنگامی که اعضایش فرستههای جدیدی بفرستند، اینجا ظاهر خواهند شد.", + "empty_column.lists": "هنوز هیچ سیاههای ندارید. هنگامی که یکی بسازید، اینجا نشان داده خواهد شد.", "empty_column.mutes": "هنوز هیچ کاربری را خموش نکردهاید.", - "empty_column.notifications": "هنوز هیچ اعلانی ندارید. به دیگران واکنش نشان دهید تا گفتگو آغاز شود.", + "empty_column.notifications": "هنوز هیچ آگاهیآی ندارید. هنگامی که دیگران با شما برهمکنش داشته باشند،اینحا خواهید دیدش.", "empty_column.public": "اینجا هنوز چیزی نیست! خودتان چیزی بنویسید یا کاربران کارسازهای دیگر را پیگیری کنید تا اینجا پُر شود", "error.unexpected_crash.explanation": "به خاطر اشکالی در کدهای ما یا ناسازگاری با مرورگر شما، این صفحه به درستی نمایش نیافت.", "error.unexpected_crash.explanation_addons": "این صفحه نمیتواند درست نشان داده شود. احتمالاً این خطا ناشی از یک افزونهٔ مرورگر یا ابزار ترجمهٔ خودکار است.", @@ -216,16 +218,16 @@ "intervals.full.hours": "{number, plural, one {# ساعت} other {# ساعت}}", "intervals.full.minutes": "{number, plural, one {# دقیقه} other {# دقیقه}}", "keyboard_shortcuts.back": "بازگشت", - "keyboard_shortcuts.blocked": "گشودن فهرست کاربران مسدود شده", + "keyboard_shortcuts.blocked": "گشودن سیاههٔ کاربران مسدود", "keyboard_shortcuts.boost": "تقویت فرسته", "keyboard_shortcuts.column": "برای تمرکز روی یک فرسته در یکی از ستونها", "keyboard_shortcuts.compose": "تمرکز روی محیط نوشتن", "keyboard_shortcuts.description": "توضیح", "keyboard_shortcuts.direct": "گشودن ستون پیامهای مستقیم", - "keyboard_shortcuts.down": "پایین رفتن در فهرست", + "keyboard_shortcuts.down": "پایین بردن در سیاهه", "keyboard_shortcuts.enter": "گشودن فرسته", "keyboard_shortcuts.favourite": "پسندیدن فرسته", - "keyboard_shortcuts.favourites": "گشودن فهرست پسندیدهها", + "keyboard_shortcuts.favourites": "گشودن سیاههٔ برگزیدهها", "keyboard_shortcuts.federated": "گشودن خط زمانی همگانی", "keyboard_shortcuts.heading": "میانبرهای صفحهکلید", "keyboard_shortcuts.home": "گشودن خط زمانی خانگی", @@ -237,10 +239,10 @@ "keyboard_shortcuts.my_profile": "گشودن نمایهتان", "keyboard_shortcuts.notifications": "گشودن ستون آگاهیها", "keyboard_shortcuts.open_media": "گشودن رسانه", - "keyboard_shortcuts.pinned": "گشودن فهرست فرستههای سنجاقشده", + "keyboard_shortcuts.pinned": "گشودن سیاههٔ فرستههای سنجاق شده", "keyboard_shortcuts.profile": "گشودن نمایهٔ نویسنده", "keyboard_shortcuts.reply": "پاسخ به فرسته", - "keyboard_shortcuts.requests": "گشودن فهرست درخواستهای پیگیری", + "keyboard_shortcuts.requests": "گشودن سیاههٔ درخواستهای پیگیری", "keyboard_shortcuts.search": "تمرکز روی جستوجو", "keyboard_shortcuts.spoilers": "نمایش/نهفتن زمینهٔ هشدار محتوا", "keyboard_shortcuts.start": "گشودن ستون «آغاز کنید»", @@ -248,32 +250,32 @@ "keyboard_shortcuts.toggle_sensitivity": "نمایش/نهفتن رسانه", "keyboard_shortcuts.toot": "شروع یک فرستهٔ جدید", "keyboard_shortcuts.unfocus": "برداشتن تمرکز از نوشتن/جستوجو", - "keyboard_shortcuts.up": "بالا رفتن در فهرست", + "keyboard_shortcuts.up": "بالا بردن در سیاهه", "lightbox.close": "بستن", "lightbox.compress": "فشردهسازی جعبهٔ نمایش تصویر", "lightbox.expand": "گسترش جعبهٔ نمایش تصویر", "lightbox.next": "بعدی", "lightbox.previous": "قبلی", - "lists.account.add": "افزودن به فهرست", - "lists.account.remove": "برداشتن از فهرست", - "lists.delete": "حذف فهرست", - "lists.edit": "ویرایش فهرست", + "lists.account.add": "افزودن به سیاهه", + "lists.account.remove": "برداشتن از سیاهه", + "lists.delete": "حذف سیاهه", + "lists.edit": "ویرایش سیاهه", "lists.edit.submit": "تغییر عنوان", - "lists.new.create": "افزودن فهرست", - "lists.new.title_placeholder": "عنوان فهرست جدید", + "lists.new.create": "افزودن سیاهه", + "lists.new.title_placeholder": "عنوان سیاههٔ جدید", "lists.replies_policy.followed": "هر کاربر پیگرفته", - "lists.replies_policy.list": "اعضای فهرست", + "lists.replies_policy.list": "اعضای سیاهه", "lists.replies_policy.none": "هیچ کدام", "lists.replies_policy.title": "نمایش پاسخها به:", "lists.search": "جستوجو بین کسانی که پیگرفتهاید", - "lists.subheading": "فهرستهای شما", + "lists.subheading": "سیاهههایتان", "load_pending": "{count, plural, one {# مورد جدید} other {# مورد جدید}}", - "loading_indicator.label": "بارگزاری...", + "loading_indicator.label": "بار کردن…", "media_gallery.toggle_visible": "{number, plural, one {نهفتن تصویر} other {نهفتن تصاویر}}", "missing_indicator.label": "پیدا نشد", "missing_indicator.sublabel": "این منبع پیدا نشد", "mute_modal.duration": "مدت زمان", - "mute_modal.hide_notifications": "اعلانهای این کاربر پنهان شود؟", + "mute_modal.hide_notifications": "نهفتن آگاهیها از این کاربر؟", "mute_modal.indefinite": "نامعلوم", "navigation_bar.apps": "برنامههای تلفن همراه", "navigation_bar.blocks": "کاربران مسدود شده", @@ -290,7 +292,7 @@ "navigation_bar.follows_and_followers": "پیگرفتگان و پیگیرندگان", "navigation_bar.info": "دربارهٔ این کارساز", "navigation_bar.keyboard_shortcuts": "میانبرها", - "navigation_bar.lists": "فهرستها", + "navigation_bar.lists": "سیاههها", "navigation_bar.logout": "خروج", "navigation_bar.mutes": "کاربران خموشانده", "navigation_bar.personal": "شخصی", @@ -306,23 +308,24 @@ "notification.poll": "نظرسنجیای که در آن رأی دادید به پایان رسیده است", "notification.reblog": "{name} فرستهتان را تقویت کرد", "notification.status": "{name} چیزی فرستاد", - "notifications.clear": "پاککردن آگاهیها", + "notifications.clear": "پاکسازی آگاهیها", "notifications.clear_confirmation": "مطمئنید میخواهید همهٔ آگاهیهایتان را برای همیشه پاک کنید؟", "notifications.column_settings.alert": "آگاهیهای میزکار", "notifications.column_settings.favourite": "پسندیدهها:", "notifications.column_settings.filter_bar.advanced": "نمایش همۀ دستهها", "notifications.column_settings.filter_bar.category": "نوار پالایش سریع", - "notifications.column_settings.filter_bar.show": "نمایش", + "notifications.column_settings.filter_bar.show_bar": "نمایش نوار پالایه", "notifications.column_settings.follow": "پیگیرندگان جدید:", "notifications.column_settings.follow_request": "درخواستهای جدید پیگیری:", "notifications.column_settings.mention": "نامبردنها:", "notifications.column_settings.poll": "نتایج نظرسنجی:", - "notifications.column_settings.push": "اعلانها از سمت سرور", + "notifications.column_settings.push": "آگاهیهای ارسالی", "notifications.column_settings.reblog": "تقویتها:", "notifications.column_settings.show": "نمایش در ستون", "notifications.column_settings.sound": "پخش صدا", "notifications.column_settings.status": "فرستههای جدید:", - "notifications.column_settings.unread_markers.category": "نشانهگذارهای آگاهیهای خواندهنشده", + "notifications.column_settings.unread_notifications.category": "آگاهیهای خوانده نشده", + "notifications.column_settings.unread_notifications.highlight": "پررنگ کردن آگاهیهای خوانده نشده", "notifications.filter.all": "همه", "notifications.filter.boosts": "تقویتها", "notifications.filter.favourites": "پسندها", @@ -335,9 +338,9 @@ "notifications.mark_as_read": "نشانهگذاری تمام آگاهیها به خواندهشده", "notifications.permission_denied": "آگاهیهای میزکار به دلیل رد کردن درخواست اجازهٔ پیشین مرورگر، در دسترس نیستند", "notifications.permission_denied_alert": "از آنجا که پیش از این اجازهٔ مرورگر رد شده است، آگاهیهای میزکار نمیتوانند به کار بیفتند", - "notifications.permission_required": "اعلانهای میزکار در دسترس نیستند زیرا نیازمند مجوزی هستند که اعطا نشده است.", + "notifications.permission_required": "آگاهیهای میزکار در دسترس نیستند زیرا اجازههای لازم، اعطا نشده.", "notifications_permission_banner.enable": "به کار انداختن آگاهیهای میزکار", - "notifications_permission_banner.how_to_control": "اگر میخواهید حتی زمانی که ماستودون باز نیست اعلانها نمایش یابند، اعلانهای میزکار را فعال کنید. به محض فعال شدن از طریق دکمه {icon} بالا میتوانید به دقت کنترل کنید که چه نوع از تعاملها باعث صادر شدن اعلانها شوند.", + "notifications_permission_banner.how_to_control": "برای دریافت آگاهیها هنگام باز نبودن ماستودون، آگاهیهای میزکار را به کار بیندازید. پس از به کار افتادنشان میتوانید گونههای دقیق برهمکنشهایی که آگاهیهای میزکار تولید میکنند را از {icon} بالا واپایید.", "notifications_permission_banner.title": "هرگز چیزی را از دست ندهید", "picture_in_picture.restore": "برگرداندن", "poll.closed": "پایانیافته", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# رأی} other {# رأی}}", "poll.vote": "رأی", "poll.voted": "شما به این جواب رأی دادید", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "# رأی", "poll_button.add_poll": "افزودن نظرسنجی", "poll_button.remove_poll": "برداشتن نظرسنجی", "privacy.change": "تغییر محرمانگی فرسته", @@ -357,17 +360,25 @@ "privacy.public.long": "نمایان برای همه، در خطهای زمانی همگانی نمایش داده خواهد شد", "privacy.public.short": "عمومی", "privacy.unlisted.long": "نمایان برای همه، ولی در خطهای زمانی همگانی نمایش داده نخواهد شد", - "privacy.unlisted.short": "فهرستنشده", + "privacy.unlisted.short": "فهرست نشده", "refresh": "نوسازی", "regeneration_indicator.label": "در حال بار شدن…", - "regeneration_indicator.sublabel": "این فهرست دارد آماده میشود!", + "regeneration_indicator.sublabel": "خوراک خانگیان دارد آماده میشود!", "relative_time.days": "{number} روز", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number} ساعت", "relative_time.just_now": "حالا", "relative_time.minutes": "{number} دقیقه", "relative_time.seconds": "{number} ثانیه", "relative_time.today": "امروز", "reply_indicator.cancel": "لغو", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "فرستادن به {target}", "report.forward_hint": "این حساب در کارساز دیگری ثبت شده. آیا میخواهید رونوشتی ناشناس از این گزارش به آنجا هم فرستاده شود؟", "report.hint": "این گزارش به مدیران کارسازتان فرستاده خواهد شد. میتوانید دلیل گزارش این حساب را در ادامه بنویسید:", @@ -396,10 +407,15 @@ "status.delete": "حذف", "status.detailed_status": "نمایش کامل گفتگو", "status.direct": "پیام مستقیم به @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "جاگذاری", "status.favourite": "پسندیدن", "status.filtered": "پالایششده", - "status.load_more": "بارگزاری بیشتر", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", + "status.load_more": "بار کردن بیشتر", "status.media_hidden": "رسانهٔ نهفته", "status.mention": "نامبردن از @{name}", "status.more": "بیشتر", @@ -462,7 +478,7 @@ "upload_form.video_description": "برای کمبینایان یا ناشنوایان توصیفش کنید", "upload_modal.analyzing_picture": "در حال پردازش تصویر…", "upload_modal.apply": "اعمال", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "اعمال کردن…", "upload_modal.choose_image": "گزینش تصویر", "upload_modal.description_placeholder": "الا یا ایّها الساقی، ادر کأساً و ناولها", "upload_modal.detect_text": "تشخیص متن درون عکس", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index 6829aced1..58e65bed1 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -9,10 +9,10 @@ "account.browse_more_on_origin_server": "Selaile lisää alkuperäisellä palvelimella", "account.cancel_follow_request": "Peruuta seurauspyyntö", "account.direct": "Pikaviesti käyttäjälle @{name}", - "account.disable_notifications": "Lopeta ilmoittamasta minulle, kun @{name} viestii", + "account.disable_notifications": "Lopeta @{name}:n julkaisuista ilmoittaminen", "account.domain_blocked": "Verkko-osoite piilotettu", "account.edit_profile": "Muokkaa profiilia", - "account.enable_notifications": "Ilmoita minulle, kun @{name} viestii", + "account.enable_notifications": "Ilmoita @{name}:n julkaisuista", "account.endorse": "Suosittele profiilissasi", "account.follow": "Seuraa", "account.followers": "Seuraajat", @@ -43,20 +43,21 @@ "account.unblock": "Salli @{name}", "account.unblock_domain": "Salli {domain}", "account.unendorse": "Poista suosittelu profiilistasi", - "account.unfollow": "Lakkaa seuraamasta", + "account.unfollow": "Lopeta seuraaminen", "account.unmute": "Poista käyttäjän @{name} mykistys", "account.unmute_notifications": "Poista mykistys käyttäjän @{name} ilmoituksilta", "account_note.placeholder": "Lisää muistiinpano napsauttamalla", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Keskimäärin", + "admin.dashboard.retention.cohort": "Kirjautumiset", + "admin.dashboard.retention.cohort_size": "Uudet käyttäjät", "alert.rate_limited.message": "Yritä uudestaan {retry_time, time, medium} jälkeen.", "alert.rate_limited.title": "Määrää rajoitettu", "alert.unexpected.message": "Tapahtui odottamaton virhe.", "alert.unexpected.title": "Hups!", "announcement.announcement": "Ilmoitus", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(käsittelemätön)", "autosuggest_hashtag.per_week": "{count} viikossa", "boost_modal.combo": "Ensi kerralla voit ohittaa tämän painamalla {combo}", "bundle_column_error.body": "Jokin meni vikaan komponenttia ladattaessa.", @@ -77,7 +78,7 @@ "column.lists": "Listat", "column.mutes": "Mykistetyt käyttäjät", "column.notifications": "Ilmoitukset", - "column.pins": "Kiinnitetyt tuuttaukset", + "column.pins": "Kiinnitetyt julkaisut", "column.public": "Yleinen aikajana", "column_back_button.label": "Takaisin", "column_header.hide_settings": "Piilota asetukset", @@ -92,7 +93,7 @@ "community.column_settings.remote_only": "Vain etäkäyttö", "compose_form.direct_message_warning": "Tämä viesti näkyy vain mainituille käyttäjille.", "compose_form.direct_message_warning_learn_more": "Lisätietoja", - "compose_form.hashtag_warning": "Tämä tuuttaus ei näy hashtag-hauissa, koska se on listaamaton. Hashtagien avulla voi hakea vain julkisia tuuttauksia.", + "compose_form.hashtag_warning": "Tätä julkaisua listata minkään hastagin alle, koska se on listaamaton. Ainoastaan julkisia julkaisuja etsiä hastageilla.", "compose_form.lock_disclaimer": "Tilisi ei ole {locked}. Kuka tahansa voi seurata tiliäsi ja nähdä vain seuraajille rajaamasi julkaisut.", "compose_form.lock_disclaimer.lock": "lukittu", "compose_form.placeholder": "Mitä sinulla on mielessäsi?", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Muuta kysely sallimaan vain yksi valinta", "compose_form.publish": "Lähetä viesti", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Merkitse media arkaluontoiseksi} other {Merkitse media arkaluontoiseksi}}", "compose_form.sensitive.marked": "{count, plural, one {Media on merkitty arkaluontoiseksi} other {Media on merkitty arkaluontoiseksi}}", "compose_form.sensitive.unmarked": "{count, plural, one {Mediaa ei ole merkitty arkaluontoiseksi} other {Mediaa ei ole merkitty arkaluontoiseksi}}", @@ -115,23 +117,23 @@ "confirmations.block.confirm": "Estä", "confirmations.block.message": "Haluatko varmasti estää käyttäjän {name}?", "confirmations.delete.confirm": "Poista", - "confirmations.delete.message": "Haluatko varmasti poistaa tämän tilapäivityksen?", + "confirmations.delete.message": "Haluatko varmasti poistaa tämän julkaisun?", "confirmations.delete_list.confirm": "Poista", "confirmations.delete_list.message": "Haluatko varmasti poistaa tämän listan kokonaan?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Hylkää", + "confirmations.discard_edit_media.message": "Onko sinulla tallentamattomia muutoksia kuvaukseen tai esikatseluun, hylätäänkö ne silti?", "confirmations.domain_block.confirm": "Piilota koko verkko-osoite", "confirmations.domain_block.message": "Oletko todella varma, että haluat estää koko {domain}? Useimmissa tapauksissa muutama kohdennettu lohko tai mykistys on riittävä ja parempi. Et näe kyseisen verkkotunnuksen sisältöä missään julkisessa aikajanassa tai ilmoituksissa. Seuraajasi tältä verkkotunnukselta poistetaan.", "confirmations.logout.confirm": "Kirjaudu ulos", "confirmations.logout.message": "Oletko varma, että haluat kirjautua ulos?", "confirmations.mute.confirm": "Mykistä", - "confirmations.mute.explanation": "Tämä piilottaa päivitykset heiltä ja päivitykset, joissa hänet mainitaan, mutta sallii silti heidän nähdä sinun päivityksesi ja seurata sinua.", + "confirmations.mute.explanation": "Tämä piilottaa heidän julkaisut ja julkaisut, joissa heidät mainitaan, mutta sallii edelleen heidän nähdä julkaisusi ja seurata sinua.", "confirmations.mute.message": "Haluatko varmasti mykistää käyttäjän {name}?", "confirmations.redraft.confirm": "Poista & palauta muokattavaksi", - "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.", + "confirmations.redraft.message": "Oletko varma että haluat poistaa tämän julkaisun ja tehdä siitä uuden luonnoksen? Suosikit ja buustaukset menetään, alkuperäisen julkaisusi vastaukset jäävät orvoiksi.", "confirmations.reply.confirm": "Vastaa", "confirmations.reply.message": "Jos vastaat nyt, vastaus korvaa tällä hetkellä työstämäsi viestin. Oletko varma, että haluat jatkaa?", - "confirmations.unfollow.confirm": "Lakkaa seuraamasta", + "confirmations.unfollow.confirm": "Lopeta seuraaminen", "confirmations.unfollow.message": "Haluatko varmasti lakata seuraamasta käyttäjää {name}?", "conversation.delete": "Poista keskustelu", "conversation.mark_as_read": "Merkitse luetuksi", @@ -141,7 +143,7 @@ "directory.local": "Vain palvelimelta {domain}", "directory.new_arrivals": "Äskettäin saapuneet", "directory.recently_active": "Hiljattain aktiiviset", - "embed.instructions": "Upota statuspäivitys sivullesi kopioimalla alla oleva koodi.", + "embed.instructions": "Upota julkaisu verkkosivullesi kopioimalla alla oleva koodi.", "embed.preview": "Se tulee näyttämään tältä:", "emoji_button.activity": "Aktiviteetit", "emoji_button.custom": "Mukautetut", @@ -184,8 +186,8 @@ "errors.unexpected_crash.copy_stacktrace": "Kopioi pinon jäljitys leikepöydälle", "errors.unexpected_crash.report_issue": "Ilmoita ongelmasta", "follow_recommendations.done": "Valmis", - "follow_recommendations.heading": "Seuraa ihmisiä, joilta haluaisit nähdä viestejä! Tässä on muutamia ehdotuksia.", - "follow_recommendations.lead": "Viestit seuraamiltasi henkilöiltä näkyvät aikajärjestyksessä kotinäytön syötteessä. Älä pelkää seurata vahingossa, voit lopettaa seuraaminen yhtä helposti milloin tahansa!", + "follow_recommendations.heading": "Seuraa ihmisiä, joilta haluaisit nähdä julkaisuja! Tässä on muutamia ehdotuksia.", + "follow_recommendations.lead": "Seuraamiesi julkaisut näkyvät aikajärjestyksessä kotisyötteessä. Älä pelkää seurata vahingossa, voit lopettaa seuraamisen yhtä helposti!", "follow_request.authorize": "Valtuuta", "follow_request.reject": "Hylkää", "follow_requests.unlocked_explanation": "Vaikka tiliäsi ei ole lukittu, {domain}:n ylläpitäjien mielestä saatat haluta tarkistaa nämä seurauspyynnöt manuaalisesti.", @@ -223,7 +225,7 @@ "keyboard_shortcuts.description": "Kuvaus", "keyboard_shortcuts.direct": "Avaa pikaviestisarake", "keyboard_shortcuts.down": "Siirry listassa alaspäin", - "keyboard_shortcuts.enter": "Avaa viesti", + "keyboard_shortcuts.enter": "Avaa julkaisu", "keyboard_shortcuts.favourite": "Lisää suosikkeihin", "keyboard_shortcuts.favourites": "Avaa lista suosikeista", "keyboard_shortcuts.federated": "Avaa yleinen aikajana", @@ -289,7 +291,7 @@ "navigation_bar.follow_requests": "Seuraamispyynnöt", "navigation_bar.follows_and_followers": "Seurattavat ja seuraajat", "navigation_bar.info": "Tietoa tästä palvelimesta", - "navigation_bar.keyboard_shortcuts": "Näppäinkomennot", + "navigation_bar.keyboard_shortcuts": "Pikanäppäimet", "navigation_bar.lists": "Listat", "navigation_bar.logout": "Kirjaudu ulos", "navigation_bar.mutes": "Mykistetyt käyttäjät", @@ -304,15 +306,15 @@ "notification.mention": "{name} mainitsi sinut", "notification.own_poll": "Kyselysi on päättynyt", "notification.poll": "Kysely, johon osallistuit, on päättynyt", - "notification.reblog": "{name} buustasi tilaasi", - "notification.status": "{name} juuri lähetetty", + "notification.reblog": "{name} buustasi julkaisusi", + "notification.status": "{name} julkaisi juuri", "notifications.clear": "Tyhjennä ilmoitukset", "notifications.clear_confirmation": "Haluatko varmasti poistaa kaikki ilmoitukset pysyvästi?", "notifications.column_settings.alert": "Työpöytäilmoitukset", "notifications.column_settings.favourite": "Tykkäykset:", "notifications.column_settings.filter_bar.advanced": "Näytä kaikki kategoriat", "notifications.column_settings.filter_bar.category": "Pikasuodatuspalkki", - "notifications.column_settings.filter_bar.show": "Näytä", + "notifications.column_settings.filter_bar.show_bar": "Näytä suodatinpalkki", "notifications.column_settings.follow": "Uudet seuraajat:", "notifications.column_settings.follow_request": "Uudet seuraamispyynnöt:", "notifications.column_settings.mention": "Maininnat:", @@ -321,8 +323,9 @@ "notifications.column_settings.reblog": "Buustit:", "notifications.column_settings.show": "Näytä sarakkeessa", "notifications.column_settings.sound": "Äänimerkki", - "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Lukemattomat ilmoitusmerkit", + "notifications.column_settings.status": "Uudet julkaisut:", + "notifications.column_settings.unread_notifications.category": "Lukemattomat ilmoitukset", + "notifications.column_settings.unread_notifications.highlight": "Korosta lukemattomat ilmoitukset", "notifications.filter.all": "Kaikki", "notifications.filter.boosts": "Buustit", "notifications.filter.favourites": "Suosikit", @@ -346,10 +349,10 @@ "poll.total_votes": "{count, plural, one {# ääni} other {# ääntä}}", "poll.vote": "Äänestä", "poll.voted": "Äänestit tätä vastausta", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# ääni} other {# ääntä}}", "poll_button.add_poll": "Lisää kysely", "poll_button.remove_poll": "Poista kysely", - "privacy.change": "Säädä tuuttauksen näkyvyyttä", + "privacy.change": "Muuta julkaisun näkyvyyttä", "privacy.direct.long": "Julkaise vain mainituille käyttäjille", "privacy.direct.short": "Suora viesti", "privacy.private.long": "Julkaise vain seuraajille", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Ladataan…", "regeneration_indicator.sublabel": "Kotinäkymääsi valmistellaan!", "relative_time.days": "{number} pv", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number} tuntia", "relative_time.just_now": "nyt", "relative_time.minutes": "{number} min", "relative_time.seconds": "{number} sek", "relative_time.today": "tänään", "reply_indicator.cancel": "Peruuta", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Välitä kohteeseen {target}", "report.forward_hint": "Tämä tili on toisella palvelimella. Haluatko lähettää nimettömän raportin myös sinne?", "report.hint": "Raportti lähetetään oman palvelimesi moderaattoreille. Voit kertoa alla, miksi raportoit tästä tilistä:", @@ -378,7 +389,7 @@ "search_popout.search_format": "Tarkennettu haku", "search_popout.tips.full_text": "Tekstihaku listaa tilapäivitykset, jotka olet kirjoittanut, lisännyt suosikkeihisi, boostannut tai joissa sinut mainitaan, sekä tekstin sisältävät käyttäjänimet, nimimerkit ja hastagit.", "search_popout.tips.hashtag": "aihetunnisteet", - "search_popout.tips.status": "tila", + "search_popout.tips.status": "julkaisu", "search_popout.tips.text": "Tekstihaku listaa hakua vastaavat nimimerkit, käyttäjänimet ja hastagit", "search_popout.tips.user": "käyttäjä", "search_results.accounts": "Ihmiset", @@ -387,25 +398,30 @@ "search_results.statuses_fts_disabled": "Viestien haku sisällön perusteella ei ole käytössä tällä Mastodon-palvelimella.", "search_results.total": "{count, number} {count, plural, one {tulos} other {tulokset}}", "status.admin_account": "Avaa moderaattorinäkymä tilistä @{name}", - "status.admin_status": "Avaa tämä viesti moderointinäkymässä", + "status.admin_status": "Avaa julkaisu moderointinäkymässä", "status.block": "Estä @{name}", "status.bookmark": "Tallenna kirjanmerkki", "status.cancel_reblog_private": "Peru buustaus", "status.cannot_reblog": "Tätä viestiä ei voi buustata", - "status.copy": "Kopioi linkki tilapäivitykseen", + "status.copy": "Kopioi linkki julkaisuun", "status.delete": "Poista", "status.detailed_status": "Yksityiskohtainen keskustelunäkymä", "status.direct": "Pikaviesti käyttäjälle @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Upota", "status.favourite": "Tykkää", "status.filtered": "Suodatettu", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Lataa lisää", "status.media_hidden": "Media piilotettu", "status.mention": "Mainitse @{name}", "status.more": "Lisää", "status.mute": "Mykistä @{name}", "status.mute_conversation": "Mykistä keskustelu", - "status.open": "Laajenna viestit", + "status.open": "Laajenna julkaisu", "status.pin": "Kiinnitä profiiliin", "status.pinned": "Kiinnitetty viesti", "status.read_more": "Näytä enemmän", @@ -443,13 +459,13 @@ "timeline_hint.remote_resource_not_displayed": "{resource} muilta palvelimilta ei näytetä.", "timeline_hint.resources.followers": "Seuraajat", "timeline_hint.resources.follows": "Seuraa", - "timeline_hint.resources.statuses": "Vanhemmat tuuttaukset", + "timeline_hint.resources.statuses": "Vanhemmat julkaisut", "trends.counter_by_accounts": "{count, plural, one {{counter} henkilö} other {{counter} henkilöä}} puhuu", "trends.trending_now": "Suosittua nyt", "ui.beforeunload": "Luonnos häviää, jos poistut Mastodonista.", - "units.short.billion": "{count} miljardia", - "units.short.million": "{count} miljoonaa", - "units.short.thousand": "{count} tuhatta", + "units.short.billion": "{count} mrd.", + "units.short.million": "{count} milj.", + "units.short.thousand": "{count} t.", "upload_area.title": "Lataa raahaamalla ja pudottamalla tähän", "upload_button.label": "Lisää mediaa", "upload_error.limit": "Tiedostolatauksien raja ylitetty.", @@ -462,7 +478,7 @@ "upload_form.video_description": "Kuvaile kuulo- tai näkövammaisille", "upload_modal.analyzing_picture": "Analysoidaan kuvaa…", "upload_modal.apply": "Käytä", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Asetetaan…", "upload_modal.choose_image": "Valitse kuva", "upload_modal.description_placeholder": "Nopea ruskea kettu hyppää laiskan koiran yli", "upload_modal.detect_text": "Tunnista teksti kuvasta", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 91efd024b..8c2b8f3e6 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -16,16 +16,16 @@ "account.endorse": "Recommander sur le profil", "account.follow": "Suivre", "account.followers": "Abonnés", - "account.followers.empty": "Personne ne suit cet utilisateur pour l’instant.", - "account.followers_counter": "{count, plural, one {{counter} Abonné} other {{counter} Abonnés}}", + "account.followers.empty": "Personne ne suit cet·te utilisateur·rice pour l’instant.", + "account.followers_counter": "{count, plural, one {{counter} Abonné·e} other {{counter} Abonné·e·s}}", "account.following_counter": "{count, plural, other {{counter} Abonnements}}", - "account.follows.empty": "Cet utilisateur ne suit personne pour l’instant.", + "account.follows.empty": "Cet·te utilisateur·rice ne suit personne pour l’instant.", "account.follows_you": "Vous suit", "account.hide_reblogs": "Masquer les partages de @{name}", "account.joined": "Ici depuis {date}", "account.last_status": "Dernière activité", "account.link_verified_on": "La propriété de ce lien a été vérifiée le {date}", - "account.locked_info": "Ce compte est privé. Son propriétaire approuve manuellement qui peut le suivre.", + "account.locked_info": "Ce compte est privé. Son ou sa propriétaire approuve manuellement qui peut le suivre.", "account.media": "Médias", "account.mention": "Mentionner @{name}", "account.moved_to": "{name} a déménagé vers :", @@ -47,16 +47,17 @@ "account.unmute": "Ne plus masquer @{name}", "account.unmute_notifications": "Ne plus masquer les notifications de @{name}", "account_note.placeholder": "Cliquez pour ajouter une note", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Moyenne", + "admin.dashboard.retention.cohort": "Mois d'inscription", + "admin.dashboard.retention.cohort_size": "Nouveaux utilisateurs", "alert.rate_limited.message": "Veuillez réessayer après {retry_time, time, medium}.", "alert.rate_limited.title": "Débit limité", "alert.unexpected.message": "Une erreur inattendue s’est produite.", "alert.unexpected.title": "Oups !", "announcement.announcement": "Annonce", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(non traité)", "autosuggest_hashtag.per_week": "{count} par semaine", "boost_modal.combo": "Vous pouvez appuyer sur {combo} pour passer ceci la prochaine fois", "bundle_column_error.body": "Une erreur s’est produite lors du chargement de ce composant.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Changer le sondage pour autoriser qu'un seul choix", "compose_form.publish": "Pouet", "compose_form.publish_loud": "{publish} !", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Marquer le média comme sensible", "compose_form.sensitive.marked": "{count, plural, one {Le média est marqué comme sensible} other {Les médias sont marqués comme sensibles}}", "compose_form.sensitive.unmarked": "Le média n’est pas marqué comme sensible", @@ -118,17 +120,17 @@ "confirmations.delete.message": "Voulez-vous vraiment supprimer ce message ?", "confirmations.delete_list.confirm": "Supprimer", "confirmations.delete_list.message": "Voulez-vous vraiment supprimer définitivement cette liste ?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Rejeter", + "confirmations.discard_edit_media.message": "Vous avez des modifications non enregistrées de la description ou de l'aperçu du média, les supprimer quand même ?", "confirmations.domain_block.confirm": "Bloquer tout le domaine", - "confirmations.domain_block.message": "Voulez-vous vraiment, vraiment bloquer {domain} en entier ? Dans la plupart des cas, quelques blocages ou masquages ciblés sont suffisants et préférables. Vous ne verrez plus de contenu provenant de ce domaine, ni dans fils publics, ni dans vos notifications. Vos abonnés utilisant ce domaine seront retirés.", + "confirmations.domain_block.message": "Voulez-vous vraiment, vraiment bloquer {domain} en entier ? Dans la plupart des cas, quelques blocages ou masquages ciblés sont suffisants et préférables. Vous ne verrez plus de contenu provenant de ce domaine, ni dans vos fils publics, ni dans vos notifications. Vos abonné·e·s utilisant ce domaine seront retiré·e·s.", "confirmations.logout.confirm": "Se déconnecter", "confirmations.logout.message": "Voulez-vous vraiment vous déconnecter ?", "confirmations.mute.confirm": "Masquer", "confirmations.mute.explanation": "Cela masquera ses messages et les messages le ou la mentionnant, mais cela lui permettra quand même de voir vos messages et de vous suivre.", "confirmations.mute.message": "Voulez-vous vraiment masquer {name} ?", "confirmations.redraft.confirm": "Supprimer et ré-écrire", - "confirmations.redraft.message": "Êtes-vous sûr de vouloir effacer ce statut pour le récrire ? Ses partages ainsi que ses mises en favori seront perdus et ses réponses seront orphelines.", + "confirmations.redraft.message": "Êtes-vous sûr·e de vouloir effacer ce statut pour le réécrire ? Ses partages ainsi que ses mises en favori seront perdus et ses réponses seront orphelines.", "confirmations.reply.confirm": "Répondre", "confirmations.reply.message": "Répondre maintenant écrasera le message que vous rédigez actuellement. Voulez-vous vraiment continuer ?", "confirmations.unfollow.confirm": "Ne plus suivre", @@ -149,7 +151,7 @@ "emoji_button.food": "Nourriture & Boisson", "emoji_button.label": "Insérer un émoji", "emoji_button.nature": "Nature", - "emoji_button.not_found": "Aucune correspondance d'émoji trouvée", + "emoji_button.not_found": "Aucun émoji correspondant n'a été trouvé", "emoji_button.objects": "Objets", "emoji_button.people": "Personnes", "emoji_button.recent": "Fréquemment utilisés", @@ -160,7 +162,7 @@ "empty_column.account_suspended": "Compte suspendu", "empty_column.account_timeline": "Aucun message ici !", "empty_column.account_unavailable": "Profil non disponible", - "empty_column.blocks": "Vous n’avez bloqué aucun utilisateur pour le moment.", + "empty_column.blocks": "Vous n’avez bloqué aucun compte pour le moment.", "empty_column.bookmarked_statuses": "Vous n'avez pas de message en marque-page. Lorsque vous en ajouterez un, il apparaîtra ici.", "empty_column.community": "Le fil public local est vide. Écrivez donc quelque chose pour le remplir !", "empty_column.direct": "Vous n’avez pas encore de messages directs. Lorsque vous en enverrez ou recevrez un, il s’affichera ici.", @@ -174,7 +176,7 @@ "empty_column.home.suggestions": "Voir quelques suggestions", "empty_column.list": "Il n’y a rien dans cette liste pour l’instant. Quand des membres de cette liste publieront de nouveaux messages, ils apparaîtront ici.", "empty_column.lists": "Vous n’avez pas encore de liste. Lorsque vous en créerez une, elle apparaîtra ici.", - "empty_column.mutes": "Vous n’avez masqué aucun utilisateur pour le moment.", + "empty_column.mutes": "Vous n’avez masqué aucun compte pour le moment.", "empty_column.notifications": "Vous n’avez pas encore de notification. Interagissez avec d’autres personnes pour débuter la conversation.", "empty_column.public": "Il n’y a rien ici ! Écrivez quelque chose publiquement, ou bien suivez manuellement des personnes d’autres serveurs pour remplir le fil public", "error.unexpected_crash.explanation": "En raison d’un bug dans notre code ou d’un problème de compatibilité avec votre navigateur, cette page n’a pas pu être affichée correctement.", @@ -232,13 +234,13 @@ "keyboard_shortcuts.hotkey": "Raccourci clavier", "keyboard_shortcuts.legend": "Afficher cet aide-mémoire", "keyboard_shortcuts.local": "Ouvrir le fil public local", - "keyboard_shortcuts.mention": "Mentionner l’auteur", + "keyboard_shortcuts.mention": "Mentionner l’auteur·rice", "keyboard_shortcuts.muted": "Ouvrir la liste des comptes masqués", "keyboard_shortcuts.my_profile": "Ouvrir votre profil", "keyboard_shortcuts.notifications": "Ouvrir la colonne de notifications", "keyboard_shortcuts.open_media": "ouvrir le média", "keyboard_shortcuts.pinned": "Ouvrir la liste des messages épinglés", - "keyboard_shortcuts.profile": "Ouvrir le profil de l’auteur", + "keyboard_shortcuts.profile": "Ouvrir le profil de l’auteur·rice", "keyboard_shortcuts.reply": "Répondre au message", "keyboard_shortcuts.requests": "Ouvrir la liste de demandes d’abonnement", "keyboard_shortcuts.search": "Se placer dans le champ de recherche", @@ -261,7 +263,7 @@ "lists.edit.submit": "Modifier le titre", "lists.new.create": "Ajouter une liste", "lists.new.title_placeholder": "Titre de la nouvelle liste", - "lists.replies_policy.followed": "N'importe quel utilisateur suivi", + "lists.replies_policy.followed": "N'importe quel compte suivi", "lists.replies_policy.list": "Membres de la liste", "lists.replies_policy.none": "Personne", "lists.replies_policy.title": "Afficher les réponses à :", @@ -301,7 +303,7 @@ "notification.favourite": "{name} a ajouté le message à ses favoris", "notification.follow": "{name} vous suit", "notification.follow_request": "{name} a demandé à vous suivre", - "notification.mention": "{name} vous a mentionné·", + "notification.mention": "{name} vous a mentionné·e :", "notification.own_poll": "Votre sondage est terminé", "notification.poll": "Un sondage auquel vous avez participé vient de se terminer", "notification.reblog": "{name} a partagé votre message", @@ -312,8 +314,8 @@ "notifications.column_settings.favourite": "Favoris :", "notifications.column_settings.filter_bar.advanced": "Afficher toutes les catégories", "notifications.column_settings.filter_bar.category": "Barre de filtrage rapide", - "notifications.column_settings.filter_bar.show": "Afficher", - "notifications.column_settings.follow": "Nouveaux abonnés :", + "notifications.column_settings.filter_bar.show_bar": "Afficher la barre de filtre", + "notifications.column_settings.follow": "Nouveaux·elles abonné·e·s :", "notifications.column_settings.follow_request": "Nouvelles demandes d’abonnement :", "notifications.column_settings.mention": "Mentions :", "notifications.column_settings.poll": "Résultats des sondage :", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Afficher dans la colonne", "notifications.column_settings.sound": "Jouer un son", "notifications.column_settings.status": "Nouveaux messages :", - "notifications.column_settings.unread_markers.category": "Marqueurs de notifications non lues", + "notifications.column_settings.unread_notifications.category": "Notifications non lues", + "notifications.column_settings.unread_notifications.highlight": "Surligner les notifications non lues", "notifications.filter.all": "Tout", "notifications.filter.boosts": "Partages", "notifications.filter.favourites": "Favoris", @@ -353,24 +356,32 @@ "privacy.direct.long": "Visible uniquement par les comptes mentionnés", "privacy.direct.short": "Direct", "privacy.private.long": "Visible uniquement par vos abonné·e·s", - "privacy.private.short": "Abonnés uniquement", - "privacy.public.long": "Visible par tous, affiché dans les fils publics", + "privacy.private.short": "Abonné·e·s uniquement", + "privacy.public.long": "Visible par tou·te·s, affiché dans les fils publics", "privacy.public.short": "Public", - "privacy.unlisted.long": "Visible par tous, mais pas dans les fils publics", + "privacy.unlisted.long": "Visible par tou·te·s, mais pas dans les fils publics", "privacy.unlisted.short": "Non listé", "refresh": "Actualiser", "regeneration_indicator.label": "Chargement…", "regeneration_indicator.sublabel": "Votre fil principal est en cours de préparation !", "relative_time.days": "{number} j", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number} h", "relative_time.just_now": "à l’instant", "relative_time.minutes": "{number} min", "relative_time.seconds": "{number} s", "relative_time.today": "aujourd’hui", "reply_indicator.cancel": "Annuler", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Transférer à {target}", "report.forward_hint": "Le compte provient d’un autre serveur. Envoyer également une copie anonyme du rapport ?", - "report.hint": "Le rapport sera envoyé aux modérateurs de votre instance. Vous pouvez expliquer pourquoi vous signalez le compte ci-dessous :", + "report.hint": "Le rapport sera envoyé aux modérateur·rice·s de votre serveur. Vous pouvez expliquer pourquoi vous signalez le compte ci-dessous :", "report.placeholder": "Commentaires additionnels", "report.submit": "Envoyer", "report.target": "Signalement de {target}", @@ -396,9 +407,14 @@ "status.delete": "Supprimer", "status.detailed_status": "Vue détaillée de la conversation", "status.direct": "Envoyer un message direct à @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Intégrer", "status.favourite": "Ajouter aux favoris", "status.filtered": "Filtré", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Charger plus", "status.media_hidden": "Média caché", "status.mention": "Mentionner @{name}", @@ -413,7 +429,7 @@ "status.reblog_private": "Partager à l’audience originale", "status.reblogged_by": "{name} a partagé", "status.reblogs.empty": "Personne n’a encore partagé ce message. Lorsque quelqu’un le fera, il apparaîtra ici.", - "status.redraft": "Supprimer et récrire", + "status.redraft": "Supprimer et réécrire", "status.remove_bookmark": "Retirer des marque-pages", "status.reply": "Répondre", "status.replyAll": "Répondre au fil", @@ -429,7 +445,7 @@ "status.unmute_conversation": "Ne plus masquer la conversation", "status.unpin": "Retirer du profil", "suggestions.dismiss": "Rejeter la suggestion", - "suggestions.header": "Vous pourriez être intéressé par…", + "suggestions.header": "Vous pourriez être intéressé·e par…", "tabs_bar.federated_timeline": "Fil public global", "tabs_bar.home": "Accueil", "tabs_bar.local_timeline": "Fil public local", @@ -462,7 +478,7 @@ "upload_form.video_description": "Décrire pour les personnes ayant des problèmes d’audition ou de vision", "upload_modal.analyzing_picture": "Analyse de l’image en cours…", "upload_modal.apply": "Appliquer", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Application en cours…", "upload_modal.choose_image": "Choisir une image", "upload_modal.description_placeholder": "Buvez de ce whisky que le patron juge fameux", "upload_modal.detect_text": "Détecter le texte de l’image", diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json index 9c94c61aa..c9f2cd414 100644 --- a/app/javascript/mastodon/locales/ga.json +++ b/app/javascript/mastodon/locales/ga.json @@ -47,7 +47,8 @@ "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", "account_note.placeholder": "No comment provided", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Show in column", "notifications.column_settings.sound": "Play sound", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "Cancel", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Load more", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/gd.json b/app/javascript/mastodon/locales/gd.json index 023ee3ecb..750674ca2 100644 --- a/app/javascript/mastodon/locales/gd.json +++ b/app/javascript/mastodon/locales/gd.json @@ -47,16 +47,17 @@ "account.unmute": "Dì-mhùch @{name}", "account.unmute_notifications": "Dì-mhùch na brathan o @{name}", "account_note.placeholder": "Briog airson nòta a chur ris", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Cuibheasach", + "admin.dashboard.retention.cohort": "Mìos a’ chlàraidh", + "admin.dashboard.retention.cohort_size": "Cleachdaichean ùra", "alert.rate_limited.message": "Feuch ris a-rithist às dèidh {retry_time, time, medium}.", "alert.rate_limited.title": "Cuingeachadh ùine", "alert.unexpected.message": "Thachair mearachd ris nach robh dùil.", "alert.unexpected.title": "Oich!", "announcement.announcement": "Brath-fios", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(gun phròiseasadh)", "autosuggest_hashtag.per_week": "{count} gach seachdain", "boost_modal.combo": "Brùth air {combo} nam b’ fheàrr leat leum a ghearradh thar seo an ath-thuras", "bundle_column_error.body": "Chaidh rudeigin cearr nuair a dh’fheuch sinn ris a’ cho-phàirt seo a luchdadh.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Atharraich an cunntas-bheachd gus nach gabh ach aon roghainn a thaghadh", "compose_form.publish": "Postaich", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Cuir comharra gu bheil am meadhan frionasach} two {Cuir comharra gu bheil na meadhanan frionasach} few {Cuir comharra gu bheil na meadhanan frionasach} other {Cuir comharra gu bheil na meadhanan frionasach}}", "compose_form.sensitive.marked": "{count, plural, one {Tha comharra ris a’ mheadhan gu bheil e frionasach} two {Tha comharra ris na meadhanan gu bheil iad frionasach} few {Tha comharra ris na meadhanan gu bheil iad frionasach} other {Tha comharra ris na meadhanan gu bheil iad frionasach}}", "compose_form.sensitive.unmarked": "{count, plural, one {Chan eil comharra ris a’ mheadhan gun robh e frionasach} two {Chan eil comharra ris na meadhanan gun robh iad frionasach} few {Chan eil comharra ris na meadhanan gun robh iad frionasach} other {Chan eil comharra ris na meadhanan gun robh iad frionasach}}", @@ -118,8 +120,8 @@ "confirmations.delete.message": "A bheil thu cinnteach gu bheil thu airson am post seo a sguabadh às?", "confirmations.delete_list.confirm": "Sguab às", "confirmations.delete_list.message": "A bheil thu cinnteach gu bheil thu airson an liosta seo a sguabadh às gu buan?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Tilg air falbh", + "confirmations.discard_edit_media.message": "Tha atharraichean gun sàbhaladh agad ann an tuairisgeul no ro-shealladh a’ mheadhain, a bheil thu airson an tilgeil air falbh co-dhiù?", "confirmations.domain_block.confirm": "Bac an àrainn uile gu lèir", "confirmations.domain_block.message": "A bheil thu cinnteach dha-rìribh gu bheil thu airson an àrainn {domain} a bhacadh uile gu lèir? Mar as trice, foghnaidh gun dèan thu bacadh no mùchadh no dhà gu sònraichte agus bhiod sin na b’ fheàrr. Chan fhaic thu susbaint on àrainn ud air loidhne-ama phoblach sam bith no am measg nam brathan agad. Thèid an luchd-leantainn agad on àrainn ud a thoirt air falbh.", "confirmations.logout.confirm": "Clàraich a-mach", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Na h-annsachdan:", "notifications.column_settings.filter_bar.advanced": "Seall a h-uile roinn-seòrsa", "notifications.column_settings.filter_bar.category": "Bàr-criathraidh luath", - "notifications.column_settings.filter_bar.show": "Seall", + "notifications.column_settings.filter_bar.show_bar": "Seall am bàr-criathraidh", "notifications.column_settings.follow": "Luchd-leantainn ùr:", "notifications.column_settings.follow_request": "Iarrtasan leantainn ùra:", "notifications.column_settings.mention": "Iomraidhean:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Seall sa cholbh", "notifications.column_settings.sound": "Cluich fuaim", "notifications.column_settings.status": "Postaichean ùra:", - "notifications.column_settings.unread_markers.category": "Comharran nach deach brath a leughadh", + "notifications.column_settings.unread_notifications.category": "Brathan nach deach a leughadh", + "notifications.column_settings.unread_notifications.highlight": "Soillsich na brathan nach deach a leughadh", "notifications.filter.all": "Na h-uile", "notifications.filter.boosts": "Brosnachaidhean", "notifications.filter.favourites": "Na h-annsachdan", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# bhòt} two {# bhòt} few {# bhòtaichean} other {# bhòt}}", "poll.vote": "Bhòt", "poll.voted": "Bhòt thu dhan fhreagairt seo", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# bhòt} two {# bhòt} few {# bhòtaichean} other {# bhòt}}", "poll_button.add_poll": "Cuir cunntas-bheachd ris", "poll_button.remove_poll": "Thoir air falbh an cunntas-bheachd", "privacy.change": "Cuir gleus air prìobhaideachd a’ phuist", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "’Ga luchdadh…", "regeneration_indicator.sublabel": "Tha inbhir na dachaigh agad ’ga ullachadh!", "relative_time.days": "{number}l", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}u", "relative_time.just_now": "an-dràsta", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}d", "relative_time.today": "an-diugh", "reply_indicator.cancel": "Sguir dheth", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Sìn air adhart gu {target}", "report.forward_hint": "Chaidh an cunntas a chlàradh air frithealaiche eile. A bheil thu airson lethbhreac dhen ghearan a chur dha-san gun ainm cuideachd?", "report.hint": "Thèid do ghearan a chur gu maoir an fhrithealaiche agad. ’S urrainn dhut mìneachadh a sholar air carson a tha thu a’ gearan mun chunntas gu h-ìosal:", @@ -396,9 +407,14 @@ "status.delete": "Sguab às", "status.detailed_status": "Mion-shealladh a’ chòmhraidh", "status.direct": "Cuir teachdaireachd dhìreach gu @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Leabaich", "status.favourite": "Cuir ris na h-annsachdan", "status.filtered": "Criathraichte", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Luchdaich barrachd dheth", "status.media_hidden": "Meadhanan falaichte", "status.mention": "Thoir iomradh air @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Mìnich e dhan fheadhainn le èisteachd bheag no cion-lèirsinne", "upload_modal.analyzing_picture": "A’ sgrùdadh an deilbh…", "upload_modal.apply": "Cuir an sàs", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "’Ga chur an sàs…", "upload_modal.choose_image": "Tagh dealbh", "upload_modal.description_placeholder": "Lorg Sìm fiù bò, cè ⁊ neup ’ad àth", "upload_modal.detect_text": "Mothaich dhan teacsa on dealbh", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index d85fd97bf..e926239bb 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -36,7 +36,7 @@ "account.posts": "Publicacións", "account.posts_with_replies": "Publicacións e respostas", "account.report": "Informar sobre @{name}", - "account.requested": "Agardando aprovación. Preme para desbotar a solicitude de seguimento", + "account.requested": "Agardando aprobación. Preme para desbotar a solicitude", "account.share": "Compartir o perfil de @{name}", "account.show_reblogs": "Amosar compartidos de @{name}", "account.statuses_counter": "{count, plural, one {{counter} Publicación} other {{counter} Publicacións}}", @@ -47,16 +47,17 @@ "account.unmute": "Deixar de silenciar a @{name}", "account.unmute_notifications": "Deixar de silenciar as notificacións de @{name}", "account_note.placeholder": "Preme para engadir nota", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Media", + "admin.dashboard.retention.cohort": "Mes de rexistro", + "admin.dashboard.retention.cohort_size": "Novas usuarias", "alert.rate_limited.message": "Téntao novamente após {retry_time, time, medium}.", "alert.rate_limited.title": "Límite de intentos", "alert.unexpected.message": "Aconteceu un fallo non agardado.", "alert.unexpected.title": "Vaites!", "announcement.announcement": "Anuncio", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(sen procesar)", "autosuggest_hashtag.per_week": "{count} por semana", "boost_modal.combo": "Preme {combo} para ignorar isto na seguinte vez", "bundle_column_error.body": "Ocorreu un erro ó cargar este compoñente.", @@ -104,13 +105,14 @@ "compose_form.poll.switch_to_single": "Mudar a enquisa para permitir unha soa escolla", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Marca multimedia como sensible} other {Marca multimedia como sensibles}}", "compose_form.sensitive.marked": "{count, plural, one {Multimedia marcado como sensible} other {Multimedia marcados como sensibles}}", "compose_form.sensitive.unmarked": "{count, plural, one {Multimedia non marcado como sensible} other {Multimedia non marcado como sensible}}", "compose_form.spoiler.marked": "Retirar o aviso sobre o contido", "compose_form.spoiler.unmarked": "Engadir aviso sobre o contido", "compose_form.spoiler_placeholder": "Escribe o teu aviso aquí", - "confirmation_modal.cancel": "Desbotar", + "confirmation_modal.cancel": "Cancelar", "confirmations.block.block_and_report": "Bloquear e denunciar", "confirmations.block.confirm": "Bloquear", "confirmations.block.message": "Tes a certeza de querer bloquear a {name}?", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Tes a certeza de querer eliminar esta publicación?", "confirmations.delete_list.confirm": "Eliminar", "confirmations.delete_list.message": "Tes a certeza de querer eliminar de xeito permanente esta listaxe?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Descartar", + "confirmations.discard_edit_media.message": "Tes cambios sen gardar para a vista previa ou descrición do multimedia, descartamos os cambios?", "confirmations.domain_block.confirm": "Agochar dominio enteiro", "confirmations.domain_block.message": "Tes a certeza de querer bloquear todo de {domain}? Na meirande parte dos casos uns bloqueos ou silenciados específicos son suficientes. Non verás máis o contido deste dominio en ningunha cronoloxía pública ou nas túas notificacións. As túas seguidoras deste dominio serán eliminadas.", "confirmations.logout.confirm": "Pechar sesión", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favoritos:", "notifications.column_settings.filter_bar.advanced": "Amosar todas as categorías", "notifications.column_settings.filter_bar.category": "Barra de filtrado rápido", - "notifications.column_settings.filter_bar.show": "Amosar", + "notifications.column_settings.filter_bar.show_bar": "Amosar barra de filtros", "notifications.column_settings.follow": "Novas seguidoras:", "notifications.column_settings.follow_request": "Novas peticións de seguimento:", "notifications.column_settings.mention": "Mencións:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Amosar en columna", "notifications.column_settings.sound": "Reproducir son", "notifications.column_settings.status": "Novas publicacións:", - "notifications.column_settings.unread_markers.category": "Indicadores de notificacións non lidas", + "notifications.column_settings.unread_notifications.category": "Notificacións non lidas", + "notifications.column_settings.unread_notifications.highlight": "Resaltar notificacións non lidas", "notifications.filter.all": "Todo", "notifications.filter.boosts": "Compartidos", "notifications.filter.favourites": "Favoritos", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# voto} other {# votos}}", "poll.vote": "Votar", "poll.voted": "Votaches por esta opción", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# voto} other {# votos}}", "poll_button.add_poll": "Engadir unha enquisa", "poll_button.remove_poll": "Eliminar enquisa", "privacy.change": "Axustar privacidade", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Estase a cargar…", "regeneration_indicator.sublabel": "Estase a preparar a túa cronoloxía de inicio!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "agora", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "hoxe", "reply_indicator.cancel": "Desbotar", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Reenviar a {target}", "report.forward_hint": "A conta é doutro servidor. Enviar unha copia anónima da denuncia aló tamén?", "report.hint": "A denuncia enviarase á moderación do teu servidor. Abaixo podes explicar a razón pola que estás a denunciar:", @@ -396,9 +407,14 @@ "status.delete": "Eliminar", "status.detailed_status": "Vista detallada da conversa", "status.direct": "Mensaxe directa a @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Incrustar", "status.favourite": "Favorito", "status.filtered": "Filtrado", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Cargar máis", "status.media_hidden": "Contido multimedia agochado", "status.mention": "Mencionar @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Describir para persoas con problemas visuais ou auditivos", "upload_modal.analyzing_picture": "Estase a analizar a imaxe…", "upload_modal.apply": "Aplicar", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Aplicando…", "upload_modal.choose_image": "Elixir imaxe", "upload_modal.description_placeholder": "Un raposo veloz brinca sobre o can preguiceiro", "upload_modal.detect_text": "Detectar texto na imaxe", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index 311323d21..1447ff711 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -47,16 +47,17 @@ "account.unmute": "הפסקת השתקת @{name}", "account.unmute_notifications": "להפסיק הסתרת הודעות מעם @{name}", "account_note.placeholder": "ללא הערה", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "ממוצע", "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.retention.cohort_size": "משתמשים חדשים", "alert.rate_limited.message": "נא לנסות אחרי {retry_time, time, medium}.", "alert.rate_limited.title": "מגבלות מיכסה", "alert.unexpected.message": "אירעה שגיאה בלתי צפויה.", "alert.unexpected.title": "אופס!", "announcement.announcement": "הודעה", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(לא מעובד)", "autosuggest_hashtag.per_week": "{count} לשבוע", "boost_modal.combo": "ניתן להקיש {combo} כדי לדלג בפעם הבאה", "bundle_column_error.body": "משהו השתבש בעת הצגת הרכיב הזה.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "אפשרו בחירה בודדת בסקר", "compose_form.publish": "ללחוש", "compose_form.publish_loud": "לחצרץ!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -127,20 +129,20 @@ "confirmations.mute.confirm": "להשתיק", "confirmations.mute.explanation": "This will hide posts from them and posts mentioning them, but it will still allow them to see your posts and follow you.", "confirmations.mute.message": "להשתיק את {name}?", - "confirmations.redraft.confirm": "Delete & redraft", + "confirmations.redraft.confirm": "מחק וערוך מחדש", "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.", - "confirmations.reply.confirm": "Reply", - "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", + "confirmations.reply.confirm": "הגב", + "confirmations.reply.message": "הגבה עכשיו ידרוס את ההודעה שאתם כותבים כעת. האם אתם בטוחים שברצונכם להמשיך?", "confirmations.unfollow.confirm": "להפסיק מעקב", "confirmations.unfollow.message": "להפסיק מעקב אחרי {name}?", - "conversation.delete": "Delete conversation", - "conversation.mark_as_read": "Mark as read", - "conversation.open": "View conversation", - "conversation.with": "With {names}", + "conversation.delete": "מחיקת שיחה", + "conversation.mark_as_read": "סמן כנקרא", + "conversation.open": "צפו בשיחה", + "conversation.with": "עם {names}", "directory.federated": "From known fediverse", "directory.local": "From {domain} only", "directory.new_arrivals": "New arrivals", - "directory.recently_active": "Recently active", + "directory.recently_active": "פעילים לאחרונה", "embed.instructions": "ניתן להטמיע את ההודעה באתרך ע\"י העתקת הקוד שלהלן.", "embed.preview": "דוגמא כיצד זה יראה:", "emoji_button.activity": "פעילות", @@ -157,13 +159,13 @@ "emoji_button.search_results": "תוצאות חיפוש", "emoji_button.symbols": "סמלים", "emoji_button.travel": "טיולים ואתרים", - "empty_column.account_suspended": "Account suspended", + "empty_column.account_suspended": "חשבון מושהה", "empty_column.account_timeline": "No toots here!", - "empty_column.account_unavailable": "Profile unavailable", - "empty_column.blocks": "You haven't blocked any users yet.", + "empty_column.account_unavailable": "פרופיל לא זמין", + "empty_column.blocks": "עדיין לא חסמתם משתמשים אחרים.", "empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.", "empty_column.community": "טור הסביבה ריק. יש לפרסם משהו כדי שדברים יתרחילו להתגלגל!", - "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.", + "empty_column.direct": "עדיין אין לכם הודעות פרטיות. כאשר תשלחו או תקבלו אחת, היא תופיע כאן.", "empty_column.domain_blocks": "There are no hidden domains yet.", "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.", "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.", @@ -220,7 +222,7 @@ "keyboard_shortcuts.boost": "להדהד", "keyboard_shortcuts.column": "להתמקד בהודעה באחד מהטורים", "keyboard_shortcuts.compose": "להתמקד בתיבת חיבור ההודעות", - "keyboard_shortcuts.description": "Description", + "keyboard_shortcuts.description": "תיאור", "keyboard_shortcuts.direct": "to open direct messages column", "keyboard_shortcuts.down": "לנוע במורד הרשימה", "keyboard_shortcuts.enter": "to open status", @@ -254,33 +256,33 @@ "lightbox.expand": "Expand image view box", "lightbox.next": "הלאה", "lightbox.previous": "הקודם", - "lists.account.add": "Add to list", - "lists.account.remove": "Remove from list", + "lists.account.add": "הוסף לרשימה", + "lists.account.remove": "הסר מרשימה", "lists.delete": "Delete list", "lists.edit": "Edit list", "lists.edit.submit": "Change title", - "lists.new.create": "Add list", - "lists.new.title_placeholder": "New list title", - "lists.replies_policy.followed": "Any followed user", - "lists.replies_policy.list": "Members of the list", - "lists.replies_policy.none": "No one", - "lists.replies_policy.title": "Show replies to:", - "lists.search": "Search among people you follow", - "lists.subheading": "Your lists", + "lists.new.create": "הוספת רשימה", + "lists.new.title_placeholder": "כותרת הרשימה החדשה", + "lists.replies_policy.followed": "משתמשים שאני עוקב אחריהם", + "lists.replies_policy.list": "משתמשים שברשימה", + "lists.replies_policy.none": "אף אחד", + "lists.replies_policy.title": "הצג תגובות ל:", + "lists.search": "חיפוש בין אנשים שאני עוקב\\ת אחריהם", + "lists.subheading": "הרשימות שלך", "load_pending": "{count, plural, one {# new item} other {# new items}}", "loading_indicator.label": "טוען...", "media_gallery.toggle_visible": "נראה\\בלתי נראה", "missing_indicator.label": "לא נמצא", - "missing_indicator.sublabel": "This resource could not be found", - "mute_modal.duration": "Duration", + "missing_indicator.sublabel": "לא ניתן היה למצוא את המשאב", + "mute_modal.duration": "משך הזמן", "mute_modal.hide_notifications": "להסתיר הודעות מחשבון זה?", - "mute_modal.indefinite": "Indefinite", + "mute_modal.indefinite": "ללא תאריך סיום", "navigation_bar.apps": "Mobile apps", "navigation_bar.blocks": "חסימות", "navigation_bar.bookmarks": "Bookmarks", "navigation_bar.community_timeline": "ציר זמן מקומי", "navigation_bar.compose": "Compose new toot", - "navigation_bar.direct": "Direct messages", + "navigation_bar.direct": "הודעות ישירות", "navigation_bar.discover": "Discover", "navigation_bar.domain_blocks": "Hidden domains", "navigation_bar.edit_profile": "עריכת פרופיל", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "מחובבים:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "עוקבים חדשים:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "פניות:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "הצגה בטור", "notifications.column_settings.sound": "שמע מופעל", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "כרגע", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "ביטול", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:", @@ -395,10 +406,15 @@ "status.copy": "Copy link to status", "status.delete": "מחיקה", "status.detailed_status": "Detailed conversation view", - "status.direct": "Direct message @{name}", + "status.direct": "הודעה ישירה ל@{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "הטמעה", "status.favourite": "חיבוב", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "עוד", "status.media_hidden": "מדיה מוסתרת", "status.mention": "פניה אל @{name}", diff --git a/app/javascript/mastodon/locales/hi.json b/app/javascript/mastodon/locales/hi.json index 0bcf2a68b..d3221c468 100644 --- a/app/javascript/mastodon/locales/hi.json +++ b/app/javascript/mastodon/locales/hi.json @@ -47,7 +47,8 @@ "account.unmute": "अनम्यूट @{name}", "account.unmute_notifications": "@{name} के नोटिफिकेशन अनम्यूट करे", "account_note.placeholder": "नोट्स जोड़ने के लिए क्लिक करें", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "एक ही विकल्प के लिए अनुमति देने के लिए पोल बदलें", "compose_form.publish": "टूट्", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "मीडिया को संवेदनशील के रूप में चिह्नित करें", "compose_form.sensitive.marked": "मीडिया संवेदनशील के रूप में चिह्नित है", "compose_form.sensitive.unmarked": "मीडिया संवेदनशील के रूप में चिह्नित नहीं है", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.filter_bar.advanced": "सभी श्रेणियाँ दिखाएं", "notifications.column_settings.filter_bar.category": "फ़िल्टर बार", - "notifications.column_settings.filter_bar.show": "दिखाएँ", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "नए फ़ॉलोअर्स", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "उल्लेख:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "कॉलम में दिखाएँ", "notifications.column_settings.sound": "ध्वनि चलाएँ", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "सभी", "notifications.filter.boosts": "बूस्ट", "notifications.filter.favourites": "पसंदीदा", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "लोड हो रहा है...", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "अभी", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "रद्द करें", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Load more", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json index d11c73860..ecdfab67a 100644 --- a/app/javascript/mastodon/locales/hr.json +++ b/app/javascript/mastodon/locales/hr.json @@ -22,7 +22,7 @@ "account.follows.empty": "Korisnik/ca još ne prati nikoga.", "account.follows_you": "Prati te", "account.hide_reblogs": "Sakrij boostove od @{name}", - "account.joined": "Joined {date}", + "account.joined": "Pridružio se {date}", "account.last_status": "Posljednja aktivnost", "account.link_verified_on": "Vlasništvo ove poveznice provjereno je {date}", "account.locked_info": "Status privatnosti ovog računa postavljen je na zaključano. Vlasnik ručno pregledava tko ih može pratiti.", @@ -47,16 +47,17 @@ "account.unmute": "Poništi utišavanje @{name}", "account.unmute_notifications": "Ne utišavaj obavijesti od @{name}", "account_note.placeholder": "Kliknite za dodavanje bilješke", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Prosječno", + "admin.dashboard.retention.cohort": "Mjesec prijave", + "admin.dashboard.retention.cohort_size": "Novi korisnici", "alert.rate_limited.message": "Molimo pokušajte nakon {retry_time, time, medium}.", "alert.rate_limited.title": "Ograničenje učestalosti", "alert.unexpected.message": "Dogodila se neočekivana greška.", "alert.unexpected.title": "Ups!", "announcement.announcement": "Najava", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(neobrađeno)", "autosuggest_hashtag.per_week": "{count} tjedno", "boost_modal.combo": "Možete pritisnuti {combo} kako biste preskočili ovo sljedeći put", "bundle_column_error.body": "Nešto je pošlo po zlu tijekom učitavanja ove komponente.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Omogući odabir samo jedne opcije ankete", "compose_form.publish": "Tootni", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Označi medijski sadržaj kao osjetljiv", "compose_form.sensitive.marked": "Medijski sadržaj označen je kao osjetljiv", "compose_form.sensitive.unmarked": "Medijski sadržaj nije označen kao osjetljiv", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Stvarno želite obrisati ovaj toot?", "confirmations.delete_list.confirm": "Obriši", "confirmations.delete_list.message": "Jeste li sigurni da želite trajno obrisati ovu listu?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Odbaciti", + "confirmations.discard_edit_media.message": "Niste spremili promjene u opisu medija ili u predpregledu, svejedno ih odbaciti?", "confirmations.domain_block.confirm": "Blokiraj cijelu domenu", "confirmations.domain_block.message": "Jeste li zaista, zaista sigurni da želite blokirati cijelu domenu {domain}? U većini slučajeva dovoljno je i preferirano nekoliko ciljanih blokiranja ili utišavanja. Nećete vidjeti sadržaj s te domene ni u kojim javnim vremenskim crtama ili Vašim obavijestima. Vaši pratitelji s te domene bit će uklonjeni.", "confirmations.logout.confirm": "Odjavi se", @@ -163,28 +165,28 @@ "empty_column.blocks": "Još niste blokirali nikoga.", "empty_column.bookmarked_statuses": "Još nemaš niti jedan označeni toot. Kada označiš jedan, prikazad će se ovdje.", "empty_column.community": "Lokalna vremenska crta je prazna. Napišite nešto javno da biste pokrenuli stvari!", - "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.", + "empty_column.direct": "Nemate još niti jedne direktne poruke. Kada ih pošaljete ili primite, prikazati će se ovdje.", "empty_column.domain_blocks": "Još nema blokiranih domena.", "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.", "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.", - "empty_column.follow_recommendations": "Looks like no suggestions could be generated for you. You can try using search to look for people you might know or explore trending hashtags.", - "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.", + "empty_column.follow_recommendations": "Čini se da se ne postoje sugestije generirane za tebe. Možeš pokušati koristiti pretragu kako bi pronašao osobe koje poznaš ili istraži popularne hashtagove.", + "empty_column.follow_requests": "Nemaš niti jedan zahtjev za praćenjem. Ako ga dobiješ, prikazat će se ovdje.", "empty_column.hashtag": "Još ne postoji ništa s ovim hashtagom.", "empty_column.home": "Vaša početna vremenska crta je prazna! Posjetite {public} ili koristite tražilicu kako biste započeli i upoznali druge korisnike.", - "empty_column.home.suggestions": "See some suggestions", + "empty_column.home.suggestions": "Pogledajte neke prijedloge", "empty_column.list": "Na ovoj listi još nema ničega. Kada članovi ove liste objave nove tootove, oni će se pojaviti ovdje.", - "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.", + "empty_column.lists": "Nemaš niti jednu listu. Kada je kreiraš, prikazat će se ovdje.", "empty_column.mutes": "Niste utišali nijednog korisnika.", "empty_column.notifications": "Još nemate obavijesti. Komunicirajte s drugima kako biste započeli razgovor.", "empty_column.public": "Ovdje nema ništa! Napišite nešto javno ili ručno pratite korisnike s drugi poslužitelja da biste ovo popunili", - "error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.", - "error.unexpected_crash.explanation_addons": "This page could not be displayed correctly. This error is likely caused by a browser add-on or automatic translation tools.", - "error.unexpected_crash.next_steps": "Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", - "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", - "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard", + "error.unexpected_crash.explanation": "Zbog bug-a u našem kodu ili zbog nekompatibilnosti pretraživača, ova stranica se ne može prikazati ispravno.", + "error.unexpected_crash.explanation_addons": "Ova stranica ne može biti ispravno prikazana. Ova greška je uzrokovana dodatkom za browser ili alatom za automatsko prevođenje.", + "error.unexpected_crash.next_steps": "Pokušaj osvježiti stranicu. Ako to ne pomogne, i dalje ćeš biti u mogućnosti koristiti Mastodon preko nekod drugog preglednika ili izvornog app-a.", + "error.unexpected_crash.next_steps_addons": "Pokušaj ih onemogućiti i osvježiti stranicu. Ako to ne pomogne, i dalje ćeš biti u mogućnosti koristiti Mastodon preko nekog drugog preglednika ili izvornog app-a.", + "errors.unexpected_crash.copy_stacktrace": "Kopiraj stacktrace u međuspremnik", "errors.unexpected_crash.report_issue": "Prijavi problem", - "follow_recommendations.done": "Done", - "follow_recommendations.heading": "Follow people you'd like to see posts from! Here are some suggestions.", + "follow_recommendations.done": "Učinjeno", + "follow_recommendations.heading": "Zaprati osobe čije objave želiš vidjeti! Evo nekoliko prijedloga.", "follow_recommendations.lead": "Posts from people you follow will show up in chronological order on your home feed. Don't be afraid to make mistakes, you can unfollow people just as easily any time!", "follow_request.authorize": "Autoriziraj", "follow_request.reject": "Odbij", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favoriti:", "notifications.column_settings.filter_bar.advanced": "Prikaži sve kategorije", "notifications.column_settings.filter_bar.category": "Brza traka filtera", - "notifications.column_settings.filter_bar.show": "Prikaži", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Novi pratitelji:", "notifications.column_settings.follow_request": "Novi zahtjevi za praćenje:", "notifications.column_settings.mention": "Spominjanja:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Prikaži u stupcu", "notifications.column_settings.sound": "Sviraj zvuk", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Sve", "notifications.filter.boosts": "Boostovi", "notifications.filter.favourites": "Favoriti", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Učitavanje…", "regeneration_indicator.sublabel": "Priprema se Vaša početna stranica!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "sada", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "danas", "reply_indicator.cancel": "Otkaži", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Proslijedi {target}", "report.forward_hint": "Račun je s drugog poslužitelja. Poslati anonimiziranu kopiju prijave i tamo?", "report.hint": "Prijava bit će poslana moderatorima poslužitelja. Ispod možete dati objašnjenje zašto prijavljujete ovaj račun:", @@ -396,9 +407,14 @@ "status.delete": "Obriši", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Označi favoritom", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Učitaj više", "status.media_hidden": "Sakriven medijski sadržaj", "status.mention": "Spomeni @{name}", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index db08bfc75..4a55c85d9 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -47,16 +47,17 @@ "account.unmute": "@{name} némítás feloldása", "account.unmute_notifications": "@{name} némított értesítéseinek feloldása", "account_note.placeholder": "Klikk a feljegyzéshez", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Átlag", + "admin.dashboard.retention.cohort": "Regisztráció hónapja", + "admin.dashboard.retention.cohort_size": "Új felhasználó", "alert.rate_limited.message": "Próbáld újra {retry_time, time, medium} után.", "alert.rate_limited.title": "Forgalomkorlátozás", "alert.unexpected.message": "Váratlan hiba történt.", "alert.unexpected.title": "Hoppá!", "announcement.announcement": "Közlemény", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(feldolgozatlan)", "autosuggest_hashtag.per_week": "{count} hetente", "boost_modal.combo": "Hogy átugord ezt következő alkalommal, használd {combo}", "bundle_column_error.body": "Valami hiba történt a komponens betöltése közben.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Szavazás megváltoztatása egyetlen választásosra", "compose_form.publish": "Tülk", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Média kényesnek jelölése} other {Média kényesnek jelölése}}", "compose_form.sensitive.marked": "{count, plural, one {A médiát kényesnek jelölték} other {A médiát kényesnek jelölték}}", "compose_form.sensitive.unmarked": "{count, plural, one {A médiát nem jelölték kényesnek} other {A médiát nem jelölték kényesnek}}", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Biztos, hogy törölni szeretnéd ezt a bejegyzést?", "confirmations.delete_list.confirm": "Törlés", "confirmations.delete_list.message": "Biztos, hogy véglegesen törölni szeretnéd ezt a listát?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Elvetés", + "confirmations.discard_edit_media.message": "Elmentetlen változtatásaid vannak a média leírásában vagy előnézetében. Eldobjuk őket?", "confirmations.domain_block.confirm": "Teljes domain elrejtése", "confirmations.domain_block.message": "Biztos, hogy le szeretnéd tiltani a teljes {domain} domaint? A legtöbb esetben néhány célzott tiltás vagy némítás elegendő, és kívánatosabb megoldás. Semmilyen tartalmat nem fogsz látni ebből a domainből se az idővonalakon, se az értesítésekben. Az ebben a domainben lévő követőidet is eltávolítjuk.", "confirmations.logout.confirm": "Kijelentkezés", @@ -167,7 +169,7 @@ "empty_column.domain_blocks": "Még nem rejtettél el egyetlen domaint sem.", "empty_column.favourited_statuses": "Még nincs egyetlen kedvenc bejegyzésed sem. Ha kedvencnek jelölsz egyet, itt fog megjelenni.", "empty_column.favourites": "Még senki sem jelölte ezt a bejegyzést kedvencnek. Ha valaki mégis megteszi, itt fogjuk mutatni.", - "empty_column.follow_recommendations": "Úgy tűnik, neked nem tudunk javaslatokat adni. Próbáld a keresést használni olyanok megtalálására, akiket ismerhetsz, vagy fedezd fel a trendi hastageket.", + "empty_column.follow_recommendations": "Úgy tűnik, neked nem tudunk javaslatokat adni. Próbáld a keresést használni olyanok megtalálására, akiket ismerhetsz, vagy fedezd fel a felkapott hastageket.", "empty_column.follow_requests": "Még nincs egy követési kérésed sem. Ha kapsz egyet, itt fogjuk feltüntetni.", "empty_column.hashtag": "Jelenleg nem található semmi ezzel a hashtaggel.", "empty_column.home": "A saját idővonalad üres! Látogasd meg a {public} oldalt vagy használd a keresőt, hogy megismerj másokat.", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Kedvencek:", "notifications.column_settings.filter_bar.advanced": "Minden kategória mutatása", "notifications.column_settings.filter_bar.category": "Gyorskereső mező", - "notifications.column_settings.filter_bar.show": "Mutat", + "notifications.column_settings.filter_bar.show_bar": "Szűrősáv mutatása", "notifications.column_settings.follow": "Új követők:", "notifications.column_settings.follow_request": "Új követési kérelmek:", "notifications.column_settings.mention": "Megemlítések:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Oszlopban mutatás", "notifications.column_settings.sound": "Hang lejátszása", "notifications.column_settings.status": "Új bejegyzések:", - "notifications.column_settings.unread_markers.category": "Olvasatlan értesítés jelzők", + "notifications.column_settings.unread_notifications.category": "Olvasatlan értesítések", + "notifications.column_settings.unread_notifications.highlight": "Olvasatlan értesítések kiemelése", "notifications.filter.all": "Mind", "notifications.filter.boosts": "Megtolások", "notifications.filter.favourites": "Kedvencnek jelölések", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# szavazat} other {# szavazat}}", "poll.vote": "Szavazás", "poll.voted": "Erre a válaszra szavaztál", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# szavazat} other {# szavazat}}", "poll_button.add_poll": "Új szavazás", "poll_button.remove_poll": "Szavazás törlése", "privacy.change": "Bejegyzés láthatóságának módosítása", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Töltődik…", "regeneration_indicator.sublabel": "A saját idővonalad épp készül!", "relative_time.days": "{number}n", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}ó", "relative_time.just_now": "most", "relative_time.minutes": "{number}p", "relative_time.seconds": "{number}mp", "relative_time.today": "ma", "reply_indicator.cancel": "Mégsem", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Továbbítás: {target}", "report.forward_hint": "Ez a fiók egy másik kiszolgálóról van. Oda is elküldöd a jelentés egy anonimizált másolatát?", "report.hint": "A bejelentést a szervered moderátorainak küldjük el. Megmagyarázhatod, miért jelented az alábbi problémát:", @@ -396,9 +407,14 @@ "status.delete": "Törlés", "status.detailed_status": "Részletes beszélgetési nézet", "status.direct": "Közvetlen üzenet @{name} számára", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Beágyazás", "status.favourite": "Kedvenc", "status.filtered": "Megszűrt", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Többet", "status.media_hidden": "Média elrejtve", "status.mention": "@{name} megemlítése", @@ -462,7 +478,7 @@ "upload_form.video_description": "Írja le a hallás- vagy látássérültek számára", "upload_modal.analyzing_picture": "Kép elemzése…", "upload_modal.apply": "Alkalmaz", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Alkalmazás…", "upload_modal.choose_image": "Kép kiválasztása", "upload_modal.description_placeholder": "A gyors, barna róka átugrik a lusta kutya fölött", "upload_modal.detect_text": "Szöveg felismerése a képről", diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json index e412917f0..dde99078b 100644 --- a/app/javascript/mastodon/locales/hy.json +++ b/app/javascript/mastodon/locales/hy.json @@ -47,10 +47,11 @@ "account.unmute": "Ապալռեցնել @{name}֊ին", "account.unmute_notifications": "Միացնել ծանուցումները @{name}֊ից", "account_note.placeholder": "Սեղմէ՛ք գրառելու համար\n", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Միջին", + "admin.dashboard.retention.cohort": "Ամսուայ գրանցումներ", + "admin.dashboard.retention.cohort_size": "Նոր օգտուող", "alert.rate_limited.message": "Փորձէք որոշ ժամանակ անց՝ {retry_time, time, medium}։", "alert.rate_limited.title": "Գործողութիւնների յաճախութիւնը գերազանցում է թոյլատրելին", "alert.unexpected.message": "Անսպասելի սխալ տեղի ունեցաւ։", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Հարցումը դարձնել եզակի ընտրութեամբ", "compose_form.publish": "Հրապարակել", "compose_form.publish_loud": "Հրապարակե՜լ", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Նշել մեդիան որպէս դիւրազգաց", "compose_form.sensitive.marked": "Մեդիան նշուած է որպէս դիւրազգաց", "compose_form.sensitive.unmarked": "Մեդիան նշուած չէ որպէս դիւրազգաց", @@ -118,14 +120,14 @@ "confirmations.delete.message": "Վստա՞հ ես, որ ուզում ես ջնջել այս գրառումը։", "confirmations.delete_list.confirm": "Ջնջել", "confirmations.delete_list.message": "Վստա՞հ ես, որ ուզում ես մշտապէս ջնջել այս ցանկը։", - "confirmations.discard_edit_media.confirm": "Discard", + "confirmations.discard_edit_media.confirm": "Չեղարկել", "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", "confirmations.domain_block.confirm": "Թաքցնել ամբողջ տիրույթը", "confirmations.domain_block.message": "Հաստատ֊հաստա՞տ վստահ ես, որ ուզում ես արգելափակել ամբողջ {domain} տիրոյթը։ Սովորաբար մի երկու թիրախաւորուած արգելափակում կամ լռեցում բաւական է ու նախընտրելի։", "confirmations.logout.confirm": "Ելք", "confirmations.logout.message": "Համոզո՞ւած ես, որ ուզում ես դուրս գալ", "confirmations.mute.confirm": "Լռեցնել", - "confirmations.mute.explanation": "Սա թաքցնելու ա իրենց գրառումներն, ինչպէս նաեւ իրենց նշող գրառումներն, բայց իրենք միեւնոյն է կը կարողանան հետեւել ձեզ եւ տեսնել ձեր գրառումները։", + "confirmations.mute.explanation": "Սա թաքցնելու է իրենց գրառումները, ինչպէս նաեւ իրենց նշող գրառումները, բայց իրենք միեւնոյն է կը կարողանան հետեւել ձեզ եւ տեսնել ձեր գրառումները։", "confirmations.mute.message": "Վստա՞հ ես, որ ուզում ես {name}֊ին լռեցնել։", "confirmations.redraft.confirm": "Ջնջել եւ խմբագրել նորից", "confirmations.redraft.message": "Վստահ ե՞ս, որ ցանկանում ես ջնջել եւ վերախմբագրել այս գրառումը։ Դու կը կորցնես այս գրառման բոլոր պատասխանները, տարածումները եւ հաւանումները։", @@ -142,7 +144,7 @@ "directory.new_arrivals": "Նորեկներ", "directory.recently_active": "Վերջերս ակտիւ", "embed.instructions": "Այս գրառումը քո կայքում ներդնելու համար կարող ես պատճէնել ներքեւի կոդը։", - "embed.preview": "Ահա, թէ ինչ տեսք կը ունենայ այն՝", + "embed.preview": "Ահա, թէ ինչ տեսք կունենայ այն՝", "emoji_button.activity": "Զբաղմունքներ", "emoji_button.custom": "Յատուկ", "emoji_button.flags": "Դրօշներ", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Հաւանածներից՝", "notifications.column_settings.filter_bar.advanced": "Ցուցադրել բոլոր կատեգորիաները", "notifications.column_settings.filter_bar.category": "Արագ զտման վահանակ", - "notifications.column_settings.filter_bar.show": "Ցուցադրել", + "notifications.column_settings.filter_bar.show_bar": "Ցոյց տալ զտման պանելը", "notifications.column_settings.follow": "Նոր հետեւողներ՝", "notifications.column_settings.follow_request": "Նոր հետեւելու հայցեր:", "notifications.column_settings.mention": "Նշումներ՝", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Ցուցադրել սիւնում", "notifications.column_settings.sound": "Ձայն հանել", "notifications.column_settings.status": "Նոր գրառումներ։", - "notifications.column_settings.unread_markers.category": "Չկարդացուած ծանուցումների նշաններ", + "notifications.column_settings.unread_notifications.category": "Չկարդացուած ծանուցումներ", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Բոլորը", "notifications.filter.boosts": "Տարածածները", "notifications.filter.favourites": "Հաւանածները", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Բեռնւում է…", "regeneration_indicator.sublabel": "պատրաստւում է հիմնական հոսքդ", "relative_time.days": "{number}օր", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}ժ", "relative_time.just_now": "նոր", "relative_time.minutes": "{number}ր", "relative_time.seconds": "{number}վ", "relative_time.today": "Այսօր", "reply_indicator.cancel": "Չեղարկել", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Փոխանցել {target}֊ին", "report.forward_hint": "Այս հաշիւ այլ հանգոյցից է։ Ուղարկե՞մ այնտեղ էլ այս բողոքի անոնիմ պատճէնը։", "report.hint": "Այս զեկոյցը կուղարկուի հանգոյցի մոդերատորներին։ Ներքեւում կարող ես տրամադրել բացատրութիւն, թէ ինչու ես զեկուցում այս հաշուի մասին․", @@ -396,9 +407,14 @@ "status.delete": "Ջնջել", "status.detailed_status": "Շղթայի ընդլայնուած դիտում", "status.direct": "Նամակ գրել {name} -ին", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Ներդնել", "status.favourite": "Հաւանել", "status.filtered": "Զտուած", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Բեռնել աւելին", "status.media_hidden": "մեդիաբովանդակութիւնը թաքցուած է", "status.mention": "Նշել @{name}֊ին", @@ -462,7 +478,7 @@ "upload_form.video_description": "Նկարագրիր տեսանիւթը լսողական կամ տեսողական խնդիրներով անձանց համար", "upload_modal.analyzing_picture": "Լուսանկարի վերլուծում…", "upload_modal.apply": "Կիրառել", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Կիրառւում է...", "upload_modal.choose_image": "Ընտրել նկար", "upload_modal.description_placeholder": "Բել դղեակի ձախ ժամն օֆ ազգութեանը ցպահանջ չճշտած վնաս էր եւ փառք։", "upload_modal.detect_text": "Յայտնաբերել տեքստը նկարից", diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json index a664aff56..3b43f60d5 100644 --- a/app/javascript/mastodon/locales/id.json +++ b/app/javascript/mastodon/locales/id.json @@ -47,16 +47,17 @@ "account.unmute": "Berhenti membisukan @{name}", "account.unmute_notifications": "Berhenti bisukan pemberitahuan dari @{name}", "account_note.placeholder": "Klik untuk menambah catatan", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Rata-rata", + "admin.dashboard.retention.cohort": "Bulan pendaftaran", + "admin.dashboard.retention.cohort_size": "Pengguna baru", "alert.rate_limited.message": "Mohon ulangi setelah {retry_time, time, medium}.", "alert.rate_limited.title": "Batasan tingkat", "alert.unexpected.message": "Terjadi kesalahan yang tidak terduga.", "alert.unexpected.title": "Ups!", "announcement.announcement": "Pengumuman", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(tidak diproses)", "autosuggest_hashtag.per_week": "{count} per minggu", "boost_modal.combo": "Anda dapat menekan {combo} untuk melewati ini", "bundle_column_error.body": "Kesalahan terjadi saat memuat komponen ini.", @@ -65,7 +66,7 @@ "bundle_modal_error.close": "Tutup", "bundle_modal_error.message": "Kesalahan terjadi saat memuat komponen ini.", "bundle_modal_error.retry": "Coba lagi", - "column.blocks": "Pengguna diblokir", + "column.blocks": "Pengguna yang diblokir", "column.bookmarks": "Markah", "column.community": "Linimasa Lokal", "column.direct": "Pesan langsung", @@ -92,18 +93,19 @@ "community.column_settings.remote_only": "Hanya jarak jauh", "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.", "compose_form.direct_message_warning_learn_more": "Pelajari selengkapnya", - "compose_form.hashtag_warning": "Toot ini tidak akan ada dalam daftar tagar manapun karena telah di set sebagai tidak terdaftar. Hanya postingan publik yang bisa dicari dengan tagar.", + "compose_form.hashtag_warning": "Toot ini tidak akan ada dalam daftar tagar manapun karena telah diatur sebagai tidak terdaftar. Hanya postingan publik yang bisa dicari dengan tagar.", "compose_form.lock_disclaimer": "Akun anda tidak {locked}. Semua orang dapat mengikuti anda untuk melihat postingan khusus untuk pengikut anda.", "compose_form.lock_disclaimer.lock": "terkunci", "compose_form.placeholder": "Apa yang ada di pikiran anda?", "compose_form.poll.add_option": "Tambahkan pilihan", - "compose_form.poll.duration": "Durasi jajak pendapat", + "compose_form.poll.duration": "Durasi polling", "compose_form.poll.option_placeholder": "Pilihan {number}", "compose_form.poll.remove_option": "Hapus opsi ini", "compose_form.poll.switch_to_multiple": "Ubah japat menjadi pilihan ganda", "compose_form.poll.switch_to_single": "Ubah japat menjadi pilihan tunggal", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, other {Tandai media sebagai sensitif}}", "compose_form.sensitive.marked": "{count, plural, other {Media ini ditandai sebagai sensitif}}", "compose_form.sensitive.unmarked": "{count, plural, other {Media ini tidak ditandai sebagai sensitif}}", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Apa anda yakin untuk menghapus status ini?", "confirmations.delete_list.confirm": "Hapus", "confirmations.delete_list.message": "Apakah anda yakin untuk menghapus daftar ini secara permanen?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Buang", + "confirmations.discard_edit_media.message": "Anda belum menyimpan perubahan deskripsi atau pratinjau media, buang saja?", "confirmations.domain_block.confirm": "Sembunyikan keseluruhan domain", "confirmations.domain_block.message": "Apakah anda benar benar yakin untuk memblokir keseluruhan {domain}? Dalam kasus tertentu beberapa pemblokiran atau penyembunyian lebih baik.", "confirmations.logout.confirm": "Keluar", @@ -127,8 +129,8 @@ "confirmations.mute.confirm": "Bisukan", "confirmations.mute.explanation": "Ini akan menyembunyikan pos dari mereka dan pos yang menyebut mereka, tapi ini tetap mengizinkan mereka melihat posmu dan mengikutimu.", "confirmations.mute.message": "Apa anda yakin ingin membisukan {name}?", - "confirmations.redraft.confirm": "Hapus dan konsep ulang", - "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.", + "confirmations.redraft.confirm": "Hapus dan susun ulang", + "confirmations.redraft.message": "Apakah anda yakin ingin menghapus dan menyusun ulang? Favorit dan boost akan hilang, dan balasan terhadap kiriman asli akan ditinggalkan.", "confirmations.reply.confirm": "Balas", "confirmations.reply.message": "Membalas sekarang akan menimpa pesan yang sedang Anda buat. Anda yakin ingin melanjutkan?", "confirmations.unfollow.confirm": "Berhenti mengikuti", @@ -141,8 +143,8 @@ "directory.local": "Dari {domain} saja", "directory.new_arrivals": "Yang baru datang", "directory.recently_active": "Baru-baru ini aktif", - "embed.instructions": "Sematkan status ini di website anda dengan menyalin kode di bawah ini.", - "embed.preview": "Seperti ini nantinya:", + "embed.instructions": "Sematkan kiriman ini di website anda dengan menyalin kode di bawah ini.", + "embed.preview": "Tampilan akan seperti ini nantinya:", "emoji_button.activity": "Aktivitas", "emoji_button.custom": "Kustom", "emoji_button.flags": "Bendera", @@ -166,8 +168,8 @@ "empty_column.direct": "Anda belum memiliki pesan langsung. Ketika Anda mengirim atau menerimanya, maka akan muncul di sini.", "empty_column.domain_blocks": "Tidak ada topik tersembunyi.", "empty_column.favourited_statuses": "Anda belum memiliki toot favorit. Ketika Anda mengirim atau menerimanya, maka akan muncul di sini.", - "empty_column.favourites": "Tidak ada seorangpun yang memfavoritkan toot ini. Ketika seseorang melakukannya, maka akan muncul disini.", - "empty_column.follow_recommendations": "Sepertinya tak ada saran yang dibuat untuk Anda. Anda dapat coba menggunakan pencarian untuk menemukan orang yang Anda ketahui atau menjelajahi tagar yang sedang tren.", + "empty_column.favourites": "Belum ada yang memfavoritkan toot ini. Ketika seseorang melakukannya, akan muncul disini.", + "empty_column.follow_recommendations": "Sepertinya tak ada saran yang dibuat untuk Anda. Anda dapat mencoba menggunakan pencarian untuk menemukan orang yang Anda ketahui atau menjelajahi tagar yang sedang tren.", "empty_column.follow_requests": "Anda belum memiliki permintaan mengikuti. Ketika Anda menerimanya, maka akan muncul disini.", "empty_column.hashtag": "Tidak ada apapun dalam hashtag ini.", "empty_column.home": "Linimasa anda kosong! Kunjungi {public} atau gunakan pencarian untuk memulai dan bertemu pengguna lain.", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favorit:", "notifications.column_settings.filter_bar.advanced": "Tampilkan semua kategori", "notifications.column_settings.filter_bar.category": "Bilah penyaring cepat", - "notifications.column_settings.filter_bar.show": "Tampilkan", + "notifications.column_settings.filter_bar.show_bar": "Tampilkan bilah filter", "notifications.column_settings.follow": "Pengikut baru:", "notifications.column_settings.follow_request": "Permintaan mengikuti baru:", "notifications.column_settings.mention": "Balasan:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Tampilkan dalam kolom", "notifications.column_settings.sound": "Mainkan suara", "notifications.column_settings.status": "Toot baru:", - "notifications.column_settings.unread_markers.category": "Penanda notifikasi belum dibaca", + "notifications.column_settings.unread_notifications.category": "Notifikasi yang belum dibaca", + "notifications.column_settings.unread_notifications.highlight": "Sorot notifikasi yang belum dibaca", "notifications.filter.all": "Semua", "notifications.filter.boosts": "Boost", "notifications.filter.favourites": "Favorit", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, other {# suara}}", "poll.vote": "Memilih", "poll.voted": "Anda memilih jawaban ini", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, other {# suara}}", "poll_button.add_poll": "Tambah japat", "poll_button.remove_poll": "Hapus japat", "privacy.change": "Tentukan privasi status", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Memuat…", "regeneration_indicator.sublabel": "Linimasa anda sedang disiapkan!", "relative_time.days": "{number}h", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}j", "relative_time.just_now": "sekarang", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}d", "relative_time.today": "hari ini", "reply_indicator.cancel": "Batal", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Teruskan ke {target}", "report.forward_hint": "Akun dari server lain. Kirim salinan laporan scr anonim ke sana?", "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Hapus", "status.detailed_status": "Tampilan detail percakapan", "status.direct": "Pesan langsung @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Tanam", "status.favourite": "Difavoritkan", "status.filtered": "Disaring", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Tampilkan semua", "status.media_hidden": "Media disembunyikan", "status.mention": "Balasan @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Penjelasan untuk orang dengan gangguan pendengaran atau penglihatan", "upload_modal.analyzing_picture": "Analisis gambar…", "upload_modal.apply": "Terapkan", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Menerapkan…", "upload_modal.choose_image": "Pilih gambar", "upload_modal.description_placeholder": "Muharjo seorang xenofobia universal yang takut pada warga jazirah, contohnya Qatar", "upload_modal.detect_text": "Deteksi teks pada gambar", diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json index a0c7c4912..ee8a2b1b9 100644 --- a/app/javascript/mastodon/locales/io.json +++ b/app/javascript/mastodon/locales/io.json @@ -47,7 +47,8 @@ "account.unmute": "Ne plus celar @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Siflar", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favorati:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Nova sequanti:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mencioni:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Montrar en kolumno", "notifications.column_settings.sound": "Plear sono", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "Nihiligar", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Efacar", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favorizar", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Kargar pluse", "status.media_hidden": "Kontenajo celita", "status.mention": "Mencionar @{name}", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index 9aeca30ac..5020bd068 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -47,16 +47,17 @@ "account.unmute": "Hætta að þagga niður í @{name}", "account.unmute_notifications": "Hætta að þagga tilkynningar frá @{name}", "account_note.placeholder": "Engin athugasemd gefin", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Meðaltal", + "admin.dashboard.retention.cohort": "Mánuður nýskráninga", + "admin.dashboard.retention.cohort_size": "Nýir notendur", "alert.rate_limited.message": "Prófaðu aftur eftir {retry_time, time, medium}.", "alert.rate_limited.title": "Með takmörkum", "alert.unexpected.message": "Upp kom óvænt villa.", "alert.unexpected.title": "Úbbs!", "announcement.announcement": "Auglýsing", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(óunnið)", "autosuggest_hashtag.per_week": "{count} á viku", "boost_modal.combo": "Þú getur ýtt á {combo} til að sleppa þessu næst", "bundle_column_error.body": "Eitthvað fór úrskeiðis við að hlaða inn þessari einingu.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Breyta könnun svo hægt sé að hafa einn stakan valkost", "compose_form.publish": "Þyt", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Merkja myndir sem viðkvæmar", "compose_form.sensitive.marked": "Mynd er merkt sem viðkvæm", "compose_form.sensitive.unmarked": "Mynd er ekki merkt sem viðkvæm", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Ertu viss um að þú viljir eyða þessari stöðufærslu?", "confirmations.delete_list.confirm": "Eyða", "confirmations.delete_list.message": "Ertu viss um að þú viljir eyða þessum lista endanlega?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Henda", + "confirmations.discard_edit_media.message": "Þú ert með óvistaðar breytingar á lýsingu myndefnis eða forskoðunar, henda þeim samt?", "confirmations.domain_block.confirm": "Fela allt lénið", "confirmations.domain_block.message": "Ertu alveg algjörlega viss um að þú viljir loka á allt {domain}? Í flestum tilfellum er vænlegra að nota færri en markvissari útilokanir eða að þagga niður tiltekna aðila. Þú munt ekki sjá efni frá þessu léni í neinum opinberum tímalínum eða í tilkynningunum þínum. Fylgjendur þínir frá þessu léni verða fjarlægðir.", "confirmations.logout.confirm": "Skrá út", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Fílanir:", "notifications.column_settings.filter_bar.advanced": "Birta alla flokka", "notifications.column_settings.filter_bar.category": "Skyndisíustika", - "notifications.column_settings.filter_bar.show": "Sýna", + "notifications.column_settings.filter_bar.show_bar": "Birta síustikuna", "notifications.column_settings.follow": "Nýir fylgjendur:", "notifications.column_settings.follow_request": "Nýjar beiðnir um að fylgjast með:", "notifications.column_settings.mention": "Tilvísanir:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Sýna í dálki", "notifications.column_settings.sound": "Spila hljóð", "notifications.column_settings.status": "Ný þyt:", - "notifications.column_settings.unread_markers.category": "Merki fyrir ólesnar tilkynningar", + "notifications.column_settings.unread_notifications.category": "Ólesnar tilkynningar", + "notifications.column_settings.unread_notifications.highlight": "Áherslulita ólesnar tilkynningar", "notifications.filter.all": "Allt", "notifications.filter.boosts": "Endurbirtingar", "notifications.filter.favourites": "Fílanir", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# atkvæði} other {# atkvæði}}", "poll.vote": "Greiða atkvæði", "poll.voted": "Þú kaust þetta svar", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# atkvæði} other {# atkvæði}}", "poll_button.add_poll": "Bæta við könnun", "poll_button.remove_poll": "Fjarlægja könnun", "privacy.change": "Aðlaga gagnaleynd stöðufærslu", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Hleð inn…", "regeneration_indicator.sublabel": "Verið er að útbúa heimastreymið þitt!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}kl.", "relative_time.just_now": "núna", "relative_time.minutes": "{number}mín", "relative_time.seconds": "{number}sek", "relative_time.today": "í dag", "reply_indicator.cancel": "Hætta við", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Áframsenda til {target}", "report.forward_hint": "Notandaaðgangurinn er af öðrum vefþjóni. Á einnig að senda nafnlaust afrit af kærunni þangað?", "report.hint": "Kæran verður send á umsjónarmenn vefþjónsins þíns. Þú getur gefið skýringu hér fyrir neðan á því af hverju þú ert að kæra þennan notandaaðgang:", @@ -396,9 +407,14 @@ "status.delete": "Eyða", "status.detailed_status": "Nákvæm spjallþráðasýn", "status.direct": "Bein skilaboð @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Ívefja", "status.favourite": "Fílanir", "status.filtered": "Síað", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Hlaða inn meiru", "status.media_hidden": "Mynd er falin", "status.mention": "Minnast á @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Lýstu þessu fyrir fólk sem heyrir illa eða er með skerta sjón", "upload_modal.analyzing_picture": "Greini mynd…", "upload_modal.apply": "Virkja", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Beiti…", "upload_modal.choose_image": "Veldu mynd", "upload_modal.description_placeholder": "Öllum dýrunum í skóginum þætti bezt að vera vinir", "upload_modal.detect_text": "Skynja texta úr mynd", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index d2c9e1179..c02c84f09 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -6,20 +6,20 @@ "account.block": "Blocca @{name}", "account.block_domain": "Blocca dominio {domain}", "account.blocked": "Bloccato", - "account.browse_more_on_origin_server": "Sfoglia ulteriormente sul profilo originale", + "account.browse_more_on_origin_server": "Sfoglia di più sul profilo originale", "account.cancel_follow_request": "Annulla richiesta di seguire", "account.direct": "Messaggio diretto a @{name}", "account.disable_notifications": "Smetti di avvisarmi quando @{name} pubblica un post", "account.domain_blocked": "Dominio bloccato", "account.edit_profile": "Modifica profilo", "account.enable_notifications": "Avvisami quando @{name} pubblica un post", - "account.endorse": "Mostra sul profilo", + "account.endorse": "Metti in evidenza sul profilo", "account.follow": "Segui", "account.followers": "Follower", - "account.followers.empty": "Ancora nessuno segue questo utente.", + "account.followers.empty": "Nessuno segue ancora questo utente.", "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Follower}}", "account.following_counter": "{count, plural, other {{counter} Seguiti}}", - "account.follows.empty": "Questo utente non segue ancora nessuno.", + "account.follows.empty": "Questo utente non segue nessuno ancora.", "account.follows_you": "Ti segue", "account.hide_reblogs": "Nascondi condivisioni da @{name}", "account.joined": "Su questa istanza dal {date}", @@ -31,15 +31,15 @@ "account.moved_to": "{name} si è trasferito su:", "account.mute": "Silenzia @{name}", "account.mute_notifications": "Silenzia notifiche da @{name}", - "account.muted": "Silenziat*", + "account.muted": "Silenziato", "account.never_active": "Mai", - "account.posts": "Toot", - "account.posts_with_replies": "Toot e risposte", + "account.posts": "Post", + "account.posts_with_replies": "Post e risposte", "account.report": "Segnala @{name}", "account.requested": "In attesa di approvazione. Clicca per annullare la richiesta di seguire", "account.share": "Condividi il profilo di @{name}", "account.show_reblogs": "Mostra condivisioni da @{name}", - "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toot}}", + "account.statuses_counter": "{count, plural, one {{counter} Post} other {{counter} Post}}", "account.unblock": "Sblocca @{name}", "account.unblock_domain": "Sblocca il dominio {domain}", "account.unendorse": "Non mostrare sul profilo", @@ -47,16 +47,17 @@ "account.unmute": "Riattiva @{name}", "account.unmute_notifications": "Riattiva le notifiche da @{name}", "account_note.placeholder": "Clicca per aggiungere una nota", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", - "alert.rate_limited.message": "Sei pregato di riprovare tra {retry_time, time, medium}.", - "alert.rate_limited.title": "Limitazione per eccesso di richieste", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Media", + "admin.dashboard.retention.cohort": "Mese di iscrizione", + "admin.dashboard.retention.cohort_size": "Nuovi utenti", + "alert.rate_limited.message": "Riprova dopo le {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limit", "alert.unexpected.message": "Si è verificato un errore imprevisto.", "alert.unexpected.title": "Oops!", "announcement.announcement": "Annuncio", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(non elaborato)", "autosuggest_hashtag.per_week": "{count} per settimana", "boost_modal.combo": "Puoi premere {combo} per saltare questo passaggio la prossima volta", "bundle_column_error.body": "E' avvenuto un errore durante il caricamento di questo componente.", @@ -77,22 +78,22 @@ "column.lists": "Elenchi", "column.mutes": "Utenti silenziati", "column.notifications": "Notifiche", - "column.pins": "Toot in evidenza", + "column.pins": "Post fissati in cima", "column.public": "Timeline federata", "column_back_button.label": "Indietro", "column_header.hide_settings": "Nascondi impostazioni", "column_header.moveLeft_settings": "Sposta colonna a sinistra", "column_header.moveRight_settings": "Sposta colonna a destra", - "column_header.pin": "Evidenzia", + "column_header.pin": "Fissa in cima", "column_header.show_settings": "Mostra impostazioni", - "column_header.unpin": "Non mettere in evidenza", + "column_header.unpin": "Non fissare in cima", "column_subheading.settings": "Impostazioni", "community.column_settings.local_only": "Solo Locale", "community.column_settings.media_only": "Solo Media", "community.column_settings.remote_only": "Solo Remoto", - "compose_form.direct_message_warning": "Questo toot sarà inviato solo agli utenti menzionati.", + "compose_form.direct_message_warning": "Questo post sarà inviato solo agli utenti menzionati.", "compose_form.direct_message_warning_learn_more": "Scopri di più", - "compose_form.hashtag_warning": "Questo toot non sarà elencato sotto alcun hashtag poiché senza elenco. Solo i toot pubblici possono essere ricercati per hashtag.", + "compose_form.hashtag_warning": "Questo post non sarà elencato sotto alcun hashtag poiché senza elenco. Solo i toot pubblici possono essere ricercati per hashtag.", "compose_form.lock_disclaimer": "Il tuo profilo non è {locked}. Chiunque può seguirti e vedere le tue pubblicazioni visibili solo dai follower.", "compose_form.lock_disclaimer.lock": "bloccato", "compose_form.placeholder": "A cosa stai pensando?", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Modifica sondaggio per consentire una singola scelta", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Segna media come sensibile", "compose_form.sensitive.marked": "Questo media è contrassegnato come sensibile", "compose_form.sensitive.unmarked": "Questo media non è contrassegnato come sensibile", @@ -115,11 +117,11 @@ "confirmations.block.confirm": "Blocca", "confirmations.block.message": "Sei sicuro di voler bloccare {name}?", "confirmations.delete.confirm": "Cancella", - "confirmations.delete.message": "Sei sicuro di voler cancellare questo toot?", + "confirmations.delete.message": "Sei sicuro di voler cancellare questo post?", "confirmations.delete_list.confirm": "Cancella", "confirmations.delete_list.message": "Sei sicuro di voler cancellare definitivamente questa lista?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Abbandona", + "confirmations.discard_edit_media.message": "Sono state apportate modifiche non salvate alla descrizione o all'anteprima del media, vuoi abbandonarle?", "confirmations.domain_block.confirm": "Blocca l'intero dominio", "confirmations.domain_block.message": "Sei davvero, davvero sicur@ di voler bloccare {domain} completamente? Nella maggioranza dei casi, è preferibile e sufficiente bloccare o silenziare pochi account in modo mirato. Non vedrai più il contenuto da quel dominio né nelle timeline pubbliche né nelle tue notifiche. Anzi, verranno rimossi dai follower gli account di questo dominio.", "confirmations.logout.confirm": "Disconnettiti", @@ -141,7 +143,7 @@ "directory.local": "Solo da {domain}", "directory.new_arrivals": "Nuovi arrivi", "directory.recently_active": "Attivo di recente", - "embed.instructions": "Incorpora questo toot sul tuo sito web copiando il codice sotto.", + "embed.instructions": "Incorpora questo post sul tuo sito web copiando il codice sotto.", "embed.preview": "Ecco come apparirà:", "emoji_button.activity": "Attività", "emoji_button.custom": "Personalizzato", @@ -158,15 +160,15 @@ "emoji_button.symbols": "Simboli", "emoji_button.travel": "Viaggi & Luoghi", "empty_column.account_suspended": "Account sospeso", - "empty_column.account_timeline": "Nessun toot qui!", + "empty_column.account_timeline": "Nessun post qui!", "empty_column.account_unavailable": "Profilo non disponibile", "empty_column.blocks": "Non hai ancora bloccato alcun utente.", - "empty_column.bookmarked_statuses": "Non hai ancora segnato alcun toot. Quando ne segni uno, sarà mostrato qui.", + "empty_column.bookmarked_statuses": "Non hai ancora segnato alcun post. Quando ne segni uno, sarà mostrato qui.", "empty_column.community": "La timeline locale è vuota. Condividi qualcosa pubblicamente per dare inizio alla festa!", "empty_column.direct": "Non hai ancora nessun messaggio privato. Quando ne manderai o riceverai qualcuno, apparirà qui.", "empty_column.domain_blocks": "Non vi sono domini nascosti.", - "empty_column.favourited_statuses": "Non hai ancora segnato nessun toot come apprezzato. Quando lo farai, comparirà qui.", - "empty_column.favourites": "Nessuno ha ancora segnato questo toot come apprezzato. Quando qualcuno lo farà, apparirà qui.", + "empty_column.favourited_statuses": "Non hai ancora segnato nessun post come apprezzato. Quando lo farai, comparirà qui.", + "empty_column.favourites": "Nessuno ha ancora segnato questo post come apprezzato. Quando qualcuno lo farà, apparirà qui.", "empty_column.follow_recommendations": "Sembra che nessun suggerimento possa essere generato per te. Puoi provare a usare la ricerca per cercare persone che potresti conoscere o esplorare hashtag di tendenza.", "empty_column.follow_requests": "Non hai ancora ricevuto nessuna richiesta di follow. Quando ne riceverai una, verrà mostrata qui.", "empty_column.hashtag": "Non c'è ancora nessun post con questo hashtag.", @@ -208,7 +210,7 @@ "hashtag.column_settings.tag_mode.none": "Nessuno di questi", "hashtag.column_settings.tag_toggle": "Include additional tags in this column", "home.column_settings.basic": "Semplice", - "home.column_settings.show_reblogs": "Mostra post condivisi", + "home.column_settings.show_reblogs": "Mostra condivisioni", "home.column_settings.show_replies": "Mostra risposte", "home.hide_announcements": "Nascondi annunci", "home.show_announcements": "Mostra annunci", @@ -217,14 +219,14 @@ "intervals.full.minutes": "{number, plural, one {# minuto} other {# minuti}}", "keyboard_shortcuts.back": "per tornare indietro", "keyboard_shortcuts.blocked": "per aprire l'elenco degli utenti bloccati", - "keyboard_shortcuts.boost": "per condividere", + "keyboard_shortcuts.boost": "Condividi il post", "keyboard_shortcuts.column": "per portare il focus su uno status in una delle colonne", "keyboard_shortcuts.compose": "per portare il focus nell'area di composizione", "keyboard_shortcuts.description": "Descrizione", "keyboard_shortcuts.direct": "per aprire la colonna dei messaggi diretti", - "keyboard_shortcuts.down": "per spostarsi in basso nella lista", - "keyboard_shortcuts.enter": "per aprire lo status", - "keyboard_shortcuts.favourite": "per segnare come apprezzato", + "keyboard_shortcuts.down": "Spostati in basso nella lista", + "keyboard_shortcuts.enter": "Apri il post", + "keyboard_shortcuts.favourite": "Apprezza post", "keyboard_shortcuts.favourites": "per aprire l'elenco dei toot apprezzati", "keyboard_shortcuts.federated": "per aprire la timeline federata", "keyboard_shortcuts.heading": "Tasti di scelta rapida", @@ -237,16 +239,16 @@ "keyboard_shortcuts.my_profile": "per aprire il tuo profilo", "keyboard_shortcuts.notifications": "per aprire la colonna delle notifiche", "keyboard_shortcuts.open_media": "per aprire media", - "keyboard_shortcuts.pinned": "per aprire l'elenco dei toot fissati in cima", + "keyboard_shortcuts.pinned": "Apri l'elenco dei toot fissati in cima", "keyboard_shortcuts.profile": "per aprire il profilo dell'autore", - "keyboard_shortcuts.reply": "per rispondere", + "keyboard_shortcuts.reply": "Rispondi al post", "keyboard_shortcuts.requests": "per aprire l'elenco di richieste di follow", "keyboard_shortcuts.search": "per spostare il focus sulla ricerca", "keyboard_shortcuts.spoilers": "per mostrare/nascondere il campo CW", "keyboard_shortcuts.start": "per aprire la colonna \"Come iniziare\"", "keyboard_shortcuts.toggle_hidden": "per mostrare/nascondere il testo dei CW", "keyboard_shortcuts.toggle_sensitivity": "mostrare/nascondere media", - "keyboard_shortcuts.toot": "per iniziare a scrivere un toot completamente nuovo", + "keyboard_shortcuts.toot": "Crea un nuovo post", "keyboard_shortcuts.unfocus": "per uscire dall'area di composizione o dalla ricerca", "keyboard_shortcuts.up": "per spostarsi in alto nella lista", "lightbox.close": "Chiudi", @@ -294,7 +296,7 @@ "navigation_bar.logout": "Esci", "navigation_bar.mutes": "Utenti silenziati", "navigation_bar.personal": "Personale", - "navigation_bar.pins": "Toot fissati in cima", + "navigation_bar.pins": "Post fissati in cima", "navigation_bar.preferences": "Impostazioni", "navigation_bar.public_timeline": "Timeline federata", "navigation_bar.security": "Sicurezza", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Apprezzati:", "notifications.column_settings.filter_bar.advanced": "Mostra tutte le categorie", "notifications.column_settings.filter_bar.category": "Filtro rapido", - "notifications.column_settings.filter_bar.show": "Mostra", + "notifications.column_settings.filter_bar.show_bar": "Mostra barra filtri", "notifications.column_settings.follow": "Nuovi follower:", "notifications.column_settings.follow_request": "Nuove richieste di follow:", "notifications.column_settings.mention": "Menzioni:", @@ -321,8 +323,9 @@ "notifications.column_settings.reblog": "Post condivisi:", "notifications.column_settings.show": "Mostra in colonna", "notifications.column_settings.sound": "Riproduci suono", - "notifications.column_settings.status": "Nuovi toot:", - "notifications.column_settings.unread_markers.category": "Marcatori di notifica non letti", + "notifications.column_settings.status": "Nuovi post:", + "notifications.column_settings.unread_notifications.category": "Notifiche non lette", + "notifications.column_settings.unread_notifications.highlight": "Evidenzia notifiche non lette", "notifications.filter.all": "Tutti", "notifications.filter.boosts": "Condivisioni", "notifications.filter.favourites": "Apprezzati", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# voto} other {# voti}}", "poll.vote": "Vota", "poll.voted": "Hai votato per questa risposta", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# voto} other {# voti}}", "poll_button.add_poll": "Aggiungi un sondaggio", "poll_button.remove_poll": "Rimuovi sondaggio", "privacy.change": "Modifica privacy del post", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Caricamento in corso…", "regeneration_indicator.sublabel": "Stiamo preparando il tuo home feed!", "relative_time.days": "{number}g", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}o", "relative_time.just_now": "ora", "relative_time.minutes": "{number} minuti", "relative_time.seconds": "{number} secondi", "relative_time.today": "oggi", "reply_indicator.cancel": "Annulla", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Inoltra a {target}", "report.forward_hint": "Questo account appartiene a un altro server. Mandare anche là una copia anonima del rapporto?", "report.hint": "La segnalazione sarà inviata ai moderatori del tuo server. Di seguito, puoi fornire il motivo per il quale stai segnalando questo account:", @@ -378,27 +389,32 @@ "search_popout.search_format": "Formato di ricerca avanzato", "search_popout.tips.full_text": "Testo semplice per trovare gli status che hai scritto, segnato come apprezzati, condiviso o in cui sei stato citato, e inoltre i nomi utente, nomi visualizzati e hashtag che lo contengono.", "search_popout.tips.hashtag": "etichetta", - "search_popout.tips.status": "stato", + "search_popout.tips.status": "post", "search_popout.tips.text": "Testo semplice per trovare nomi visualizzati, nomi utente e hashtag che lo contengono", "search_popout.tips.user": "utente", "search_results.accounts": "Gente", "search_results.hashtags": "Hashtag", - "search_results.statuses": "Toot", - "search_results.statuses_fts_disabled": "La ricerca di toot per il loro contenuto non è abilitata su questo server Mastodon.", + "search_results.statuses": "Post", + "search_results.statuses_fts_disabled": "La ricerca di post per il loro contenuto non è abilitata su questo server Mastodon.", "search_results.total": "{count} {count, plural, one {risultato} other {risultati}}", "status.admin_account": "Apri interfaccia di moderazione per @{name}", - "status.admin_status": "Apri questo status nell'interfaccia di moderazione", + "status.admin_status": "Apri questo post nell'interfaccia di moderazione", "status.block": "Blocca @{name}", "status.bookmark": "Aggiungi segnalibro", "status.cancel_reblog_private": "Annulla condivisione", "status.cannot_reblog": "Questo post non può essere condiviso", - "status.copy": "Copia link allo status", + "status.copy": "Copia link al post", "status.delete": "Elimina", "status.detailed_status": "Vista conversazione dettagliata", "status.direct": "Messaggio privato @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Incorpora", "status.favourite": "Apprezzato", "status.filtered": "Filtrato", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Mostra di più", "status.media_hidden": "Allegato nascosto", "status.mention": "Nomina @{name}", @@ -407,12 +423,12 @@ "status.mute_conversation": "Silenzia conversazione", "status.open": "Espandi questo post", "status.pin": "Fissa in cima sul profilo", - "status.pinned": "Toot fissato in cima", + "status.pinned": "Post fissato in cima", "status.read_more": "Leggi altro", "status.reblog": "Condividi", "status.reblog_private": "Condividi con i destinatari iniziali", "status.reblogged_by": "{name} ha condiviso", - "status.reblogs.empty": "Nessuno ha ancora condiviso questo toot. Quando qualcuno lo farà, comparirà qui.", + "status.reblogs.empty": "Nessuno ha ancora condiviso questo post. Quando qualcuno lo farà, comparirà qui.", "status.redraft": "Cancella e riscrivi", "status.remove_bookmark": "Elimina segnalibro", "status.reply": "Rispondi", @@ -443,7 +459,7 @@ "timeline_hint.remote_resource_not_displayed": "{resource] da altri server non sono mostrati.", "timeline_hint.resources.followers": "Follower", "timeline_hint.resources.follows": "Segue", - "timeline_hint.resources.statuses": "Toot meno recenti", + "timeline_hint.resources.statuses": "Post meno recenti", "trends.counter_by_accounts": "{count, plural, one {{counter} persona} other {{counter} persone}} ne parla·no", "trends.trending_now": "Di tendenza ora", "ui.beforeunload": "La bozza andrà persa se esci da Mastodon.", @@ -462,7 +478,7 @@ "upload_form.video_description": "Descrizione per persone con difetti uditivi o visivi", "upload_modal.analyzing_picture": "Analisi immagine…", "upload_modal.apply": "Applica", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Applicazione in corso…", "upload_modal.choose_image": "Scegli immagine", "upload_modal.description_placeholder": "Ma la volpe col suo balzo ha raggiunto il quieto Fido", "upload_modal.detect_text": "Rileva testo dall'immagine", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index baba5d66b..a54922ef6 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -47,16 +47,17 @@ "account.unmute": "@{name}さんのミュートを解除", "account.unmute_notifications": "@{name}さんからの通知を受け取るようにする", "account_note.placeholder": "クリックしてメモを追加", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "平均", + "admin.dashboard.retention.cohort": "サインアップ月", + "admin.dashboard.retention.cohort_size": "新しいユーザー", "alert.rate_limited.message": "{retry_time, time, medium} 以降に再度実行してください。", "alert.rate_limited.title": "制限に達しました", "alert.unexpected.message": "不明なエラーが発生しました。", "alert.unexpected.title": "エラー!", "announcement.announcement": "お知らせ", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(未処理)", "autosuggest_hashtag.per_week": "{count} 回 / 週", "boost_modal.combo": "次からは{combo}を押せばスキップできます", "bundle_column_error.body": "コンポーネントの読み込み中に問題が発生しました。", @@ -108,6 +109,7 @@ "compose_form.poll.switch_to_single": "単一選択に変更", "compose_form.publish": "トゥート", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "メディアを閲覧注意にする", "compose_form.sensitive.marked": "メディアに閲覧注意が設定されています", "compose_form.sensitive.unmarked": "メディアに閲覧注意が設定されていません", @@ -122,8 +124,8 @@ "confirmations.delete.message": "本当に削除しますか?", "confirmations.delete_list.confirm": "削除", "confirmations.delete_list.message": "本当にこのリストを完全に削除しますか?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "破棄", + "confirmations.discard_edit_media.message": "メディアの説明またはプレビューに保存されていない変更があります。それでも破棄しますか?", "confirmations.domain_block.confirm": "ドメイン全体をブロック", "confirmations.domain_block.message": "本当に{domain}全体を非表示にしますか? 多くの場合は個別にブロックやミュートするだけで充分であり、また好ましいです。公開タイムラインにそのドメインのコンテンツが表示されなくなり、通知も届かなくなります。そのドメインのフォロワーはアンフォローされます。", "confirmations.logout.confirm": "ログアウト", @@ -316,8 +318,8 @@ "notifications.column_settings.alert": "デスクトップ通知", "notifications.column_settings.favourite": "お気に入り:", "notifications.column_settings.filter_bar.advanced": "すべてのカテゴリを表示", - "notifications.column_settings.filter_bar.category": "クイックフィルターバー", - "notifications.column_settings.filter_bar.show": "表示", + "notifications.column_settings.filter_bar.category": "クイックフィルターバー:", + "notifications.column_settings.filter_bar.show_bar": "フィルターバーを表示", "notifications.column_settings.follow": "新しいフォロワー:", "notifications.column_settings.follow_request": "新しいフォローリクエスト:", "notifications.column_settings.mention": "返信:", @@ -327,7 +329,8 @@ "notifications.column_settings.show": "カラムに表示", "notifications.column_settings.sound": "通知音を再生", "notifications.column_settings.status": "新しい投稿:", - "notifications.column_settings.unread_markers.category": "未読マーカー", + "notifications.column_settings.unread_notifications.category": "未読の通知:", + "notifications.column_settings.unread_notifications.highlight": "未読の通知を強調表示", "notifications.filter.all": "すべて", "notifications.filter.boosts": "ブースト", "notifications.filter.favourites": "お気に入り", @@ -351,7 +354,7 @@ "poll.total_votes": "{count}票", "poll.vote": "投票", "poll.voted": "この項目に投票しました", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes}票", "poll_button.add_poll": "アンケートを追加", "poll_button.remove_poll": "アンケートを削除", "privacy.change": "公開範囲を変更", @@ -367,12 +370,20 @@ "regeneration_indicator.label": "読み込み中…", "regeneration_indicator.sublabel": "ホームタイムラインは準備中です!", "relative_time.days": "{number}日前", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}時間前", "relative_time.just_now": "今", "relative_time.minutes": "{number}分前", "relative_time.seconds": "{number}秒前", "relative_time.today": "今日", "reply_indicator.cancel": "キャンセル", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "{target} に転送する", "report.forward_hint": "このアカウントは別のサーバーに所属しています。通報内容を匿名で転送しますか?", "report.hint": "通報内容はあなたのサーバーのモデレーターへ送信されます。通報理由を入力してください。:", @@ -401,9 +412,14 @@ "status.delete": "削除", "status.detailed_status": "詳細な会話ビュー", "status.direct": "@{name}さんにダイレクトメッセージ", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "埋め込み", "status.favourite": "お気に入り", "status.filtered": "フィルターされました", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "もっと見る", "status.media_hidden": "非表示のメディア", "status.mention": "@{name}さんに投稿", @@ -467,7 +483,7 @@ "upload_form.video_description": "視聴が難しいユーザーへの説明", "upload_modal.analyzing_picture": "画像を解析中…", "upload_modal.apply": "適用", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "適用中...", "upload_modal.choose_image": "画像を選択", "upload_modal.description_placeholder": "あのイーハトーヴォのすきとおった風", "upload_modal.detect_text": "画像からテキストを検出", diff --git a/app/javascript/mastodon/locales/ka.json b/app/javascript/mastodon/locales/ka.json index 2b1221d6f..12ff62dba 100644 --- a/app/javascript/mastodon/locales/ka.json +++ b/app/javascript/mastodon/locales/ka.json @@ -47,7 +47,8 @@ "account.unmute": "ნუღარ აჩუმებ @{name}-ს", "account.unmute_notifications": "ნუღარ აჩუმებ შეტყობინებებს @{name}-სგან", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "ტუტი", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "მედია მონიშნულია მგრძნობიარედ", "compose_form.sensitive.unmarked": "მედია არაა მონიშნული მგრძნობიარედ", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "ფავორიტები:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "ახალი მიმდევრები:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "ხსენებები:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "გამოჩნდეს სვეტში", "notifications.column_settings.sound": "ხმის დაკვრა", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "იტვირთება…", "regeneration_indicator.sublabel": "თქვენი სახლის ლენტა მზადდება!", "relative_time.days": "{number}დღ", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}სთ", "relative_time.just_now": "ახლა", "relative_time.minutes": "{number}წთ", "relative_time.seconds": "{number}წმ", "relative_time.today": "today", "reply_indicator.cancel": "უარყოფა", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "ფორვარდი {target}-ს", "report.forward_hint": "ანგარიში სხვა სერვერიდანაა. გავაგზავნოთ რეპორტის ანონიმური ასლიც?", "report.hint": "რეპორტი გაეგზავნება თქვენი ინსტანციის მოდერატორებს. ქვემოთ შეგიძლიათ დაამატოთ მიზეზი თუ რატომ არეპორტებთ ამ ანგარიშს:", @@ -396,9 +407,14 @@ "status.delete": "წაშლა", "status.detailed_status": "Detailed conversation view", "status.direct": "პირდაპირი წერილი @{name}-ს", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "ჩართვა", "status.favourite": "ფავორიტი", "status.filtered": "ფილტრირებული", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "მეტის ჩატვირთვა", "status.media_hidden": "მედია დამალულია", "status.mention": "ასახელე @{name}", diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json index 632054786..f420ac45b 100644 --- a/app/javascript/mastodon/locales/kab.json +++ b/app/javascript/mastodon/locales/kab.json @@ -47,10 +47,11 @@ "account.unmute": "Kkes asgugem ɣef @{name}", "account.unmute_notifications": "Serreḥ ilɣa sɣur @{name}", "account_note.placeholder": "Ulac iwenniten", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.retention.cohort_size": "Iseqdacen imaynuten", "alert.rate_limited.message": "Ma ulac aɣilif ɛreḍ tikelt-nniḍen akka {retry_time, time, medium}.", "alert.rate_limited.title": "Aktum s talast", "alert.unexpected.message": "Yeḍra-d unezri ur netturaǧu ara.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Jewweq", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Creḍ allal n teywalt d anafri", "compose_form.sensitive.marked": "Allal n teywalt yettwacreḍ d anafri", "compose_form.sensitive.unmarked": "Allal n teywalt ur yettwacreḍ ara d anafri", @@ -118,7 +120,7 @@ "confirmations.delete.message": "Tebɣiḍ s tidet ad tekkseḍ tasuffeɣt-agi?", "confirmations.delete_list.confirm": "Kkes", "confirmations.delete_list.message": "Tebɣiḍ s tidet ad tekkseḍ umuɣ-agi i lebda?", - "confirmations.discard_edit_media.confirm": "Discard", + "confirmations.discard_edit_media.confirm": "Sefsex", "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", "confirmations.domain_block.confirm": "Ffer taɣult meṛṛa", "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Ismenyifen:", "notifications.column_settings.filter_bar.advanced": "Ssken-d meṛṛa tiggayin", "notifications.column_settings.filter_bar.category": "Iri n usizdeg uzrib", - "notifications.column_settings.filter_bar.show": "Ssken", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Imeḍfaṛen imaynuten:", "notifications.column_settings.follow_request": "Isuturen imaynuten n teḍfeṛt:", "notifications.column_settings.mention": "Abdar:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Ssken-d tilɣa deg ujgu", "notifications.column_settings.sound": "Rmed imesli", "notifications.column_settings.status": "Tiẓenẓunin timaynutin:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Akk", "notifications.filter.boosts": "Seǧhed", "notifications.filter.favourites": "Ismenyifen", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Yessalay-d…", "regeneration_indicator.sublabel": "Tasuddemt tagejdant ara d-tettwaheggay!", "relative_time.days": "{number}u", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}isr", "relative_time.just_now": "tura", "relative_time.minutes": "{number}tis", "relative_time.seconds": "{number}tas", "relative_time.today": "assa", "reply_indicator.cancel": "Sefsex", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Bren-it ɣeṛ {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Kkes", "status.detailed_status": "Detailed conversation view", "status.direct": "Izen usrid i @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Seddu", "status.favourite": "Rnu ɣer yismenyifen", "status.filtered": "Yettwasizdeg", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Sali ugar", "status.media_hidden": "Taɣwalt tettwaffer", "status.mention": "Bder-d @{name}", diff --git a/app/javascript/mastodon/locales/kk.json b/app/javascript/mastodon/locales/kk.json index 1407a0991..074ae5844 100644 --- a/app/javascript/mastodon/locales/kk.json +++ b/app/javascript/mastodon/locales/kk.json @@ -47,7 +47,8 @@ "account.unmute": "@{name} ескертпелерін қосу", "account.unmute_notifications": "@{name} ескертпелерін көрсету", "account_note.placeholder": "Жазба қалдыру үшін бас", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Тек бір жауап таңдайтындай қылу", "compose_form.publish": "Түрт", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Сезімтал ретінде белгіле", "compose_form.sensitive.marked": "Медиа нәзік деп белгіленген", "compose_form.sensitive.unmarked": "Медиа нәзік деп белгіленбеген", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Таңдаулылар:", "notifications.column_settings.filter_bar.advanced": "Барлық категорияны көрсет", "notifications.column_settings.filter_bar.category": "Жедел сүзгі", - "notifications.column_settings.filter_bar.show": "Көрсету", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Жаңа оқырмандар:", "notifications.column_settings.follow_request": "Жазылуға жаңа сұранымдар:", "notifications.column_settings.mention": "Аталымдар:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Бағанда көрсет", "notifications.column_settings.sound": "Дыбысын қос", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Барлығы", "notifications.filter.boosts": "Бөлісулер", "notifications.filter.favourites": "Таңдаулылар", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Жүктеу…", "regeneration_indicator.sublabel": "Жергілікті желі құрылуда!", "relative_time.days": "{number}күн", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}сағ", "relative_time.just_now": "жаңа", "relative_time.minutes": "{number}мин", "relative_time.seconds": "{number}с", "relative_time.today": "бүгін", "reply_indicator.cancel": "Қайтып алу", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Жіберу {target}", "report.forward_hint": "Бұл аккаунт басқа серверден. Аноним шағым жібересіз бе?", "report.hint": "Шағым сіздің модераторларға жіберіледі. Шағымның себептерін мына жерге жазуыңызға болады:", @@ -396,9 +407,14 @@ "status.delete": "Өшіру", "status.detailed_status": "Толық пікірталас көрінісі", "status.direct": "Хат жіберу @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embеd", "status.favourite": "Таңдаулы", "status.filtered": "Фильтрленген", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Тағы әкел", "status.media_hidden": "Жабық медиа", "status.mention": "Аталым @{name}", diff --git a/app/javascript/mastodon/locales/kmr.json b/app/javascript/mastodon/locales/kmr.json index 8f862606d..f45e305cd 100644 --- a/app/javascript/mastodon/locales/kmr.json +++ b/app/javascript/mastodon/locales/kmr.json @@ -21,7 +21,7 @@ "account.following_counter": "{count, plural, one {{counter} Dişopîne} other {{counter} Dişopîne}}", "account.follows.empty": "Ev bikarhêner hin kesekî heya niha neşopandiye.", "account.follows_you": "Te dişopîne", - "account.hide_reblogs": "Boost ên ji @{name} veşêre", + "account.hide_reblogs": "Bilindkirinên ji @{name} veşêre", "account.joined": "Tevlîbû di {date} de", "account.last_status": "Çalakiya dawî", "account.link_verified_on": "Xwedaniya li vê girêdanê di {date} de hatiye kontrolkirin", @@ -34,11 +34,11 @@ "account.muted": "Bêdengkirî", "account.never_active": "Tu car", "account.posts": "Şandî", - "account.posts_with_replies": "Toot û bersiv", + "account.posts_with_replies": "Şandî û bersiv", "account.report": "@{name} Ragihîne", "account.requested": "Li benda erêkirinê ye. Ji bo betal kirina daxwazê pêl bikin", "account.share": "Profîla @{name} parve bike", - "account.show_reblogs": "Boostên @{name} nîşan bike", + "account.show_reblogs": "Bilindkirinên ji @{name} nîşan bike", "account.statuses_counter": "{count, plural,one {{counter} şandî}other {{counter} şandî}}", "account.unblock": "Astengê li ser @{name} rake", "account.unblock_domain": "Astengê li ser navperê {domain} rake", @@ -47,16 +47,17 @@ "account.unmute": "@{name} Bêdeng bike", "account.unmute_notifications": "Agahdariyan ji @{name} bêdeng bike", "account_note.placeholder": "Bitikîne bo nîşeyekê tevlî bikî", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Navîn", + "admin.dashboard.retention.cohort": "Meha tomarkirinê", + "admin.dashboard.retention.cohort_size": "Bikarhênerên nû", "alert.rate_limited.message": "Jkx dîsa biceribîne piştî {retry_time, time, medium}.\n \n", "alert.rate_limited.title": "Rêje sînorkirî ye", "alert.unexpected.message": "Çewtiyeke bêhêvî çê bû.", "alert.unexpected.title": "Wey li min!", "announcement.announcement": "Daxuyanî", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(bêpêvajo)", "autosuggest_hashtag.per_week": "Her hefte {count}", "boost_modal.combo": "Ji bo derbas bî carekî din de pêlê {combo} bike", "bundle_column_error.body": "Di dema barkirina vê hêmanê de tiştek çewt çê bû.", @@ -77,7 +78,7 @@ "column.lists": "Rêzok", "column.mutes": "Bikarhênerên bêdengkirî", "column.notifications": "Agahdarî", - "column.pins": "Toot a derzîkirî", + "column.pins": "Şandiya derzîkirî", "column.public": "Demnameyê federalîkirî", "column_back_button.label": "Veger", "column_header.hide_settings": "Sazkariyan veşêre", @@ -90,7 +91,7 @@ "community.column_settings.local_only": "Tenê herêmî", "community.column_settings.media_only": "Tenê media", "community.column_settings.remote_only": "Tenê ji dûr ve", - "compose_form.direct_message_warning": "Ev toot tenê ji bikarhênerên behskirî re were şandin.", + "compose_form.direct_message_warning": "Ev şandî tenê ji bikarhênerên qalkirî re wê were şandin.", "compose_form.direct_message_warning_learn_more": "Bêtir fêr bibe", "compose_form.hashtag_warning": "Ev şandî ji ber ku nehatiye tomarkirin dê di binê hashtagê de neyê tomar kirin. Tenê peyamên gelemperî dikarin bi hashtagê werin lêgerîn.", "compose_form.lock_disclaimer": "Ajimêrê te {locked} nîne. Herkes dikare te bişopîne da ku şandiyên te yên tenê şopînerên te ra xûya dibin bibînin.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Rapirsîyê biguherîne da ku mafê bidî tenê vebijêrkek", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Medya wekî hestiyar nîşan bide} other {Medya wekî hestiyar nîşan bide}}", "compose_form.sensitive.marked": "{count, plural, one {Medya wekî hestiyar hate nîşan} other {Medya wekî hestiyar nîşan}}", "compose_form.sensitive.unmarked": "{count, plural, one {Medya wekî hestiyar nehatiye nîşan} other {Medya wekî hestiyar nehatiye nîşan}}", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Ma tu dixwazî vê şandiyê jê bibî?", "confirmations.delete_list.confirm": "Jê bibe", "confirmations.delete_list.message": "Ma tu dixwazî bi awayekî herdemî vê rêzokê jê bibî?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Biavêje", + "confirmations.discard_edit_media.message": "Guhertinên neqedandî di danasîna an pêşdîtina medyayê de hene, wan bi her awayî bavêje?", "confirmations.domain_block.confirm": "Hemî navperê asteng bike", "confirmations.domain_block.message": "Tu ji xwe bawerî, bi rastî tu dixwazî hemû {domain} asteng bikî? Di gelek rewşan de asteng kirin an jî bêdeng kirin têrê dike û tê tercîh kirin. Tu nikarî naveroka vê navperê di demnameyê an jî agahdariyên xwe de bibînî. Şopînerên te yê di vê navperê were jêbirin.", "confirmations.logout.confirm": "Derkeve", @@ -128,7 +130,7 @@ "confirmations.mute.explanation": "Ev ê şandinên ji wan tê û şandinên ku behsa wan dike veşêre, lê hê jî maf dide ku ew şandinên te bibînin û te bişopînin.", "confirmations.mute.message": "Bi rastî tu dixwazî {name} bêdeng bikî?", "confirmations.redraft.confirm": "Jê bibe & ji nû ve serrast bike", - "confirmations.redraft.message": "Bi rastî tu dixwazî şandî ye jê bibî û nûve reşnivîsek çê bikî? Bijare û şandîyên wenda bibin û bersivên ji bo şandiye orîjînal sêwî bimînin.", + "confirmations.redraft.message": "Bi rastî tu dixwazî şandî ye jê bibî û nûve reşnivîsek çê bikî? Bijare û şandî wê wenda bibin û bersivên ji bo şandiyê resen wê sêwî bimînin.", "confirmations.reply.confirm": "Bersivê bide", "confirmations.reply.message": "Bersiva niha li ser peyama ku tu niha berhev dikî dê binivsîne. Ma pê bawer î ku tu dixwazî bidomînî?", "confirmations.unfollow.confirm": "Neşopîne", @@ -187,7 +189,7 @@ "follow_recommendations.heading": "Mirovên ku tu dixwazî ji wan peyaman bibînî bişopîne! Hin pêşnîyar li vir in.", "follow_recommendations.lead": "Li gorî rêza kronolojîkî peyamên mirovên ku tu dişopînî dê demnameya te de xûya bike. Ji xeletiyan netirse, bi awayekî hêsan her wextî tu dikarî dev ji şopandinê berdî!", "follow_request.authorize": "Mafê bide", - "follow_request.reject": "Nepejir", + "follow_request.reject": "Nepejirîne", "follow_requests.unlocked_explanation": "Tevlî ku ajimêra te ne kilît kiriye, karmendên {domain} digotin qey tu dixwazî ku pêşdîtina daxwazên şopandinê bi destan bike.", "generic.saved": "Tomarkirî", "getting_started.developers": "Pêşdebir", @@ -208,7 +210,7 @@ "hashtag.column_settings.tag_mode.none": "Ne yek ji van", "hashtag.column_settings.tag_toggle": "Ji bo vê stûnê hin pêvekan tevlî bike", "home.column_settings.basic": "Bingehîn", - "home.column_settings.show_reblogs": "Boost'an nîşan bike", + "home.column_settings.show_reblogs": "Bilindkirinan nîşan bike", "home.column_settings.show_replies": "Bersivan nîşan bide", "home.hide_announcements": "Reklaman veşêre", "home.show_announcements": "Reklaman nîşan bide", @@ -217,7 +219,7 @@ "intervals.full.minutes": "{number, plural, one {# xulek} other {# xulek}}", "keyboard_shortcuts.back": "Vegere paşê", "keyboard_shortcuts.blocked": "Rêzoka bikarhênerên astengkirî veke", - "keyboard_shortcuts.boost": "Şandiya parve (boost) bike", + "keyboard_shortcuts.boost": "Şandiyê bilind bike", "keyboard_shortcuts.column": "Stûna balkişandinê", "keyboard_shortcuts.compose": "Bal bikşîne cîhê nivîsê/textarea", "keyboard_shortcuts.description": "Danasîn", @@ -294,8 +296,8 @@ "navigation_bar.logout": "Derkeve", "navigation_bar.mutes": "Bikarhênerên bêdengkirî", "navigation_bar.personal": "Kesanî", - "navigation_bar.pins": "Toot a derzîkirî", - "navigation_bar.preferences": "Hilbijarte", + "navigation_bar.pins": "Şandiya derzîkirî", + "navigation_bar.preferences": "Sazkarî", "navigation_bar.public_timeline": "Demnameyê federalîkirî", "navigation_bar.security": "Ewlehî", "notification.favourite": "{name} şandiya te hez kir", @@ -304,7 +306,7 @@ "notification.mention": "{name} qale te kir", "notification.own_poll": "Rapirsîya te qediya", "notification.poll": "Rapirsiyeke ku te deng daye qediya", - "notification.reblog": "{name} şandiya te belav kir/ boost kir", + "notification.reblog": "{name} şandiya te bilind kir", "notification.status": "{name} niha şand", "notifications.clear": "Agahdariyan pak bike", "notifications.clear_confirmation": "Bi rastî tu dixwazî bi awayekî dawî hemû agahdariyên xwe pak bikî?", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Bijarte:", "notifications.column_settings.filter_bar.advanced": "Hemû beşan nîşan bide", "notifications.column_settings.filter_bar.category": "Şivika parzûna bilêz", - "notifications.column_settings.filter_bar.show": "Nîşan bike", + "notifications.column_settings.filter_bar.show_bar": "Darika parzûnê nîşan bide", "notifications.column_settings.follow": "Şopînerên nû:", "notifications.column_settings.follow_request": "Daxwazên şopandinê nû:", "notifications.column_settings.mention": "Qalkirin:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Di nav stûnê de nîşan bike", "notifications.column_settings.sound": "Deng lêxe", "notifications.column_settings.status": "Şandiyên nû:", - "notifications.column_settings.unread_markers.category": "Nîşankerê agahdariyên nexwendî", + "notifications.column_settings.unread_notifications.category": "Agahdariyên nexwendî", + "notifications.column_settings.unread_notifications.highlight": "Agahiyên nexwendî nîşan bike", "notifications.filter.all": "Hemû", "notifications.filter.boosts": "Bilindkirî", "notifications.filter.favourites": "Bijarte", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# deng} other {# deng}}", "poll.vote": "Deng bide", "poll.voted": "Te dengê xwe da vê bersivê", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# deng} other {# deng}}", "poll_button.add_poll": "Rapirsîyek zêde bike", "poll_button.remove_poll": "Rapirsî yê rake", "privacy.change": "Nepênîtiya şandiyan biguherîne", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Tê barkirin…", "regeneration_indicator.sublabel": "Mala te da tê amedekirin!", "relative_time.days": "{number}r", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}d", "relative_time.just_now": "niha", "relative_time.minutes": "{number}x", "relative_time.seconds": "{number}ç", "relative_time.today": "îro", "reply_indicator.cancel": "Dev jê berde", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Biçe bo {target}", "report.forward_hint": "Ajimêr ji rajekarek din da ne. Tu kopîyeka anonîm ya raporê bişînî li wur?", "report.hint": "Ev rapor yê rajekarê lihevkarên te ra were şandin. Tu dikarî şiroveyekê pêşkêş bikî bê ka tu çima vê ajimêrê jor radigîhînî:", @@ -396,9 +407,14 @@ "status.delete": "Jê bibe", "status.detailed_status": "Dîtina axaftina berfireh", "status.direct": "Peyama rasterast @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Hedimandî", "status.favourite": "Bijarte", "status.filtered": "Parzûnkirî", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Bêtir bar bike", "status.media_hidden": "Medya veşartî ye", "status.mention": "Qal @{name} bike", @@ -409,7 +425,7 @@ "status.pin": "Li ser profîlê derzî bike", "status.pinned": "Şandiya derzîkirî", "status.read_more": "Bêtir bixwîne", - "status.reblog": "Bilindkirî", + "status.reblog": "Bilind bike", "status.reblog_private": "Bi dîtina resen bilind bike", "status.reblogged_by": "{name} bilind kir", "status.reblogs.empty": "Kesekî hin ev şandî bilind nekiriye. Gava kesek bilind bike, ew ên li vir werin xuyakirin.", @@ -462,7 +478,7 @@ "upload_form.video_description": "Ji bo kesên kerr û lalan pênase bike", "upload_modal.analyzing_picture": "Wêne tê analîzkirin…", "upload_modal.apply": "Bisepîne", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Tê sepandin…", "upload_modal.choose_image": "Wêneyê hilbijêre", "upload_modal.description_placeholder": "Rovîyek qehweyî û bilez li ser kûçikê tîral banz dide", "upload_modal.detect_text": "Ji nivîsa wêneyê re serwext be", diff --git a/app/javascript/mastodon/locales/kn.json b/app/javascript/mastodon/locales/kn.json index 72b8f7f0a..cc6c34e4a 100644 --- a/app/javascript/mastodon/locales/kn.json +++ b/app/javascript/mastodon/locales/kn.json @@ -47,7 +47,8 @@ "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Show in column", "notifications.column_settings.sound": "Play sound", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "Cancel", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Load more", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index 4252141e7..613ef7600 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -47,16 +47,17 @@ "account.unmute": "@{name} 뮤트 해제", "account.unmute_notifications": "@{name}의 알림 뮤트 해제", "account_note.placeholder": "클릭해서 노트 추가", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "평균", + "admin.dashboard.retention.cohort": "가입한 달", + "admin.dashboard.retention.cohort_size": "새로운 사용자", "alert.rate_limited.message": "{retry_time, time, medium}에 다시 시도해 주세요.", "alert.rate_limited.title": "빈도 제한됨", "alert.unexpected.message": "예측하지 못한 에러가 발생했습니다.", "alert.unexpected.title": "앗!", "announcement.announcement": "공지사항", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(처리 안 됨)", "autosuggest_hashtag.per_week": "주간 {count}회", "boost_modal.combo": "다음엔 {combo}를 눌러서 이 과정을 건너뛸 수 있습니다", "bundle_column_error.body": "컴포넌트를 불러오는 과정에서 문제가 발생했습니다.", @@ -65,17 +66,17 @@ "bundle_modal_error.close": "닫기", "bundle_modal_error.message": "컴포넌트를 불러오는 과정에서 문제가 발생했습니다.", "bundle_modal_error.retry": "다시 시도", - "column.blocks": "차단된 사용자", + "column.blocks": "차단한 사용자", "column.bookmarks": "보관함", "column.community": "로컬 타임라인", "column.direct": "다이렉트 메시지", "column.directory": "프로필 둘러보기", - "column.domain_blocks": "차단된 도메인", + "column.domain_blocks": "차단한 도메인", "column.favourites": "즐겨찾기", "column.follow_requests": "팔로우 요청", "column.home": "홈", "column.lists": "리스트", - "column.mutes": "뮤트된 사용자", + "column.mutes": "뮤트한 사용자", "column.notifications": "알림", "column.pins": "고정된 게시물", "column.public": "연합 타임라인", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "단일 선택 투표로 변경", "compose_form.publish": "뿌우", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "미디어를 민감함으로 설정하기", "compose_form.sensitive.marked": "미디어가 열람주의로 설정되어 있습니다", "compose_form.sensitive.unmarked": "미디어가 열람주의로 설정 되어 있지 않습니다", @@ -118,8 +120,8 @@ "confirmations.delete.message": "정말로 이 게시물을 삭제하시겠습니까?", "confirmations.delete_list.confirm": "삭제", "confirmations.delete_list.message": "정말로 이 리스트를 영구적으로 삭제하시겠습니까?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "취소", + "confirmations.discard_edit_media.message": "미디어 설명이나 미리보기에 대한 저장하지 않은 변경사항이 있습니다. 버리시겠습니까?", "confirmations.domain_block.confirm": "도메인 전체를 차단", "confirmations.domain_block.message": "정말로 {domain} 전체를 차단하시겠습니까? 대부분의 경우 개별 차단이나 뮤트로 충분합니다. 모든 공개 타임라인과 알림에서 해당 도메인에서 작성된 컨텐츠를 보지 못합니다. 해당 도메인에 속한 팔로워와의 관계가 사라집니다.", "confirmations.logout.confirm": "로그아웃", @@ -164,7 +166,7 @@ "empty_column.bookmarked_statuses": "아직 보관한 게시물이 없습니다. 게시물을 보관하면 여기에 나타납니다.", "empty_column.community": "로컬 타임라인에 아무 것도 없습니다. 아무거나 적어 보세요!", "empty_column.direct": "아직 다이렉트 메시지가 없습니다. 다이렉트 메시지를 보내거나 받은 경우, 여기에 표시 됩니다.", - "empty_column.domain_blocks": "아직 차단된 도메인이 없습니다.", + "empty_column.domain_blocks": "아직 차단한 도메인이 없습니다.", "empty_column.favourited_statuses": "아직 즐겨찾기 한 게시물이 없습니다. 게시물을 즐겨찾기 하면 여기에 나타납니다.", "empty_column.favourites": "아직 아무도 이 게시물을 즐겨찾기 하지 않았습니다. 누군가 즐겨찾기를 하면 여기에 나타납니다.", "empty_column.follow_recommendations": "당신을 위한 제안이 생성될 수 없는 것 같습니다. 알 수도 있는 사람을 검색하거나 유행하는 해시태그를 둘러볼 수 있습니다.", @@ -282,17 +284,17 @@ "navigation_bar.compose": "새 게시물 작성", "navigation_bar.direct": "다이렉트 메시지", "navigation_bar.discover": "발견하기", - "navigation_bar.domain_blocks": "차단된 도메인", + "navigation_bar.domain_blocks": "차단한 도메인", "navigation_bar.edit_profile": "프로필 편집", "navigation_bar.favourites": "즐겨찾기", - "navigation_bar.filters": "뮤트된 단어", + "navigation_bar.filters": "뮤트한 단어", "navigation_bar.follow_requests": "팔로우 요청", "navigation_bar.follows_and_followers": "팔로우와 팔로워", "navigation_bar.info": "이 서버에 대해서", "navigation_bar.keyboard_shortcuts": "단축키", "navigation_bar.lists": "리스트", "navigation_bar.logout": "로그아웃", - "navigation_bar.mutes": "뮤트 중인 사용자", + "navigation_bar.mutes": "뮤트한 사용자", "navigation_bar.personal": "개인용", "navigation_bar.pins": "고정된 게시물", "navigation_bar.preferences": "사용자 설정", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "즐겨찾기:", "notifications.column_settings.filter_bar.advanced": "카테고리의 모든 종류를 표시", "notifications.column_settings.filter_bar.category": "퀵 필터 바", - "notifications.column_settings.filter_bar.show": "표시", + "notifications.column_settings.filter_bar.show_bar": "필터 막대 표시", "notifications.column_settings.follow": "새 팔로워:", "notifications.column_settings.follow_request": "새 팔로우 요청:", "notifications.column_settings.mention": "답글:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "컬럼에 표시", "notifications.column_settings.sound": "효과음 재생", "notifications.column_settings.status": "새 게시물:", - "notifications.column_settings.unread_markers.category": "읽지 않음 알림 마커", + "notifications.column_settings.unread_notifications.category": "읽지 않은 알림", + "notifications.column_settings.unread_notifications.highlight": "읽지 않은 알림 강조", "notifications.filter.all": "모두", "notifications.filter.boosts": "부스트", "notifications.filter.favourites": "즐겨찾기", @@ -346,7 +349,7 @@ "poll.total_votes": "{count} 표", "poll.vote": "투표", "poll.voted": "이 답변에 투표했습니다", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes} 표", "poll_button.add_poll": "투표 추가", "poll_button.remove_poll": "투표 삭제", "privacy.change": "포스트의 프라이버시 설정을 변경", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "불러오는 중…", "regeneration_indicator.sublabel": "당신의 홈 피드가 준비되는 중입니다!", "relative_time.days": "{number}일 전", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}시간 전", "relative_time.just_now": "방금", "relative_time.minutes": "{number}분 전", "relative_time.seconds": "{number}초 전", "relative_time.today": "오늘", "reply_indicator.cancel": "취소", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "{target}에 포워드 됨", "report.forward_hint": "이 계정은 다른 서버에 있습니다. 익명화 된 사본을 해당 서버에도 전송할까요?", "report.hint": "신고는 당신의 서버 스태프에게 전송 됩니다. 왜 이 계정을 신고하는 지에 대한 설명을 아래에 작성할 수 있습니다:", @@ -396,12 +407,17 @@ "status.delete": "삭제", "status.detailed_status": "대화 자세히 보기", "status.direct": "@{name}에게 다이렉트 메시지", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "공유하기", "status.favourite": "즐겨찾기", "status.filtered": "필터로 걸러짐", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "더 보기", "status.media_hidden": "미디어 숨겨짐", - "status.mention": "답장", + "status.mention": "@{name}에게 글쓰기", "status.more": "자세히", "status.mute": "@{name} 뮤트", "status.mute_conversation": "이 대화를 뮤트", @@ -416,7 +432,7 @@ "status.redraft": "지우고 다시 쓰기", "status.remove_bookmark": "보관한 게시물 삭제", "status.reply": "답장", - "status.replyAll": "전원에게 답장", + "status.replyAll": "글타래에 답장", "status.report": "신고", "status.sensitive_warning": "민감한 미디어", "status.share": "공유", @@ -462,7 +478,7 @@ "upload_form.video_description": "청각, 시각 장애인을 위한 설명", "upload_modal.analyzing_picture": "이미지 분석 중…", "upload_modal.apply": "적용", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "적용 중...", "upload_modal.choose_image": "이미지 선택", "upload_modal.description_placeholder": "다람쥐 헌 쳇바퀴 타고파", "upload_modal.detect_text": "이미지에서 텍스트 추출", diff --git a/app/javascript/mastodon/locales/ku.json b/app/javascript/mastodon/locales/ku.json index 2f0c4e511..36b2ffef1 100644 --- a/app/javascript/mastodon/locales/ku.json +++ b/app/javascript/mastodon/locales/ku.json @@ -47,7 +47,8 @@ "account.unmute": "بێدەنگکردنی @{name}", "account.unmute_notifications": "بێدەنگکردنی هۆشیارییەکان لە @{name}", "account_note.placeholder": "کرتەبکە بۆ زیادکردنی تێبینی", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "گۆڕینی ڕاپرسی بۆ ڕێگەدان بە تاکە هەڵبژاردنێک", "compose_form.publish": "توت", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "نیشانکردنی میدیا وەک هەستیار", "compose_form.sensitive.marked": "وادەی کۆتایی", "compose_form.sensitive.unmarked": "میدیا وەک هەستیار نیشان نەکراوە", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "دڵخوازترین:", "notifications.column_settings.filter_bar.advanced": "هەموو پۆلەکان پیشان بدە", "notifications.column_settings.filter_bar.category": "شریتی پاڵێوەری خێرا", - "notifications.column_settings.filter_bar.show": "نیشاندان", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "شوێنکەوتوانی نوێ:", "notifications.column_settings.follow_request": "شوینکەوتنی داواکاری نوێ:", "notifications.column_settings.mention": "ئاماژەکان:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "لە ستووندا پیشان بدە", "notifications.column_settings.sound": "لێدانی دەنگ", "notifications.column_settings.status": "توتەکانی نوێ:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "هەموو", "notifications.filter.boosts": "دووبارەتوتەکان", "notifications.filter.favourites": "دڵخوازەکان", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "بارکردن…", "regeneration_indicator.sublabel": "ڕاگەیەنەری ماڵەوەت ئامادە دەکرێت!", "relative_time.days": "{number}ڕۆژ", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}کات", "relative_time.just_now": "ئێستا", "relative_time.minutes": "{number}کات", "relative_time.seconds": "{number}کات", "relative_time.today": "ئیمڕۆ", "reply_indicator.cancel": "هەڵوەشاندنەوه", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "ناردن بۆ {target}", "report.forward_hint": "هەژمارەکە لە ڕاژەیەکی ترە. ڕونووسێکی نەناسراو بنێرە بۆ گوزارشت لەوێ?", "report.hint": "گوزارشتەکە دەنێردرێت بۆ بەرپرسانی ڕاژەکەت. دەتوانیت ڕوونکردنەوەیەک پێشکەش بکەیت کە بۆچی ئەم هەژمارە لە خوارەوە گوزارش دەکەیت:", @@ -396,9 +407,14 @@ "status.delete": "سڕینەوە", "status.detailed_status": "ڕوانگەی گفتوگۆ بە وردەکاری", "status.direct": "پەیامی ڕاستەوخۆ @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "نیشتەجێ بکە", "status.favourite": "دڵخواز", "status.filtered": "پاڵاوتن", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "بارکردنی زیاتر", "status.media_hidden": "میدیای شاراوە", "status.mention": "ناوبنێ @{name}", diff --git a/app/javascript/mastodon/locales/kw.json b/app/javascript/mastodon/locales/kw.json index 14dcd9618..c8638e56a 100644 --- a/app/javascript/mastodon/locales/kw.json +++ b/app/javascript/mastodon/locales/kw.json @@ -47,7 +47,8 @@ "account.unmute": "Antawhe @{name}", "account.unmute_notifications": "Antawhe gwarnyansow a @{name}", "account_note.placeholder": "Klyckya dhe geworra noten", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Chanjya sondyans dhe asa unn dewis hepken", "compose_form.publish": "Tout", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Merkya myski vel tender} other {Merkya myski vel tender}}", "compose_form.sensitive.marked": "{count, plural, one {Myski merkys vel tender} other {Myski merkys vel tender}}", "compose_form.sensitive.unmarked": "{count, plural, one {Nyns yw myski merkys vel tender} other {Nyns yw myski merkys vel tender}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Re drudh:", "notifications.column_settings.filter_bar.advanced": "Displetya rummow oll", "notifications.column_settings.filter_bar.category": "Barr sidhla skav", - "notifications.column_settings.filter_bar.show": "Diskwedhes", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Holyoryon nowydh:", "notifications.column_settings.follow_request": "Govynnow holya nowydh:", "notifications.column_settings.mention": "Menegow:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Diskwedhes yn koloven", "notifications.column_settings.sound": "Seni son", "notifications.column_settings.status": "Postow nowydh:", - "notifications.column_settings.unread_markers.category": "Merkys gwarnyansow anredys", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Oll", "notifications.filter.boosts": "Kenerthow", "notifications.filter.favourites": "Re drudh", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Ow karga…", "regeneration_indicator.sublabel": "Yma agas lin dre ow pos pareusys!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}o", "relative_time.just_now": "lemmyn", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}e", "relative_time.today": "hedhyw", "reply_indicator.cancel": "Hedhi", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Dasvovya dhe {target}", "report.forward_hint": "Yma'n akont ma a leuren aral. Dannvon dasskrif dihanow an derivas ena ynwedh?", "report.hint": "An derivas a vydh danvenys dhe goswydhyon agas leuren. Hwi a yll profya displegyans a prag ytho owgh hwi ow reportya'n akont ma a-wòles:", @@ -396,9 +407,14 @@ "status.delete": "Dilea", "status.detailed_status": "Gwel kesklapp a-vanyl", "status.direct": "Messach didro dhe @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Staga", "status.favourite": "Merkya vel drudh", "status.filtered": "Sidhlys", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Karga moy", "status.media_hidden": "Myski kudhys", "status.mention": "Meneges @{name}", diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json index 0c1a46de3..1ed083f0c 100644 --- a/app/javascript/mastodon/locales/lt.json +++ b/app/javascript/mastodon/locales/lt.json @@ -47,7 +47,8 @@ "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Show in column", "notifications.column_settings.sound": "Play sound", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "Cancel", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Load more", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json index 4d65daa83..f8f61532a 100644 --- a/app/javascript/mastodon/locales/lv.json +++ b/app/javascript/mastodon/locales/lv.json @@ -47,16 +47,17 @@ "account.unmute": "Noņemt apklusinājumu @{name}", "account.unmute_notifications": "Rādīt paziņojumus no lietotāja @{name}", "account_note.placeholder": "Noklikšķiniet, lai pievienotu piezīmi", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Vidēji", + "admin.dashboard.retention.cohort": "Reģistrēšanās mēnesis", + "admin.dashboard.retention.cohort_size": "Jauni lietotāji", "alert.rate_limited.message": "Lūdzu, mēģini vēlreiz pāc {retry_time, time, medium}.", "alert.rate_limited.title": "Biežums ierobežots", - "alert.unexpected.message": "Negaidīta kļūda.", + "alert.unexpected.message": "Radās negaidīta kļūda.", "alert.unexpected.title": "Ups!", "announcement.announcement": "Paziņojums", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(neapstrādāti)", "autosuggest_hashtag.per_week": "{count} nedēļā", "boost_modal.combo": "Nospied {combo} lai izlaistu šo nākamreiz", "bundle_column_error.body": "Kaut kas nogāja greizi ielādējot šo komponenti.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Maini aptaujas veidu, lai atļautu vienu izvēli", "compose_form.publish": "Taurēt", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Atzīmēt mediju kā sensitīvu} other {Atzīmēt medijus kā sensitīvus}}", "compose_form.sensitive.marked": "{count, plural, one {Medijs ir atzīmēts kā sensitīvs} other {Mediji ir atzīmēti kā sensitīvi}}", "compose_form.sensitive.unmarked": "{count, plural, one {Medijs nav atzīmēts kā sensitīvs} other {Mediji nav atzīmēti kā sensitīvi}}", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Vai tiešām vēlaties dzēst šo ziņu?", "confirmations.delete_list.confirm": "Dzēst", "confirmations.delete_list.message": "Vai tiešam vēlies neatgriezeniski dzēst šo sarakstu?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Izmest", + "confirmations.discard_edit_media.message": "Vai tev ir nesaglabātas izmaiņas mediju aprakstā vai priekšskatījumā, vai tomēr atmest tās?", "confirmations.domain_block.confirm": "Bloķēt visu domēnu", "confirmations.domain_block.message": "Vai tu tiešām, tiešam vēlies bloķēt visu domēnu {domain}? Lielākajā daļā gadījumu pietiek ja nobloķē vai apklusini kādu. Tu neredzēsi saturu vai paziņojumus no šī domēna nevienā laika līnijā. Tavi sekotāji no šī domēna tiks noņemti.", "confirmations.logout.confirm": "Iziet", @@ -202,7 +204,7 @@ "hashtag.column_header.tag_mode.any": "vai {additional}", "hashtag.column_header.tag_mode.none": "bez {additional}", "hashtag.column_settings.select.no_options_message": "Ieteikumi netika atrasti", - "hashtag.column_settings.select.placeholder": "Ievadīt mirkļbirkas…", + "hashtag.column_settings.select.placeholder": "Ievadīt tēmturus…", "hashtag.column_settings.tag_mode.all": "Visi no šiem", "hashtag.column_settings.tag_mode.any": "Kāds no šiem", "hashtag.column_settings.tag_mode.none": "Neviens no šiem", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Izlases:", "notifications.column_settings.filter_bar.advanced": "Rādīt visas kategorijas", "notifications.column_settings.filter_bar.category": "Ātro filtru josla", - "notifications.column_settings.filter_bar.show": "Parādīt", + "notifications.column_settings.filter_bar.show_bar": "Rādīt filtru joslu", "notifications.column_settings.follow": "Jauni sekotāji:", "notifications.column_settings.follow_request": "Jauni sekotāju pieprasījumi:", "notifications.column_settings.mention": "Pieminējumi:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Rādīt kolonnā", "notifications.column_settings.sound": "Atskaņot skaņu", "notifications.column_settings.status": "Jaunas ziņas:", - "notifications.column_settings.unread_markers.category": "Nelasīto paziņojumu marķieri", + "notifications.column_settings.unread_notifications.category": "Nelasītie paziņojumi", + "notifications.column_settings.unread_notifications.highlight": "Iezīmēt nelasītos paziņojumus", "notifications.filter.all": "Visi", "notifications.filter.boosts": "Palielinājumi", "notifications.filter.favourites": "Izlases", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# balsojums} other {# balsojumi}}", "poll.vote": "Balsot", "poll.voted": "Tu balsoji par šo atbildi", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# balss} other {# balsis}}", "poll_button.add_poll": "Pievienot aptauju", "poll_button.remove_poll": "Noņemt aptauju", "privacy.change": "Mainīt ziņas privātumu", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Ielādē…", "regeneration_indicator.sublabel": "Tiek gatavota tava plūsma!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}st", "relative_time.just_now": "tagad", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "šodien", "reply_indicator.cancel": "Atcelt", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Pārsūtīt {target}", "report.forward_hint": "Konts ir no cita servera. Vai nosūtīt anonimizētu ziņojuma kopiju arī tam?", "report.hint": "Pārskats tiks nosūtīts tava servera moderatoriem. Tu vari pievienot paskaidrojumu, kādēļ tu ziņo par kontu:", @@ -382,7 +393,7 @@ "search_popout.tips.text": "Vienkāršs teksts atgriež atbilstošus parādāmos vārdus, lietotājvārdus un mirkļbirkas", "search_popout.tips.user": "lietotājs", "search_results.accounts": "Cilvēki", - "search_results.hashtags": "Mirkļbirkas", + "search_results.hashtags": "Tēmturi", "search_results.statuses": "Ziņas", "search_results.statuses_fts_disabled": "Šajā Mastodon serverī nav iespējota ziņu meklēšana pēc to satura.", "search_results.total": "{count, number} {count, plural, one {rezultāts} other {rezultāti}}", @@ -396,9 +407,14 @@ "status.delete": "Dzēst", "status.detailed_status": "Detalizēts sarunas skats", "status.direct": "Privāta ziņa @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Iestrādāt", "status.favourite": "Iecienītā", "status.filtered": "Filtrēts", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Ielādēt vairāk", "status.media_hidden": "Medijs ir paslēpts", "status.mention": "Pieminēt @{name}", @@ -417,7 +433,7 @@ "status.remove_bookmark": "Noņemt grāmatzīmi", "status.reply": "Atbildēt", "status.replyAll": "Atbildēt uz tematu", - "status.report": "Atskaite @{name}", + "status.report": "Ziņot par @{name}", "status.sensitive_warning": "Sensitīvs saturs", "status.share": "Kopīgot", "status.show_less": "Rādīt mazāk", @@ -430,7 +446,7 @@ "status.unpin": "Noņemt no profila", "suggestions.dismiss": "Noraidīt ieteikumu", "suggestions.header": "Jūs varētu interesēt arī…", - "tabs_bar.federated_timeline": "Apvienotā", + "tabs_bar.federated_timeline": "Federētā", "tabs_bar.home": "Sākums", "tabs_bar.local_timeline": "Vietējā", "tabs_bar.notifications": "Paziņojumi", @@ -462,7 +478,7 @@ "upload_form.video_description": "Aprakstiet cilvēkiem ar dzirdes vai redzes traucējumiem", "upload_modal.analyzing_picture": "Analizē attēlu…", "upload_modal.apply": "Apstiprināt", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Pielieto…", "upload_modal.choose_image": "Izvēlēties attēlu", "upload_modal.description_placeholder": "Raibais runcis rīgā ratu rumbā rūc", "upload_modal.detect_text": "Noteikt tekstu no attēla", diff --git a/app/javascript/mastodon/locales/mk.json b/app/javascript/mastodon/locales/mk.json index 36ea33bb8..ae925b391 100644 --- a/app/javascript/mastodon/locales/mk.json +++ b/app/javascript/mastodon/locales/mk.json @@ -47,7 +47,8 @@ "account.unmute": "Зачути го @{name}", "account.unmute_notifications": "Исклучи известувања од @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Тутови", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Обележи медиа како сензитивна", "compose_form.sensitive.marked": "Медиата е обележана како сензитивна", "compose_form.sensitive.unmarked": "Медиата не е обележана како сензитивна", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Прикажи во колона", "notifications.column_settings.sound": "Свири звуци", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Сите", "notifications.filter.boosts": "Бустови", "notifications.filter.favourites": "Омилени", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Вчитување…", "regeneration_indicator.sublabel": "Вашиот новости се подготвуваат!", "relative_time.days": "{number}д", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}ч", "relative_time.just_now": "сега", "relative_time.minutes": "{number}м", "relative_time.seconds": "{number}с", "relative_time.today": "today", "reply_indicator.cancel": "Откажи", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Проследи до {target}", "report.forward_hint": "Оваа сметка е од друг сервер. Испрати анонимна копија од пријавата и таму?", "report.hint": "Пријавата ќе биде испратена до вашиот серверски модератор. Подолу можете да ставите опис зошто ја пријавувате сметката:", @@ -396,9 +407,14 @@ "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Load more", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/ml.json b/app/javascript/mastodon/locales/ml.json index cb320a661..b17642b3c 100644 --- a/app/javascript/mastodon/locales/ml.json +++ b/app/javascript/mastodon/locales/ml.json @@ -47,7 +47,8 @@ "account.unmute": "നിശ്ശബ്ദമാക്കുന്നത് നിർത്തുക @{name}", "account.unmute_notifications": "@{name} യിൽ നിന്നുള്ള അറിയിപ്പുകൾ പ്രസിദ്ധപ്പെടുത്തുക", "account_note.placeholder": "കുറിപ്പ് ചേർക്കാൻ ക്ലിക്കുചെയ്യുക", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "വോട്ടെടുപ്പിൽ ഒരൊറ്റ ചോയ്സ് മാത്രം ആക്കുക", "compose_form.publish": "ടൂട്ട്", "compose_form.publish_loud": "{പ്രസിദ്ധീകരിക്കുക}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "പ്രിയപ്പെട്ടവ:", "notifications.column_settings.filter_bar.advanced": "എല്ലാ വിഭാഗങ്ങളും പ്രദർശിപ്പിക്കുക", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "കാണിക്കുക", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "പുതിയ പിന്തുടരുന്നവർ:", "notifications.column_settings.follow_request": "പുതിയ പിന്തുടരൽ അഭ്യർത്ഥനകൾ:", "notifications.column_settings.mention": "സൂചനകൾ:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Show in column", "notifications.column_settings.sound": "ശബ്ദം പ്ലേ ചെയ്യുക", "notifications.column_settings.status": "പുതിയ ടൂട്ടുകൾ:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "എല്ലാം", "notifications.filter.boosts": "ബൂസ്റ്റുകൾ", "notifications.filter.favourites": "പ്രിയപ്പെട്ടവ", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "ലഭ്യമാക്കുന്നു…", "regeneration_indicator.sublabel": "നിങ്ങളുടെ ഹോം ഫീഡ് തയാറാക്കുന്നു!", "relative_time.days": "{number}ദിവസം", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}മണി", "relative_time.just_now": "ഇപ്പോൾ", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "ഇന്ന്", "reply_indicator.cancel": "റദ്ദാക്കുക", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "ഈ അക്കൗണ്ട് മറ്റൊരു സെർവറിൽ നിന്നാണ്. റിപ്പോർട്ടിന്റെ അജ്ഞാത പകർപ്പ് അവിടെ അയയ്ക്കണോ?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "മായ്ക്കുക", "status.detailed_status": "വിശദമായ സംഭാഷണ കാഴ്ച", "status.direct": "@{name} ന് നേരിട്ട് മെസേജ് അയക്കുക", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "ഉൾച്ചേർക്കുക", "status.favourite": "പ്രിയപ്പെട്ടത്", "status.filtered": "ഫിൽട്ടർ ചെയ്തു", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "കൂടുതൽ ലോഡു ചെയ്യുക", "status.media_hidden": "മീഡിയ മറച്ചു", "status.mention": "@{name} സൂചിപ്പിക്കുക", diff --git a/app/javascript/mastodon/locales/mr.json b/app/javascript/mastodon/locales/mr.json index 979f910ee..14e5d2de9 100644 --- a/app/javascript/mastodon/locales/mr.json +++ b/app/javascript/mastodon/locales/mr.json @@ -47,7 +47,8 @@ "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Show in column", "notifications.column_settings.sound": "Play sound", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "Cancel", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Load more", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/ms.json b/app/javascript/mastodon/locales/ms.json index 50526f74c..5db089d5a 100644 --- a/app/javascript/mastodon/locales/ms.json +++ b/app/javascript/mastodon/locales/ms.json @@ -47,7 +47,8 @@ "account.unmute": "Nyahbisukan @{name}", "account.unmute_notifications": "Nyahbisukan pemberitahuan daripada @{name}", "account_note.placeholder": "Klik untuk tambah catatan", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Ubah kepada undian pilihan tunggal", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Tandakan media sbg sensitif} other {Tandakan media sbg sensitif}}", "compose_form.sensitive.marked": "{count, plural, one {Media telah ditanda sbg sensitif} other {Media telah ditanda sbg sensitif}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media tidak ditanda sbg sensitif} other {Media tidak ditanda sbg sensitif}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Kegemaran:", "notifications.column_settings.filter_bar.advanced": "Papar semua kategori", "notifications.column_settings.filter_bar.category": "Bar penapis pantas", - "notifications.column_settings.filter_bar.show": "Tunjuk", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Pengikut baharu:", "notifications.column_settings.follow_request": "Permintaan ikutan baharu:", "notifications.column_settings.mention": "Sebutan:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Tunjukkan dalam lajur", "notifications.column_settings.sound": "Mainkan bunyi", "notifications.column_settings.status": "Hantaran baharu:", - "notifications.column_settings.unread_markers.category": "Penanda pemberitahuan belum dibaca", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Semua", "notifications.filter.boosts": "Galakan", "notifications.filter.favourites": "Kegemaran", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Memuatkan…", "regeneration_indicator.sublabel": "Suapan rumah anda sedang disediakan!", "relative_time.days": "{number}h", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}j", "relative_time.just_now": "sekarang", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "hari ini", "reply_indicator.cancel": "Batal", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Panjangkan ke {target}", "report.forward_hint": "Akaun ini daripada pelayan lain. Hantar salinan laporan yang ditanpanamakan ke sana juga?", "report.hint": "Laporan akan dihantar ke penyederhana pelayan anda. Anda boleh sertakan penerangan kenapa anda laporkan akaun ini di bawah:", @@ -396,9 +407,14 @@ "status.delete": "Padam", "status.detailed_status": "Paparan perbualan terperinci", "status.direct": "Mesej terus @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Benaman", "status.favourite": "Kegemaran", "status.filtered": "Ditapis", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Muatkan lagi", "status.media_hidden": "Media disembunyikan", "status.mention": "Sebut @{name}", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 7ef5a05e1..ec4e4aabd 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -47,16 +47,17 @@ "account.unmute": "@{name} niet langer negeren", "account.unmute_notifications": "Meldingen van @{name} niet langer negeren", "account_note.placeholder": "Klik om een opmerking toe te voegen", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Gemiddelde", + "admin.dashboard.retention.cohort": "Aanmeldingsmaand", + "admin.dashboard.retention.cohort_size": "Nieuwe gebruikers", "alert.rate_limited.message": "Probeer het nog een keer na {retry_time, time, medium}.", "alert.rate_limited.title": "Beperkt te gebruiken", "alert.unexpected.message": "Er deed zich een onverwachte fout voor", "alert.unexpected.title": "Oeps!", "announcement.announcement": "Mededeling", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(niet verwerkt)", "autosuggest_hashtag.per_week": "{count} per week", "boost_modal.combo": "Je kunt {combo} klikken om dit de volgende keer over te slaan", "bundle_column_error.body": "Tijdens het laden van dit onderdeel is er iets fout gegaan.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Poll wijzigen om een enkele keuze toe te staan", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Media als gevoelig markeren} other {Media als gevoelig markeren}}", "compose_form.sensitive.marked": "{count, plural, one {Media is als gevoelig gemarkeerd} other {Media is als gevoelig gemarkeerd}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is niet als gevoelig gemarkeerd} other {Media is niet als gevoelig gemarkeerd}}", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Weet je het zeker dat je deze toot wilt verwijderen?", "confirmations.delete_list.confirm": "Verwijderen", "confirmations.delete_list.message": "Weet je zeker dat je deze lijst definitief wilt verwijderen?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Weggooien", + "confirmations.discard_edit_media.message": "Je hebt niet-opgeslagen wijzigingen in de mediabeschrijving of voorvertonning, wil je deze toch weggooien?", "confirmations.domain_block.confirm": "Verberg alles van deze server", "confirmations.domain_block.message": "Weet je het echt heel erg zeker dat je alles van {domain} wilt negeren? In de meeste gevallen is het blokkeren of negeren van een paar specifieke personen voldoende en beter. Je zult geen toots van deze server op openbare tijdlijnen zien of in jouw meldingen. Jouw volgers van deze server worden verwijderd.", "confirmations.logout.confirm": "Uitloggen", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favorieten:", "notifications.column_settings.filter_bar.advanced": "Alle categorieën tonen", "notifications.column_settings.filter_bar.category": "Snelle filterbalk", - "notifications.column_settings.filter_bar.show": "Tonen", + "notifications.column_settings.filter_bar.show_bar": "Filterbalk tonen", "notifications.column_settings.follow": "Nieuwe volgers:", "notifications.column_settings.follow_request": "Nieuw volgverzoek:", "notifications.column_settings.mention": "Vermeldingen:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "In kolom tonen", "notifications.column_settings.sound": "Geluid afspelen", "notifications.column_settings.status": "Nieuwe toots:", - "notifications.column_settings.unread_markers.category": "Markeringen voor ongelezen meldingen", + "notifications.column_settings.unread_notifications.category": "Ongelezen meldingen", + "notifications.column_settings.unread_notifications.highlight": "Ongelezen meldingen markeren", "notifications.filter.all": "Alles", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favorieten", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# stem} other {# stemmen}}", "poll.vote": "Stemmen", "poll.voted": "Je hebt hier op gestemd", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# stem} other {# stemmen}}", "poll_button.add_poll": "Poll toevoegen", "poll_button.remove_poll": "Poll verwijderen", "privacy.change": "Zichtbaarheid van toot aanpassen", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Aan het laden…", "regeneration_indicator.sublabel": "Jouw tijdlijn wordt aangemaakt!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}u", "relative_time.just_now": "nu", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "vandaag", "reply_indicator.cancel": "Annuleren", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Naar {target} doorsturen", "report.forward_hint": "Het account bevindt zich op een andere server. Wil je daar eveneens een geanonimiseerde kopie van deze rapportage naar toe sturen?", "report.hint": "De rapportage wordt naar de moderator(en) van jouw server gestuurd. Je kunt hieronder een uitleg geven waarom je dit account rapporteert:", @@ -396,9 +407,14 @@ "status.delete": "Verwijderen", "status.detailed_status": "Uitgebreide gespreksweergave", "status.direct": "@{name} een direct bericht sturen", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Insluiten", "status.favourite": "Favoriet", "status.filtered": "Gefilterd", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Meer laden", "status.media_hidden": "Media verborgen", "status.mention": "@{name} vermelden", @@ -462,7 +478,7 @@ "upload_form.video_description": "Omschrijf dit voor mensen met een auditieve of visuele beperking", "upload_modal.analyzing_picture": "Afbeelding analyseren…", "upload_modal.apply": "Toepassen", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Aan het toepassen…", "upload_modal.choose_image": "Kies een afbeelding", "upload_modal.description_placeholder": "Pa's wijze lynx bezag vroom het fikse aquaduct", "upload_modal.detect_text": "Tekst in een afbeelding detecteren", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index cfd9aaca9..17e1a4d25 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -22,7 +22,7 @@ "account.follows.empty": "Denne brukaren fylgjer ikkje nokon enno.", "account.follows_you": "Fylgjer deg", "account.hide_reblogs": "Gøym fremhevingar frå @{name}", - "account.joined": "Ble med den {date}", + "account.joined": "Vart med {date}", "account.last_status": "Sist aktiv", "account.link_verified_on": "Eigarskap for denne lenkja vart sist sjekka {date}", "account.locked_info": "Denne kontoen er privat. Eigaren kan sjølv velja kven som kan fylgja han.", @@ -47,10 +47,11 @@ "account.unmute": "Av-demp @{name}", "account.unmute_notifications": "Vis varsel frå @{name}", "account_note.placeholder": "Klikk for å leggja til merknad", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.retention.cohort_size": "Nye brukere", "alert.rate_limited.message": "Ver venleg å prøva igjen etter {retry_time, time, medium}.", "alert.rate_limited.title": "Begrensa rate", "alert.unexpected.message": "Eit uventa problem oppstod.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Endra avstemninga til tillate berre eitt val", "compose_form.publish": "Tut", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Merk medium som sensitivt", "compose_form.sensitive.marked": "Medium er markert som sensitivt", "compose_form.sensitive.unmarked": "Medium er ikkje merka som sensitivt", @@ -118,7 +120,7 @@ "confirmations.delete.message": "Er du sikker på at du vil sletta denne statusen?", "confirmations.delete_list.confirm": "Slett", "confirmations.delete_list.message": "Er du sikker på at du vil sletta denne lista for alltid?", - "confirmations.discard_edit_media.confirm": "Discard", + "confirmations.discard_edit_media.confirm": "Forkast", "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", "confirmations.domain_block.confirm": "Gøym heile domenet", "confirmations.domain_block.message": "Er du heilt, heilt sikker på at du vil blokkera heile {domain}? I dei fleste tilfelle er det godt nok og føretrekt med nokre få målretta blokkeringar eller målbindingar. Du kjem ikkje til å sjå innhald frå det domenet i nokon fødererte tidsliner eller i varsla dine. Fylgjarane dine frå det domenet vert fjerna.", @@ -183,7 +185,7 @@ "error.unexpected_crash.next_steps_addons": "Prøv å deaktivere dem og laste siden på nytt. Hvis det ikke hjelper, kan du fremdeles bruke Mastodon via en annen nettleser eller en annen app.", "errors.unexpected_crash.copy_stacktrace": "Kopier stacktrace til utklippstavla", "errors.unexpected_crash.report_issue": "Rapporter problem", - "follow_recommendations.done": "Utført", + "follow_recommendations.done": "Ferdig", "follow_recommendations.heading": "Følg folk du ønsker å se innlegg fra! Her er noen forslag.", "follow_recommendations.lead": "Innlegg fra mennesker du følger vil vises i kronologisk rekkefølge på hjemmefeed. Ikke vær redd for å gjøre feil, du kan slutte å følge folk like enkelt som alt!", "follow_request.authorize": "Autoriser", @@ -263,7 +265,7 @@ "lists.new.title_placeholder": "Ny listetittel", "lists.replies_policy.followed": "Enhver fulgt bruker", "lists.replies_policy.list": "Medlemmer i listen", - "lists.replies_policy.none": "Ingen", + "lists.replies_policy.none": "Ikkje nokon", "lists.replies_policy.title": "Vis svar på:", "lists.search": "Søk gjennom folk du følgjer", "lists.subheading": "Dine lister", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favorittar:", "notifications.column_settings.filter_bar.advanced": "Vis alle kategoriar", "notifications.column_settings.filter_bar.category": "Snarfilterlinje", - "notifications.column_settings.filter_bar.show": "Vis", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Nye fylgjarar:", "notifications.column_settings.follow_request": "Ny fylgjarførespurnader:", "notifications.column_settings.mention": "Nemningar:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Vis i kolonne", "notifications.column_settings.sound": "Spel av lyd", "notifications.column_settings.status": "Nye tuter:", - "notifications.column_settings.unread_markers.category": "Ulest meldingsmarkører", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Alle", "notifications.filter.boosts": "Framhevingar", "notifications.filter.favourites": "Favorittar", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Lastar…", "regeneration_indicator.sublabel": "Heimetidslinja di vert førebudd!", "relative_time.days": "{number}dg", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}t", "relative_time.just_now": "nå", "relative_time.minutes": "{number}min", "relative_time.seconds": "{number}sek", "relative_time.today": "i dag", "reply_indicator.cancel": "Avbryt", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Vidaresend til {target}", "report.forward_hint": "Kontoen er frå ein annan tenar. Vil du senda ein anonymisert kopi av rapporten dit òg?", "report.hint": "Rapporten vil verte sendt til dine tenarmoderatorar. Du kan oppgje ei forklaring på kvifor du rapporterer denne kontoen, under:", @@ -396,9 +407,14 @@ "status.delete": "Slett", "status.detailed_status": "Detaljert samtalevisning", "status.direct": "Send melding til @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Bygg inn", "status.favourite": "Favoritt", "status.filtered": "Filtrert", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Last inn meir", "status.media_hidden": "Medium gøymd", "status.mention": "Nemn @{name}", @@ -444,7 +460,7 @@ "timeline_hint.resources.followers": "Fylgjarar", "timeline_hint.resources.follows": "Fylgjer", "timeline_hint.resources.statuses": "Eldre tut", - "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} folk}} pratar", + "trends.counter_by_accounts": "Pratas om av {count, plural, one {{counter} person} other {{counter} folk}}", "trends.trending_now": "Populært no", "ui.beforeunload": "Kladden din forsvinn om du forlèt Mastodon no.", "units.short.billion": "{count}m.ard", @@ -468,7 +484,7 @@ "upload_modal.detect_text": "Gjenkjenn tekst i biletet", "upload_modal.edit_media": "Rediger medium", "upload_modal.hint": "Klikk og dra sirkelen på førehandsvisninga for å velge fokuspunktet som alltid vil vere synleg på alle miniatyrbileta.", - "upload_modal.preparing_ocr": "Forbereder OCR…", + "upload_modal.preparing_ocr": "Førebur OCR…", "upload_modal.preview_label": "Førehandsvis ({ratio})", "upload_progress.label": "Lastar opp...", "video.close": "Lukk video", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index 179bbd1bd..0ede09267 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -47,10 +47,11 @@ "account.unmute": "Avdemp @{name}", "account.unmute_notifications": "Vis varsler fra @{name}", "account_note.placeholder": "Klikk for å legge til et notat", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.retention.cohort_size": "Nye brukere", "alert.rate_limited.message": "Vennligst prøv igjen etter kl. {retry_time, time, medium}.", "alert.rate_limited.title": "Hastighetsbegrenset", "alert.unexpected.message": "En uventet feil oppstod.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Endre avstemning til å tillate ett valg", "compose_form.publish": "Tut", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Merk media som sensitivt", "compose_form.sensitive.marked": "Mediet er merket som sensitiv", "compose_form.sensitive.unmarked": "Mediet er ikke merket som sensitiv", @@ -118,7 +120,7 @@ "confirmations.delete.message": "Er du sikker på at du vil slette denne statusen?", "confirmations.delete_list.confirm": "Slett", "confirmations.delete_list.message": "Er du sikker på at du vil slette denne listen permanent?", - "confirmations.discard_edit_media.confirm": "Discard", + "confirmations.discard_edit_media.confirm": "Forkast", "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", "confirmations.domain_block.confirm": "Skjul alt fra domenet", "confirmations.domain_block.message": "Er du sikker på at du vil skjule hele domenet {domain}? I de fleste tilfeller er det bedre med målrettet blokkering eller demping.", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Likt:", "notifications.column_settings.filter_bar.advanced": "Vis alle kategorier", "notifications.column_settings.filter_bar.category": "Hurtigfiltreringslinje", - "notifications.column_settings.filter_bar.show": "Vis", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Nye følgere:", "notifications.column_settings.follow_request": "Nye følgerforespørsler:", "notifications.column_settings.mention": "Nevnt:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Vis i kolonne", "notifications.column_settings.sound": "Spill lyd", "notifications.column_settings.status": "Nye tuter:", - "notifications.column_settings.unread_markers.category": "Ulest meldingsmarkører", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Alle", "notifications.filter.boosts": "Fremhevinger", "notifications.filter.favourites": "Favoritter", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Laster…", "regeneration_indicator.sublabel": "Dine startside forberedes!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}t", "relative_time.just_now": "nå", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "i dag", "reply_indicator.cancel": "Avbryt", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Videresend til {target}", "report.forward_hint": "Denne kontoen er fra en annen tjener. Vil du sende en anonymisert kopi av rapporten dit også?", "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Slett", "status.detailed_status": "Detaljert samtalevisning", "status.direct": "Send direktemelding til @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Bygge inn", "status.favourite": "Lik", "status.filtered": "Filtrert", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Last mer", "status.media_hidden": "Media skjult", "status.mention": "Nevn @{name}", @@ -444,7 +460,7 @@ "timeline_hint.resources.followers": "Følgere", "timeline_hint.resources.follows": "Følger", "timeline_hint.resources.statuses": "Eldre tuter", - "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} personer}} snakker", + "trends.counter_by_accounts": "Snakkes om av {count, plural, one {{counter} person} other {{counter} personer}}", "trends.trending_now": "Trender nå", "ui.beforeunload": "Din kladd vil bli forkastet om du forlater Mastodon.", "units.short.billion": "{count}m.ard", diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json index 6f7bc9761..7e7b68f77 100644 --- a/app/javascript/mastodon/locales/oc.json +++ b/app/javascript/mastodon/locales/oc.json @@ -47,16 +47,17 @@ "account.unmute": "Quitar de rescondre @{name}", "account.unmute_notifications": "Mostrar las notificacions de @{name}", "account_note.placeholder": "Clicar per ajustar una nòta", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Mejana", + "admin.dashboard.retention.cohort": "Mes d’inscripcion", + "admin.dashboard.retention.cohort_size": "Utilizaires novèls", "alert.rate_limited.message": "Mercés de tornar ensajar aprèp {retry_time, time, medium}.", "alert.rate_limited.title": "Taus limitat", "alert.unexpected.message": "Una error s’es producha.", "alert.unexpected.title": "Ops !", "announcement.announcement": "Anóncia", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(pas tractat)", "autosuggest_hashtag.per_week": "{count} per setmana", "boost_modal.combo": "Podètz botar {combo} per passar aquò lo còp que ven", "bundle_column_error.body": "Quicòm a fach mèuca pendent lo cargament d’aqueste compausant.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Cambiar lo sondatge per permetre una sola causida", "compose_form.publish": "Tut", "compose_form.publish_loud": "{publish} !", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Marcar coma sensible", "compose_form.sensitive.marked": "Lo mèdia es marcat coma sensible", "compose_form.sensitive.unmarked": "Lo mèdia es pas marcat coma sensible", @@ -118,7 +120,7 @@ "confirmations.delete.message": "Volètz vertadièrament escafar l’estatut ?", "confirmations.delete_list.confirm": "Suprimir", "confirmations.delete_list.message": "Volètz vertadièrament suprimir aquesta lista per totjorn ?", - "confirmations.discard_edit_media.confirm": "Discard", + "confirmations.discard_edit_media.confirm": "Ignorar", "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", "confirmations.domain_block.confirm": "Amagar tot lo domeni", "confirmations.domain_block.message": "Volètz vertadièrament blocar complètament {domain} ? De còps cal pas que blocar o rescondre unas personas solament.\nVeiretz pas cap de contengut d’aquel domeni dins cap de flux public o dins vòstras notificacions. Vòstres seguidors d’aquel domeni seràn levats.", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favorits :", "notifications.column_settings.filter_bar.advanced": "Mostrar totas las categorias", "notifications.column_settings.filter_bar.category": "Barra de recèrca rapida", - "notifications.column_settings.filter_bar.show": "Mostrar", + "notifications.column_settings.filter_bar.show_bar": "Afichar la barra de filtres", "notifications.column_settings.follow": "Nòus seguidors :", "notifications.column_settings.follow_request": "Novèla demanda d’abonament :", "notifications.column_settings.mention": "Mencions :", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Mostrar dins la colomna", "notifications.column_settings.sound": "Emetre un son", "notifications.column_settings.status": "Tuts novèls :", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Notificacions pas legidas", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Totas", "notifications.filter.boosts": "Partages", "notifications.filter.favourites": "Favorits", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Cargament…", "regeneration_indicator.sublabel": "Sèm a preparar vòstre flux d’acuèlh !", "relative_time.days": "fa {number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "fa {number}h", "relative_time.just_now": "ara", "relative_time.minutes": "fa {number} min", "relative_time.seconds": "fa {number}s", "relative_time.today": "uèi", "reply_indicator.cancel": "Anullar", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Far sègre a {target}", "report.forward_hint": "Lo compte ven d’un autre servidor. Volètz mandar una còpia anonima del rapòrt enlai tanben ?", "report.hint": "Lo moderator del servidor aurà lo rapòrt. Podètz fornir una explicacion de vòstre senhalament aquí dejós :", @@ -396,9 +407,14 @@ "status.delete": "Escafar", "status.detailed_status": "Vista detalhada de la convèrsa", "status.direct": "Messatge per @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embarcar", "status.favourite": "Apondre als favorits", "status.filtered": "Filtrat", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Cargar mai", "status.media_hidden": "Mèdia rescondut", "status.mention": "Mencionar", @@ -462,7 +478,7 @@ "upload_form.video_description": "Descriure per las personas amb pèrdas auditivas o mal vesent", "upload_modal.analyzing_picture": "Analisi de l’imatge…", "upload_modal.apply": "Aplicar", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Aplicacion…", "upload_modal.choose_image": "Causir un imatge", "upload_modal.description_placeholder": "Lo dròlle bilingüe manja un yaourt de ròcs exagonals e kiwis verds farà un an mai", "upload_modal.detect_text": "Detectar lo tèxt de l’imatge", diff --git a/app/javascript/mastodon/locales/pa.json b/app/javascript/mastodon/locales/pa.json index eca4765c4..2675da68c 100644 --- a/app/javascript/mastodon/locales/pa.json +++ b/app/javascript/mastodon/locales/pa.json @@ -47,7 +47,8 @@ "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Show in column", "notifications.column_settings.sound": "Play sound", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "Cancel", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Load more", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index e8c894c37..07754475f 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -47,16 +47,17 @@ "account.unmute": "Cofnij wyciszenie @{name}", "account.unmute_notifications": "Cofnij wyciszenie powiadomień od @{name}", "account_note.placeholder": "Naciśnij aby dodać notatkę", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Średnia", + "admin.dashboard.retention.cohort": "Miesiąc rejestracji", + "admin.dashboard.retention.cohort_size": "Nowi użytkownicy", "alert.rate_limited.message": "Spróbuj ponownie po {retry_time, time, medium}.", "alert.rate_limited.title": "Ograniczony czasowo", "alert.unexpected.message": "Wystąpił nieoczekiwany błąd.", "alert.unexpected.title": "O nie!", "announcement.announcement": "Ogłoszenie", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(nieprzetworzone)", "autosuggest_hashtag.per_week": "{count} co tydzień", "boost_modal.combo": "Naciśnij {combo}, aby pominąć to następnym razem", "bundle_column_error.body": "Coś poszło nie tak podczas ładowania tego składnika.", @@ -108,6 +109,7 @@ "compose_form.poll.switch_to_single": "Pozwól na wybranie tylko jednej opcji", "compose_form.publish": "Wyślij", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Oznacz multimedia jako wrażliwe", "compose_form.sensitive.marked": "Zawartość multimedia jest oznaczona jako wrażliwa", "compose_form.sensitive.unmarked": "Zawartość multimedialna nie jest oznaczona jako wrażliwa", @@ -122,8 +124,8 @@ "confirmations.delete.message": "Czy na pewno chcesz usunąć ten wpis?", "confirmations.delete_list.confirm": "Usuń", "confirmations.delete_list.message": "Czy na pewno chcesz bezpowrotnie usunąć tą listę?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Odrzuć", + "confirmations.discard_edit_media.message": "Masz niezapisane zmiany w opisie lub podglądzie, odrzucić je mimo to?", "confirmations.domain_block.confirm": "Ukryj wszystko z domeny", "confirmations.domain_block.message": "Czy na pewno chcesz zablokować całą domenę {domain}? Zwykle lepszym rozwiązaniem jest blokada lub wyciszenie kilku użytkowników.", "confirmations.logout.confirm": "Wyloguj", @@ -317,7 +319,7 @@ "notifications.column_settings.favourite": "Dodanie do ulubionych:", "notifications.column_settings.filter_bar.advanced": "Wyświetl wszystkie kategorie", "notifications.column_settings.filter_bar.category": "Szybkie filtrowanie", - "notifications.column_settings.filter_bar.show": "Pokaż", + "notifications.column_settings.filter_bar.show_bar": "Pokaż filtry", "notifications.column_settings.follow": "Nowi śledzący:", "notifications.column_settings.follow_request": "Nowe prośby o możliwość śledzenia:", "notifications.column_settings.mention": "Wspomnienia:", @@ -327,7 +329,8 @@ "notifications.column_settings.show": "Pokaż w kolumnie", "notifications.column_settings.sound": "Odtwarzaj dźwięk", "notifications.column_settings.status": "Nowe wpisy:", - "notifications.column_settings.unread_markers.category": "Znaczniki nieprzeczytanych powiadomień", + "notifications.column_settings.unread_notifications.category": "Nieprzeczytane powiadomienia", + "notifications.column_settings.unread_notifications.highlight": "Podświetl nieprzeczytane powiadomienia", "notifications.filter.all": "Wszystkie", "notifications.filter.boosts": "Podbicia", "notifications.filter.favourites": "Ulubione", @@ -351,7 +354,7 @@ "poll.total_votes": "{count, plural, one {# głos} few {# głosy} many {# głosów} other {# głosów}}", "poll.vote": "Zagłosuj", "poll.voted": "Zagłosowałeś_aś na tą odpowiedź", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# głos} few {# głosy} many {# głosów} other {# głosów}}", "poll_button.add_poll": "Dodaj głosowanie", "poll_button.remove_poll": "Usuń głosowanie", "privacy.change": "Dostosuj widoczność wpisów", @@ -367,12 +370,20 @@ "regeneration_indicator.label": "Ładuję…", "regeneration_indicator.sublabel": "Twoja oś czasu jest przygotowywana!", "relative_time.days": "{number} dni", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number} godz.", "relative_time.just_now": "teraz", "relative_time.minutes": "{number} min.", "relative_time.seconds": "{number} s.", "relative_time.today": "dzisiaj", "reply_indicator.cancel": "Anuluj", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Przekaż na {target}", "report.forward_hint": "To konto znajduje się na innej instancji. Czy chcesz wysłać anonimową kopię zgłoszenia rnież na nią?", "report.hint": "Zgłoszenie zostanie wysłane moderatorom Twojego serwera. Poniżej możesz też umieścić wyjaśnienie dlaczego zgłaszasz to konto:", @@ -401,9 +412,14 @@ "status.delete": "Usuń", "status.detailed_status": "Szczegółowy widok konwersacji", "status.direct": "Wyślij wiadomość bezpośrednią do @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Osadź", "status.favourite": "Dodaj do ulubionych", "status.filtered": "Filtrowany(-a)", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Załaduj więcej", "status.media_hidden": "Zawartość multimedialna ukryta", "status.mention": "Wspomnij o @{name}", @@ -467,7 +483,7 @@ "upload_form.video_description": "Opisz dla osób niesłyszących, niedosłyszących, niewidomych i niedowidzących", "upload_modal.analyzing_picture": "Analizowanie obrazu…", "upload_modal.apply": "Zastosuj", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Stosowanie…", "upload_modal.choose_image": "Wybierz obraz", "upload_modal.description_placeholder": "Pchnąć w tę łódź jeża lub ośm skrzyń fig", "upload_modal.detect_text": "Wykryj tekst z obrazu", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index 7745f0ca6..e61c3ef5a 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -47,16 +47,17 @@ "account.unmute": "Dessilenciar @{name}", "account.unmute_notifications": "Mostrar notificações de @{name}", "account_note.placeholder": "Nota pessoal sobre este perfil aqui", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Média", + "admin.dashboard.retention.cohort": "Mês de inscrição", + "admin.dashboard.retention.cohort_size": "Novos usuários", "alert.rate_limited.message": "Tente novamente após {retry_time, time, medium}.", "alert.rate_limited.title": "Tentativas limitadas", "alert.unexpected.message": "Ocorreu um erro inesperado.", "alert.unexpected.title": "Eita!", "announcement.announcement": "Comunicados", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(não processado)", "autosuggest_hashtag.per_week": "{count} por semana", "boost_modal.combo": "Pressione {combo} para pular isso na próxima vez", "bundle_column_error.body": "Erro ao carregar este componente.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Opção única", "compose_form.publish": "TOOT", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Marcar mídia como sensível} other {Marcar mídias como sensível}}", "compose_form.sensitive.marked": "{count, plural, one {Mídia marcada como sensível} other {Mídias marcadas como sensível}}", "compose_form.sensitive.unmarked": "{count, plural, one {Mídia não está marcada como sensível} other {Mídias não estão marcadas como sensível}}", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Você tem certeza de que deseja excluir este toot?", "confirmations.delete_list.confirm": "Excluir", "confirmations.delete_list.message": "Você tem certeza de que deseja excluir esta lista?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Descartar", + "confirmations.discard_edit_media.message": "Há mudanças não salvas na descrição ou pré-visualização da mídia; descartar assim mesmo?", "confirmations.domain_block.confirm": "Bloquear instância", "confirmations.domain_block.message": "Você tem certeza de que deseja bloquear tudo de {domain}? Você não verá mais o conteúdo desta instância em nenhuma linha do tempo pública ou nas suas notificações. Seus seguidores desta instância serão removidos.", "confirmations.logout.confirm": "Sair", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favoritos:", "notifications.column_settings.filter_bar.advanced": "Mostrar todas as categorias", "notifications.column_settings.filter_bar.category": "Barra de filtro rápido das notificações", - "notifications.column_settings.filter_bar.show": "Mostrar", + "notifications.column_settings.filter_bar.show_bar": "Mostrar barra de filtro", "notifications.column_settings.follow": "Seguidores:", "notifications.column_settings.follow_request": "Seguidores pendentes:", "notifications.column_settings.mention": "Menções:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Mostrar na coluna", "notifications.column_settings.sound": "Tocar som", "notifications.column_settings.status": "Novos toots:", - "notifications.column_settings.unread_markers.category": "Marcar como não lidas", + "notifications.column_settings.unread_notifications.category": "Notificações não lidas", + "notifications.column_settings.unread_notifications.highlight": "Destacar notificações não lidas", "notifications.filter.all": "Tudo", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favoritos", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# voto} other {# votos}}", "poll.vote": "Votar", "poll.voted": "Você votou nesta opção", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# voto} other {# votos}}", "poll_button.add_poll": "Adicionar enquete", "poll_button.remove_poll": "Remover enquete", "privacy.change": "Alterar privacidade do toot", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Carregando…", "regeneration_indicator.sublabel": "Sua página inicial está sendo preparada!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "agora", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "hoje", "reply_indicator.cancel": "Cancelar", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Encaminhar para {target}", "report.forward_hint": "A conta está em outra instância. Enviar uma cópia anônima da denúncia para lá?", "report.hint": "A denúncia será enviada aos moderadores da instância. Explique por que denunciou a conta:", @@ -396,9 +407,14 @@ "status.delete": "Excluir", "status.detailed_status": "Visão detalhada da conversa", "status.direct": "Enviar toot direto para @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Incorporar", "status.favourite": "Favoritar", "status.filtered": "Filtrado", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Ver mais", "status.media_hidden": "Mídia sensível", "status.mention": "Mencionar @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Descrever para deficientes auditivos ou visuais", "upload_modal.analyzing_picture": "Analisando imagem…", "upload_modal.apply": "Aplicar", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Aplicando…", "upload_modal.choose_image": "Escolher imagem", "upload_modal.description_placeholder": "Um pequeno jabuti xereta viu dez cegonhas felizes", "upload_modal.detect_text": "Transcrever imagem", diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json index a5cb6a335..988ecef3a 100644 --- a/app/javascript/mastodon/locales/pt-PT.json +++ b/app/javascript/mastodon/locales/pt-PT.json @@ -47,16 +47,17 @@ "account.unmute": "Não silenciar @{name}", "account.unmute_notifications": "Deixar de silenciar @{name}", "account_note.placeholder": "Clique para adicionar nota", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Média", + "admin.dashboard.retention.cohort": "Mês de inscrição", + "admin.dashboard.retention.cohort_size": "Novos utilizadores", "alert.rate_limited.message": "Volte a tentar depois das {retry_time, time, medium}.", "alert.rate_limited.title": "Limite de tentativas", "alert.unexpected.message": "Ocorreu um erro inesperado.", "alert.unexpected.title": "Bolas!", "announcement.announcement": "Anúncio", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(não processado)", "autosuggest_hashtag.per_week": "{count} por semana", "boost_modal.combo": "Pode clicar {combo} para não voltar a ver", "bundle_column_error.body": "Algo de errado aconteceu enquanto este componente era carregado.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Alterar a votação para permitir uma única escolha", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Marcar media como sensível", "compose_form.sensitive.marked": "Media marcada como sensível", "compose_form.sensitive.unmarked": "Media não está marcada como sensível", @@ -111,15 +113,15 @@ "compose_form.spoiler.unmarked": "O texto não está escondido", "compose_form.spoiler_placeholder": "Escreva o seu aviso aqui", "confirmation_modal.cancel": "Cancelar", - "confirmations.block.block_and_report": "Bloquear e denunciar", + "confirmations.block.block_and_report": "Bloquear e Denunciar", "confirmations.block.confirm": "Bloquear", "confirmations.block.message": "De certeza que queres bloquear {name}?", "confirmations.delete.confirm": "Eliminar", "confirmations.delete.message": "De certeza que quer eliminar esta publicação?", "confirmations.delete_list.confirm": "Eliminar", "confirmations.delete_list.message": "Tens a certeza de que deseja eliminar permanentemente esta lista?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Descartar", + "confirmations.discard_edit_media.message": "Tem alterações não salvas na descrição ou pré-visualização da media. Descartar mesmo assim?", "confirmations.domain_block.confirm": "Esconder tudo deste domínio", "confirmations.domain_block.message": "De certeza que queres bloquear completamente o domínio {domain}? Na maioria dos casos, silenciar ou bloquear alguns utilizadores é suficiente e é o recomendado. Não irás ver conteúdo daquele domínio em cronologia alguma nem nas tuas notificações. Os teus seguidores daquele domínio serão removidos.", "confirmations.logout.confirm": "Terminar sessão", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favoritos:", "notifications.column_settings.filter_bar.advanced": "Mostrar todas as categorias", "notifications.column_settings.filter_bar.category": "Barra de filtros rápidos", - "notifications.column_settings.filter_bar.show": "Mostrar", + "notifications.column_settings.filter_bar.show_bar": "Mostrar barra de filtros", "notifications.column_settings.follow": "Novos seguidores:", "notifications.column_settings.follow_request": "Novos pedidos de seguidor:", "notifications.column_settings.mention": "Menções:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Mostrar na coluna", "notifications.column_settings.sound": "Reproduzir som", "notifications.column_settings.status": "Novos toots:", - "notifications.column_settings.unread_markers.category": "Marcadores de notificação não lidas", + "notifications.column_settings.unread_notifications.category": "Notificações não lidas", + "notifications.column_settings.unread_notifications.highlight": "Destacar notificações não lidas", "notifications.filter.all": "Todas", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favoritos", @@ -346,7 +349,7 @@ "poll.total_votes": "{contar, plural, um {# vote} outro {# votes}}", "poll.vote": "Votar", "poll.voted": "Votaste nesta resposta", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# voto } other {# votos}}", "poll_button.add_poll": "Adicionar votação", "poll_button.remove_poll": "Remover votação", "privacy.change": "Ajustar a privacidade da publicação", @@ -362,18 +365,26 @@ "regeneration_indicator.label": "A carregar…", "regeneration_indicator.sublabel": "A tua página inicial está a ser preparada!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "agora", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "hoje", "reply_indicator.cancel": "Cancelar", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Reenviar para {target}", - "report.forward_hint": "A conta é de outra instância. Enviar uma cópia anónima do relatório para lá também?", - "report.hint": "O relatório será enviado para os moderadores da sua instância. Pode fornecer, em baixo, uma explicação do motivo pelo qual está a denunciar esta conta:", + "report.forward_hint": "A conta é de outro servidor. Enviar uma cópia anónima da denúncia para lá também?", + "report.hint": "A denúncia será enviada para os moderadores do seu servidor. Pode fornecer, em baixo, uma explicação do motivo pelo qual está a denunciar esta conta:", "report.placeholder": "Comentários adicionais", "report.submit": "Enviar", - "report.target": "Denunciar", + "report.target": "A denunciar {target}", "search.placeholder": "Pesquisar", "search_popout.search_format": "Formato avançado de pesquisa", "search_popout.tips.full_text": "Texto simples devolve publicações que escreveu, marcou como favorita, partilhou ou em que foi mencionado, tal como nomes de utilizador, alcunhas e hashtags.", @@ -396,9 +407,14 @@ "status.delete": "Eliminar", "status.detailed_status": "Vista de conversação detalhada", "status.direct": "Mensagem direta @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Incorporar", "status.favourite": "Adicionar aos favoritos", "status.filtered": "Filtrada", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Carregar mais", "status.media_hidden": "Media escondida", "status.mention": "Mencionar @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Descreva para pessoas com diminuição da acuidade auditiva ou visual", "upload_modal.analyzing_picture": "A analizar imagem…", "upload_modal.apply": "Aplicar", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "A aplicar…", "upload_modal.choose_image": "Escolher imagem", "upload_modal.description_placeholder": "Grave e cabisbaixo, o filho justo zelava pela querida mãe doente", "upload_modal.detect_text": "Detectar texto na imagem", diff --git a/app/javascript/mastodon/locales/ro.json b/app/javascript/mastodon/locales/ro.json index b6cb0a86c..15baeef12 100644 --- a/app/javascript/mastodon/locales/ro.json +++ b/app/javascript/mastodon/locales/ro.json @@ -47,16 +47,17 @@ "account.unmute": "Nu mai ignora pe @{name}", "account.unmute_notifications": "Activează notificările de la @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "În medie", + "admin.dashboard.retention.cohort": "Înregistrări lunar", + "admin.dashboard.retention.cohort_size": "Utilizatori noi", "alert.rate_limited.message": "Vă rugăm să reîncercați după {retry_time, time, medium}.", "alert.rate_limited.title": "Debit limitat", "alert.unexpected.message": "A apărut o eroare neașteptată.", "alert.unexpected.title": "Ups!", "announcement.announcement": "Anunț", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(neprocesate)", "autosuggest_hashtag.per_week": "{count} pe săptămână", "boost_modal.combo": "Poți apăsa {combo} pentru a sări peste asta data viitoare", "bundle_column_error.body": "A apărut o eroare la încărcarea acestui element.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Modifică sondajul pentru a permite o singură opțiune", "compose_form.publish": "Postează", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Marchează conținutul media ca fiind sensibil} few {Marchează conținuturile media ca fiind sensibile} other {Marchează conținuturile media ca fiind sensibile}}", "compose_form.sensitive.marked": "{count, plural, one {Conținutul media este marcat ca fiind sensibil} other {Conținuturile media sunt marcate ca fiind sensibile}}", "compose_form.sensitive.unmarked": "{count, plural, one {Conținutul media nu este marcat ca fiind sensibil} other {Conținuturile media nu sunt marcate ca fiind sensibile}}", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Ești sigur că vrei să elimini această postare?", "confirmations.delete_list.confirm": "Elimină", "confirmations.delete_list.message": "Ești sigur că vrei să elimini definitiv această listă?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Renunță", + "confirmations.discard_edit_media.message": "Ai modificări nesalvate în descrierea sau previzualizarea media, renunți oricum?", "confirmations.domain_block.confirm": "Blochează întregul domeniu", "confirmations.domain_block.message": "Ești absolut sigur că vrei să blochezi tot domeniul {domain}? În cele mai multe cazuri, raportarea sau blocarea anumitor lucruri este suficientă și de preferat. Nu vei mai vedea niciun conținut din acest domeniu în vreun flux public sau în vreo notificare. Abonații tăi din acest domeniu vor fi eliminați.", "confirmations.logout.confirm": "Deconectare", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favorite:", "notifications.column_settings.filter_bar.advanced": "Afișează toate categoriile", "notifications.column_settings.filter_bar.category": "Bară de filtrare rapidă", - "notifications.column_settings.filter_bar.show": "Afișează", + "notifications.column_settings.filter_bar.show_bar": "Arată bara de filtrare", "notifications.column_settings.follow": "Noi abonați:", "notifications.column_settings.follow_request": "Noi cereri de abonare:", "notifications.column_settings.mention": "Mențiuni:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Afișează în coloană", "notifications.column_settings.sound": "Redare sunet", "notifications.column_settings.status": "Postări noi:", - "notifications.column_settings.unread_markers.category": "Marcaje de notificări necitite", + "notifications.column_settings.unread_notifications.category": "Notificări necitite", + "notifications.column_settings.unread_notifications.highlight": "Evidențiază notificările necitite", "notifications.filter.all": "Toate", "notifications.filter.boosts": "Distribuiri", "notifications.filter.favourites": "Favorite", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# vot} other {# voturi}}", "poll.vote": "Votează", "poll.voted": "Ai votat pentru acest răspuns", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# vot} other {# voturi}}", "poll_button.add_poll": "Adaugă un sondaj", "poll_button.remove_poll": "Elimină sondajul", "privacy.change": "Modifică confidențialitatea postării", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Se încarcă…", "regeneration_indicator.sublabel": "Cronologia ta principală este în curs de pregătire!", "relative_time.days": "{number}z", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}o", "relative_time.just_now": "acum", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "astăzi", "reply_indicator.cancel": "Anulează", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Redirecționează către {target}", "report.forward_hint": "Acest cont este de pe un alt server. Trimitem o copie anonimă a raportului și acolo?", "report.hint": "Sesizarea va fi trimisă către moderatorii acestei instanțe. Poți oferi o explicație pentru această sesizare mai jos:", @@ -396,9 +407,14 @@ "status.delete": "Șterge", "status.detailed_status": "Conversația detaliată", "status.direct": "Mesaj direct către @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Înglobează", "status.favourite": "Favorite", "status.filtered": "Sortate", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Încarcă mai multe", "status.media_hidden": "Media ascunsă", "status.mention": "Menționează pe @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Adaugă o descriere pentru persoanele cu deficiențe vizuale sau auditive", "upload_modal.analyzing_picture": "Se analizează imaginea…", "upload_modal.apply": "Aplică", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Se aplică…", "upload_modal.choose_image": "Alege imaginea", "upload_modal.description_placeholder": "Vând muzică de jazz și haine de bun-gust în New-York și Quebec la preț fix", "upload_modal.detect_text": "Detectare text din imagine", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index a37418101..c414f9e7c 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -47,16 +47,17 @@ "account.unmute": "Убрать {name} из игнорируемых", "account.unmute_notifications": "Показывать уведомления от @{name}", "account_note.placeholder": "Текст заметки", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Среднее", + "admin.dashboard.retention.cohort": "Месяц регистрации", + "admin.dashboard.retention.cohort_size": "Новые пользователи", "alert.rate_limited.message": "Пожалуйста, повторите после {retry_time, time, medium}.", "alert.rate_limited.title": "Вы выполняете действие слишком часто", "alert.unexpected.message": "Произошла непредвиденная ошибка.", "alert.unexpected.title": "Упс!", "announcement.announcement": "Объявление", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(не обработан)", "autosuggest_hashtag.per_week": "{count} / неделю", "boost_modal.combo": "{combo}, чтобы пропустить это в следующий раз", "bundle_column_error.body": "Что-то пошло не так при загрузке этого компонента.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Переключить в режим выбора одного ответа", "compose_form.publish": "Запостить", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Отметить медифайл как деликатный} other {Отметить медифайлы как деликатные}}", "compose_form.sensitive.marked": "Медиа{count, plural, =1 {файл отмечен} other {файлы отмечены}} как «деликатного характера»", "compose_form.sensitive.unmarked": "Медиа{count, plural, =1 {файл не отмечен} other {файлы не отмечены}} как «деликатного характера»", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Вы уверены, что хотите удалить этот пост?", "confirmations.delete_list.confirm": "Удалить", "confirmations.delete_list.message": "Вы действительно хотите навсегда удалить этот список?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Отменить", + "confirmations.discard_edit_media.message": "У вас имеются несохранённые изменения превью и описания медиафайла, отменить их?", "confirmations.domain_block.confirm": "Да, заблокировать узел", "confirmations.domain_block.message": "Вы точно уверены, что хотите скрыть все посты с узла {domain}? В большинстве случаев пары блокировок и скрытий вполне достаточно.\n\nПри блокировке узла, вы перестанете получать уведомления оттуда, все посты будут скрыты из публичных лент, а подписчики убраны.", "confirmations.logout.confirm": "Выйти", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Ваш пост добавили в «избранное»:", "notifications.column_settings.filter_bar.advanced": "Отображать все категории", "notifications.column_settings.filter_bar.category": "Панель сортировки", - "notifications.column_settings.filter_bar.show": "Отображать панель сортировки", + "notifications.column_settings.filter_bar.show_bar": "Отображать панель сортировки", "notifications.column_settings.follow": "У вас новый подписчик:", "notifications.column_settings.follow_request": "Новые запросы на подписку:", "notifications.column_settings.mention": "Вас упомянули в посте:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Отображать в списке", "notifications.column_settings.sound": "Проигрывать звук", "notifications.column_settings.status": "Новые посты:", - "notifications.column_settings.unread_markers.category": "Маркеры непрочитанных уведомлений", + "notifications.column_settings.unread_notifications.category": "Непрочитанные уведомления", + "notifications.column_settings.unread_notifications.highlight": "Выделять непрочитанные уведомления", "notifications.filter.all": "Все", "notifications.filter.boosts": "Продвижения", "notifications.filter.favourites": "Отметки «избранного»", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# голос} few {# голоса} many {# голосов} other {# голосов}}", "poll.vote": "Голосовать", "poll.voted": "Вы проголосовали за этот вариант", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# голос} many {# голосов} other {# голоса}}", "poll_button.add_poll": "Добавить опрос", "poll_button.remove_poll": "Удалить опрос", "privacy.change": "Изменить видимость поста", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Загрузка…", "regeneration_indicator.sublabel": "Один момент, мы подготавливаем вашу ленту!", "relative_time.days": "{number} д", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number} ч", "relative_time.just_now": "только что", "relative_time.minutes": "{number} мин", "relative_time.seconds": "{number} с", "relative_time.today": "сегодня", "reply_indicator.cancel": "Отмена", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Переслать в {target}", "report.forward_hint": "Эта учётная запись расположена на другом узле. Отправить туда анонимную копию вашей жалобы?", "report.hint": "Жалоба будет отправлена модераторам вашего узла. Вы также можете указать подробную причину жалобы ниже:", @@ -396,9 +407,14 @@ "status.delete": "Удалить", "status.detailed_status": "Подробный просмотр обсуждения", "status.direct": "Написать @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Встроить на свой сайт", "status.favourite": "В избранное", "status.filtered": "Отфильтровано", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Загрузить остальное", "status.media_hidden": "Файл скрыт", "status.mention": "Упомянуть @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Опишите видео для людей с нарушением слуха или зрения", "upload_modal.analyzing_picture": "Обработка изображения…", "upload_modal.apply": "Применить", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Применение…", "upload_modal.choose_image": "Выбрать изображение", "upload_modal.description_placeholder": "На дворе трава, на траве дрова", "upload_modal.detect_text": "Найти текст на картинке", diff --git a/app/javascript/mastodon/locales/sa.json b/app/javascript/mastodon/locales/sa.json index 1e496c3ec..a2a22e758 100644 --- a/app/javascript/mastodon/locales/sa.json +++ b/app/javascript/mastodon/locales/sa.json @@ -47,7 +47,8 @@ "account.unmute": "सशब्दम् @{name}", "account.unmute_notifications": "@{name} सूचनाः सक्रियन्ताम्", "account_note.placeholder": "टीकायोजनार्थं नुद्यताम्", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "मतदानं परिवर्तयित्वा निर्विकल्पमतदानं क्रियताम्", "compose_form.publish": "दौत्यम्", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "संवेदनशीलसामग्रीत्यङ्यताम्", "compose_form.sensitive.marked": "संवेदनशीलसामग्रीत्यङ्कितम्", "compose_form.sensitive.unmarked": "संवेदनशीलसामग्रीति नाङ्कितम्", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Show in column", "notifications.column_settings.sound": "Play sound", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "Cancel", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Load more", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/sc.json b/app/javascript/mastodon/locales/sc.json index 339bbac09..4f8f12357 100644 --- a/app/javascript/mastodon/locales/sc.json +++ b/app/javascript/mastodon/locales/sc.json @@ -47,7 +47,8 @@ "account.unmute": "Torra a ativare a @{name}", "account.unmute_notifications": "Ativa notìficas pro @{name}", "account_note.placeholder": "Incarca pro agiùnghere una nota", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Muda su sondàgiu pro permìtere un'optzione isceti", "compose_form.publish": "Tut", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Marca elementu multimediale comente a sensìbile} other {Marca elementos multimediales comente sensìbiles}}", "compose_form.sensitive.marked": "{count, plural, one {Elementu multimediale marcadu comente a sensìbile} other {Elementos multimediales marcados comente a sensìbiles}}", "compose_form.sensitive.unmarked": "{count, plural, one {Elementu multimediale non marcadu comente a sensìbile} other {Elementos multimediales non marcados comente a sensìbiles}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Preferidos:", "notifications.column_settings.filter_bar.advanced": "Ammustra totu is categorias", "notifications.column_settings.filter_bar.category": "Barra lestra de filtros", - "notifications.column_settings.filter_bar.show": "Ammustra", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Sighiduras noas:", "notifications.column_settings.follow_request": "Rechestas noas de sighidura:", "notifications.column_settings.mention": "Mèntovos:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Ammustra in sa colunna", "notifications.column_settings.sound": "Reprodue unu sonu", "notifications.column_settings.status": "Publicatziones noas:", - "notifications.column_settings.unread_markers.category": "Marcadores de notìficas de lèghere", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Totus", "notifications.filter.boosts": "Cumpartziduras", "notifications.filter.favourites": "Preferidos", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Carrighende…", "regeneration_indicator.sublabel": "Preparende sa lìnia de tempus printzipale tua.", "relative_time.days": "{number} dies a oe", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number} oras a immoe", "relative_time.just_now": "immoe", "relative_time.minutes": "{number} minutos a immoe", "relative_time.seconds": "{number} segundos a immoe", "relative_time.today": "oe", "reply_indicator.cancel": "Annulla", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Torra a imbiare a {target}", "report.forward_hint": "Custu contu est de un'àteru serbidore. Ddi boles imbiare puru una còpia anònima de custu informe?", "report.hint": "S'informe at a èssere imbiadu a sa moderatzione de su serbidore. Podes frunire un'ispiegatzione de sa signalatzione tua de custu contu:", @@ -396,9 +407,14 @@ "status.delete": "Cantzella", "status.detailed_status": "Visualizatzione de detàlliu de arresonada", "status.direct": "Messàgiu deretu a @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Afissa", "status.favourite": "Preferidos", "status.filtered": "Filtradu", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Càrriga·nde àteros", "status.media_hidden": "Elementos multimediales cuados", "status.mention": "Mèntova a @{name}", diff --git a/app/javascript/mastodon/locales/si.json b/app/javascript/mastodon/locales/si.json index 0baa6c7ae..40939f1b2 100644 --- a/app/javascript/mastodon/locales/si.json +++ b/app/javascript/mastodon/locales/si.json @@ -47,7 +47,8 @@ "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", "account_note.placeholder": "සටහන එකතු කිරීමට ක්ලික් කරන්න", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "තනි තේරීමකට ඉඩ දීම සඳහා මත විමසුම වෙනස් කරන්න", "compose_form.publish": "පිඹින්න", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {මාධ්ය සංවේදී ලෙස සලකුණු කරන්න} other {මාධ්ය සංවේදී ලෙස සලකුණු කරන්න}}", "compose_form.sensitive.marked": "{count, plural, one {මාධ්ය සංවේදී ලෙස සලකුණු කර ඇත} other {මාධ්ය සංවේදී ලෙස සලකුණු කර ඇත}}", "compose_form.sensitive.unmarked": "{count, plural, one {මාධ්ය සංවේදී ලෙස සලකුණු කර නැත} other {මාධ්ය සංවේදී ලෙස සලකුණු කර නැත}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "ප්රියතමයන්:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "පෙන්වන්න", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "සැඳහුම්:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "තීරුවෙහි පෙන්වන්න", "notifications.column_settings.sound": "ශබ්දය ධාවනය", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "සියල්ල", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "ප්රියතමයන්", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "පූරණය වෙමින්…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "දැන්", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "අද", "reply_indicator.cancel": "අවලංගු කරන්න", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "@{name} සෘජු පණිවිඩය", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "එබ්බවූ", "status.favourite": "ප්රියතම", "status.filtered": "පෙරන ලද", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "තව පූරණය කරන්න", "status.media_hidden": "මාධ්ය සඟවා ඇත", "status.mention": "@{name} සැඳහුම", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index 5911881bb..34c3da043 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -9,7 +9,7 @@ "account.browse_more_on_origin_server": "Prehľadávaj viac na pôvodnom profile", "account.cancel_follow_request": "Zruš žiadosť o sledovanie", "account.direct": "Priama správa pre @{name}", - "account.disable_notifications": "Prestaň oboznamovať keď má príspevky @{name}", + "account.disable_notifications": "Prestaň oznamovať, keď má príspevky @{name}", "account.domain_blocked": "Doména ukrytá", "account.edit_profile": "Uprav profil", "account.enable_notifications": "Oboznamuj ma, keď má @{name} príspevky", @@ -33,7 +33,7 @@ "account.mute_notifications": "Stĺm oboznámenia od @{name}", "account.muted": "Utíšený/á", "account.never_active": "Nikdy", - "account.posts": "Príspevkov", + "account.posts": "Príspevky", "account.posts_with_replies": "Príspevky, aj s odpoveďami", "account.report": "Nahlás @{name}", "account.requested": "Čaká na schválenie. Klikni pre zrušenie žiadosti", @@ -47,16 +47,17 @@ "account.unmute": "Prestaň ignorovať @{name}", "account.unmute_notifications": "Zruš stĺmenie oboznámení od @{name}", "account_note.placeholder": "Klikni pre vloženie poznámky", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Priemer", + "admin.dashboard.retention.cohort": "Mesiac zaregistrovania sa", + "admin.dashboard.retention.cohort_size": "Noví užívatelia", "alert.rate_limited.message": "Prosím, skús to znova za {retry_time, time, medium}.", "alert.rate_limited.title": "Tempo obmedzené", "alert.unexpected.message": "Vyskytla sa nečakaná chyba.", "alert.unexpected.title": "Ups!", "announcement.announcement": "Oboznámenie", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(nespracované)", "autosuggest_hashtag.per_week": "{count} týždenne", "boost_modal.combo": "Nabudúce môžeš kliknúť {combo} pre preskočenie", "bundle_column_error.body": "Pri načítaní tohto prvku nastala nejaká chyba.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Zmeň anketu na takú s jedinou voľbou", "compose_form.publish": "Pošli", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Označ médiá ako chúlostivé", "compose_form.sensitive.marked": "Médiálny obsah je označený ako chúlostivý", "compose_form.sensitive.unmarked": "Médiálny obsah nieje označený ako chúlostivý", @@ -118,7 +120,7 @@ "confirmations.delete.message": "Si si istý/á, že chceš vymazať túto správu?", "confirmations.delete_list.confirm": "Vymaž", "confirmations.delete_list.message": "Si si istý/á, že chceš natrvalo vymazať tento zoznam?", - "confirmations.discard_edit_media.confirm": "Discard", + "confirmations.discard_edit_media.confirm": "Zahoď", "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", "confirmations.domain_block.confirm": "Skry celú doménu", "confirmations.domain_block.message": "Si si naozaj istý/á, že chceš blokovať celú doménu {domain}? Vo väčšine prípadov stačí blokovať alebo ignorovať pár konkrétnych užívateľov, čo sa doporučuje. Neuvidíš obsah z tejto domény v žiadnej verejnej časovej osi, ani v oznámeniach. Tvoji následovníci pochádzajúci z tejto domény budú odstránení.", @@ -158,7 +160,7 @@ "emoji_button.symbols": "Symboly", "emoji_button.travel": "Cestovanie a miesta", "empty_column.account_suspended": "Účet bol vylúčený", - "empty_column.account_timeline": "Niesú tu žiadne príspevky!", + "empty_column.account_timeline": "Niesu tu žiadne príspevky!", "empty_column.account_unavailable": "Profil nedostupný", "empty_column.blocks": "Ešte si nikoho nezablokoval/a.", "empty_column.bookmarked_statuses": "Ešte nemáš žiadné záložky. Keď si pridáš príspevok k záložkám, zobrazí sa tu.", @@ -217,13 +219,13 @@ "intervals.full.minutes": "{number, plural, one {# minúta} few {# minút} many {# minút} other {# minút}}", "keyboard_shortcuts.back": "dostať sa naspäť", "keyboard_shortcuts.blocked": "otvor zoznam blokovaných užívateľov", - "keyboard_shortcuts.boost": "vyzdvihnúť", + "keyboard_shortcuts.boost": "Vyzdvihni príspevok", "keyboard_shortcuts.column": "zameraj sa na príspevok v jednom zo stĺpcov", "keyboard_shortcuts.compose": "zameraj sa na písaciu plochu", "keyboard_shortcuts.description": "Popis", "keyboard_shortcuts.direct": "pre otvorenie panelu priamých správ", "keyboard_shortcuts.down": "posunúť sa dole v zozname", - "keyboard_shortcuts.enter": "otvoriť správu", + "keyboard_shortcuts.enter": "Otvor príspevok", "keyboard_shortcuts.favourite": "pridaj do obľúbených", "keyboard_shortcuts.favourites": "otvor zoznam obľúbených", "keyboard_shortcuts.federated": "otvor federovanú časovú os", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Obľúbené:", "notifications.column_settings.filter_bar.advanced": "Zobraz všetky kategórie", "notifications.column_settings.filter_bar.category": "Rýchle triedenie", - "notifications.column_settings.filter_bar.show": "Ukáž", + "notifications.column_settings.filter_bar.show_bar": "Ukáž filtrovací panel", "notifications.column_settings.follow": "Noví sledujúci:", "notifications.column_settings.follow_request": "Nové žiadosti o následovanie:", "notifications.column_settings.mention": "Zmienenia:", @@ -321,8 +323,9 @@ "notifications.column_settings.reblog": "Vyzdvihnutia:", "notifications.column_settings.show": "Ukáž v stĺpci", "notifications.column_settings.sound": "Prehraj zvuk", - "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Značenia neprečítaných oboznámení", + "notifications.column_settings.status": "Nové príspevky:", + "notifications.column_settings.unread_notifications.category": "Neprečítané oboznámenia", + "notifications.column_settings.unread_notifications.highlight": "Zdôrazni neprečítané oboznámenia", "notifications.filter.all": "Všetky", "notifications.filter.boosts": "Vyzdvihnutia", "notifications.filter.favourites": "Obľúbené", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Načítava sa…", "regeneration_indicator.sublabel": "Vaša nástenka sa pripravuje!", "relative_time.days": "{number}dní", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}hod", "relative_time.just_now": "teraz", "relative_time.minutes": "{number}min", "relative_time.seconds": "{number}sek", "relative_time.today": "dnes", "reply_indicator.cancel": "Zrušiť", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Posuň ku {target}", "report.forward_hint": "Tento účet je z iného serveru. Chceš poslať anonymnú kópiu hlásenia aj tam?", "report.hint": "Toto nahlásenie bude zaslané správcom tvojho servera. Môžeš napísať odvôvodnenie, prečo nahlasuješ tento účet:", @@ -396,9 +407,14 @@ "status.delete": "Zmazať", "status.detailed_status": "Podrobný náhľad celej konverzácie", "status.direct": "Priama správa pre @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Vložiť", "status.favourite": "Páči sa mi", "status.filtered": "Filtrované", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Ukáž viac", "status.media_hidden": "Skryté médiá", "status.mention": "Spomeň @{name}", diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json index 0919fc3cd..212e9256c 100644 --- a/app/javascript/mastodon/locales/sl.json +++ b/app/javascript/mastodon/locales/sl.json @@ -1,28 +1,28 @@ { "account.account_note_header": "Opombe", - "account.add_or_remove_from_list": "Dodaj ali odstrani iz seznama", + "account.add_or_remove_from_list": "Dodaj ali odstrani s seznamov", "account.badges.bot": "Robot", - "account.badges.group": "Group", + "account.badges.group": "Skupina", "account.block": "Blokiraj @{name}", - "account.block_domain": "Skrij vse iz {domain}", + "account.block_domain": "Blokiraj domeno {domain}", "account.blocked": "Blokirano", - "account.browse_more_on_origin_server": "Browse more on the original profile", - "account.cancel_follow_request": "Cancel follow request", + "account.browse_more_on_origin_server": "Brskaj več po izvirnem profilu", + "account.cancel_follow_request": "Prekliči prošnjo za sledenje", "account.direct": "Neposredno sporočilo @{name}", - "account.disable_notifications": "Stop notifying me when @{name} posts", - "account.domain_blocked": "Skrita domena", + "account.disable_notifications": "Ne obveščaj me več, ko ima @{name} novo objavo", + "account.domain_blocked": "Blokirana domena", "account.edit_profile": "Uredi profil", - "account.enable_notifications": "Notify me when @{name} posts", - "account.endorse": "Zmožnost profila", + "account.enable_notifications": "Obvesti me, ko ima @{name} novo objavo", + "account.endorse": "Izpostavi v profilu", "account.follow": "Sledi", "account.followers": "Sledilci", "account.followers.empty": "Nihče ne sledi temu uporabniku.", - "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}", - "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}", + "account.followers_counter": "{count, plural, one {ima {count} sledilca} two {ima {count} sledilca} few {ima {count} sledilcev} other {ima {count} sledilce}}", + "account.following_counter": "{count, plural, one {sledi {count} osebi} two {sledi {count} osebama} few {sledi {count} osebam} other {sledi {count} osebam}}", "account.follows.empty": "Ta uporabnik še ne sledi nikomur.", - "account.follows_you": "Sledi tebi", + "account.follows_you": "Vam sledi", "account.hide_reblogs": "Skrij spodbude od @{name}", - "account.joined": "Joined {date}", + "account.joined": "Pridružen/a {date}", "account.last_status": "Zadnja dejavnost", "account.link_verified_on": "Lastništvo te povezave je bilo preverjeno {date}", "account.locked_info": "Stanje zasebnosti računa je nastavljeno na zaklenjeno. Lastnik ročno pregleda, kdo ga lahko spremlja.", @@ -47,17 +47,18 @@ "account.unmute": "Odtišaj @{name}", "account.unmute_notifications": "Vklopi obvestila od @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", - "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", - "alert.rate_limited.title": "Rate limited", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Povprečje", + "admin.dashboard.retention.cohort": "Mesec prijave", + "admin.dashboard.retention.cohort_size": "Novi uporabniki", + "alert.rate_limited.message": "Poskusite znova čez {retry_time, time, medium}.", + "alert.rate_limited.title": "Hitrost omejena", "alert.unexpected.message": "Zgodila se je nepričakovana napaka.", "alert.unexpected.title": "Uups!", - "announcement.announcement": "Announcement", - "attachments_list.unprocessed": "(unprocessed)", - "autosuggest_hashtag.per_week": "{count} per week", + "announcement.announcement": "Objava", + "attachments_list.unprocessed": "(neobdelano)", + "autosuggest_hashtag.per_week": "{count} na teden", "boost_modal.combo": "Če želite preskočiti to, lahko pritisnete {combo}", "bundle_column_error.body": "Med nalaganjem te komponente je prišlo do napake.", "bundle_column_error.retry": "Poskusi ponovno", @@ -66,10 +67,10 @@ "bundle_modal_error.message": "Med nalaganjem te komponente je prišlo do napake.", "bundle_modal_error.retry": "Poskusi ponovno", "column.blocks": "Blokirani uporabniki", - "column.bookmarks": "Bookmarks", + "column.bookmarks": "Zaznamki", "column.community": "Lokalna časovnica", "column.direct": "Neposredna sporočila", - "column.directory": "Browse profiles", + "column.directory": "Prebrskaj profile", "column.domain_blocks": "Skrite domene", "column.favourites": "Priljubljene", "column.follow_requests": "Sledi prošnjam", @@ -87,9 +88,9 @@ "column_header.show_settings": "Prikaži nastavitve", "column_header.unpin": "Odpni", "column_subheading.settings": "Nastavitve", - "community.column_settings.local_only": "Local only", + "community.column_settings.local_only": "Samo krajevno", "community.column_settings.media_only": "Samo mediji", - "community.column_settings.remote_only": "Remote only", + "community.column_settings.remote_only": "Samo oddaljeno", "compose_form.direct_message_warning": "Ta tut bo viden le vsem omenjenim uporabnikom.", "compose_form.direct_message_warning_learn_more": "Nauči se več", "compose_form.hashtag_warning": "Ta tut ne bo naveden pod nobenim ključnikom, ker ni javen. Samo javne tute lahko iščete s ključniki.", @@ -100,10 +101,11 @@ "compose_form.poll.duration": "Trajanje ankete", "compose_form.poll.option_placeholder": "Izbira {number}", "compose_form.poll.remove_option": "Odstrani to izbiro", - "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", - "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", + "compose_form.poll.switch_to_multiple": "Spremenite anketo, da omogočite več izbir", + "compose_form.poll.switch_to_single": "Spremenite anketo, da omogočite eno izbiro", "compose_form.publish": "Tutni", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Označi medij kot občutljiv", "compose_form.sensitive.marked": "Medij je označen kot občutljiv", "compose_form.sensitive.unmarked": "Medij ni označen kot občutljiv", @@ -118,14 +120,14 @@ "confirmations.delete.message": "Ali ste prepričani, da želite izbrisati to stanje?", "confirmations.delete_list.confirm": "Izbriši", "confirmations.delete_list.message": "Ali ste prepričani, da želite trajno izbrisati ta seznam?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Opusti", + "confirmations.discard_edit_media.message": "Imate ne shranjene spremembe za medijski opis ali predogled; jih želite kljub temu opustiti?", "confirmations.domain_block.confirm": "Skrij celotno domeno", "confirmations.domain_block.message": "Ali ste res, res prepričani, da želite blokirati celotno {domain}? V večini primerov je nekaj ciljnih blokiranj ali utišanj dovolj in boljše. Vsebino iz te domene ne boste videli v javnih časovnicah ali obvestilih. Vaši sledilci iz te domene bodo odstranjeni.", - "confirmations.logout.confirm": "Log out", - "confirmations.logout.message": "Are you sure you want to log out?", + "confirmations.logout.confirm": "Odjava", + "confirmations.logout.message": "Ali ste prepričani, da se želite odjaviti?", "confirmations.mute.confirm": "Utišanje", - "confirmations.mute.explanation": "This will hide posts from them and posts mentioning them, but it will still allow them to see your posts and follow you.", + "confirmations.mute.explanation": "S tem boste skrili objave pred njimi in objave, ki jih omenjajo, še vedno pa bodo lahko videli vaše objave in vam sledili.", "confirmations.mute.message": "Ali ste prepričani, da želite utišati {name}?", "confirmations.redraft.confirm": "Izbriši in preoblikuj", "confirmations.redraft.message": "Ali ste prepričani, da želite izbrisati ta status in ga preoblikovati? Vzljubi in spodbude bodo izgubljeni, odgovori na izvirno objavo pa bodo osiroteli.", @@ -133,14 +135,14 @@ "confirmations.reply.message": "Odgovarjanje bo prepisalo sporočilo, ki ga trenutno sestavljate. Ali ste prepričani, da želite nadaljevati?", "confirmations.unfollow.confirm": "Prenehaj slediti", "confirmations.unfollow.message": "Ali ste prepričani, da ne želite več slediti {name}?", - "conversation.delete": "Delete conversation", - "conversation.mark_as_read": "Mark as read", - "conversation.open": "View conversation", - "conversation.with": "With {names}", - "directory.federated": "From known fediverse", - "directory.local": "From {domain} only", - "directory.new_arrivals": "New arrivals", - "directory.recently_active": "Recently active", + "conversation.delete": "Izbriši pogovor", + "conversation.mark_as_read": "Označi kot prebrano", + "conversation.open": "Prikaži pogovor", + "conversation.with": "Z {names}", + "directory.federated": "Iz znanega fediverzuma", + "directory.local": "Samo iz {domain}", + "directory.new_arrivals": "Novi prišleki", + "directory.recently_active": "Nedavno aktiven/a", "embed.instructions": "Vstavi ta status na svojo spletno stran tako, da kopirate spodnjo kodo.", "embed.preview": "Tako bo izgledalo:", "emoji_button.activity": "Dejavnost", @@ -157,7 +159,7 @@ "emoji_button.search_results": "Rezultati iskanja", "emoji_button.symbols": "Simboli", "emoji_button.travel": "Potovanja in Kraji", - "empty_column.account_suspended": "Account suspended", + "empty_column.account_suspended": "Račun je suspendiran", "empty_column.account_timeline": "Tukaj ni tutov!", "empty_column.account_unavailable": "Profil ni na voljo", "empty_column.blocks": "Niste še blokirali nobenega uporabnika.", @@ -167,29 +169,29 @@ "empty_column.domain_blocks": "Še vedno ni skritih domen.", "empty_column.favourited_statuses": "Nimate priljubljenih tutov. Ko boste vzljubili kakšnega, se bo prikazal tukaj.", "empty_column.favourites": "Nihče še ni vzljubil tega tuta. Ko ga bo nekdo, se bo pojavil tukaj.", - "empty_column.follow_recommendations": "Looks like no suggestions could be generated for you. You can try using search to look for people you might know or explore trending hashtags.", + "empty_column.follow_recommendations": "Kaže, da za vas ni mogoče pripraviti nobenih predlogov. Poskusite uporabiti iskanje, da poiščete osebe, ki jih poznate, ali raziščete ključnike, ki so v trendu.", "empty_column.follow_requests": "Nimate prošenj za sledenje. Ko boste prejeli kakšno, se bo prikazala tukaj.", "empty_column.hashtag": "V tem ključniku še ni nič.", "empty_column.home": "Vaša domača časovnica je prazna! Obiščite {public} ali uporabite iskanje, da se boste srečali druge uporabnike.", - "empty_column.home.suggestions": "See some suggestions", + "empty_column.home.suggestions": "Oglejte si nekaj predlogov", "empty_column.list": "Na tem seznamu ni ničesar. Ko bodo člani tega seznama objavili nove statuse, se bodo pojavili tukaj.", "empty_column.lists": "Nimate seznamov. Ko ga boste ustvarili, se bo prikazal tukaj.", "empty_column.mutes": "Niste utišali še nobenega uporabnika.", "empty_column.notifications": "Nimate še nobenih obvestil. Povežite se z drugimi, da začnete pogovor.", "empty_column.public": "Tukaj ni ničesar! Da ga napolnite, napišite nekaj javnega ali pa ročno sledite uporabnikom iz drugih strežnikov", - "error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.", - "error.unexpected_crash.explanation_addons": "This page could not be displayed correctly. This error is likely caused by a browser add-on or automatic translation tools.", - "error.unexpected_crash.next_steps": "Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", - "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", - "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard", - "errors.unexpected_crash.report_issue": "Report issue", - "follow_recommendations.done": "Done", - "follow_recommendations.heading": "Follow people you'd like to see posts from! Here are some suggestions.", - "follow_recommendations.lead": "Posts from people you follow will show up in chronological order on your home feed. Don't be afraid to make mistakes, you can unfollow people just as easily any time!", + "error.unexpected_crash.explanation": "Zaradi hrošča v naši kodi ali težave z združljivostjo brskalnika te strani ni mogoče ustrezno prikazati.", + "error.unexpected_crash.explanation_addons": "Te strani ni mogoče ustrezno prikazati. To napako najverjetneje povzroča dodatek briskalnika ali samodejna orodja za prevajanje.", + "error.unexpected_crash.next_steps": "Poskusite osvežiti stran. Če to ne pomaga, boste morda še vedno lahko uporabljali Mastodon prek drugega brskalnika ali z domorodno aplikacijo.", + "error.unexpected_crash.next_steps_addons": "Poskusite jih onemogočiti in osvežiti stran. Če to ne pomaga, boste morda še vedno lahko uporabljali Mastodon prek drugega brskalnika ali z domorodno aplikacijo.", + "errors.unexpected_crash.copy_stacktrace": "Kopiraj sledenje sklada na odložišče", + "errors.unexpected_crash.report_issue": "Prijavi težavo", + "follow_recommendations.done": "Opravljeno", + "follow_recommendations.heading": "Sledite osebam, katerih objave želite videti! Tukaj je nekaj predlogov.", + "follow_recommendations.lead": "Objave oseb, ki jim sledite, se bodo prikazale v kronološkem zaporedju v vašem domačem viru. Ne bojte se storiti napake, osebam enako enostavno nehate slediti kadar koli!", "follow_request.authorize": "Overi", "follow_request.reject": "Zavrni", - "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.", - "generic.saved": "Saved", + "follow_requests.unlocked_explanation": "Čeprav vaš račun ni zaklenjen, zaposleni pri {domain} menijo, da bi morda želeli pregledati zahteve za sledenje teh računov ročno.", + "generic.saved": "Shranjeno", "getting_started.developers": "Razvijalci", "getting_started.directory": "Imenik profilov", "getting_started.documentation": "Dokumentacija", @@ -210,8 +212,8 @@ "home.column_settings.basic": "Osnovno", "home.column_settings.show_reblogs": "Pokaži spodbude", "home.column_settings.show_replies": "Pokaži odgovore", - "home.hide_announcements": "Hide announcements", - "home.show_announcements": "Show announcements", + "home.hide_announcements": "Skrij objave", + "home.show_announcements": "Prikaži objave", "intervals.full.days": "{number, plural, one {# dan} two {# dni} few {# dni} other {# dni}}", "intervals.full.hours": "{number, plural, one {# ura} two {# uri} few {# ure} other {# ur}}", "intervals.full.minutes": "{number, plural, one {# minuta} two {# minuti} few {# minute} other {# minut}}", @@ -250,8 +252,8 @@ "keyboard_shortcuts.unfocus": "odfokusiraj območje za sestavljanje besedila/iskanje", "keyboard_shortcuts.up": "premakni se navzgor po seznamu", "lightbox.close": "Zapri", - "lightbox.compress": "Compress image view box", - "lightbox.expand": "Expand image view box", + "lightbox.compress": "Strni ogledno polje slike", + "lightbox.expand": "Razširi ogledno polje slike", "lightbox.next": "Naslednji", "lightbox.previous": "Prejšnji", "lists.account.add": "Dodaj na seznam", @@ -261,10 +263,10 @@ "lists.edit.submit": "Spremeni naslov", "lists.new.create": "Dodaj seznam", "lists.new.title_placeholder": "Nov naslov seznama", - "lists.replies_policy.followed": "Any followed user", - "lists.replies_policy.list": "Members of the list", - "lists.replies_policy.none": "No one", - "lists.replies_policy.title": "Show replies to:", + "lists.replies_policy.followed": "Vsem sledenim uporabnikom", + "lists.replies_policy.list": "Članom seznama", + "lists.replies_policy.none": "Nikomur", + "lists.replies_policy.title": "Pokaži odgovore:", "lists.search": "Išči med ljudmi, katerim sledite", "lists.subheading": "Vaši seznami", "load_pending": "{count, plural, one {# nov element} other {# novih elementov}}", @@ -272,12 +274,12 @@ "media_gallery.toggle_visible": "Preklopi vidljivost", "missing_indicator.label": "Ni najdeno", "missing_indicator.sublabel": "Tega vira ni bilo mogoče najti", - "mute_modal.duration": "Duration", + "mute_modal.duration": "Trajanje", "mute_modal.hide_notifications": "Skrij obvestila tega uporabnika?", - "mute_modal.indefinite": "Indefinite", + "mute_modal.indefinite": "Nedoločeno", "navigation_bar.apps": "Mobilne aplikacije", "navigation_bar.blocks": "Blokirani uporabniki", - "navigation_bar.bookmarks": "Bookmarks", + "navigation_bar.bookmarks": "Zaznamki", "navigation_bar.community_timeline": "Lokalna časovnica", "navigation_bar.compose": "Sestavi nov tut", "navigation_bar.direct": "Neposredna sporočila", @@ -300,21 +302,21 @@ "navigation_bar.security": "Varnost", "notification.favourite": "{name} je vzljubil/a vaš status", "notification.follow": "{name} vam sledi", - "notification.follow_request": "{name} has requested to follow you", + "notification.follow_request": "{name} vam želi slediti", "notification.mention": "{name} vas je omenil/a", - "notification.own_poll": "Your poll has ended", + "notification.own_poll": "Vaša anketa se je končala", "notification.poll": "Glasovanje, v katerem ste sodelovali, se je končalo", "notification.reblog": "{name} je spodbudil/a vaš status", - "notification.status": "{name} just posted", + "notification.status": "{name} je pravkar objavil/a", "notifications.clear": "Počisti obvestila", "notifications.clear_confirmation": "Ali ste prepričani, da želite trajno izbrisati vsa vaša obvestila?", "notifications.column_settings.alert": "Namizna obvestila", "notifications.column_settings.favourite": "Priljubljeni:", "notifications.column_settings.filter_bar.advanced": "Prikaži vse kategorije", "notifications.column_settings.filter_bar.category": "Vrstica za hitro filtriranje", - "notifications.column_settings.filter_bar.show": "Pokaži", + "notifications.column_settings.filter_bar.show_bar": "Pokaži vrstico s filtri", "notifications.column_settings.follow": "Novi sledilci:", - "notifications.column_settings.follow_request": "New follow requests:", + "notifications.column_settings.follow_request": "Nove prošnje za sledenje:", "notifications.column_settings.mention": "Omembe:", "notifications.column_settings.poll": "Rezultati glasovanja:", "notifications.column_settings.push": "Potisna obvestila", @@ -322,31 +324,32 @@ "notifications.column_settings.show": "Prikaži v stolpcu", "notifications.column_settings.sound": "Predvajaj zvok", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Neprebrana obvestila", + "notifications.column_settings.unread_notifications.highlight": "Poudari neprebrana obvestila", "notifications.filter.all": "Vse", "notifications.filter.boosts": "Spodbude", "notifications.filter.favourites": "Priljubljeni", "notifications.filter.follows": "Sledi", "notifications.filter.mentions": "Omembe", "notifications.filter.polls": "Rezultati glasovanj", - "notifications.filter.statuses": "Updates from people you follow", - "notifications.grant_permission": "Grant permission.", + "notifications.filter.statuses": "Posodobitve pri osebah, ki jih spremljate", + "notifications.grant_permission": "Dovoli.", "notifications.group": "{count} obvestil", - "notifications.mark_as_read": "Mark every notification as read", - "notifications.permission_denied": "Desktop notifications are unavailable due to previously denied browser permissions request", - "notifications.permission_denied_alert": "Desktop notifications can't be enabled, as browser permission has been denied before", - "notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.", - "notifications_permission_banner.enable": "Enable desktop notifications", - "notifications_permission_banner.how_to_control": "To receive notifications when Mastodon isn't open, enable desktop notifications. You can control precisely which types of interactions generate desktop notifications through the {icon} button above once they're enabled.", - "notifications_permission_banner.title": "Never miss a thing", - "picture_in_picture.restore": "Put it back", + "notifications.mark_as_read": "Vsa obvestila ozači kot prebrana", + "notifications.permission_denied": "Namizna obvestila niso na voljo zaradi poprej zavrnjene zahteve dovoljenja brskalnika.", + "notifications.permission_denied_alert": "Namiznih obvestil ni mogoče omogočiti, ker je bilo dovoljenje brskalnika že prej zavrnjeno", + "notifications.permission_required": "Namizna obvestila niso na voljo, ker zahtevano dovoljenje ni bilo podeljeno.", + "notifications_permission_banner.enable": "Omogoči obvestila na namizju", + "notifications_permission_banner.how_to_control": "Če želite prejemati obvestila, ko Mastodon ni odprt, omogočite namizna obvestila. Natančno lahko nadzirate, katere vrste interakcij naj tvorijo namizna obvestila; ko so omogočena, za to uporabite gumb {icon} zgoraj.", + "notifications_permission_banner.title": "Nikoli ne zamudite ničesar", + "picture_in_picture.restore": "Postavi nazaj", "poll.closed": "Zaprto", "poll.refresh": "Osveži", - "poll.total_people": "{count, plural, one {# person} other {# people}}", + "poll.total_people": "{count, plural, one {# oseba} two {# osebi} few {# osebe} other {# oseb}}", "poll.total_votes": "{count, plural,one {# glas} other {# glasov}}", "poll.vote": "Glasuj", - "poll.voted": "You voted for this answer", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.voted": "Glasovali ste za ta odgovor", + "poll.votes": "{votes, plural, one {# glas} two {# glasova} few {# glasovi} other {# glasov}}", "poll_button.add_poll": "Dodaj anketo", "poll_button.remove_poll": "Odstrani anketo", "privacy.change": "Prilagodi zasebnost statusa", @@ -358,16 +361,24 @@ "privacy.public.short": "Javno", "privacy.unlisted.long": "Ne objavi na javne časovnice", "privacy.unlisted.short": "Ni prikazano", - "refresh": "Refresh", + "refresh": "Osveži", "regeneration_indicator.label": "Nalaganje…", "regeneration_indicator.sublabel": "Vaš domači vir se pripravlja!", "relative_time.days": "{number}d", - "relative_time.hours": "{number}h", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", + "relative_time.hours": "{number}u", "relative_time.just_now": "zdaj", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "danes", "reply_indicator.cancel": "Prekliči", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Posreduj do {target}", "report.forward_hint": "Račun je iz drugega strežnika. Pošljem anonimno kopijo poročila tudi na drugi strežnik?", "report.hint": "Poročilo bo poslano moderatorjem vašega vozlišča. Spodaj lahko navedete, zakaj prijavljate ta račun:", @@ -389,16 +400,21 @@ "status.admin_account": "Odpri vmesnik za moderiranje za @{name}", "status.admin_status": "Odpri status v vmesniku za moderiranje", "status.block": "Blokiraj @{name}", - "status.bookmark": "Bookmark", + "status.bookmark": "Dodaj med zaznamke", "status.cancel_reblog_private": "Prekini spodbudo", "status.cannot_reblog": "Te objave ni mogoče spodbuditi", "status.copy": "Kopiraj povezavo do statusa", "status.delete": "Izbriši", "status.detailed_status": "Podroben pogled pogovora", "status.direct": "Neposredno sporočilo @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Vgradi", "status.favourite": "Priljubljen", "status.filtered": "Filtrirano", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Naloži več", "status.media_hidden": "Mediji so skriti", "status.mention": "Omeni @{name}", @@ -414,7 +430,7 @@ "status.reblogged_by": "{name} spodbuja", "status.reblogs.empty": "Nihče še ni spodbudil tega tuta. Ko se bo to zgodilo, se bodo pojavili tukaj.", "status.redraft": "Izbriši in preoblikuj", - "status.remove_bookmark": "Remove bookmark", + "status.remove_bookmark": "Odstrani zaznamek", "status.reply": "Odgovori", "status.replyAll": "Odgovori na objavo", "status.report": "Prijavi @{name}", @@ -425,7 +441,7 @@ "status.show_more": "Prikaži več", "status.show_more_all": "Prikaži več za vse", "status.show_thread": "Prikaži objavo", - "status.uncached_media_warning": "Not available", + "status.uncached_media_warning": "Ni na voljo", "status.unmute_conversation": "Odtišaj pogovor", "status.unpin": "Odpni iz profila", "suggestions.dismiss": "Zavrni predlog", @@ -440,39 +456,39 @@ "time_remaining.minutes": "{number, plural, one {# minuta} other {# minut}} je ostalo", "time_remaining.moments": "Preostali trenutki", "time_remaining.seconds": "{number, plural, one {# sekunda} other {# sekund}} je ostalo", - "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.", - "timeline_hint.resources.followers": "Followers", - "timeline_hint.resources.follows": "Follows", + "timeline_hint.remote_resource_not_displayed": "{resource} z drugih strežnikov ni prikazano.", + "timeline_hint.resources.followers": "sledilcev", + "timeline_hint.resources.follows": "Sledi", "timeline_hint.resources.statuses": "Older toots", - "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking", - "trends.trending_now": "Trending now", + "trends.counter_by_accounts": "{count, plural, one {{count} oseba govori} two {{count} osebi govorita} few {{count} osebe govorijo} other {{count} oseb govori}}", + "trends.trending_now": "Zdaj v trendu", "ui.beforeunload": "Vaš osnutek bo izgubljen, če zapustite Mastodona.", - "units.short.billion": "{count}B", - "units.short.million": "{count}M", - "units.short.thousand": "{count}K", + "units.short.billion": "{count} milijard", + "units.short.million": "{count} mio.", + "units.short.thousand": "{count} tisoč", "upload_area.title": "Za pošiljanje povlecite in spustite", "upload_button.label": "Dodaj medije", "upload_error.limit": "Omejitev prenosa datoteke je presežena.", "upload_error.poll": "Prenos datoteke z anketami ni dovoljen.", - "upload_form.audio_description": "Describe for people with hearing loss", + "upload_form.audio_description": "Opiši za osebe z okvaro sluha", "upload_form.description": "Opišite za slabovidne", - "upload_form.edit": "Edit", - "upload_form.thumbnail": "Change thumbnail", + "upload_form.edit": "Uredi", + "upload_form.thumbnail": "Spremeni sličico", "upload_form.undo": "Izbriši", - "upload_form.video_description": "Describe for people with hearing loss or visual impairment", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", - "upload_modal.applying": "Applying…", - "upload_modal.choose_image": "Choose image", + "upload_form.video_description": "Opiši za osebe z okvaro sluha in/ali vida", + "upload_modal.analyzing_picture": "Analiziranje slike …", + "upload_modal.apply": "Uveljavi", + "upload_modal.applying": "Uveljavljanje poteka …", + "upload_modal.choose_image": "Izberite sliko", "upload_modal.description_placeholder": "Pri Jakcu bom vzel šest čudežnih fig", - "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", - "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preparing_ocr": "Preparing OCR…", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.detect_text": "Zaznaj besedilo s slike", + "upload_modal.edit_media": "Uredi medij", + "upload_modal.hint": "Kliknite ali povlecite krog v predogledu, da izberete točko pozornosti, ki bo vedno vidna na vseh oglednih sličicah.", + "upload_modal.preparing_ocr": "Priprava optične prepoznave znakov (OCR) ...", + "upload_modal.preview_label": "Predogled ({ratio})", "upload_progress.label": "Pošiljanje...", "video.close": "Zapri video", - "video.download": "Download file", + "video.download": "Prenesi datoteko", "video.exit_fullscreen": "Izhod iz celozaslonskega načina", "video.expand": "Razširi video", "video.fullscreen": "Celozaslonski način", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 062b566d0..2a9a12e17 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -47,16 +47,17 @@ "account.unmute": "Ktheji zërin @{name}", "account.unmute_notifications": "Hiqua ndalimin e shfaqjes njoftimeve nga @{name}", "account_note.placeholder": "Klikoni për të shtuar shënim", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Mesatare", + "admin.dashboard.retention.cohort": "Muaj regjistrimi", + "admin.dashboard.retention.cohort_size": "Përdorues të rinj", "alert.rate_limited.message": "Ju lutemi, riprovoni pas {retry_time, time, medium}.", "alert.rate_limited.title": "Shpejtësi e kufizuar", "alert.unexpected.message": "Ndodhi një gabim të papritur.", "alert.unexpected.title": "Hëm!", "announcement.announcement": "Lajmërim", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(e papërpunuar)", "autosuggest_hashtag.per_week": "{count} për javë", "boost_modal.combo": "Që kjo të anashkalohet herës tjetër, mund të shtypni {combo}", "bundle_column_error.body": "Diç shkoi ters teksa ngarkohej ky përbërës.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Ndrysho votimin për të lejuar vetëm një zgjedhje", "compose_form.publish": "Mesazh", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Vëri shenjë medias si rezervat} other {Vëru shenjë mediave si rezervat}}", "compose_form.sensitive.marked": "{count, plural, one {Medias i është vënë shenjë rezervat} other {Mediave u është vënë shenjë si rezervat}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media s’ka shenjë si rezervat} other {Mediat s’kanë shenja si rezervat}}", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Jeni i sigurt se doni të fshihet kjo gjendje?", "confirmations.delete_list.confirm": "Fshije", "confirmations.delete_list.message": "Jeni i sigurt se doni të fshihet përgjithmonë kjo listë?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Hidhe tej", + "confirmations.discard_edit_media.message": "Keni ndryshime të paruajtura te përshkrimi ose paraparja e medias, të hidhen tej, sido qoftë?", "confirmations.domain_block.confirm": "Bllokoje krejt përkatësinë", "confirmations.domain_block.message": "Jeni i sigurt, shumë i sigurt se doni të bllokohet krejt {domain}? Në shumicën e rasteve, ndoca bllokime ose heshtime me synim të caktuar janë të mjaftueshme dhe të parapëlqyera. S’keni për të parë lëndë nga kjo përkatësi në ndonjë rrjedhë kohore publike, apo te njoftimet tuaja. Ndjekësit tuaj prej asaj përkatësie do të hiqen.", "confirmations.logout.confirm": "Dilni", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Të parapëlqyer:", "notifications.column_settings.filter_bar.advanced": "Shfaq krejt kategoritë", "notifications.column_settings.filter_bar.category": "Shtyllë filtrimesh të shpejta", - "notifications.column_settings.filter_bar.show": "Shfaq", + "notifications.column_settings.filter_bar.show_bar": "Shfaq shtyllë filtrash", "notifications.column_settings.follow": "Ndjekës të rinj:", "notifications.column_settings.follow_request": "Kërkesa të reja për ndjekje:", "notifications.column_settings.mention": "Përmendje:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Shfaqi në shtylla", "notifications.column_settings.sound": "Luaj një tingull", "notifications.column_settings.status": "Mesazhe të rinj:", - "notifications.column_settings.unread_markers.category": "Shenja njoftimesh të palexuara", + "notifications.column_settings.unread_notifications.category": "Njoftime të palexuara", + "notifications.column_settings.unread_notifications.highlight": "Theksoji njoftimet e palexuara", "notifications.filter.all": "Krejt", "notifications.filter.boosts": "Përforcime", "notifications.filter.favourites": "Të parapëlqyer", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural,one {# votë }other {# vota }}", "poll.vote": "Votoni", "poll.voted": "Votuat për këtë përgjigje", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# votë} other {# vota}}", "poll_button.add_poll": "Shtoni një pyetësor", "poll_button.remove_poll": "Hiqe pyetësorin", "privacy.change": "Rregulloni privatësi mesazhesh", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Po ngarkohet…", "regeneration_indicator.sublabel": "Prurja juaj vetjake po përgatitet!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}o", "relative_time.just_now": "tani", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "sot", "reply_indicator.cancel": "Anuloje", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Përcillja {target}", "report.forward_hint": "Llogaria është nga një shërbyes tjetër. Të dërgohet edhe një kopje e anonimizuar e raportimit?", "report.hint": "Raportimi do t’u dërgohet moderatorëve të shërbyesit tuaj. Më poshtë mund të jepni një shpjegim se pse po e raportoni këtë llogari:", @@ -396,9 +407,14 @@ "status.delete": "Fshije", "status.detailed_status": "Pamje e hollësishme bisede", "status.direct": "Mesazh i drejtpërdrejtë për @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Trupëzim", "status.favourite": "I parapëlqyer", "status.filtered": "I filtruar", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Ngarko më tepër", "status.media_hidden": "Me media të fshehur", "status.mention": "Përmendni @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Përshkruajeni për persona me dëgjim të kufizuar ose probleme shikimi", "upload_modal.analyzing_picture": "Po analizohet fotoja…", "upload_modal.apply": "Aplikoje", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Po zbatohet…", "upload_modal.choose_image": "Zgjidhni figurë", "upload_modal.description_placeholder": "Deshe Korçën, Korçën të dhamë", "upload_modal.detect_text": "Pikase tekstin prej fotoje", diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json index 3e29734ef..c12cad908 100644 --- a/app/javascript/mastodon/locales/sr-Latn.json +++ b/app/javascript/mastodon/locales/sr-Latn.json @@ -47,7 +47,8 @@ "account.unmute": "Ukloni ućutkavanje korisniku @{name}", "account.unmute_notifications": "Uključi nazad obaveštenja od korisnika @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Tutni", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Omiljeni:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Novi pratioci:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Pominjanja:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Prikaži u koloni", "notifications.column_settings.sound": "Puštaj zvuk", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "sada", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "Poništi", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Obriši", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Ugradi na sajt", "status.favourite": "Omiljeno", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Učitaj još", "status.media_hidden": "Multimedija sakrivena", "status.mention": "Pomeni korisnika @{name}", diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json index ba822e15d..fb94b0098 100644 --- a/app/javascript/mastodon/locales/sr.json +++ b/app/javascript/mastodon/locales/sr.json @@ -47,7 +47,8 @@ "account.unmute": "Уклони ућуткавање кориснику @{name}", "account.unmute_notifications": "Укључи назад обавештења од корисника @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Промените анкету да бисте омогућили један избор", "compose_form.publish": "Труби", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Означи мултимедију као осетљиву", "compose_form.sensitive.marked": "Медији су означени као осетљиви", "compose_form.sensitive.unmarked": "Медији су означени као не-осетљиви", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Омиљени:", "notifications.column_settings.filter_bar.advanced": "Прикажи све категорије", "notifications.column_settings.filter_bar.category": "Трака за брзи филтер", - "notifications.column_settings.filter_bar.show": "Прикажи", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "Нови пратиоци:", "notifications.column_settings.follow_request": "Нови захтеви за праћење:", "notifications.column_settings.mention": "Помињања:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Прикажи у колони", "notifications.column_settings.sound": "Пуштај звук", "notifications.column_settings.status": "Нови тутови:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Све", "notifications.filter.boosts": "Подршки", "notifications.filter.favourites": "Омиљене", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Учитавање…", "regeneration_indicator.sublabel": "Ваша почетна страница се припрема!", "relative_time.days": "{number}д", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}х", "relative_time.just_now": "сада", "relative_time.minutes": "{number}м", "relative_time.seconds": "{number}с", "relative_time.today": "данас", "reply_indicator.cancel": "Поништи", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Проследити {target}", "report.forward_hint": "Налог је са другог сервера. Послати анонимну копију пријаве и тамо?", "report.hint": "Пријава ће бити послата модераторима ваше инстанце. Можете додати објашњење зашто пријављујете овај налог у наставку:", @@ -396,9 +407,14 @@ "status.delete": "Обриши", "status.detailed_status": "Детаљни преглед разговора", "status.direct": "Директна порука @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Угради на сајт", "status.favourite": "Омиљено", "status.filtered": "Филтрирано", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Учитај још", "status.media_hidden": "Мултимедија сакривена", "status.mention": "Помени корисника @{name}", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index f80d1ce0e..47d70fb54 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -47,16 +47,17 @@ "account.unmute": "Sluta tysta @{name}", "account.unmute_notifications": "Återaktivera aviseringar från @{name}", "account_note.placeholder": "Klicka för att lägga till anteckning", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Genomsnittlig", + "admin.dashboard.retention.cohort": "Registreringsmånad", + "admin.dashboard.retention.cohort_size": "Nya användare", "alert.rate_limited.message": "Vänligen försök igen efter {retry_time, time, medium}.", "alert.rate_limited.title": "Mängd begränsad", "alert.unexpected.message": "Ett oväntat fel uppstod.", "alert.unexpected.title": "Hoppsan!", "announcement.announcement": "Meddelande", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(obearbetad)", "autosuggest_hashtag.per_week": "{count} per vecka", "boost_modal.combo": "Du kan trycka {combo} för att slippa detta nästa gång", "bundle_column_error.body": "Något gick fel medan denna komponent laddades.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Ändra enkät för att tillåta ett enda val", "compose_form.publish": "Tut", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "Markera media som känsligt", "compose_form.sensitive.marked": "Media har markerats som känsligt", "compose_form.sensitive.unmarked": "Media är inte markerat som känsligt", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Är du säker på att du vill radera denna status?", "confirmations.delete_list.confirm": "Radera", "confirmations.delete_list.message": "Är du säker på att du vill radera denna lista permanent?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Kasta", + "confirmations.discard_edit_media.message": "Du har o-sparade ändringar till mediabeskrivningen eller förhandsgranskningen, kasta bort dem ändå?", "confirmations.domain_block.confirm": "Dölj hela domänen", "confirmations.domain_block.message": "Är du verkligen, verkligen säker på att du vill blockera hela {domain}? I de flesta fall är några riktade blockeringar eller nedtystade konton tillräckligt och att föredra. Du kommer inte se innehåll från den domänen i den allmänna tidslinjen eller i dina aviseringar. Dina följare från den domänen komer att tas bort.", "confirmations.logout.confirm": "Logga ut", @@ -167,7 +169,7 @@ "empty_column.domain_blocks": "Det finns ännu inga dolda domäner.", "empty_column.favourited_statuses": "Du har inga favoritmarkerade toots än. När du favoritmarkerar en kommer den visas här.", "empty_column.favourites": "Ingen har favoritmarkerat den här tooten än. När någon gör det kommer den visas här.", - "empty_column.follow_recommendations": "Looks like no suggestions could be generated for you. You can try using search to look for people you might know or explore trending hashtags.", + "empty_column.follow_recommendations": "Det ser ut som om inga förslag kan genereras till dig. Du kan prova att använda sök för att leta efter personer som du kanske känner eller utforska trendande hash-taggar.", "empty_column.follow_requests": "Du har inga följarförfrågningar än. När du får en kommer den visas här.", "empty_column.hashtag": "Det finns inget i denna hashtag ännu.", "empty_column.home": "Din hemma-tidslinje är tom! Besök {public} eller använd sökning för att komma igång och träffa andra användare.", @@ -184,8 +186,8 @@ "errors.unexpected_crash.copy_stacktrace": "Kopiera stacktrace till urklipp", "errors.unexpected_crash.report_issue": "Rapportera problem", "follow_recommendations.done": "Klar", - "follow_recommendations.heading": "Follow people you'd like to see posts from! Here are some suggestions.", - "follow_recommendations.lead": "Posts from people you follow will show up in chronological order on your home feed. Don't be afraid to make mistakes, you can unfollow people just as easily any time!", + "follow_recommendations.heading": "Följ personer som du skulle vilja se inlägg från! Här finns det några förslag.", + "follow_recommendations.lead": "Inlägg från personer du följer kommer att dyka upp i kronologisk ordning i ditt hem-flöde. Var inte rädd för att göra misstag, du kan sluta följa människor lika enkelt när som helst!", "follow_request.authorize": "Godkänn", "follow_request.reject": "Avvisa", "follow_requests.unlocked_explanation": "Även om ditt konto inte är låst tror {domain} personalen att du kanske vill granska dessa följares förfrågningar manuellt.", @@ -250,8 +252,8 @@ "keyboard_shortcuts.unfocus": "för att avfokusera skrivfält/sökfält", "keyboard_shortcuts.up": "för att flytta uppåt i listan", "lightbox.close": "Stäng", - "lightbox.compress": "Compress image view box", - "lightbox.expand": "Expand image view box", + "lightbox.compress": "Komprimera bildvyrutan", + "lightbox.expand": "Utöka bildvyrutan", "lightbox.next": "Nästa", "lightbox.previous": "Tidigare", "lists.account.add": "Lägg till i lista", @@ -261,7 +263,7 @@ "lists.edit.submit": "Ändra titel", "lists.new.create": "Lägg till lista", "lists.new.title_placeholder": "Ny listrubrik", - "lists.replies_policy.followed": "Any followed user", + "lists.replies_policy.followed": "Alla användare som följs", "lists.replies_policy.list": "Medlemmar i listan", "lists.replies_policy.none": "Ingen", "lists.replies_policy.title": "Visa svar till:", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favoriter:", "notifications.column_settings.filter_bar.advanced": "Visa alla kategorier", "notifications.column_settings.filter_bar.category": "Snabbfilter", - "notifications.column_settings.filter_bar.show": "Visa", + "notifications.column_settings.filter_bar.show_bar": "Visa filterfält", "notifications.column_settings.follow": "Nya följare:", "notifications.column_settings.follow_request": "Ny följ-förfrågan:", "notifications.column_settings.mention": "Omnämningar:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Visa i kolumnen", "notifications.column_settings.sound": "Spela upp ljud", "notifications.column_settings.status": "Nya tutor:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "O-lästa aviseringar", + "notifications.column_settings.unread_notifications.highlight": "Markera o-lästa aviseringar", "notifications.filter.all": "Alla", "notifications.filter.boosts": "Knuffar", "notifications.filter.favourites": "Favoriter", @@ -333,9 +336,9 @@ "notifications.grant_permission": "Godkänn åtkomst.", "notifications.group": "{count} aviseringar", "notifications.mark_as_read": "Markera varje avisering som läst", - "notifications.permission_denied": "Desktop notifications are unavailable due to previously denied browser permissions request", - "notifications.permission_denied_alert": "Desktop notifications can't be enabled, as browser permission has been denied before", - "notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.", + "notifications.permission_denied": "Skrivbordsaviseringar är otillgängliga på grund av tidigare nekade förfrågningar om behörighet i webbläsaren", + "notifications.permission_denied_alert": "Skrivbordsaviseringar kan inte aktiveras, eftersom att webbläsarens behörighet har nekats innan", + "notifications.permission_required": "Skrivbordsaviseringar är otillgängliga eftersom att rättigheten som krävs inte har godkänts.", "notifications_permission_banner.enable": "Aktivera skrivbordsaviseringar", "notifications_permission_banner.how_to_control": "För att ta emot aviseringar när Mastodon inte är öppet, aktivera skrivbordsaviseringar. När de är aktiverade kan du styra exakt vilka typer av interaktioner som aviseras via {icon} -knappen ovan.", "notifications_permission_banner.title": "Missa aldrig något", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {1 röst} other {# röster}}", "poll.vote": "Rösta", "poll.voted": "Du röstade för detta svar", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# röst} other {# röster}}", "poll_button.add_poll": "Lägg till en omröstning", "poll_button.remove_poll": "Ta bort omröstning", "privacy.change": "Justera sekretess", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Laddar…", "regeneration_indicator.sublabel": "Ditt hemmaflöde förbereds!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}tim", "relative_time.just_now": "nu", "relative_time.minutes": "{number}min", "relative_time.seconds": "{number}sek", "relative_time.today": "idag", "reply_indicator.cancel": "Ångra", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Vidarebefordra till {target}", "report.forward_hint": "Kontot är från en annan server. Skicka även en anonymiserad kopia av anmälan dit?", "report.hint": "Anmälan skickas till din instans moderatorer. Du kan ge en förklaring till varför du har anmält detta konto nedan:", @@ -396,9 +407,14 @@ "status.delete": "Radera", "status.detailed_status": "Detaljerad samtalsvy", "status.direct": "Direktmeddela @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Bädda in", "status.favourite": "Favorit", "status.filtered": "Filtrerat", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Ladda fler", "status.media_hidden": "Media dold", "status.mention": "Omnämn @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Beskriv för personer med hörsel- eller synnedsättning", "upload_modal.analyzing_picture": "Analyserar bild…", "upload_modal.apply": "Verkställ", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Verkställer…", "upload_modal.choose_image": "Välj bild", "upload_modal.description_placeholder": "En snabb brun räv hoppar över den lata hunden", "upload_modal.detect_text": "Upptäck bildens text", diff --git a/app/javascript/mastodon/locales/szl.json b/app/javascript/mastodon/locales/szl.json index eca4765c4..2675da68c 100644 --- a/app/javascript/mastodon/locales/szl.json +++ b/app/javascript/mastodon/locales/szl.json @@ -47,7 +47,8 @@ "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Show in column", "notifications.column_settings.sound": "Play sound", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "Cancel", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Load more", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/ta.json b/app/javascript/mastodon/locales/ta.json index 1b3e70fb6..2e329f270 100644 --- a/app/javascript/mastodon/locales/ta.json +++ b/app/javascript/mastodon/locales/ta.json @@ -47,7 +47,8 @@ "account.unmute": "@{name} இன் மீது மௌனத் தடையை நீக்குக", "account.unmute_notifications": "@{name} இலிருந்து அறிவிப்புகளின் மீது மௌனத் தடையை நீக்குக", "account_note.placeholder": "குறிப்பு ஒன்றை சேர்க்க சொடுக்கவும்", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "ஒரே ஒரு தேர்வை மட்டும் அனுமதிக்குமாறு மாற்று", "compose_form.publish": "டூட்", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "அனைவருக்கும் ஏற்றப் படம் இல்லை எனக் குறியிடு", "compose_form.sensitive.marked": "இப்படம் அனைவருக்கும் ஏற்றதல்ல எனக் குறியிடப்பட்டுள்ளது", "compose_form.sensitive.unmarked": "இப்படம் அனைவருக்கும் ஏற்றதல்ல எனக் குறியிடப்படவில்லை", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "பிடித்தவை:", "notifications.column_settings.filter_bar.advanced": "எல்லா வகைகளையும் காட்டு", "notifications.column_settings.filter_bar.category": "விரைவு வடிகட்டி பட்டை", - "notifications.column_settings.filter_bar.show": "காட்டு", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "புதிய பின்பற்றுபவர்கள்:", "notifications.column_settings.follow_request": "புதிய பின்தொடர் கோரிக்கைகள்:", "notifications.column_settings.mention": "குறிப்பிடுகிறது:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "பத்தியில் காண்பி", "notifications.column_settings.sound": "ஒலி விளையாட", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "எல்லா", "notifications.filter.boosts": "மதிப்பை உயர்த்து", "notifications.filter.favourites": "விருப்பத்துக்குகந்த", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "சுமையேற்றம்…", "regeneration_indicator.sublabel": "உங்கள் வீட்டு ஊட்டம் தயார் செய்யப்படுகிறது!", "relative_time.days": "{number}நா", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}ம", "relative_time.just_now": "இப்பொழுது", "relative_time.minutes": "{number}நி", "relative_time.seconds": "{number}வி", "relative_time.today": "இன்று", "reply_indicator.cancel": "எதிராணை", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "முன்னோக்கி {target}", "report.forward_hint": "கணக்கு மற்றொரு சேவையகத்திலிருந்து வருகிறது. அறிக்கையின் அநாமதேய பிரதி ஒன்றை அனுப்பவும்.?", "report.hint": "அறிக்கை உங்கள் மாதிரியாக மாற்றியமைக்கப்படும். கீழே உள்ள கணக்கை நீங்கள் ஏன் புகாரளிக்கிறீர்கள் என்பதற்கான விளக்கத்தை வழங்கலாம்:", @@ -396,9 +407,14 @@ "status.delete": "நீக்கு", "status.detailed_status": "விரிவான உரையாடல் காட்சி", "status.direct": "நேரடி செய்தி @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "கிடத்து", "status.favourite": "விருப்பத்துக்குகந்த", "status.filtered": "வடிகட்டு", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "அதிகமாய் ஏற்று", "status.media_hidden": "மீடியா மறைக்கப்பட்டது", "status.mention": "குறிப்பிடு @{name}", diff --git a/app/javascript/mastodon/locales/tai.json b/app/javascript/mastodon/locales/tai.json index 2302e7ccc..6ef519315 100644 --- a/app/javascript/mastodon/locales/tai.json +++ b/app/javascript/mastodon/locales/tai.json @@ -47,7 +47,8 @@ "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Show in column", "notifications.column_settings.sound": "Play sound", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "Cancel", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Load more", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/te.json b/app/javascript/mastodon/locales/te.json index 348d753dc..b84ee23ec 100644 --- a/app/javascript/mastodon/locales/te.json +++ b/app/javascript/mastodon/locales/te.json @@ -47,7 +47,8 @@ "account.unmute": "@{name}పై మ్యూట్ ని తొలగించు", "account.unmute_notifications": "@{name} నుంచి ప్రకటనలపై మ్యూట్ ని తొలగించు", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "టూట్", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "మీడియా సున్నితమైనదిగా గుర్తించబడింది", "compose_form.sensitive.unmarked": "మీడియా సున్నితమైనదిగా గుర్తించబడలేదు", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "ఇష్టపడినవి:", "notifications.column_settings.filter_bar.advanced": "అన్ని విభాగాలను చూపించు", "notifications.column_settings.filter_bar.category": "క్విక్ ఫిల్టర్ బార్", - "notifications.column_settings.filter_bar.show": "చూపించు", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "క్రొత్త అనుచరులు:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "ప్రస్తావనలు:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "నిలువు వరుసలో చూపు", "notifications.column_settings.sound": "ధ్వనిని ప్లే చేయి", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "అన్నీ", "notifications.filter.boosts": "బూస్ట్లు", "notifications.filter.favourites": "ఇష్టాలు", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "లోడ్ అవుతోంది…", "regeneration_indicator.sublabel": "మీ హోమ్ ఫీడ్ సిద్ధమవుతోంది!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "ఇప్పుడు", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "రద్దు చెయ్యి", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "{target}కి ఫార్వార్డ్ చేయండి", "report.forward_hint": "ఖాతా మరొక సర్వర్లో ఉంది. నివేదిక యొక్క ఒక అనామకంగా ఉన్న కాపీని అక్కడికి కూడా పంపించమంటారా?", "report.hint": "మీ సేవిక మోడరేటర్లకు నివేదిక పంపబడుతుంది. ఈ ఖాతాను ఎందుకు నివేదిస్తున్నారనేదాని వివరణను మీరు దిగువన అందించవచ్చు:", @@ -396,9 +407,14 @@ "status.delete": "తొలగించు", "status.detailed_status": "వివరణాత్మక సంభాషణ వీక్షణ", "status.direct": "@{name}కు నేరుగా సందేశం పంపు", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "ఎంబెడ్", "status.favourite": "ఇష్టపడు", "status.filtered": "వడకట్టబడిన", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "మరిన్ని లోడ్ చేయి", "status.media_hidden": "మీడియా దాచబడింది", "status.mention": "@{name}ను ప్రస్తావించు", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index 90b8ba464..27bcbc4bb 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -13,7 +13,7 @@ "account.domain_blocked": "ปิดกั้นโดเมนอยู่", "account.edit_profile": "แก้ไขโปรไฟล์", "account.enable_notifications": "แจ้งเตือนฉันเมื่อ @{name} โพสต์", - "account.endorse": "แสดงให้เห็นในโปรไฟล์", + "account.endorse": "แนะนำในโปรไฟล์", "account.follow": "ติดตาม", "account.followers": "ผู้ติดตาม", "account.followers.empty": "ยังไม่มีใครติดตามผู้ใช้นี้", @@ -42,21 +42,22 @@ "account.statuses_counter": "{count, plural, other {{counter} โพสต์}}", "account.unblock": "เลิกปิดกั้น @{name}", "account.unblock_domain": "เลิกปิดกั้นโดเมน {domain}", - "account.unendorse": "ไม่แสดงให้เห็นในโปรไฟล์", + "account.unendorse": "ไม่แนะนำในโปรไฟล์", "account.unfollow": "เลิกติดตาม", "account.unmute": "เลิกซ่อน @{name}", "account.unmute_notifications": "เลิกซ่อนการแจ้งเตือนจาก @{name}", "account_note.placeholder": "คลิกเพื่อเพิ่มหมายเหตุ", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "ค่าเฉลี่ย", + "admin.dashboard.retention.cohort": "เดือนที่ลงทะเบียน", + "admin.dashboard.retention.cohort_size": "ผู้ใช้ใหม่", "alert.rate_limited.message": "โปรดลองใหม่หลังจาก {retry_time, time, medium}", "alert.rate_limited.title": "มีการจำกัดอัตรา", "alert.unexpected.message": "เกิดข้อผิดพลาดที่ไม่คาดคิด", "alert.unexpected.title": "อุปส์!", "announcement.announcement": "ประกาศ", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(ยังไม่ได้ประมวลผล)", "autosuggest_hashtag.per_week": "{count} ต่อสัปดาห์", "boost_modal.combo": "คุณสามารถกด {combo} เพื่อข้ามสิ่งนี้ในครั้งถัดไป", "bundle_column_error.body": "มีบางอย่างผิดพลาดขณะโหลดส่วนประกอบนี้", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "เปลี่ยนการสำรวจความคิดเห็นเป็นอนุญาตตัวเลือกเดี่ยว", "compose_form.publish": "โพสต์", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, other {ทำเครื่องหมายสื่อว่าละเอียดอ่อน}}", "compose_form.sensitive.marked": "{count, plural, other {มีการทำเครื่องหมายสื่อว่าละเอียดอ่อน}}", "compose_form.sensitive.unmarked": "{count, plural, other {ไม่มีการทำเครื่องหมายสื่อว่าละเอียดอ่อน}}", @@ -118,8 +120,8 @@ "confirmations.delete.message": "คุณแน่ใจหรือไม่ว่าต้องการลบโพสต์นี้?", "confirmations.delete_list.confirm": "ลบ", "confirmations.delete_list.message": "คุณแน่ใจหรือไม่ว่าต้องการลบรายการนี้อย่างถาวร?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "ละทิ้ง", + "confirmations.discard_edit_media.message": "คุณมีการเปลี่ยนแปลงคำอธิบายหรือตัวอย่างสื่อที่ยังไม่ได้บันทึก ละทิ้งการเปลี่ยนแปลงต่อไป?", "confirmations.domain_block.confirm": "ปิดกั้นทั้งโดเมน", "confirmations.domain_block.message": "คุณแน่ใจจริง ๆ หรือไม่ว่าต้องการปิดกั้นทั้ง {domain}? ในกรณีส่วนใหญ่ การปิดกั้นหรือการซ่อนแบบกำหนดเป้าหมายไม่กี่รายการนั้นเพียงพอและเป็นที่นิยม คุณจะไม่เห็นเนื้อหาจากโดเมนนั้นในเส้นเวลาสาธารณะใด ๆ หรือการแจ้งเตือนของคุณ จะเอาผู้ติดตามของคุณจากโดเมนนั้นออก", "confirmations.logout.confirm": "ออกจากระบบ", @@ -137,7 +139,7 @@ "conversation.mark_as_read": "ทำเครื่องหมายว่าอ่านแล้ว", "conversation.open": "ดูการสนทนา", "conversation.with": "กับ {names}", - "directory.federated": "จากเฟดิเวิร์สที่รู้จัก", + "directory.federated": "จากจักรวาลสหพันธ์ที่รู้จัก", "directory.local": "จาก {domain} เท่านั้น", "directory.new_arrivals": "มาใหม่", "directory.recently_active": "ใช้งานล่าสุด", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "รายการโปรด:", "notifications.column_settings.filter_bar.advanced": "แสดงหมวดหมู่ทั้งหมด", "notifications.column_settings.filter_bar.category": "แถบตัวกรองด่วน", - "notifications.column_settings.filter_bar.show": "แสดง", + "notifications.column_settings.filter_bar.show_bar": "แสดงแถบตัวกรอง", "notifications.column_settings.follow": "ผู้ติดตามใหม่:", "notifications.column_settings.follow_request": "คำขอติดตามใหม่:", "notifications.column_settings.mention": "การกล่าวถึง:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "แสดงในคอลัมน์", "notifications.column_settings.sound": "เล่นเสียง", "notifications.column_settings.status": "โพสต์ใหม่:", - "notifications.column_settings.unread_markers.category": "เครื่องหมายการแจ้งเตือนที่ยังไม่ได้อ่าน", + "notifications.column_settings.unread_notifications.category": "การแจ้งเตือนที่ยังไม่ได้อ่าน", + "notifications.column_settings.unread_notifications.highlight": "เน้นการแจ้งเตือนที่ยังไม่ได้อ่าน", "notifications.filter.all": "ทั้งหมด", "notifications.filter.boosts": "การดัน", "notifications.filter.favourites": "รายการโปรด", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, other {# การลงคะแนน}}", "poll.vote": "ลงคะแนน", "poll.voted": "คุณได้ลงคะแนนให้กับคำตอบนี้", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, other {# การลงคะแนน}}", "poll_button.add_poll": "เพิ่มการสำรวจความคิดเห็น", "poll_button.remove_poll": "เอาการสำรวจความคิดเห็นออก", "privacy.change": "เปลี่ยนความเป็นส่วนตัวของโพสต์", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "กำลังโหลด…", "regeneration_indicator.sublabel": "กำลังเตรียมฟีดหน้าแรกของคุณ!", "relative_time.days": "{number} วัน", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number} ชั่วโมง", "relative_time.just_now": "ตอนนี้", "relative_time.minutes": "{number} นาที", "relative_time.seconds": "{number} วินาที", "relative_time.today": "วันนี้", "reply_indicator.cancel": "ยกเลิก", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "ส่งต่อไปยัง {target}", "report.forward_hint": "บัญชีมาจากเซิร์ฟเวอร์อื่น ส่งสำเนาของรายงานที่ไม่ระบุตัวตนไปที่นั่นด้วย?", "report.hint": "จะส่งรายงานไปยังผู้ควบคุมเซิร์ฟเวอร์ของคุณ คุณสามารถให้คำอธิบายเหตุผลที่คุณรายงานบัญชีนี้ได้ด้านล่าง:", @@ -396,9 +407,14 @@ "status.delete": "ลบ", "status.detailed_status": "มุมมองการสนทนาโดยละเอียด", "status.direct": "ส่งข้อความโดยตรงถึง @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "ฝัง", "status.favourite": "ชื่นชอบ", "status.filtered": "กรองอยู่", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "โหลดเพิ่มเติม", "status.media_hidden": "ซ่อนสื่ออยู่", "status.mention": "กล่าวถึง @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "อธิบายสำหรับผู้สูญเสียการได้ยินหรือบกพร่องทางการมองเห็น", "upload_modal.analyzing_picture": "กำลังวิเคราะห์รูปภาพ…", "upload_modal.apply": "นำไปใช้", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "กำลังนำไปใช้…", "upload_modal.choose_image": "เลือกภาพ", "upload_modal.description_placeholder": "สุนัขจิ้งจอกสีน้ำตาลที่ว่องไวกระโดดข้ามสุนัขขี้เกียจ", "upload_modal.detect_text": "ตรวจหาข้อความจากรูปภาพ", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 2ae8a908a..a8c602caa 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -47,16 +47,17 @@ "account.unmute": "@{name} adlı kişinin sesini aç", "account.unmute_notifications": "@{name} adlı kişinin bildirimlerini aç", "account_note.placeholder": "Not eklemek için tıklayın", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Ortalama", + "admin.dashboard.retention.cohort": "Kayıt ayı", + "admin.dashboard.retention.cohort_size": "Yeni kullanıcılar", "alert.rate_limited.message": "Lütfen {retry_time, time, medium} süresinden sonra tekrar deneyin.", "alert.rate_limited.title": "Oran sınırlıdır", "alert.unexpected.message": "Beklenmedik bir hata oluştu.", "alert.unexpected.title": "Hay aksi!", "announcement.announcement": "Duyuru", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(işlenmemiş)", "autosuggest_hashtag.per_week": "Haftada {count}", "boost_modal.combo": "Bir daha ki sefere {combo} tuşuna basabilirsin", "bundle_column_error.body": "Bu bileşen yüklenirken bir şeyler ters gitti.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Tek bir seçeneğe izin vermek için anketi değiştir", "compose_form.publish": "Tootla", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Medyayı hassas olarak işaretle} other {Medyayı hassas olarak işaretle}}", "compose_form.sensitive.marked": "{count, plural, one {Medya hassas olarak işaretlendi} other {Medya hassas olarak işaretlendi}}", "compose_form.sensitive.unmarked": "{count, plural, one {Medya hassas olarak işaretlenmemiş} other {Medya hassas olarak işaretlenmemiş}}", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Bu tootu silmek istediğinden emin misin?", "confirmations.delete_list.confirm": "Sil", "confirmations.delete_list.message": "Bu listeyi kalıcı olarak silmek istediğinden emin misin?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Vazgeç", + "confirmations.discard_edit_media.message": "Ortam açıklaması veya ön izlemede kaydedilmemiş değişiklikleriniz var, yine de vazgeçmek istiyor musunuz?", "confirmations.domain_block.confirm": "Alanın tamamını engelle", "confirmations.domain_block.message": "{domain} alanının tamamını engellemek istediğinden gerçekten emin misin? Genellikle hedeflenen birkaç engelleme veya sessize alma yeterlidir ve tercih edilir. Bu alan adından gelen içeriği herhangi bir genel zaman çizelgesinde veya bildirimlerinde görmezsin. Bu alan adındaki takipçilerin kaldırılır.", "confirmations.logout.confirm": "Oturumu kapat", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Beğeniler:", "notifications.column_settings.filter_bar.advanced": "Tüm kategorileri görüntüle", "notifications.column_settings.filter_bar.category": "Hızlı filtre çubuğu", - "notifications.column_settings.filter_bar.show": "Göster", + "notifications.column_settings.filter_bar.show_bar": "Süzme çubuğunu göster", "notifications.column_settings.follow": "Yeni takipçiler:", "notifications.column_settings.follow_request": "Yeni takip istekleri:", "notifications.column_settings.mention": "Bahsetmeler:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Sütunda göster", "notifications.column_settings.sound": "Ses çal", "notifications.column_settings.status": "Yeni gönderiler:", - "notifications.column_settings.unread_markers.category": "Okunmamış bildirim işaretleri", + "notifications.column_settings.unread_notifications.category": "Okunmamış bildirimler", + "notifications.column_settings.unread_notifications.highlight": "Okunmamış bildirimleri öne çıkar", "notifications.filter.all": "Tümü", "notifications.filter.boosts": "Boostlar", "notifications.filter.favourites": "Beğeniler", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# oy} other {# oy}}", "poll.vote": "Oy ver", "poll.voted": "Bu cevap için oy kullandınız", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# oy} other {# oy}}", "poll_button.add_poll": "Bir anket ekleyin", "poll_button.remove_poll": "Anketi kaldır", "privacy.change": "Gönderi gizliliğini değiştir", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Yükleniyor…", "regeneration_indicator.sublabel": "Ana akışın hazırlanıyor!", "relative_time.days": "{number}g", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}sa", "relative_time.just_now": "şimdi", "relative_time.minutes": "{number}dk", "relative_time.seconds": "{number}sn", "relative_time.today": "bugün", "reply_indicator.cancel": "İptal", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "{target} ilet", "report.forward_hint": "Hesap başka bir sunucudan. Raporun anonim bir kopyası da oraya gönderilsin mi?", "report.hint": "Bu rapor sunucu moderatörlerine gönderilecek. Bu hesabı neden bildirdiğiniz hakkında bilgi verebirsiniz:", @@ -396,9 +407,14 @@ "status.delete": "Sil", "status.detailed_status": "Ayrıntılı sohbet görünümü", "status.direct": "@{name} adlı kişiye direkt mesaj", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Gömülü", "status.favourite": "Beğen", "status.filtered": "Filtrelenmiş", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Daha fazlasını yükle", "status.media_hidden": "Medya gizli", "status.mention": "@{name} kişisinden bahset", @@ -462,7 +478,7 @@ "upload_form.video_description": "İşitme kaybı veya görme engeli olan kişiler için tarif edin", "upload_modal.analyzing_picture": "Resim analiz ediliyor…", "upload_modal.apply": "Uygula", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Uygulanıyor…", "upload_modal.choose_image": "Resim seç", "upload_modal.description_placeholder": "Pijamalı hasta yağız şoföre çabucak güvendi", "upload_modal.detect_text": "Resimdeki metni algıla", diff --git a/app/javascript/mastodon/locales/tt.json b/app/javascript/mastodon/locales/tt.json index 456c5f72d..e66a7d4e1 100644 --- a/app/javascript/mastodon/locales/tt.json +++ b/app/javascript/mastodon/locales/tt.json @@ -47,7 +47,8 @@ "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Күрсәтү", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Show in column", "notifications.column_settings.sound": "Play sound", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "Бөтенесе", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Йөкләү...", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}к", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}с", "relative_time.just_now": "хәзер", "relative_time.minutes": "{number}м", "relative_time.seconds": "{number}сек", "relative_time.today": "бүген", "reply_indicator.cancel": "Баш тарту", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Бетерү", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Load more", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/ug.json b/app/javascript/mastodon/locales/ug.json index eca4765c4..2675da68c 100644 --- a/app/javascript/mastodon/locales/ug.json +++ b/app/javascript/mastodon/locales/ug.json @@ -47,7 +47,8 @@ "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Show in column", "notifications.column_settings.sound": "Play sound", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "Cancel", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Load more", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 808701957..5adbd832b 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -47,16 +47,17 @@ "account.unmute": "Зняти глушення з @{name}", "account.unmute_notifications": "Показувати сповіщення від @{name}", "account_note.placeholder": "Коментарі відсутні", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Середнє", + "admin.dashboard.retention.cohort": "Місяць реєстрації", + "admin.dashboard.retention.cohort_size": "Нові користувачі", "alert.rate_limited.message": "Спробуйте ще раз через {retry_time, time, medium}.", "alert.rate_limited.title": "Швидкість обмежена", "alert.unexpected.message": "Трапилась неочікувана помилка.", "alert.unexpected.title": "Ой!", "announcement.announcement": "Оголошення", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(не оброблено)", "autosuggest_hashtag.per_week": "{count} в тиждень", "boost_modal.combo": "Ви можете натиснути {combo}, щоб пропустити це наступного разу", "bundle_column_error.body": "Щось пішло не так під час завантаження компоненту.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Перемкнути у режим вибору однієї відповіді", "compose_form.publish": "Дмухнути", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Позначити медіа делікатним} other {Позначити медіа делікатними}}", "compose_form.sensitive.marked": "{count, plural, one {Медіа позначене делікатним} other {Медіа позначені делікатними}}", "compose_form.sensitive.unmarked": "{count, plural, one {Медіа не позначене делікатним} other {Медіа не позначені делікатними}}", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Ви впевнені, що хочете видалити цей допис?", "confirmations.delete_list.confirm": "Видалити", "confirmations.delete_list.message": "Ви впевнені, що хочете видалити цей список назавжди?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Відкинути", + "confirmations.discard_edit_media.message": "У вас є незбережені зміни в описі медіа або попереднього перегляду, все одно відкинути їх?", "confirmations.domain_block.confirm": "Сховати весь домен", "confirmations.domain_block.message": "Ви точно, точно впевнені, що хочете заблокувати весь домен {domain}? У більшості випадків для нормальної роботи краще заблокувати/заглушити лише деяких користувачів. Ви не зможете бачити контент з цього домену у будь-яких стрічках або ваших сповіщеннях. Ваші підписники з цього домену будуть відписані від вас.", "confirmations.logout.confirm": "Вийти", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Вподобане:", "notifications.column_settings.filter_bar.advanced": "Показати всі категорії", "notifications.column_settings.filter_bar.category": "Панель швидкого фільтру", - "notifications.column_settings.filter_bar.show": "Показати", + "notifications.column_settings.filter_bar.show_bar": "Показати панель фільтра", "notifications.column_settings.follow": "Нові підписники:", "notifications.column_settings.follow_request": "Нові запити на підписку:", "notifications.column_settings.mention": "Згадки:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Показати в колонці", "notifications.column_settings.sound": "Відтворювати звуки", "notifications.column_settings.status": "Нові дмухи:", - "notifications.column_settings.unread_markers.category": "Мітки непрочитаних сповіщень", + "notifications.column_settings.unread_notifications.category": "Непрочитані сповіщення", + "notifications.column_settings.unread_notifications.highlight": "Виділити непрочитані сповіщення", "notifications.filter.all": "Усі", "notifications.filter.boosts": "Передмухи", "notifications.filter.favourites": "Улюблені", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# голос} few {# голоси} many {# голосів} other {# голосів}}", "poll.vote": "Проголосувати", "poll.voted": "Ви голосували за цю відповідь", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# голос} few {# голоси} many {# голосів} other {# голоса}}", "poll_button.add_poll": "Додати опитування", "poll_button.remove_poll": "Видалити опитування", "privacy.change": "Змінити видимість допису", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Завантаження…", "regeneration_indicator.sublabel": "Ваша домашня стрічка готується!", "relative_time.days": "{number}д", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}г", "relative_time.just_now": "щойно", "relative_time.minutes": "{number}х", "relative_time.seconds": "{number}с", "relative_time.today": "сьогодні", "reply_indicator.cancel": "Відмінити", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Надіслати до {target}", "report.forward_hint": "Це акаунт з іншого серверу. Відправити анонімізовану копію скарги і туди?", "report.hint": "Скаргу буде відправлено модераторам Вашого сайту. Ви можете надати їм пояснення, чому ви скаржитесь на акаунт нижче:", @@ -396,9 +407,14 @@ "status.delete": "Видалити", "status.detailed_status": "Детальний вигляд бесіди", "status.direct": "Пряме повідомлення до @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Вбудувати", "status.favourite": "Подобається", "status.filtered": "Відфільтровано", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Завантажити більше", "status.media_hidden": "Медіа приховано", "status.mention": "Згадати @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Опишіть для людей із вадами слуху або зору", "upload_modal.analyzing_picture": "Аналізуємо малюнок…", "upload_modal.apply": "Застосувати", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Застосування…", "upload_modal.choose_image": "Вибрати зображення", "upload_modal.description_placeholder": "Щурячий бугай із їжаком-харцизом в'ючись підписали ґешефт у єнах", "upload_modal.detect_text": "Виявити текст на малюнку", diff --git a/app/javascript/mastodon/locales/ur.json b/app/javascript/mastodon/locales/ur.json index 55f6856d2..e029f074c 100644 --- a/app/javascript/mastodon/locales/ur.json +++ b/app/javascript/mastodon/locales/ur.json @@ -47,7 +47,8 @@ "account.unmute": "@{name} کو با آواز کریں", "account.unmute_notifications": "@{name} سے اطلاعات کو با آواز کریں", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "کسی ایک انتخاب کے لیے پول تبدیل کریں", "compose_form.publish": "ٹوٹ", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "وسائل کو حساس نشاندہ کریں", "compose_form.sensitive.marked": "وسائل حساس نشاندہ ہے", "compose_form.sensitive.unmarked": "{count, plural, one {میڈیا کو حساس کے طور پر نشان زد نہیں کیا گیا ہے} other {میڈیا کو حساس کے طور پر نشان زد نہیں کیا گیا ہے}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "پسندیدہ:", "notifications.column_settings.filter_bar.advanced": "تمام زمرے دکھائیں", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Show in column", "notifications.column_settings.sound": "Play sound", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}d", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}h", "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", "reply_indicator.cancel": "Cancel", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Load more", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index 9922707be..f5620638a 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -47,16 +47,17 @@ "account.unmute": "Bỏ ẩn @{name}", "account.unmute_notifications": "Mở lại thông báo từ @{name}", "account_note.placeholder": "Nhấn để thêm", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "Trung bình", + "admin.dashboard.retention.cohort": "Đăng ký tháng", + "admin.dashboard.retention.cohort_size": "Người dùng mới", "alert.rate_limited.message": "Vui lòng thử lại sau {retry_time, time, medium}.", "alert.rate_limited.title": "Vượt giới hạn", "alert.unexpected.message": "Đã xảy ra lỗi không mong muốn.", "alert.unexpected.title": "Ốiii!", "announcement.announcement": "Thông báo chung", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(chưa xử lí)", "autosuggest_hashtag.per_week": "{count} mỗi tuần", "boost_modal.combo": "Nhấn {combo} để chia sẻ nhanh hơn", "bundle_column_error.body": "Đã có lỗi xảy ra trong khi tải nội dung này.", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Chỉ cho phép chọn duy nhất một lựa chọn", "compose_form.publish": "Đăng tút", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, other {Đánh dấu nội dung nhạy cảm}}", "compose_form.sensitive.marked": "{count, plural, other {Nội dung này nhạy cảm}}", "compose_form.sensitive.unmarked": "{count, plural, other {Nội dung này bình thường}}", @@ -118,8 +120,8 @@ "confirmations.delete.message": "Bạn \bthật sự muốn xóa tút này?", "confirmations.delete_list.confirm": "Xóa bỏ", "confirmations.delete_list.message": "Bạn thật sự muốn xóa vĩnh viễn danh sách này?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "Bỏ qua", + "confirmations.discard_edit_media.message": "Bạn chưa lưu thay đổi đối với phần mô tả hoặc bản xem trước của media, vẫn bỏ luôn?", "confirmations.domain_block.confirm": "Ẩn toàn bộ máy chủ", "confirmations.domain_block.message": "Bạn thật sự muốn ẩn toàn bộ nội dung từ {domain}? Sẽ hợp lý hơn nếu bạn chỉ chặn hoặc ẩn một vài tài khoản cụ thể. Ẩn toàn bộ nội dung từ máy chủ sẽ khiến bạn không còn thấy nội dung từ máy chủ đó ở bất kỳ nơi nào, kể cả thông báo. Người quan tâm bạn từ máy chủ đó cũng sẽ bị xóa luôn.", "confirmations.logout.confirm": "Đăng xuất", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Lượt thích:", "notifications.column_settings.filter_bar.advanced": "Toàn bộ", "notifications.column_settings.filter_bar.category": "Phân loại", - "notifications.column_settings.filter_bar.show": "Lượt nhắc", + "notifications.column_settings.filter_bar.show_bar": "Hiện bộ lọc", "notifications.column_settings.follow": "Người theo dõi mới:", "notifications.column_settings.follow_request": "Yêu cầu theo dõi mới:", "notifications.column_settings.mention": "Lượt nhắc đến:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Thông báo trên thanh menu", "notifications.column_settings.sound": "Kèm theo tiếng \"bíp\"", "notifications.column_settings.status": "Tút mới:", - "notifications.column_settings.unread_markers.category": "Đánh dấu những thông báo chưa đọc", + "notifications.column_settings.unread_notifications.category": "Thông báo chưa đọc", + "notifications.column_settings.unread_notifications.highlight": "Nổi bật thông báo chưa đọc", "notifications.filter.all": "Toàn bộ", "notifications.filter.boosts": "Chia sẻ", "notifications.filter.favourites": "Thích", @@ -346,11 +349,11 @@ "poll.total_votes": "{count, plural, other {# người bình chọn}}", "poll.vote": "Bình chọn", "poll.voted": "Bạn đã bình chọn rồi", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, other {# lượt bình chọn}}", "poll_button.add_poll": "Tạo bình chọn", "poll_button.remove_poll": "Hủy cuộc bình chọn", "privacy.change": "Thay đổi quyền riêng tư", - "privacy.direct.long": "Gửi trực tiếp cho người được nhắc đến", + "privacy.direct.long": "Chỉ người được nhắc đến mới thấy", "privacy.direct.short": "Tin nhắn", "privacy.private.long": "Dành riêng cho người theo dõi", "privacy.private.short": "Riêng tư", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "Đang tải…", "regeneration_indicator.sublabel": "Bảng tin của bạn đang được cập nhật!", "relative_time.days": "{number} ngày", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number} giờ", "relative_time.just_now": "vừa xong", "relative_time.minutes": "{number} phút", "relative_time.seconds": "{number}s", "relative_time.today": "hôm nay", "reply_indicator.cancel": "Hủy bỏ", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "Chuyển đến {target}", "report.forward_hint": "Người này thuộc máy chủ khác. Gửi một báo cáo ẩn danh tới máy chủ đó?", "report.hint": "Hãy cho quản trị viên biết lý do vì sao bạn báo cáo người này:", @@ -396,9 +407,14 @@ "status.delete": "Xóa", "status.detailed_status": "Xem chi tiết thêm", "status.direct": "Nhắn tin @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Nhúng", "status.favourite": "Thích", "status.filtered": "Bộ lọc", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "Xem thêm", "status.media_hidden": "Đã ẩn", "status.mention": "Nhắc đến @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "Mô tả cho người mất thị lực hoặc không thể nghe", "upload_modal.analyzing_picture": "Phân tích hình ảnh", "upload_modal.apply": "Áp dụng", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Đang áp dụng…", "upload_modal.choose_image": "Chọn ảnh", "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", "upload_modal.detect_text": "Trích văn bản từ trong ảnh", diff --git a/app/javascript/mastodon/locales/zgh.json b/app/javascript/mastodon/locales/zgh.json index 22f6823fe..bc9b8bc83 100644 --- a/app/javascript/mastodon/locales/zgh.json +++ b/app/javascript/mastodon/locales/zgh.json @@ -47,7 +47,8 @@ "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", "account_note.placeholder": "Click to add a note", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "Show in column", "notifications.column_settings.sound": "ⵖⵔ ⵉⵎⵙⵍⵉ", "notifications.column_settings.status": "New toots:", - "notifications.column_settings.unread_markers.category": "Unread notification markers", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "ⴰⴽⴽⵯ", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favourites", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "ⴰⵣⴷⴰⵎ…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", "relative_time.days": "{number}ⴰⵙ", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}ⵙⵔⴳ", "relative_time.just_now": "ⴷⵖⵉ", "relative_time.minutes": "{number}ⵙⴷ", "relative_time.seconds": "{number}ⵙⵏ", "relative_time.today": "ⴰⵙⵙⴰ", "reply_indicator.cancel": "ⵙⵔ", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "ⵙⵙⵉⴼⴹ ⵉ {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", @@ -396,9 +407,14 @@ "status.delete": "ⴽⴽⵙ", "status.detailed_status": "Detailed conversation view", "status.direct": "ⵜⵓⵣⵉⵏⵜ ⵜⵓⵙⵔⵉⴷⵜ ⵉ @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favourite", "status.filtered": "Filtered", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "ⵙⵙⵉⵍⵉ ⵓⴳⴳⴰⵔ", "status.media_hidden": "Media hidden", "status.mention": "Mention @{name}", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index 286d54fb8..cb971126e 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -47,16 +47,17 @@ "account.unmute": "不再隐藏 @{name}", "account.unmute_notifications": "不再隐藏来自 @{name} 的通知", "account_note.placeholder": "点击添加备注", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "平均", + "admin.dashboard.retention.cohort": "注册月", + "admin.dashboard.retention.cohort_size": "新用户", "alert.rate_limited.message": "请在{retry_time, time, medium}后重试。", "alert.rate_limited.title": "频率受限", "alert.unexpected.message": "发生了意外错误。", "alert.unexpected.title": "哎呀!", "announcement.announcement": "公告", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(未处理)", "autosuggest_hashtag.per_week": "每星期 {count} 条", "boost_modal.combo": "下次按住 {combo} 即可跳过此提示", "bundle_column_error.body": "载入这个组件时发生了错误。", @@ -83,9 +84,9 @@ "column_header.hide_settings": "隐藏设置", "column_header.moveLeft_settings": "将此栏左移", "column_header.moveRight_settings": "将此栏右移", - "column_header.pin": "固定", + "column_header.pin": "置顶", "column_header.show_settings": "显示设置", - "column_header.unpin": "取消固定", + "column_header.unpin": "取消置顶", "column_subheading.settings": "设置", "community.column_settings.local_only": "只显示本站", "community.column_settings.media_only": "仅媒体", @@ -96,7 +97,7 @@ "compose_form.lock_disclaimer": "你的帐户没有{locked}。任何人都可以在关注你后立即查看仅关注者可见的嘟文。", "compose_form.lock_disclaimer.lock": "开启保护", "compose_form.placeholder": "在想啥?", - "compose_form.poll.add_option": "添加一个选项", + "compose_form.poll.add_option": "添加选项", "compose_form.poll.duration": "投票持续时间", "compose_form.poll.option_placeholder": "选项 {number}", "compose_form.poll.remove_option": "移除这个选项", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "将投票改为单选", "compose_form.publish": "嘟嘟", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "标记媒体为敏感内容", "compose_form.sensitive.marked": "媒体已被标记为敏感内容", "compose_form.sensitive.unmarked": "媒体未被标记为敏感内容", @@ -118,8 +120,8 @@ "confirmations.delete.message": "你确定要删除这条嘟文吗?", "confirmations.delete_list.confirm": "删除", "confirmations.delete_list.message": "你确定要永久删除这个列表吗?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "丢弃", + "confirmations.discard_edit_media.message": "您还有未保存的媒体描述或预览修改,仍然丢弃它们吗?", "confirmations.domain_block.confirm": "隐藏整个网站的内容", "confirmations.domain_block.message": "你真的确定要屏蔽所有来自 {domain} 的内容吗?多数情况下,屏蔽或隐藏几个特定的用户就已经足够了。来自该网站的内容将不再出现在你的任何公共时间轴或通知列表里。来自该网站的关注者将会被移除。", "confirmations.logout.confirm": "登出", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "当你的嘟文被喜欢时:", "notifications.column_settings.filter_bar.advanced": "显示所有类别", "notifications.column_settings.filter_bar.category": "快速过滤栏", - "notifications.column_settings.filter_bar.show": "显示", + "notifications.column_settings.filter_bar.show_bar": "显示过滤栏", "notifications.column_settings.follow": "当有人关注你时:", "notifications.column_settings.follow_request": "新的关注请求:", "notifications.column_settings.mention": "当有人在嘟文中提及你时:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "在通知栏显示", "notifications.column_settings.sound": "播放音效", "notifications.column_settings.status": "新嘟文:", - "notifications.column_settings.unread_markers.category": "未读通知标记", + "notifications.column_settings.unread_notifications.category": "未读通知", + "notifications.column_settings.unread_notifications.highlight": "高亮显示未读通知", "notifications.filter.all": "全部", "notifications.filter.boosts": "转嘟", "notifications.filter.favourites": "喜欢", @@ -346,7 +349,7 @@ "poll.total_votes": "{count} 票", "poll.vote": "投票", "poll.voted": "你已经对这个答案投过票了", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# 票} other {# 票}}", "poll_button.add_poll": "发起投票", "poll_button.remove_poll": "移除投票", "privacy.change": "设置嘟文的可见范围", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "加载中……", "regeneration_indicator.sublabel": "你的主页动态正在准备中!", "relative_time.days": "{number}天", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}时", "relative_time.just_now": "刚刚", "relative_time.minutes": "{number}分", "relative_time.seconds": "{number}秒", "relative_time.today": "今天", "reply_indicator.cancel": "取消", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "转发举报至 {target}", "report.forward_hint": "这名用户来自另一个服务器。是否要向那个服务器发送一条匿名的举报?", "report.hint": "举报将会发送给你所在服务器的监察员。你可以在下面填写举报该用户的理由:", @@ -396,9 +407,14 @@ "status.delete": "删除", "status.detailed_status": "对话详情", "status.direct": "发送私信给 @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "嵌入", "status.favourite": "喜欢", "status.filtered": "已过滤", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "加载更多", "status.media_hidden": "已隐藏的媒体内容", "status.mention": "提及 @{name}", @@ -422,7 +438,7 @@ "status.share": "分享", "status.show_less": "隐藏内容", "status.show_less_all": "隐藏所有内容", - "status.show_more": "显示内容", + "status.show_more": "显示更多", "status.show_more_all": "显示所有内容", "status.show_thread": "显示全部对话", "status.uncached_media_warning": "暂不可用", @@ -462,7 +478,7 @@ "upload_form.video_description": "为听障人士和视障人士添加文字描述", "upload_modal.analyzing_picture": "分析图片…", "upload_modal.apply": "应用", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "正在应用…", "upload_modal.choose_image": "选择图像", "upload_modal.description_placeholder": "天地玄黄 宇宙洪荒 日月盈仄 辰宿列张", "upload_modal.detect_text": "从图片中检测文本", diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json index e93c81f94..bd6666b15 100644 --- a/app/javascript/mastodon/locales/zh-HK.json +++ b/app/javascript/mastodon/locales/zh-HK.json @@ -47,7 +47,8 @@ "account.unmute": "取消 @{name} 的靜音", "account.unmute_notifications": "取消來自 @{name} 通知的靜音", "account_note.placeholder": "按此添加備注", - "admin.dashboard.retention": "Retention", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", "admin.dashboard.retention.average": "Average", "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "New users", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "變更投票為限定單一選項", "compose_form.publish": "發文", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "標記媒體為敏感內容", "compose_form.sensitive.marked": "媒體被標示為敏感", "compose_form.sensitive.unmarked": "媒體沒有被標示為敏感", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "你最愛的文章:", "notifications.column_settings.filter_bar.advanced": "顯示所有分類", "notifications.column_settings.filter_bar.category": "快速過濾欄", - "notifications.column_settings.filter_bar.show": "顯示", + "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "關注你:", "notifications.column_settings.follow_request": "新的關注請求:", "notifications.column_settings.mention": "提及你:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "在通知欄顯示", "notifications.column_settings.sound": "播放音效", "notifications.column_settings.status": "新的文章", - "notifications.column_settings.unread_markers.category": "未讀通知標記", + "notifications.column_settings.unread_notifications.category": "Unread notifications", + "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications", "notifications.filter.all": "全部", "notifications.filter.boosts": "轉推", "notifications.filter.favourites": "最愛", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "載入中……", "regeneration_indicator.sublabel": "你的主頁時間軸正在準備中!", "relative_time.days": "{number}日前", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}小時前", "relative_time.just_now": "剛剛", "relative_time.minutes": "{number}分鐘前", "relative_time.seconds": "{number}秒前", "relative_time.today": "今天", "reply_indicator.cancel": "取消", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "轉寄到 {target}", "report.forward_hint": "這個帳戶屬於其他服務站。要向該服務站發送匿名的舉報訊息嗎?", "report.hint": "這訊息會發送到你服務站的管理員。你可以提供舉報這個帳戶的理由:", @@ -396,9 +407,14 @@ "status.delete": "刪除", "status.detailed_status": "詳細對話內容", "status.direct": "私訊 @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "嵌入", "status.favourite": "最愛", "status.filtered": "已過濾", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "載入更多", "status.media_hidden": "隱藏媒體內容", "status.mention": "提及 @{name}", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 7fdd156ea..60f4bc2f4 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -47,16 +47,17 @@ "account.unmute": "取消靜音 @{name}", "account.unmute_notifications": "重新接收來自 @{name} 的通知", "account_note.placeholder": "按此添加備注", - "admin.dashboard.retention": "Retention", - "admin.dashboard.retention.average": "Average", - "admin.dashboard.retention.cohort": "Sign-up month", - "admin.dashboard.retention.cohort_size": "New users", + "admin.dashboard.daily_retention": "User retention rate by day after sign-up", + "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", + "admin.dashboard.retention.average": "平均", + "admin.dashboard.retention.cohort": "註冊月份", + "admin.dashboard.retention.cohort_size": "新使用者", "alert.rate_limited.message": "請在 {retry_time, time, medium} 後重試", "alert.rate_limited.title": "已限速", "alert.unexpected.message": "發生了非預期的錯誤。", "alert.unexpected.title": "哎呀!", "announcement.announcement": "公告", - "attachments_list.unprocessed": "(unprocessed)", + "attachments_list.unprocessed": "(未經處理)", "autosuggest_hashtag.per_week": "{count} / 週", "boost_modal.combo": "下次您可以按 {combo} 跳過", "bundle_column_error.body": "載入此元件時發生錯誤。", @@ -104,6 +105,7 @@ "compose_form.poll.switch_to_single": "變更投票為允許單一選項", "compose_form.publish": "嘟出去", "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Save changes", "compose_form.sensitive.hide": "標記媒體為敏感內容", "compose_form.sensitive.marked": "此媒體被標記為敏感內容", "compose_form.sensitive.unmarked": "此媒體未被標記為敏感內容", @@ -118,8 +120,8 @@ "confirmations.delete.message": "您確定要刪除這則嘟文?", "confirmations.delete_list.confirm": "刪除", "confirmations.delete_list.message": "確定永久刪除此名單?", - "confirmations.discard_edit_media.confirm": "Discard", - "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?", + "confirmations.discard_edit_media.confirm": "捨棄", + "confirmations.discard_edit_media.message": "您在媒體描述或預覽區塊有未儲存的變更。是否要捨棄這些變更?", "confirmations.domain_block.confirm": "隱藏整個域名", "confirmations.domain_block.message": "真的非常確定封鎖整個 {domain} 網域嗎?大部分情況下,您只需要封鎖或靜音少數特定的帳帳戶能滿足需求了。您將不能在任何公開的時間軸及通知中看到來自此網域的內容。您來自該網域的跟隨者也將被移除。", "confirmations.logout.confirm": "登出", @@ -312,7 +314,7 @@ "notifications.column_settings.favourite": "最愛:", "notifications.column_settings.filter_bar.advanced": "顯示所有分類", "notifications.column_settings.filter_bar.category": "快速過濾欄", - "notifications.column_settings.filter_bar.show": "顯示", + "notifications.column_settings.filter_bar.show_bar": "顯示過濾器列", "notifications.column_settings.follow": "新的跟隨者:", "notifications.column_settings.follow_request": "新的跟隨請求:", "notifications.column_settings.mention": "提及:", @@ -322,7 +324,8 @@ "notifications.column_settings.show": "在欄位中顯示", "notifications.column_settings.sound": "播放聲音", "notifications.column_settings.status": "新嘟文:", - "notifications.column_settings.unread_markers.category": "未讀通知標記", + "notifications.column_settings.unread_notifications.category": "未讀通知", + "notifications.column_settings.unread_notifications.highlight": "突顯未讀通知", "notifications.filter.all": "全部", "notifications.filter.boosts": "轉嘟", "notifications.filter.favourites": "最愛", @@ -346,7 +349,7 @@ "poll.total_votes": "{count, plural, one {# 個投票} other {# 個投票}}", "poll.vote": "投票", "poll.voted": "您已對此問題投票", - "poll.votes": "{votes, plural, one {# vote} other {# votes}}", + "poll.votes": "{votes, plural, one {# 張票} other {# 張票}}", "poll_button.add_poll": "建立投票", "poll_button.remove_poll": "移除投票", "privacy.change": "調整嘟文隱私狀態", @@ -362,12 +365,20 @@ "regeneration_indicator.label": "載入中…", "regeneration_indicator.sublabel": "您的主頁時間軸正在準備中!", "relative_time.days": "{number} 天", + "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago", + "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago", + "relative_time.full.just_now": "just now", + "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", + "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", "relative_time.hours": "{number}小時前", "relative_time.just_now": "剛剛", "relative_time.minutes": "{number} 分前", "relative_time.seconds": "{number} 秒", "relative_time.today": "今天", "reply_indicator.cancel": "取消", + "report.categories.other": "Other", + "report.categories.spam": "Spam", + "report.categories.violation": "Content violates one or more server rules", "report.forward": "轉寄到 {target}", "report.forward_hint": "這個帳戶屬於其他伺服器。要像該伺服器發送匿名的檢舉訊息嗎?", "report.hint": "這項訊息會發送到您伺服器的管理員。您可以提供檢舉這個帳戶的理由:", @@ -396,9 +407,14 @@ "status.delete": "刪除", "status.detailed_status": "詳細的對話內容", "status.direct": "發送私訊給 @{name}", + "status.edit": "Edit", + "status.edited": "Edited {date}", + "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "內嵌", "status.favourite": "最愛", "status.filtered": "已過濾", + "status.history.created": "{name} created {date}", + "status.history.edited": "{name} edited {date}", "status.load_more": "載入更多", "status.media_hidden": "隱藏媒體內容", "status.mention": "提及 @{name}", @@ -462,7 +478,7 @@ "upload_form.video_description": "描述給聽障或視障人士", "upload_modal.analyzing_picture": "正在分析圖片…", "upload_modal.apply": "套用", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "正在套用⋯⋯", "upload_modal.choose_image": "選擇圖片", "upload_modal.description_placeholder": "我能吞下玻璃而不傷身體", "upload_modal.detect_text": "從圖片中偵測文字", diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index 06a908e9d..ea882a71f 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -43,6 +43,7 @@ import { INIT_MEDIA_EDIT_MODAL, COMPOSE_CHANGE_MEDIA_DESCRIPTION, COMPOSE_CHANGE_MEDIA_FOCUS, + COMPOSE_SET_STATUS, } from '../actions/compose'; import { TIMELINE_DELETE } from '../actions/timelines'; import { STORE_HYDRATE } from '../actions/store'; @@ -58,6 +59,7 @@ const initialState = ImmutableMap({ spoiler: false, spoiler_text: '', privacy: null, + id: null, text: '', focusDate: null, caretPosition: null, @@ -107,6 +109,7 @@ function statusToTextMentions(state, status) { function clearAll(state) { return state.withMutations(map => { + map.set('id', null); map.set('text', ''); map.set('spoiler', false); map.set('spoiler_text', ''); @@ -313,6 +316,7 @@ export default function compose(state = initialState, action) { return state.set('is_composing', action.value); case COMPOSE_REPLY: return state.withMutations(map => { + map.set('id', null); map.set('in_reply_to', action.status.get('id')); map.set('text', statusToTextMentions(state, action.status)); map.set('privacy', privacyPreference(action.status.get('visibility'), state.get('default_privacy'))); @@ -329,21 +333,12 @@ export default function compose(state = initialState, action) { map.set('spoiler_text', ''); } }); - case COMPOSE_REPLY_CANCEL: - case COMPOSE_RESET: - return state.withMutations(map => { - map.set('in_reply_to', null); - map.set('text', ''); - map.set('spoiler', false); - map.set('spoiler_text', ''); - map.set('privacy', state.get('default_privacy')); - map.set('poll', null); - map.set('idempotencyKey', uuid()); - }); case COMPOSE_SUBMIT_REQUEST: return state.set('is_submitting', true); case COMPOSE_UPLOAD_CHANGE_REQUEST: return state.set('is_changing_upload', true); + case COMPOSE_REPLY_CANCEL: + case COMPOSE_RESET: case COMPOSE_SUBMIT_SUCCESS: return clearAll(state); case COMPOSE_SUBMIT_FAIL: @@ -462,6 +457,34 @@ export default function compose(state = initialState, action) { })); } }); + case COMPOSE_SET_STATUS: + return state.withMutations(map => { + map.set('id', action.status.get('id')); + map.set('text', action.text); + map.set('in_reply_to', action.status.get('in_reply_to_id')); + map.set('privacy', action.status.get('visibility')); + map.set('media_attachments', action.status.get('media_attachments')); + map.set('focusDate', new Date()); + map.set('caretPosition', null); + map.set('idempotencyKey', uuid()); + map.set('sensitive', action.status.get('sensitive')); + + if (action.spoiler_text.length > 0) { + map.set('spoiler', true); + map.set('spoiler_text', action.spoiler_text); + } else { + map.set('spoiler', false); + map.set('spoiler_text', ''); + } + + if (action.status.get('poll')) { + map.set('poll', ImmutableMap({ + options: action.status.getIn(['poll', 'options']).map(x => x.get('title')), + multiple: action.status.getIn(['poll', 'multiple']), + expires_in: expiresInFromExpiresAt(action.status.getIn(['poll', 'expires_at'])), + })); + } + }); case COMPOSE_POLL_ADD: return state.set('poll', initialPoll); case COMPOSE_POLL_REMOVE: diff --git a/app/javascript/mastodon/reducers/history.js b/app/javascript/mastodon/reducers/history.js new file mode 100644 index 000000000..00b01aa6e --- /dev/null +++ b/app/javascript/mastodon/reducers/history.js @@ -0,0 +1,28 @@ +import { HISTORY_FETCH_REQUEST, HISTORY_FETCH_SUCCESS, HISTORY_FETCH_FAIL } from 'mastodon/actions/history'; +import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable'; + +const initialHistory = ImmutableMap({ + loading: false, + items: ImmutableList(), +}); + +const initialState = ImmutableMap(); + +export default function history(state = initialState, action) { + switch(action.type) { + case HISTORY_FETCH_REQUEST: + return state.update(action.statusId, initialHistory, history => history.withMutations(map => { + map.set('loading', true); + map.set('items', ImmutableList()); + })); + case HISTORY_FETCH_SUCCESS: + return state.update(action.statusId, initialHistory, history => history.withMutations(map => { + map.set('loading', false); + map.set('items', fromJS(action.history.map((x, i) => ({ ...x, account: x.account.id, original: i === 0 })).reverse())); + })); + case HISTORY_FETCH_FAIL: + return state.update(action.statusId, initialHistory, history => history.set('loading', false)); + default: + return state; + } +} diff --git a/app/javascript/mastodon/reducers/index.js b/app/javascript/mastodon/reducers/index.js index 53e2dd681..af2ef595e 100644 --- a/app/javascript/mastodon/reducers/index.js +++ b/app/javascript/mastodon/reducers/index.js @@ -38,6 +38,7 @@ import announcements from './announcements'; import markers from './markers'; import picture_in_picture from './picture_in_picture'; import accounts_map from './accounts_map'; +import history from './history'; const reducers = { announcements, @@ -79,6 +80,7 @@ const reducers = { missed_updates, markers, picture_in_picture, + history, }; export default combineReducers(reducers); diff --git a/app/javascript/mastodon/reducers/settings.js b/app/javascript/mastodon/reducers/settings.js index 2a89919e1..5146abe98 100644 --- a/app/javascript/mastodon/reducers/settings.js +++ b/app/javascript/mastodon/reducers/settings.js @@ -36,6 +36,7 @@ const initialState = ImmutableMap({ mention: false, poll: false, status: false, + update: false, }), quickFilter: ImmutableMap({ @@ -55,6 +56,7 @@ const initialState = ImmutableMap({ mention: true, poll: true, status: true, + update: true, }), sounds: ImmutableMap({ @@ -65,6 +67,7 @@ const initialState = ImmutableMap({ mention: true, poll: true, status: true, + update: true, }), }), diff --git a/app/javascript/mastodon/service_worker/web_push_locales.js b/app/javascript/mastodon/service_worker/web_push_locales.js index 1265f3cfa..807a1bcb9 100644 --- a/app/javascript/mastodon/service_worker/web_push_locales.js +++ b/app/javascript/mastodon/service_worker/web_push_locales.js @@ -20,6 +20,8 @@ filenames.forEach(filename => { 'notification.mention': full['notification.mention'] || '', 'notification.reblog': full['notification.reblog'] || '', 'notification.poll': full['notification.poll'] || '', + 'notification.status': full['notification.status'] || '', + 'notification.update': full['notification.update'] || '', 'status.show_more': full['status.show_more'] || '', 'status.reblog': full['status.reblog'] || '', diff --git a/app/javascript/mastodon/service_worker/web_push_notifications.js b/app/javascript/mastodon/service_worker/web_push_notifications.js index 926c5c4d7..48a2be7e7 100644 --- a/app/javascript/mastodon/service_worker/web_push_notifications.js +++ b/app/javascript/mastodon/service_worker/web_push_notifications.js @@ -102,7 +102,7 @@ const handlePush = (event) => { options.image = undefined; options.actions = [actionExpand(preferred_locale)]; - } else if (notification.type === 'mention') { + } else if (['mention', 'status'].includes(notification.type)) { options.actions = [actionReblog(preferred_locale), actionFavourite(preferred_locale)]; } diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 92061585a..66ce92ce2 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -1203,6 +1203,10 @@ a.sparkline { } } } + + @media screen and (max-width: 930px) { + grid-template-columns: minmax(0, 1fr); + } } .account-card { @@ -1410,8 +1414,9 @@ a.sparkline { } &__button { + box-sizing: border-box; flex: 0 0 auto; - width: 100px; + width: 200px; padding: 15px; padding-right: 0; @@ -1427,4 +1432,38 @@ a.sparkline { color: $dark-text-color; } } + + @media screen and (max-width: 800px) { + border: 0; + + &__item { + flex-direction: column; + border: 0; + + &__button { + width: 100%; + padding: 15px 0; + } + + &__description { + padding: 0; + padding-bottom: 15px; + } + } + } +} + +.section-skip-link { + float: right; + + a { + color: $ui-highlight-color; + text-decoration: none; + + &:hover, + &:focus, + &:active { + text-decoration: underline; + } + } } diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 919480e7e..5304bec34 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -1889,8 +1889,47 @@ a.account__display-name { box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4); z-index: 9999; - ul { - list-style: none; + &__text-button { + display: inline; + color: inherit; + background: transparent; + border: 0; + margin: 0; + padding: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; + + &:focus { + outline: 1px dotted; + } + } + + &__container { + &__header { + border-bottom: 1px solid darken($ui-secondary-color, 8%); + padding: 4px 14px; + padding-bottom: 8px; + font-size: 13px; + line-height: 18px; + color: $inverted-text-color; + } + + &__list { + list-style: none; + + &--scrollable { + max-height: 300px; + overflow-y: scroll; + } + } + + &--loading { + display: flex; + align-items: center; + justify-content: center; + padding: 30px 45px; + } } &.left { @@ -1946,18 +1985,29 @@ a.account__display-name { } .dropdown-menu__item { - a { - font-size: 13px; - line-height: 18px; + font-size: 13px; + line-height: 18px; + display: block; + color: $inverted-text-color; + + a, + button { + font-family: inherit; + font-size: inherit; + line-height: inherit; display: block; + width: 100%; padding: 4px 14px; + border: 0; + margin: 0; box-sizing: border-box; text-decoration: none; background: $ui-secondary-color; - color: $inverted-text-color; + color: inherit; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; + text-align: inherit; &:focus, &:hover, @@ -1969,6 +2019,42 @@ a.account__display-name { } } +.dropdown-menu__item--text { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + padding: 4px 14px; +} + +.dropdown-menu__item.edited-timestamp__history__item { + border-bottom: 1px solid darken($ui-secondary-color, 8%); + + &:last-child { + border-bottom: 0; + } + + &.dropdown-menu__item--text, + a, + button { + padding: 8px 14px; + } +} + +.inline-account { + display: inline-flex; + align-items: center; + vertical-align: top; + + .account__avatar { + margin-right: 5px; + border-radius: 50%; + } + + strong { + font-weight: 600; + } +} + .dropdown--active .dropdown__content { display: block; line-height: 18px; @@ -3631,36 +3717,48 @@ a.status-card.compact:hover { top: 50%; left: 50%; transform: translate(-50%, -50%); + display: flex; + align-items: center; + justify-content: center; +} - span { - display: block; - float: left; - transform: translateX(-50%); - margin: 82px 0 0 50%; - white-space: nowrap; +.circular-progress { + color: lighten($ui-base-color, 26%); + animation: 1.4s linear 0s infinite normal none running simple-rotate; + + circle { + stroke: currentColor; + stroke-dasharray: 80px, 200px; + stroke-dashoffset: 0; + animation: circular-progress 1.4s ease-in-out infinite; } } -.loading-indicator__figure { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 42px; - height: 42px; - box-sizing: border-box; - background-color: transparent; - border: 0 solid lighten($ui-base-color, 26%); - border-width: 6px; - border-radius: 50%; -} +@keyframes circular-progress { + 0% { + stroke-dasharray: 1px, 200px; + stroke-dashoffset: 0; + } -.no-reduce-motion .loading-indicator span { - animation: loader-label 1.15s infinite cubic-bezier(0.215, 0.61, 0.355, 1); + 50% { + stroke-dasharray: 100px, 200px; + stroke-dashoffset: -15px; + } + + 100% { + stroke-dasharray: 100px, 200px; + stroke-dashoffset: -125px; + } } -.no-reduce-motion .loading-indicator__figure { - animation: loader-figure 1.15s infinite cubic-bezier(0.215, 0.61, 0.355, 1); +@keyframes simple-rotate { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } } @keyframes spring-rotate-in { @@ -3707,40 +3805,6 @@ a.status-card.compact:hover { } } -@keyframes loader-figure { - 0% { - width: 0; - height: 0; - background-color: lighten($ui-base-color, 26%); - } - - 29% { - background-color: lighten($ui-base-color, 26%); - } - - 30% { - width: 42px; - height: 42px; - background-color: transparent; - border-width: 21px; - opacity: 1; - } - - 100% { - width: 42px; - height: 42px; - border-width: 0; - opacity: 0; - background-color: transparent; - } -} - -@keyframes loader-label { - 0% { opacity: 0.25; } - 30% { opacity: 1; } - 100% { opacity: 0.25; } -} - .video-error-cover { align-items: center; background: $base-overlay-background; @@ -4940,7 +5004,8 @@ a.status-card.compact:hover { .report-modal, .actions-modal, .mute-modal, -.block-modal { +.block-modal, +.compare-history-modal { background: lighten($ui-secondary-color, 8%); color: $inverted-text-color; border-radius: 8px; @@ -5342,6 +5407,41 @@ a.status-card.compact:hover { } } +.compare-history-modal { + .report-modal__target { + border-bottom: 1px solid $ui-secondary-color; + } + + &__container { + padding: 30px; + pointer-events: all; + } + + .status__content { + color: $inverted-text-color; + font-size: 19px; + line-height: 24px; + + .emojione { + width: 24px; + height: 24px; + margin: -1px 0 0; + } + + a { + color: $highlight-text-color; + } + + hr { + height: 0.25rem; + padding: 0; + background-color: $ui-secondary-color; + border: 0; + margin: 20px 0; + } + } +} + .loading-bar { background-color: $highlight-text-color; height: 3px; diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index ad273c20b..cf31b6ff6 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -112,7 +112,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity url: @status_parser.url || @status_parser.uri, account: @account, text: converted_object_type? ? converted_text : (@status_parser.text || ''), - language: @status_parser.language || detected_language, + language: @status_parser.language, spoiler_text: converted_object_type? ? '' : (@status_parser.spoiler_text || ''), created_at: @status_parser.created_at, edited_at: @status_parser.edited_at, @@ -370,10 +370,6 @@ class ActivityPub::Activity::Create < ActivityPub::Activity Formatter.instance.linkify([@status_parser.title.presence, @status_parser.spoiler_text.presence, @status_parser.url || @status_parser.uri].compact.join("\n\n")) end - def detected_language - LanguageDetector.instance.detect(@status_parser.text, @account) if supported_object_type? - end - def unsupported_media_type?(mime_type) mime_type.present? && !MediaAttachment.supported_mime_types.include?(mime_type) end diff --git a/app/lib/admin/metrics/dimension/languages_dimension.rb b/app/lib/admin/metrics/dimension/languages_dimension.rb index a6aaf5d21..1cc5f4120 100644 --- a/app/lib/admin/metrics/dimension/languages_dimension.rb +++ b/app/lib/admin/metrics/dimension/languages_dimension.rb @@ -20,6 +20,6 @@ class Admin::Metrics::Dimension::LanguagesDimension < Admin::Metrics::Dimension: rows = ActiveRecord::Base.connection.select_all(sql, nil, [[nil, @start_at], [nil, @end_at], [nil, @limit]]) - rows.map { |row| { key: row['locale'], human_key: human_locale(row['locale']), value: row['value'].to_s } } + rows.map { |row| { key: row['locale'], human_key: standard_locale_name(row['locale']), value: row['value'].to_s } } end end diff --git a/app/lib/admin/metrics/dimension/tag_languages_dimension.rb b/app/lib/admin/metrics/dimension/tag_languages_dimension.rb index 1cfa07478..afbc8cde8 100644 --- a/app/lib/admin/metrics/dimension/tag_languages_dimension.rb +++ b/app/lib/admin/metrics/dimension/tag_languages_dimension.rb @@ -25,7 +25,7 @@ class Admin::Metrics::Dimension::TagLanguagesDimension < Admin::Metrics::Dimensi rows = ActiveRecord::Base.connection.select_all(sql, nil, [[nil, params[:id]], [nil, Mastodon::Snowflake.id_at(@start_at, with_random: false)], [nil, Mastodon::Snowflake.id_at(@end_at, with_random: false)], [nil, @limit]]) - rows.map { |row| { key: row['language'], human_key: human_locale(row['language']), value: row['value'].to_s } } + rows.map { |row| { key: row['language'], human_key: standard_locale_name(row['language']), value: row['value'].to_s } } end private diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index f2c4beed5..94d149da3 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -32,7 +32,7 @@ class Formatter include ActionView::Helpers::TextHelper def format(status, **options) - if status.reblog? + if status.respond_to?(:reblog?) && status.reblog? prepend_reblog = status.reblog.account.acct status = status.proper else @@ -53,7 +53,7 @@ class Formatter return html.html_safe # rubocop:disable Rails/OutputSafety end - linkable_accounts = status.active_mentions.map(&:account) + linkable_accounts = status.respond_to?(:active_mentions) ? status.active_mentions.map(&:account) : [] linkable_accounts << status.account html = raw_content diff --git a/app/lib/language_detector.rb b/app/lib/language_detector.rb deleted file mode 100644 index 40452eddc..000000000 --- a/app/lib/language_detector.rb +++ /dev/null @@ -1,101 +0,0 @@ -# frozen_string_literal: true - -class LanguageDetector - include Singleton - - WORDS_THRESHOLD = 4 - RELIABLE_CHARACTERS_RE = /[\p{Hebrew}\p{Arabic}\p{Syriac}\p{Thaana}\p{Nko}\p{Han}\p{Katakana}\p{Hiragana}\p{Hangul}\p{Thai}]+/m - - def initialize - @identifier = CLD3::NNetLanguageIdentifier.new(1, 2048) - end - - def detect(text, account) - input_text = prepare_text(text) - - return if input_text.blank? - - detect_language_code(input_text) || default_locale(account) - end - - def language_names - @language_names = CLD3::TaskContextParams::LANGUAGE_NAMES.map { |name| iso6391(name.to_s).to_sym }.uniq - end - - private - - def prepare_text(text) - simplify_text(text).strip - end - - def unreliable_input?(text) - !reliable_input?(text) - end - - def reliable_input?(text) - sufficient_text_length?(text) || language_specific_character_set?(text) - end - - def sufficient_text_length?(text) - text.split(/\s+/).size >= WORDS_THRESHOLD - end - - def language_specific_character_set?(text) - words = text.scan(RELIABLE_CHARACTERS_RE) - - if words.present? - words.reduce(0) { |acc, elem| acc + elem.size }.to_f / text.size > 0.3 - else - false - end - end - - def detect_language_code(text) - return if unreliable_input?(text) - - result = @identifier.find_language(text) - - iso6391(result.language.to_s).to_sym if result&.reliable? - end - - def iso6391(bcp47) - iso639 = bcp47.split('-').first - - # CLD3 returns grandfathered language code for Hebrew - return 'he' if iso639 == 'iw' - - ISO_639.find(iso639).alpha2 - end - - def simplify_text(text) - new_text = remove_html(text) - new_text.gsub!(FetchLinkCardService::URL_PATTERN, '\1') - new_text.gsub!(Account::MENTION_RE, '') - new_text.gsub!(Tag::HASHTAG_RE) { |string| string.gsub(/[#_]/, '#' => '', '_' => ' ').gsub(/[a-z][A-Z]|[a-zA-Z][\d]/) { |s| s.insert(1, ' ') }.downcase } - new_text.gsub!(/:#{CustomEmoji::SHORTCODE_RE_FRAGMENT}:/, '') - new_text.gsub!(/\s+/, ' ') - new_text - end - - def new_scrubber - scrubber = Rails::Html::PermitScrubber.new - scrubber.tags = %w(br p) - scrubber - end - - def scrubber - @scrubber ||= new_scrubber - end - - def remove_html(text) - text = Loofah.fragment(text).scrub!(scrubber).to_s - text.gsub!('<br>', "\n") - text.gsub!('</p><p>', "\n\n") - text.gsub!(/(^<p>|<\/p>$)/, '') - text - end - - def default_locale(account) - account.user_locale&.to_sym || I18n.default_locale if account.local? - end -end diff --git a/app/lib/link_details_extractor.rb b/app/lib/link_details_extractor.rb index 56ad0717b..fabbd244d 100644 --- a/app/lib/link_details_extractor.rb +++ b/app/lib/link_details_extractor.rb @@ -2,6 +2,20 @@ class LinkDetailsExtractor include ActionView::Helpers::TagHelper + include LanguagesHelper + + # Some publications wrap their JSON-LD data in their <script> tags + # in commented-out CDATA blocks, they need to be removed before + # attempting to parse JSON + CDATA_JUNK_PATTERN = %r{^[\s]*( + (/\*[\s]*<!\[CDATA\[[\s]*\*/) # Block comment style opening + | + (//[\s]*<!\[CDATA\[) # Single-line comment style opening + | + (/\*[\s]*\]\]>[\s]*\*/) # Block comment style closing + | + (//[\s]*\]\]>) # Single-line comment style closing + )[\s]*$}x class StructuredData SUPPORTED_TYPES = %w( @@ -61,6 +75,10 @@ class LinkDetailsExtractor publisher.dig('logo', 'url') end + def valid? + json.present? + end + private def author @@ -134,11 +152,11 @@ class LinkDetailsExtractor end def title - structured_data&.headline || opengraph_tag('og:title') || document.xpath('//title').map(&:content).first + html_entities.decode(structured_data&.headline || opengraph_tag('og:title') || document.xpath('//title').map(&:content).first) end def description - structured_data&.description || opengraph_tag('og:description') || meta_tag('description') + html_entities.decode(structured_data&.description || opengraph_tag('og:description') || meta_tag('description')) end def image @@ -146,11 +164,11 @@ class LinkDetailsExtractor end def canonical_url - valid_url_or_nil(opengraph_tag('og:url') || link_tag('canonical'), same_origin_only: true) || @original_url.to_s + valid_url_or_nil(link_tag('canonical') || opengraph_tag('og:url'), same_origin_only: true) || @original_url.to_s end def provider_name - structured_data&.publisher_name || opengraph_tag('og:site_name') + html_entities.decode(structured_data&.publisher_name || opengraph_tag('og:site_name')) end def provider_url @@ -158,7 +176,7 @@ class LinkDetailsExtractor end def author_name - structured_data&.author_name || opengraph_tag('og:author') || opengraph_tag('og:author:username') + html_entities.decode(structured_data&.author_name || opengraph_tag('og:author') || opengraph_tag('og:author:username')) end def author_url @@ -201,14 +219,6 @@ class LinkDetailsExtractor nil end - def valid_locale_or_nil(str) - return nil if str.blank? - - code, = str.split(/_-/) # Strip out the region from e.g. en_US or ja-JA - locale = ISO_639.find(code) - locale&.alpha2 - end - def link_tag(name) document.xpath("//link[@rel=\"#{name}\"]").map { |link| link['href'] }.first end @@ -223,10 +233,24 @@ class LinkDetailsExtractor def structured_data @structured_data ||= begin - json_ld = document.xpath('//script[@type="application/ld+json"]').map(&:content).first - json_ld.present? ? StructuredData.new(json_ld) : nil - rescue Oj::ParseError - nil + # Some publications have more than one JSON-LD definition on the page, + # and some of those definitions aren't valid JSON either, so we have + # to loop through here until we find something that is the right type + # and doesn't break + document.xpath('//script[@type="application/ld+json"]').filter_map do |element| + json_ld = element.content&.gsub(CDATA_JUNK_PATTERN, '') + + next if json_ld.blank? + + structured_data = StructuredData.new(html_entities.decode(json_ld)) + + next unless structured_data.valid? + + structured_data + rescue Oj::ParseError, EncodingError + Rails.logger.debug("Invalid JSON-LD in #{@original_url}") + next + end.first end end @@ -246,4 +270,8 @@ class LinkDetailsExtractor detector.strip_tags = true end end + + def html_entities + @html_entities ||= HTMLEntities.new + end end diff --git a/app/models/account_suggestions/global_source.rb b/app/models/account_suggestions/global_source.rb index ac764de50..7bca530d4 100644 --- a/app/models/account_suggestions/global_source.rb +++ b/app/models/account_suggestions/global_source.rb @@ -6,7 +6,7 @@ class AccountSuggestions::GlobalSource < AccountSuggestions::Source end def get(account, skip_account_ids: [], limit: 40) - account_ids = account_ids_for_locale(account.user_locale) - [account.id] - skip_account_ids + account_ids = account_ids_for_locale(I18n.locale.to_s.split(/[_-]/).first) - [account.id] - skip_account_ids as_ordered_suggestions( scope(account).where(id: account_ids), diff --git a/app/models/admin/status_batch_action.rb b/app/models/admin/status_batch_action.rb index 85822214b..40f60f379 100644 --- a/app/models/admin/status_batch_action.rb +++ b/app/models/admin/status_batch_action.rb @@ -8,6 +8,12 @@ class Admin::StatusBatchAction attr_accessor :current_account, :type, :status_ids, :report_id + attr_reader :send_email_notification + + def send_email_notification=(value) + @send_email_notification = ActiveModel::Type::Boolean.new.cast(value) + end + def save! process_action! end @@ -55,7 +61,7 @@ class Admin::StatusBatchAction statuses.each { |status| Tombstone.find_or_create_by(uri: status.uri, account: status.account, by_moderator: true) } unless target_account.local? end - UserMailer.warning(target_account.user, @warning).deliver_later! if target_account.local? + UserMailer.warning(target_account.user, @warning).deliver_later! if warnable? RemovalWorker.push_bulk(status_ids) { |status_id| [status_id, { 'preserve' => target_account.local?, 'immediate' => !target_account.local? }] } end @@ -82,6 +88,10 @@ class Admin::StatusBatchAction !report.nil? end + def warnable? + send_email_notification && target_account.local? + end + def target_account @target_account ||= statuses.first.account end diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index 14e6cabae..9eaacdc03 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -208,6 +208,10 @@ class MediaAttachment < ApplicationRecord file.blank? && remote_url.present? end + def significantly_changed? + description_previously_changed? || thumbnail_updated_at_previously_changed? || file_meta_previously_changed? + end + def larger_media_format? video? || gifv? || audio? end diff --git a/app/models/notification.rb b/app/models/notification.rb index 3bf9dd483..c14eb8a7e 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -35,6 +35,7 @@ class Notification < ApplicationRecord follow_request favourite poll + update ).freeze TARGET_STATUS_INCLUDES_BY_TYPE = { @@ -43,6 +44,7 @@ class Notification < ApplicationRecord mention: [mention: :status], favourite: [favourite: :status], poll: [poll: :status], + update: :status, }.freeze belongs_to :account, optional: true @@ -76,7 +78,7 @@ class Notification < ApplicationRecord def target_status case type - when :status + when :status, :update status when :reblog status&.reblog @@ -110,7 +112,7 @@ class Notification < ApplicationRecord cached_status = cached_statuses_by_id[notification.target_status.id] case notification.type - when :status + when :status, :update notification.status = cached_status when :reblog notification.status.reblog = cached_status diff --git a/app/models/poll.rb b/app/models/poll.rb index 71b5e191f..ba08309a1 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -83,6 +83,12 @@ class Poll < ApplicationRecord end end + def reset_votes! + self.cached_tallies = options.map { 0 } + self.votes_count = 0 + votes.delete_all unless new_record? + end + private def prepare_cached_tallies diff --git a/app/models/report.rb b/app/models/report.rb index ceb15133b..3dd8a6fdd 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -39,6 +39,9 @@ class Report < ApplicationRecord scope :with_accounts, -> { includes([:account, :target_account, :action_taken_by_account, :assigned_account].index_with({ user: [:invite_request, :invite] })) } validates :comment, length: { maximum: 1_000 } + validates :rule_ids, absence: true, unless: :violation? + + validate :validate_rule_ids enum category: { other: 0, @@ -122,4 +125,10 @@ class Report < ApplicationRecord def set_uri self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil? && account.local? end + + def validate_rule_ids + return unless violation? + + errors.add(:rule_ids, I18n.t('reports.errors.invalid_rules')) unless rules.size == rule_ids.size + end end diff --git a/app/models/status.rb b/app/models/status.rb index 9bb2b3746..607b70712 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -65,6 +65,7 @@ class Status < ApplicationRecord has_many :favourites, inverse_of: :status, dependent: :destroy has_many :bookmarks, inverse_of: :status, dependent: :destroy has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblog, dependent: :destroy + has_many :reblogged_by_accounts, through: :reblogs, class_name: 'Account', source: :account has_many :replies, foreign_key: 'in_reply_to_id', class_name: 'Status', inverse_of: :thread has_many :mentions, dependent: :destroy, inverse_of: :status has_many :active_mentions, -> { active }, class_name: 'Mention', inverse_of: :status @@ -215,6 +216,17 @@ class Status < ApplicationRecord public_visibility? || unlisted_visibility? end + def snapshot!(media_attachments_changed: false, account_id: nil, at_time: nil) + edits.create!( + text: text, + spoiler_text: spoiler_text, + media_attachments_changed: media_attachments_changed, + account_id: account_id || self.account_id, + content_type: content_type, + created_at: at_time || edited_at + ) + end + def edited? edited_at.present? end diff --git a/app/models/status_edit.rb b/app/models/status_edit.rb index a89df86c5..3d8098fe7 100644 --- a/app/models/status_edit.rb +++ b/app/models/status_edit.rb @@ -11,6 +11,7 @@ # media_attachments_changed :boolean default(FALSE), not null # created_at :datetime not null # updated_at :datetime not null +# content_type :string # class StatusEdit < ApplicationRecord @@ -20,4 +21,9 @@ class StatusEdit < ApplicationRecord default_scope { order(id: :asc) } delegate :local?, to: :status + + def emojis + return @emojis if defined?(@emojis) + @emojis = CustomEmoji.from_text([spoiler_text, text].join(' '), status.account.domain) + end end diff --git a/app/models/trends/tags.rb b/app/models/trends/tags.rb index a425fd207..2ea4550df 100644 --- a/app/models/trends/tags.rb +++ b/app/models/trends/tags.rb @@ -11,12 +11,9 @@ class Trends::Tags < Trends::Base } def register(status, at_time = Time.now.utc) - original_status = status.reblog? ? status.reblog : status + return unless !status.reblog? && status.public_visibility? && !status.account.silenced? - return unless original_status.public_visibility? && status.public_visibility? && - !original_status.account.silenced? && !status.account.silenced? - - original_status.tags.each do |tag| + status.tags.each do |tag| add(tag, status.account_id, at_time) if tag.usable? end end diff --git a/app/models/user.rb b/app/models/user.rb index 9afdc481d..ee20e293e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -245,6 +245,10 @@ class User < ApplicationRecord save! end + def preferred_posting_language + settings.default_language || locale + end + def setting_default_privacy settings.default_privacy || (account.locked? ? 'private' : 'public') end diff --git a/app/policies/status_policy.rb b/app/policies/status_policy.rb index d0359580d..8746fb2c6 100644 --- a/app/policies/status_policy.rb +++ b/app/policies/status_policy.rb @@ -39,7 +39,7 @@ class StatusPolicy < ApplicationPolicy alias unreblog? destroy? def update? - staff? + staff? || owned? end private diff --git a/app/presenters/activitypub/activity_presenter.rb b/app/presenters/activitypub/activity_presenter.rb index 5d174767f..38e8527e8 100644 --- a/app/presenters/activitypub/activity_presenter.rb +++ b/app/presenters/activitypub/activity_presenter.rb @@ -4,7 +4,7 @@ class ActivityPub::ActivityPresenter < ActiveModelSerializers::Model attributes :id, :type, :actor, :published, :to, :cc, :virtual_object class << self - def from_status(status) + def from_status(status, allow_inlining: true) new.tap do |presenter| presenter.id = ActivityPub::TagManager.instance.activity_uri_for(status) presenter.type = status.reblog? ? 'Announce' : 'Create' @@ -15,7 +15,7 @@ class ActivityPub::ActivityPresenter < ActiveModelSerializers::Model presenter.virtual_object = begin if status.reblog? - if status.account == status.proper.account && status.proper.private_visibility? && status.local? + if allow_inlining && status.account == status.proper.account && status.proper.private_visibility? && status.local? status.proper else ActivityPub::TagManager.instance.uri_for(status.proper) diff --git a/app/serializers/activitypub/undo_announce_serializer.rb b/app/serializers/activitypub/undo_announce_serializer.rb index a925efc18..a0f09e8ab 100644 --- a/app/serializers/activitypub/undo_announce_serializer.rb +++ b/app/serializers/activitypub/undo_announce_serializer.rb @@ -22,6 +22,6 @@ class ActivityPub::UndoAnnounceSerializer < ActivityPub::Serializer end def virtual_object - ActivityPub::ActivityPresenter.from_status(object) + ActivityPub::ActivityPresenter.from_status(object, allow_inlining: false) end end diff --git a/app/serializers/rest/notification_serializer.rb b/app/serializers/rest/notification_serializer.rb index 27b031fcc..69b81f6de 100644 --- a/app/serializers/rest/notification_serializer.rb +++ b/app/serializers/rest/notification_serializer.rb @@ -11,6 +11,6 @@ class REST::NotificationSerializer < ActiveModel::Serializer end def status_type? - [:favourite, :reblog, :status, :mention, :poll].include?(object.type) + [:favourite, :reblog, :status, :mention, :poll, :update].include?(object.type) end end diff --git a/app/serializers/rest/status_edit_serializer.rb b/app/serializers/rest/status_edit_serializer.rb index b123b4e09..a1f9e824e 100644 --- a/app/serializers/rest/status_edit_serializer.rb +++ b/app/serializers/rest/status_edit_serializer.rb @@ -1,6 +1,14 @@ # frozen_string_literal: true class REST::StatusEditSerializer < ActiveModel::Serializer - attributes :text, :spoiler_text, :media_attachments_changed, - :created_at + has_one :account, serializer: REST::AccountSerializer + + attributes :content, :spoiler_text, + :media_attachments_changed, :created_at + + has_many :emojis, serializer: REST::CustomEmojiSerializer + + def content + Formatter.instance.format(object) + end end diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index 977928127..7438a7c53 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -95,10 +95,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService # If for some reasons the options were changed, it invalidates all previous # votes, so we need to remove them - if poll_parser.significantly_changes?(poll) - @poll_changed = true - poll.votes.delete_all unless poll.new_record? - end + @poll_changed = true if poll_parser.significantly_changes?(poll) poll.last_fetched_at = Time.now.utc poll.options = poll_parser.options @@ -106,6 +103,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService poll.expires_at = poll_parser.expires_at poll.voters_count = poll_parser.voters_count poll.cached_tallies = poll_parser.cached_tallies + poll.reset_votes! if @poll_changed poll.save! @status.poll_id = poll.id @@ -120,7 +118,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService @status.text = @status_parser.text || '' @status.spoiler_text = @status_parser.spoiler_text || '' @status.sensitive = @account.sensitized? || @status_parser.sensitive || false - @status.language = @status_parser.language || detected_language + @status.language = @status_parser.language @status.edited_at = @status_parser.edited_at || Time.now.utc if significant_changes? @status.save! @@ -210,10 +208,6 @@ class ActivityPub::ProcessStatusUpdateService < BaseService { redis: Redis.current, key: "create:#{@uri}", autorelease: 15.minutes.seconds } end - def detected_language - LanguageDetector.instance.detect(@status_parser.text, @account) - end - def create_previous_edit! # We only need to create a previous edit when no previous edits exist, e.g. # when the status has never been edited. For other cases, we always create @@ -221,24 +215,18 @@ class ActivityPub::ProcessStatusUpdateService < BaseService return if @status.edits.any? - @status.edits.create( - text: @status.text, - spoiler_text: @status.spoiler_text, + @status.snapshot!( media_attachments_changed: false, - account_id: @account.id, - created_at: @status.created_at + at_time: @status.created_at ) end def create_edit! return unless significant_changes? - @status_edit = @status.edits.create( - text: @status.text, - spoiler_text: @status.spoiler_text, + @status.snapshot!( media_attachments_changed: @media_attachments_changed || @poll_changed, - account_id: @account.id, - created_at: @status.edited_at + account_id: @account.id ) end diff --git a/app/services/concerns/payloadable.rb b/app/services/concerns/payloadable.rb index 3e45570c3..04c3798fe 100644 --- a/app/services/concerns/payloadable.rb +++ b/app/services/concerns/payloadable.rb @@ -1,13 +1,21 @@ # frozen_string_literal: true module Payloadable + # @param [ActiveModelSerializers::Model] record + # @param [ActiveModelSerializers::Serializer] serializer + # @param [Hash] options + # @option options [Account] :signer + # @option options [String] :sign_with + # @option options [Boolean] :always_sign + # @return [Hash] def serialize_payload(record, serializer, options = {}) - signer = options.delete(:signer) - sign_with = options.delete(:sign_with) - payload = ActiveModelSerializers::SerializableResource.new(record, options.merge(serializer: serializer, adapter: ActivityPub::Adapter)).as_json - object = record.respond_to?(:virtual_object) ? record.virtual_object : record + signer = options.delete(:signer) + sign_with = options.delete(:sign_with) + always_sign = options.delete(:always_sign) + payload = ActiveModelSerializers::SerializableResource.new(record, options.merge(serializer: serializer, adapter: ActivityPub::Adapter)).as_json + object = record.respond_to?(:virtual_object) ? record.virtual_object : record - if (object.respond_to?(:sign?) && object.sign?) && signer && signing_enabled? + if (object.respond_to?(:sign?) && object.sign?) && signer && (always_sign || signing_enabled?) ActivityPub::LinkedDataSignature.new(payload).sign!(signer, sign_with: sign_with) else payload diff --git a/app/services/delete_account_service.rb b/app/services/delete_account_service.rb index 0e3fedfe7..a572a7c59 100644 --- a/app/services/delete_account_service.rb +++ b/app/services/delete_account_service.rb @@ -265,7 +265,7 @@ class DeleteAccountService < BaseService end def delete_actor_json - @delete_actor_json ||= Oj.dump(serialize_payload(@account, ActivityPub::DeleteActorSerializer, signer: @account)) + @delete_actor_json ||= Oj.dump(serialize_payload(@account, ActivityPub::DeleteActorSerializer, signer: @account, always_sign: true)) end def delivery_inboxes diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index 46feec5aa..08fae7935 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -34,6 +34,7 @@ class FanOutOnWriteService < BaseService def fan_out_to_local_recipients! deliver_to_self! notify_mentioned_accounts! + notify_about_update! if update? case @status.visibility.to_sym when :public, :unlisted, :private @@ -66,6 +67,14 @@ class FanOutOnWriteService < BaseService end end + def notify_about_update! + @status.reblogged_by_accounts.merge(Account.local).select(:id).reorder(nil).find_in_batches do |accounts| + LocalNotificationWorker.push_bulk(accounts) do |account| + [account.id, @status.id, 'Status', 'update'] + end + end + end + def deliver_to_all_followers! @account.followers_for_local_distribution.select(:id).reorder(nil).find_in_batches do |followers| FeedInsertWorker.push_bulk(followers) do |follower| diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb index 0f3516d28..039e007f5 100644 --- a/app/services/notify_service.rb +++ b/app/services/notify_service.rb @@ -46,6 +46,10 @@ class NotifyService < BaseService false end + def blocked_update? + false + end + def following_sender? return @following_sender if defined?(@following_sender) @following_sender = @recipient.following?(@notification.from_account) || @recipient.requested?(@notification.from_account) diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 9d26e0f5b..c5061dd63 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -2,6 +2,7 @@ class PostStatusService < BaseService include Redisable + include LanguagesHelper MIN_SCHEDULE_OFFSET = 5.minutes.freeze @@ -118,10 +119,6 @@ class PostStatusService < BaseService raise Mastodon::ValidationError, I18n.t('media_attachments.validations.not_ready') if @media.any?(&:not_processed?) end - def language_from_option(str) - ISO_639.find(str)&.alpha2 - end - def process_mentions_service ProcessMentionsService.new end @@ -174,7 +171,7 @@ class PostStatusService < BaseService sensitive: @sensitive, spoiler_text: @options[:spoiler_text] || '', visibility: @visibility, - language: language_from_option(@options[:language]) || @account.user&.setting_default_language&.presence || LanguageDetector.instance.detect(@text, @account), + language: valid_locale_or_nil(@options[:language].presence || @account.user&.preferred_posting_language || I18n.default_locale), application: @options[:application], content_type: @options[:content_type] || @account.user&.setting_default_content_type, rate_limit: @options[:with_rate_limit], diff --git a/app/services/process_hashtags_service.rb b/app/services/process_hashtags_service.rb index 47277c56c..43d7bcca6 100644 --- a/app/services/process_hashtags_service.rb +++ b/app/services/process_hashtags_service.rb @@ -1,20 +1,40 @@ # frozen_string_literal: true class ProcessHashtagsService < BaseService - def call(status, tags = []) - tags = Extractor.extract_hashtags(status.text) if status.local? - records = [] - - Tag.find_or_create_by_names(tags) do |tag| - status.tags << tag - records << tag - tag.update(last_status_at: status.created_at) if tag.last_status_at.nil? || (tag.last_status_at < status.created_at && tag.last_status_at < 12.hours.ago) + def call(status, raw_tags = []) + @status = status + @account = status.account + @raw_tags = status.local? ? Extractor.extract_hashtags(status.text) : raw_tags + @previous_tags = status.tags.to_a + @current_tags = [] + + assign_tags! + update_featured_tags! + end + + private + + def assign_tags! + @status.tags = @current_tags = Tag.find_or_create_by_names(@raw_tags) + end + + def update_featured_tags! + return unless @status.distributable? + + added_tags = @current_tags - @previous_tags + + unless added_tags.empty? + @account.featured_tags.where(tag_id: added_tags.map(&:id)).each do |featured_tag| + featured_tag.increment(@status.created_at) + end end - return unless status.distributable? + removed_tags = @previous_tags - @current_tags - status.account.featured_tags.where(tag_id: records.map(&:id)).each do |featured_tag| - featured_tag.increment(status.created_at) + unless removed_tags.empty? + @account.featured_tags.where(tag_id: removed_tags.map(&:id)).each do |featured_tag| + featured_tag.decrement(@status.id) + end end end end diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb index e41ad2b0a..361cd4d82 100644 --- a/app/services/remove_status_service.rb +++ b/app/services/remove_status_service.rb @@ -97,7 +97,7 @@ class RemoveStatusService < BaseService end def signed_activity_json - @signed_activity_json ||= Oj.dump(serialize_payload(@status, @status.reblog? ? ActivityPub::UndoAnnounceSerializer : ActivityPub::DeleteSerializer, signer: @account)) + @signed_activity_json ||= Oj.dump(serialize_payload(@status, @status.reblog? ? ActivityPub::UndoAnnounceSerializer : ActivityPub::DeleteSerializer, signer: @account, always_sign: true)) end def remove_reblogs diff --git a/app/services/report_service.rb b/app/services/report_service.rb index bc0a8b464..caf99ab6e 100644 --- a/app/services/report_service.rb +++ b/app/services/report_service.rb @@ -8,13 +8,15 @@ class ReportService < BaseService @target_account = target_account @status_ids = options.delete(:status_ids) || [] @comment = options.delete(:comment) || '' + @category = options.delete(:category) || 'other' + @rule_ids = options.delete(:rule_ids) @options = options raise ActiveRecord::RecordNotFound if @target_account.suspended? create_report! notify_staff! - forward_to_origin! if !@target_account.local? && ActiveModel::Type::Boolean.new.cast(@options[:forward]) + forward_to_origin! if forward? @report end @@ -27,7 +29,9 @@ class ReportService < BaseService status_ids: @status_ids, comment: @comment, uri: @options[:uri], - forwarded: ActiveModel::Type::Boolean.new.cast(@options[:forward]) + forwarded: forward?, + category: @category, + rule_ids: @rule_ids ) end @@ -48,6 +52,10 @@ class ReportService < BaseService ) end + def forward? + !@target_account.local? && ActiveModel::Type::Boolean.new.cast(@options[:forward]) + end + def payload Oj.dump(serialize_payload(@report, ActivityPub::FlagSerializer, account: some_local_account)) end diff --git a/app/services/update_status_service.rb b/app/services/update_status_service.rb new file mode 100644 index 000000000..76530a54c --- /dev/null +++ b/app/services/update_status_service.rb @@ -0,0 +1,153 @@ +# frozen_string_literal: true + +class UpdateStatusService < BaseService + include Redisable + include LanguagesHelper + + # @param [Status] status + # @param [Integer] account_id + # @param [Hash] options + # @option options [Array<Integer>] :media_ids + # @option options [Hash] :poll + # @option options [String] :text + # @option options [String] :spoiler_text + # @option options [Boolean] :sensitive + # @option options [String] :language + # @option options [String] :content_type + def call(status, account_id, options = {}) + @status = status + @options = options + @account_id = account_id + @media_attachments_changed = false + @poll_changed = false + + Status.transaction do + create_previous_edit! + update_media_attachments! + update_poll! + update_immediate_attributes! + create_edit! + end + + queue_poll_notifications! + reset_preview_card! + update_metadata! + broadcast_updates! + + @status + end + + private + + def update_media_attachments! + previous_media_attachments = @status.media_attachments.to_a + next_media_attachments = validate_media! + removed_media_attachments = previous_media_attachments - next_media_attachments + added_media_attachments = next_media_attachments - previous_media_attachments + + MediaAttachment.where(id: removed_media_attachments.map(&:id)).update_all(status_id: nil) + MediaAttachment.where(id: added_media_attachments.map(&:id)).update_all(status_id: @status.id) + + @status.media_attachments.reload + @media_attachments_changed = true if removed_media_attachments.any? || added_media_attachments.any? + end + + def validate_media! + return [] if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable) + + raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4 || @options[:poll].present? + + media_attachments = @status.account.media_attachments.where(status_id: [nil, @status.id]).where(scheduled_status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i)).to_a + + raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if media_attachments.size > 1 && media_attachments.find(&:audio_or_video?) + raise Mastodon::ValidationError, I18n.t('media_attachments.validations.not_ready') if media_attachments.any?(&:not_processed?) + + media_attachments + end + + def update_poll! + previous_poll = @status.preloadable_poll + @previous_expires_at = previous_poll&.expires_at + + if @options[:poll].present? + poll = previous_poll || @status.account.polls.new(status: @status, votes_count: 0) + + # If for some reasons the options were changed, it invalidates all previous + # votes, so we need to remove them + @poll_changed = true if @options[:poll][:options] != poll.options || ActiveModel::Type::Boolean.new.cast(@options[:poll][:multiple]) != poll.multiple + + poll.options = @options[:poll][:options] + poll.hide_totals = @options[:poll][:hide_totals] || false + poll.multiple = @options[:poll][:multiple] || false + poll.expires_in = @options[:poll][:expires_in] + poll.reset_votes! if @poll_changed + poll.save! + + @status.poll_id = poll.id + elsif previous_poll.present? + previous_poll.destroy + @poll_changed = true + @status.poll_id = nil + end + end + + def update_immediate_attributes! + @status.text = @options[:text].presence || @options.delete(:spoiler_text) || '' + @status.spoiler_text = @options[:spoiler_text] || '' + @status.sensitive = @options[:sensitive] || @options[:spoiler_text].present? + @status.language = valid_locale_or_nil(@options[:language] || @status.language || @status.account.user&.preferred_posting_language || I18n.default_locale) + @status.content_type = @options[:content_type] || @status.content_type + @status.edited_at = Time.now.utc + + @status.save! + end + + def reset_preview_card! + return unless @status.text_previously_changed? + + @status.preview_cards.clear + LinkCrawlWorker.perform_async(@status.id) + end + + def update_metadata! + ProcessHashtagsService.new.call(@status) + ProcessMentionsService.new.call(@status) + end + + def broadcast_updates! + DistributionWorker.perform_async(@status.id, { 'update' => true }) + ActivityPub::StatusUpdateDistributionWorker.perform_async(@status.id) unless @status.local_only? + end + + def queue_poll_notifications! + poll = @status.preloadable_poll + + # If the poll had no expiration date set but now has, or now has a sooner + # expiration date, and people have voted, schedule a notification + + return unless poll.present? && poll.expires_at.present? && poll.votes.exists? + + PollExpirationNotifyWorker.remove_from_scheduled(poll.id) if @previous_expires_at.present? && @previous_expires_at > poll.expires_at + PollExpirationNotifyWorker.perform_at(poll.expires_at + 5.minutes, poll.id) + end + + def create_previous_edit! + # We only need to create a previous edit when no previous edits exist, e.g. + # when the status has never been edited. For other cases, we always create + # an edit, so the step can be skipped + + return if @status.edits.any? + + @status.snapshot!( + media_attachments_changed: false, + at_time: @status.created_at + ) + end + + def create_edit! + @status.snapshot!( + media_attachments_changed: @media_attachments_changed || @poll_changed, + account_id: @account_id + ) + end +end diff --git a/app/validators/import_validator.rb b/app/validators/import_validator.rb index a182abfa5..9f19aee2a 100644 --- a/app/validators/import_validator.rb +++ b/app/validators/import_validator.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'csv' + class ImportValidator < ActiveModel::Validator KNOWN_HEADERS = [ 'Account address', diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index 3867d1b19..f3853d629 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -147,7 +147,7 @@ %tr %th= t('simple_form.labels.defaults.locale') - %td= @account.user_locale + %td= standard_locale_name(@account.user_locale) %td %tr diff --git a/app/views/admin/follow_recommendations/show.html.haml b/app/views/admin/follow_recommendations/show.html.haml index 2878f07d7..85dee210a 100644 --- a/app/views/admin/follow_recommendations/show.html.haml +++ b/app/views/admin/follow_recommendations/show.html.haml @@ -10,7 +10,7 @@ .filter-subset.filter-subset--with-select %strong= t('admin.follow_recommendations.language') .input.select.optional - = select_tag :language, options_for_select(I18n.available_locales.map { |key| [human_locale(key), key]}, @language) + = select_tag :language, options_for_select(I18n.available_locales.map { |key| key.to_s.split(/[_-]/).first.to_sym }.uniq.map { |key| [standard_locale_name(key), key]}, @language) .filter-subset %strong= t('admin.follow_recommendations.status') diff --git a/app/views/admin/instances/show.html.haml b/app/views/admin/instances/show.html.haml index e520bca0c..4db8fd15c 100644 --- a/app/views/admin/instances/show.html.haml +++ b/app/views/admin/instances/show.html.haml @@ -84,5 +84,5 @@ = link_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }, class: 'button' - else = link_to t('admin.instances.delivery.restart'), restart_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }, class: 'button' - - unless @instance.delivery_failure_tracker.available? && @instance.accounts_count > 0 + - if !@instance.delivery_failure_tracker.available? || @instance.accounts_count.zero? || @instance.domain_block&.suspend? = link_to t('admin.instances.purge'), admin_instance_path(@instance), data: { confirm: t('admin.instances.confirm_purge'), method: :delete }, class: 'button' diff --git a/app/views/admin/reports/_actions.html.haml b/app/views/admin/reports/_actions.html.haml new file mode 100644 index 000000000..f3162b325 --- /dev/null +++ b/app/views/admin/reports/_actions.html.haml @@ -0,0 +1,27 @@ += form_tag admin_report_actions_path(@report), method: :post do + .report-actions + .report-actions__item + .report-actions__item__button + = link_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(@report), method: :post, class: 'button' + .report-actions__item__description + = t('admin.reports.actions.resolve_description_html') + .report-actions__item + .report-actions__item__button + = button_tag t('admin.reports.delete_and_resolve'), name: :delete, class: 'button button--destructive' + .report-actions__item__description + = t('admin.reports.actions.delete_description_html') + .report-actions__item + .report-actions__item__button + = button_tag t('admin.accounts.silence'), name: :silence, class: 'button button--destructive' + .report-actions__item__description + = t('admin.reports.actions.silence_description_html') + .report-actions__item + .report-actions__item__button + = button_tag t('admin.accounts.suspend'), name: :suspend, class: 'button button--destructive' + .report-actions__item__description + = t('admin.reports.actions.suspend_description_html') + .report-actions__item + .report-actions__item__button + = link_to t('admin.accounts.custom'), new_admin_account_action_path(@report.target_account_id, report_id: @report.id), class: 'button' + .report-actions__item__description + = t('admin.reports.actions.other_description_html') diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml index e03c1220c..018a0c54a 100644 --- a/app/views/admin/reports/show.html.haml +++ b/app/views/admin/reports/show.html.haml @@ -120,24 +120,30 @@ - if @report.comment.present? %p= t('admin.reports.comment_description_html', name: content_tag(:strong, @report.account.username, class: 'username')) - .report-notes__item - = image_tag @report.account.avatar.url, class: 'report-notes__item__avatar' - - .report-notes__item__header - %span.username - = link_to display_name(@report.account), admin_account_path(@report.account_id) - %time{ datetime: @report.created_at.iso8601, title: l(@report.created_at) } - - if @report.created_at.today? - = t('admin.report_notes.today_at', time: l(@report.created_at, format: :time)) - - else - = l @report.created_at.to_date + .report-notes + .report-notes__item + = image_tag @report.account.avatar.url, class: 'report-notes__item__avatar' + + .report-notes__item__header + %span.username + = link_to display_name(@report.account), admin_account_path(@report.account_id) + %time{ datetime: @report.created_at.iso8601, title: l(@report.created_at) } + - if @report.created_at.today? + = t('admin.report_notes.today_at', time: l(@report.created_at, format: :time)) + - else + = l @report.created_at.to_date - .report-notes__item__content - = simple_format(h(@report.comment)) + .report-notes__item__content + = simple_format(h(@report.comment)) %hr.spacer/ -%h3= t 'admin.reports.statuses' +%h3 + = t 'admin.reports.statuses' + %small.section-skip-link + = link_to '#actions' do + = fa_icon 'angle-double-down' + = t('admin.reports.skip_to_actions') %p = t 'admin.reports.statuses_description_html' @@ -152,8 +158,6 @@ .batch-table__toolbar__actions - if !@statuses.empty? && @report.unresolved? = f.button safe_join([fa_icon('times'), t('admin.statuses.batch.remove_from_report')]), name: :remove_from_report, class: 'table-action-link', type: :submit - = f.button safe_join([fa_icon('trash'), t('admin.reports.delete_and_resolve')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - - else .batch-table__body - if @statuses.empty? = nothing_here 'nothing-here--under-tabs' @@ -163,24 +167,9 @@ - if @report.unresolved? %hr.spacer/ - %p= t 'admin.reports.actions_description_html' - - .report-actions - .report-actions__item - .report-actions__item__button - = link_to t('admin.accounts.silence'), new_admin_account_action_path(@report.target_account_id, type: 'silence', report_id: @report.id), class: 'button button--destructive' - .report-actions__item__description - = t('admin.reports.actions.silence_description_html') - .report-actions__item - .report-actions__item__button - = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(@report.target_account_id, report_id: @report.id, type: 'suspend'), class: 'button button--destructive' - .report-actions__item__description - = t('admin.reports.actions.suspend_description_html') - .report-actions__item - .report-actions__item__button - = link_to t('admin.accounts.custom'), new_admin_account_action_path(@report.target_account_id, report_id: @report.id), class: 'button' - .report-actions__item__description - = t('admin.reports.actions.other_description_html') + %p#actions= t 'admin.reports.actions_description_html' + + = render partial: 'admin/reports/actions' - unless @action_logs.empty? %hr.spacer/ diff --git a/app/views/admin/trends/links/_preview_card.html.haml b/app/views/admin/trends/links/_preview_card.html.haml index b88c1be2f..d88e06bfd 100644 --- a/app/views/admin/trends/links/_preview_card.html.haml +++ b/app/views/admin/trends/links/_preview_card.html.haml @@ -13,7 +13,7 @@ • - if preview_card.language.present? - = human_locale(preview_card.language) + = standard_locale_name(preview_card.language) • = t('admin.trends.links.shared_by_over_week', count: preview_card.history.reduce(0) { |sum, day| sum + day.accounts }) diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml index 4170c9e44..c3342ddf0 100644 --- a/app/views/settings/preferences/appearance/show.html.haml +++ b/app/views/settings/preferences/appearance/show.html.haml @@ -6,7 +6,7 @@ = simple_form_for current_user, url: settings_preferences_appearance_path, html: { method: :put, id: 'edit_user' } do |f| .fields-group - = f.input :locale, collection: I18n.available_locales, wrapper: :with_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, selected: I18n.locale, hint: false + = f.input :locale, collection: I18n.available_locales, wrapper: :with_label, include_blank: false, label_method: lambda { |locale| native_locale_name(locale) }, selected: I18n.locale, hint: false - unless I18n.locale == :en .flash-message.translation-prompt diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index 372d934fb..1f922a5c6 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -27,7 +27,7 @@ = f.input :setting_default_privacy, collection: Status.selectable_visibilities, wrapper: :with_label, include_blank: false, label_method: lambda { |visibility| safe_join([I18n.t("statuses.visibilities.#{visibility}"), I18n.t("statuses.visibilities.#{visibility}_long")], ' - ') }, required: false, hint: false .fields-group.fields-row__column.fields-row__column-6 - = f.input :setting_default_language, collection: [nil] + filterable_languages.sort, wrapper: :with_label, label_method: lambda { |locale| locale.nil? ? I18n.t('statuses.language_detection') : human_locale(locale) }, required: false, include_blank: false, hint: false + = f.input :setting_default_language, collection: [nil] + filterable_languages, wrapper: :with_label, label_method: lambda { |locale| locale.nil? ? I18n.t('statuses.default_language') : native_locale_name(locale) }, required: false, include_blank: false, hint: false .fields-group = f.input :setting_default_sensitive, as: :boolean, wrapper: :with_label @@ -41,7 +41,7 @@ %h4= t 'preferences.public_timelines' .fields-group - = f.input :chosen_languages, collection: filterable_languages.sort, wrapper: :with_block_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' + = f.input :chosen_languages, collection: filterable_languages, wrapper: :with_block_label, include_blank: false, label_method: lambda { |locale| native_locale_name(locale) }, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' .actions = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/workers/activitypub/processing_worker.rb b/app/workers/activitypub/processing_worker.rb index cef595319..37e316354 100644 --- a/app/workers/activitypub/processing_worker.rb +++ b/app/workers/activitypub/processing_worker.rb @@ -6,7 +6,10 @@ class ActivityPub::ProcessingWorker sidekiq_options backtrace: true, retry: 8 def perform(account_id, body, delivered_to_account_id = nil) - ActivityPub::ProcessCollectionService.new.call(body, Account.find(account_id), override_timestamps: true, delivered_to_account_id: delivered_to_account_id, delivery: true) + account = Account.find_by(id: account_id) + return if account.nil? + + ActivityPub::ProcessCollectionService.new.call(body, account, override_timestamps: true, delivered_to_account_id: delivered_to_account_id, delivery: true) rescue ActiveRecord::RecordInvalid => e Rails.logger.debug "Error processing incoming ActivityPub object: #{e}" end diff --git a/app/workers/activitypub/status_update_distribution_worker.rb b/app/workers/activitypub/status_update_distribution_worker.rb new file mode 100644 index 000000000..a79ede2bf --- /dev/null +++ b/app/workers/activitypub/status_update_distribution_worker.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class ActivityPub::StatusUpdateDistributionWorker < ActivityPub::DistributionWorker + # Distribute an profile update to servers that might have a copy + # of the account in question + def perform(status_id, options = {}) + @options = options.with_indifferent_access + @status = Status.find(status_id) + @account = @status.account + + distribute! + rescue ActiveRecord::RecordNotFound + true + end + + protected + + def activity + ActivityPub::ActivityPresenter.new( + id: [ActivityPub::TagManager.instance.uri_for(@status), '#updates/', @status.edited_at.to_i].join, + type: 'Update', + actor: ActivityPub::TagManager.instance.uri_for(@status.account), + published: @status.edited_at, + to: ActivityPub::TagManager.instance.to(@status), + cc: ActivityPub::TagManager.instance.cc(@status), + virtual_object: @status + ) + end +end diff --git a/app/workers/local_notification_worker.rb b/app/workers/local_notification_worker.rb index a22e2834d..749a54b73 100644 --- a/app/workers/local_notification_worker.rb +++ b/app/workers/local_notification_worker.rb @@ -12,7 +12,14 @@ class LocalNotificationWorker activity = activity_class_name.constantize.find(activity_id) end - return if Notification.where(account: receiver, activity: activity).any? + # For most notification types, only one notification should exist, and the older one is + # preferred. For updates, such as when a status is edited, the new notification + # should replace the previous ones. + if type == 'update' + Notification.where(account: receiver, activity: activity, type: 'update').in_batches.delete_all + elsif Notification.where(account: receiver, activity: activity, type: type).any? + return + end NotifyService.new.call(receiver, type || activity_class_name.underscore, activity) rescue ActiveRecord::RecordNotFound diff --git a/app/workers/scheduler/accounts_statuses_cleanup_scheduler.rb b/app/workers/scheduler/accounts_statuses_cleanup_scheduler.rb index f42d4bca6..7195f0ff9 100644 --- a/app/workers/scheduler/accounts_statuses_cleanup_scheduler.rb +++ b/app/workers/scheduler/accounts_statuses_cleanup_scheduler.rb @@ -66,7 +66,7 @@ class Scheduler::AccountsStatusesCleanupScheduler end def compute_budget - threads = Sidekiq::ProcessSet.new.filter { |x| x['queues'].include?('push') }.map { |x| x['concurrency'] }.sum + threads = Sidekiq::ProcessSet.new.select { |x| x['queues'].include?('push') }.map { |x| x['concurrency'] }.sum [PER_THREAD_BUDGET * threads, MAX_BUDGET].min end diff --git a/app/workers/scheduler/follow_recommendations_scheduler.rb b/app/workers/scheduler/follow_recommendations_scheduler.rb index effc63e59..084619cbd 100644 --- a/app/workers/scheduler/follow_recommendations_scheduler.rb +++ b/app/workers/scheduler/follow_recommendations_scheduler.rb @@ -16,28 +16,33 @@ class Scheduler::FollowRecommendationsScheduler AccountSummary.refresh FollowRecommendation.refresh - fallback_recommendations = FollowRecommendation.order(rank: :desc).limit(SET_SIZE).index_by(&:account_id) + fallback_recommendations = FollowRecommendation.order(rank: :desc).limit(SET_SIZE) - I18n.available_locales.each do |locale| + I18n.available_locales.map { |locale| locale.to_s.split(/[_-]/).first }.uniq.each do |locale| recommendations = begin if AccountSummary.safe.filtered.localized(locale).exists? # We can skip the work if no accounts with that language exist - FollowRecommendation.localized(locale).order(rank: :desc).limit(SET_SIZE).index_by(&:account_id) + FollowRecommendation.localized(locale).order(rank: :desc).limit(SET_SIZE).map { |recommendation| [recommendation.account_id, recommendation.rank] } else - {} + [] end end # Use language-agnostic results if there are not enough language-specific ones - missing = SET_SIZE - recommendations.keys.size + missing = SET_SIZE - recommendations.size + + if missing.positive? && fallback_recommendations.size.positive? + max_fallback_rank = fallback_recommendations.first.rank || 0 + + # Language-specific results should be above language-agnostic ones, + # otherwise language-agnostic ones will always overshadow them + recommendations.map! { |(account_id, rank)| [account_id, rank + max_fallback_rank] } - if missing.positive? added = 0 - # Avoid duplicate results - fallback_recommendations.each_value do |recommendation| - next if recommendations.key?(recommendation.account_id) + fallback_recommendations.each do |recommendation| + next if recommendations.any? { |(account_id, _)| account_id == recommendation.account_id } - recommendations[recommendation.account_id] = recommendation + recommendations << [recommendation.account_id, recommendation.rank] added += 1 break if added >= missing @@ -47,8 +52,8 @@ class Scheduler::FollowRecommendationsScheduler redis.pipelined do redis.del(key(locale)) - recommendations.each_value do |recommendation| - redis.zadd(key(locale), recommendation.rank, recommendation.account_id) + recommendations.each do |(account_id, rank)| + redis.zadd(key(locale), rank, account_id) end end end |