diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 137bebc599..40dc72c12d 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -70,7 +70,7 @@ services: hard: -1 libretranslate: - image: libretranslate/libretranslate:v1.4.1 + image: libretranslate/libretranslate:v1.5.2 restart: unless-stopped volumes: - lt-data:/home/libretranslate/.local diff --git a/.simplecov b/.simplecov new file mode 100644 index 0000000000..fbd0207bec --- /dev/null +++ b/.simplecov @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +if ENV['CI'] + require 'simplecov-lcov' + SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true + SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter +else + SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter +end + +SimpleCov.start 'rails' do + enable_coverage :branch + + add_filter 'lib/linter' + + add_group 'Libraries', 'lib' + add_group 'Policies', 'app/policies' + add_group 'Presenters', 'app/presenters' + add_group 'Serializers', 'app/serializers' + add_group 'Services', 'app/services' + add_group 'Validators', 'app/validators' +end diff --git a/app/javascript/mastodon/components/copy_icon_button.jsx b/app/javascript/mastodon/components/copy_icon_button.jsx new file mode 100644 index 0000000000..9b1a36d83a --- /dev/null +++ b/app/javascript/mastodon/components/copy_icon_button.jsx @@ -0,0 +1,44 @@ +import PropTypes from 'prop-types'; +import { useState, useCallback } from 'react'; + +import { defineMessages } from 'react-intl'; + +import classNames from 'classnames'; + +import { useDispatch } from 'react-redux'; + +import { ReactComponent as ContentCopyIcon } from '@material-symbols/svg-600/outlined/content_copy.svg'; + +import { showAlert } from 'mastodon/actions/alerts'; +import { IconButton } from 'mastodon/components/icon_button'; + +const messages = defineMessages({ + copied: { id: 'copy_icon_button.copied', defaultMessage: 'Copied to clipboard' }, +}); + +export const CopyIconButton = ({ title, value, className }) => { + const [copied, setCopied] = useState(false); + const dispatch = useDispatch(); + + const handleClick = useCallback(() => { + navigator.clipboard.writeText(value); + setCopied(true); + dispatch(showAlert({ message: messages.copied })); + setTimeout(() => setCopied(false), 700); + }, [setCopied, value, dispatch]); + + return ( + + ); +}; + +CopyIconButton.propTypes = { + title: PropTypes.string, + value: PropTypes.string, + className: PropTypes.string, +}; diff --git a/app/javascript/mastodon/features/account/components/header.jsx b/app/javascript/mastodon/features/account/components/header.jsx index 7594135a4e..29b46cb43d 100644 --- a/app/javascript/mastodon/features/account/components/header.jsx +++ b/app/javascript/mastodon/features/account/components/header.jsx @@ -14,10 +14,12 @@ import { ReactComponent as LockIcon } from '@material-symbols/svg-600/outlined/l import { ReactComponent as MoreHorizIcon } from '@material-symbols/svg-600/outlined/more_horiz.svg'; import { ReactComponent as NotificationsIcon } from '@material-symbols/svg-600/outlined/notifications.svg'; import { ReactComponent as NotificationsActiveIcon } from '@material-symbols/svg-600/outlined/notifications_active-fill.svg'; +import { ReactComponent as ShareIcon } from '@material-symbols/svg-600/outlined/share.svg'; import { Avatar } from 'mastodon/components/avatar'; import { Badge, AutomatedBadge, GroupBadge } from 'mastodon/components/badge'; import { Button } from 'mastodon/components/button'; +import { CopyIconButton } from 'mastodon/components/copy_icon_button'; import { FollowersCounter, FollowingCounter, StatusesCounter } from 'mastodon/components/counters'; import { Icon } from 'mastodon/components/icon'; import { IconButton } from 'mastodon/components/icon_button'; @@ -46,6 +48,7 @@ const messages = defineMessages({ mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' }, report: { id: 'account.report', defaultMessage: 'Report @{name}' }, share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' }, + copy: { id: 'account.copy', defaultMessage: 'Copy link to profile' }, media: { id: 'account.media', defaultMessage: 'Media' }, blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' }, unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' }, @@ -245,11 +248,10 @@ class Header extends ImmutablePureComponent { const isRemote = account.get('acct') !== account.get('username'); const remoteDomain = isRemote ? account.get('acct').split('@')[1] : null; - let info = []; - let actionBtn = ''; - let bellBtn = ''; - let lockedIcon = ''; - let menu = []; + let actionBtn, bellBtn, lockedIcon, shareBtn; + + let info = []; + let menu = []; if (me !== account.get('id') && account.getIn(['relationship', 'followed_by'])) { info.push(); @@ -267,6 +269,12 @@ class Header extends ImmutablePureComponent { bellBtn = ; } + if ('share' in navigator) { + shareBtn = ; + } else { + shareBtn = ; + } + if (me !== account.get('id')) { if (signedIn && !account.get('relationship')) { // Wait until the relationship is loaded actionBtn = ''; @@ -297,10 +305,6 @@ class Header extends ImmutablePureComponent { if (isRemote) { menu.push({ text: intl.formatMessage(messages.openOriginalPage), href: account.get('url') }); - } - - if ('share' in navigator && !account.get('suspended')) { - menu.push({ text: intl.formatMessage(messages.share, { name: account.get('username') }), action: this.handleShare }); menu.push(null); } @@ -414,6 +418,7 @@ class Header extends ImmutablePureComponent { <> {actionBtn} {bellBtn} + {shareBtn} )} diff --git a/app/javascript/mastodon/locales/an.json b/app/javascript/mastodon/locales/an.json index 6243f8d4ca..a652272fad 100644 --- a/app/javascript/mastodon/locales/an.json +++ b/app/javascript/mastodon/locales/an.json @@ -334,7 +334,6 @@ "lists.search": "Buscar entre la chent a la quala sigues", "lists.subheading": "Las tuyas listas", "load_pending": "{count, plural, one {# nuevo elemento} other {# nuevos elementos}}", - "loading_indicator.label": "Cargando...", "media_gallery.toggle_visible": "{number, plural, one {Amaga la imachen} other {Amaga las imáchens}}", "moved_to_account_banner.text": "La tuya cuenta {disabledAccount} ye actualment deshabilitada perque t'has mudau a {movedToAccount}.", "mute_modal.duration": "Duración", diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index 4a5e047647..979bc9a701 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -389,7 +389,6 @@ "lists.search": "إبحث في قائمة الحسابات التي تُتابِعها", "lists.subheading": "قوائمك", "load_pending": "{count, plural, one {# عنصر جديد} other {# عناصر جديدة}}", - "loading_indicator.label": "جارٍ التحميل…", "media_gallery.toggle_visible": "{number, plural, zero {} one {اخف الصورة} two {اخف الصورتين} few {اخف الصور} many {اخف الصور} other {اخف الصور}}", "moved_to_account_banner.text": "حسابك {disabledAccount} معطل حاليًا لأنك انتقلت إلى {movedToAccount}.", "mute_modal.duration": "المدة", diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json index fed324e2d0..0d49d9a19d 100644 --- a/app/javascript/mastodon/locales/ast.json +++ b/app/javascript/mastodon/locales/ast.json @@ -272,7 +272,6 @@ "lists.search": "Buscar ente los perfiles que sigues", "lists.subheading": "Les tos llistes", "load_pending": "{count, plural, one {# elementu nuevu} other {# elementos nuevos}}", - "loading_indicator.label": "Cargando…", "media_gallery.toggle_visible": "{number, plural, one {Anubrir la imaxe} other {Anubrir les imáxenes}}", "mute_modal.duration": "Duración", "mute_modal.hide_notifications": "¿Quies anubrir los avisos d'esti perfil?", diff --git a/app/javascript/mastodon/locales/be.json b/app/javascript/mastodon/locales/be.json index e8a52ee29c..4f5b247b64 100644 --- a/app/javascript/mastodon/locales/be.json +++ b/app/javascript/mastodon/locales/be.json @@ -390,7 +390,7 @@ "lists.search": "Шукайце сярод людзей, на якіх Вы падпісаны", "lists.subheading": "Вашыя спісы", "load_pending": "{count, plural, one {# новы элемент} few {# новыя элементы} many {# новых элементаў} other {# новых элементаў}}", - "loading_indicator.label": "Загрузка...", + "loading_indicator.label": "Загрузка…", "media_gallery.toggle_visible": "{number, plural, one {Схаваць відарыс} other {Схаваць відарысы}}", "moved_to_account_banner.text": "Ваш уліковы запіс {disabledAccount} зараз адключаны таму што вы перанесены на {movedToAccount}.", "mute_modal.duration": "Працягласць", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "На жаль, зараз немагчыма паказаць вынікі. Вы можаце паспрабаваць выкарыстоўваць пошук і праглядзець старонку агляду, каб знайсці людзей, на якіх можна падпісацца, або паўтарыце спробу пазней.", "onboarding.follows.lead": "Вы самі ствараеце свой хатні канал. Чым больш людзей вы падпішаце, тым больш актыўна і цікавей гэта будзе. Гэтыя профілі могуць стаць добрай адпраўной кропкай — вы заўсёды можаце адмяніць падпіску на іх пазней!", "onboarding.follows.title": "Папулярна на Mastodon", + "onboarding.profile.discoverable": "Уключыць профіль і допісы ў алгарытмы рэкамендацый", + "onboarding.profile.display_name": "Бачнае імя", + "onboarding.profile.display_name_hint": "Ваша поўнае імя або ваш псеўданім…", + "onboarding.profile.indexable": "Індэксаваць публічныя допісы ў пошукавых сістэмах", + "onboarding.profile.lead": "Вы заўсёды можаце выканаць гэта пазней у Наладах, дзе даступна яшчэ больш параметраў.", + "onboarding.profile.note": "Біяграфія", + "onboarding.profile.note_hint": "Вы можаце @згадаць іншых людзей або выкарыстоўваць #хэштэгі…", + "onboarding.profile.save_and_continue": "Захаваць і працягнуць", + "onboarding.profile.title": "Налады профілю", + "onboarding.profile.upload_avatar": "Загрузіць фота профілю", + "onboarding.profile.upload_header": "Загрузіць шапку профілю", "onboarding.share.lead": "Дайце людзям ведаць, як яны могуць знайсці вас на Mastodon!", "onboarding.share.message": "Я {username} на #Mastodon! Сачыце за мной на {url}", "onboarding.share.next_steps": "Магчымыя наступныя крокі:", diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index 83bffd946d..b30dfecaa6 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Резултати от търсене", "emoji_button.symbols": "Символи", "emoji_button.travel": "Пътуване и места", + "empty_column.account_hides_collections": "Този потребител е избрал да не прави това сведение достъпно", "empty_column.account_suspended": "Спрян акаунт", "empty_column.account_timeline": "Тук няма публикации!", "empty_column.account_unavailable": "Профилът не е наличен", @@ -389,7 +390,7 @@ "lists.search": "Търсене измежду последваните", "lists.subheading": "Вашите списъци", "load_pending": "{count, plural, one {# нов елемент} other {# нови елемента}}", - "loading_indicator.label": "Зареждане...", + "loading_indicator.label": "Зареждане…", "media_gallery.toggle_visible": "Скриване на {number, plural, one {изображение} other {изображения}}", "moved_to_account_banner.text": "Вашият акаунт {disabledAccount} сега е изключен, защото се преместихте в {movedToAccount}.", "mute_modal.duration": "Времетраене", @@ -478,6 +479,17 @@ "onboarding.follows.empty": "За съжаление, в момента не могат да се показват резултати. Може да опитате да употребявате търсене или да прегледате страницата за изследване, за да намерите страница за последване, или да опитате пак по-късно.", "onboarding.follows.lead": "Може да бъдете куратор на началния си инфоканал. Последвайки повече хора, по-деен и по-интересен ще става. Тези профили може да са добра начална точка, от която винаги по-късно да спрете да следвате!", "onboarding.follows.title": "Популярно в Mastodon", + "onboarding.profile.discoverable": "Включване на профила и публикации в алгоритмите за откриване", + "onboarding.profile.display_name": "Името на показ", + "onboarding.profile.display_name_hint": "Вашето пълно име или псевдоним…", + "onboarding.profile.indexable": "Включване на обществени публикации в резултатите от търсене", + "onboarding.profile.lead": "Винаги може да завършите това по-късно в настройките, където дори има повече възможности за настройване.", + "onboarding.profile.note": "Биогр.", + "onboarding.profile.note_hint": "Може да @споменавате други хора или #хаштагове…", + "onboarding.profile.save_and_continue": "Запазване и продължаване", + "onboarding.profile.title": "Настройване на профила", + "onboarding.profile.upload_avatar": "Качване на снимка на профила", + "onboarding.profile.upload_header": "Качване на заглавка на профила", "onboarding.share.lead": "Позволете на хората да знаят, че могат да ви намерят в Mastodon!", "onboarding.share.message": "Аз съм {username} в #Mastodon! Елате да ме последвате при {url}", "onboarding.share.next_steps": "Възможни следващи стъпки:", diff --git a/app/javascript/mastodon/locales/bn.json b/app/javascript/mastodon/locales/bn.json index 85d6f2474a..b6e4fbb965 100644 --- a/app/javascript/mastodon/locales/bn.json +++ b/app/javascript/mastodon/locales/bn.json @@ -314,7 +314,6 @@ "lists.search": "যাদের অনুসরণ করেন তাদের ভেতরে খুঁজুন", "lists.subheading": "আপনার তালিকা", "load_pending": "{count, plural, one {# নতুন জিনিস} other {# নতুন জিনিস}}", - "loading_indicator.label": "আসছে...", "media_gallery.toggle_visible": "দৃশ্যতার অবস্থা বদলান", "mute_modal.duration": "সময়কাল", "mute_modal.hide_notifications": "এই ব্যবহারকারীর প্রজ্ঞাপন বন্ধ করবেন ?", diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json index 8449762c2d..39cd732419 100644 --- a/app/javascript/mastodon/locales/br.json +++ b/app/javascript/mastodon/locales/br.json @@ -329,7 +329,6 @@ "lists.search": "Klask e-touez tud heuliet ganeoc'h", "lists.subheading": "Ho listennoù", "load_pending": "{count, plural, one {# dra nevez} other {# dra nevez}}", - "loading_indicator.label": "O kargañ...", "media_gallery.toggle_visible": "{number, plural, one {Kuzhat ar skeudenn} other {Kuzhat ar skeudenn}}", "mute_modal.duration": "Padelezh", "mute_modal.hide_notifications": "Kuzhat kemenadennoù eus an implijer-se ?", diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index 99cae584b0..926343f676 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -390,7 +390,6 @@ "lists.search": "Cerca entre les persones que segueixes", "lists.subheading": "Les teves llistes", "load_pending": "{count, plural, one {# element nou} other {# elements nous}}", - "loading_indicator.label": "Es carrega...", "media_gallery.toggle_visible": "{number, plural, one {Amaga la imatge} other {Amaga les imatges}}", "moved_to_account_banner.text": "El teu compte {disabledAccount} està desactivat perquè l'has mogut a {movedToAccount}.", "mute_modal.duration": "Durada", diff --git a/app/javascript/mastodon/locales/ckb.json b/app/javascript/mastodon/locales/ckb.json index 381eaa5b16..7e96418329 100644 --- a/app/javascript/mastodon/locales/ckb.json +++ b/app/javascript/mastodon/locales/ckb.json @@ -342,7 +342,6 @@ "lists.search": "بگەڕێ لەناو ئەو کەسانەی کە شوێنیان کەوتویت", "lists.subheading": "لیستەکانت", "load_pending": "{count, plural, one {# بەڕگەی نوێ} other {# بەڕگەی نوێ}}", - "loading_indicator.label": "بارکردن...", "media_gallery.toggle_visible": "شاردنەوەی {number, plural, one {image} other {images}}", "moved_to_account_banner.text": "ئەکاونتەکەت {disabledAccount} لە ئێستادا لەکارخراوە چونکە تۆ چوویتە {movedToAccount}.", "mute_modal.duration": "ماوە", diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json index 1d878a0cd8..d4bb2f82ba 100644 --- a/app/javascript/mastodon/locales/co.json +++ b/app/javascript/mastodon/locales/co.json @@ -236,7 +236,6 @@ "lists.search": "Circà indè i vostr'abbunamenti", "lists.subheading": "E vo liste", "load_pending": "{count, plural, one {# entrata nova} other {# entrate nove}}", - "loading_indicator.label": "Caricamentu...", "media_gallery.toggle_visible": "Piattà {number, plural, one {ritrattu} other {ritratti}}", "mute_modal.duration": "Durata", "mute_modal.hide_notifications": "Piattà nutificazione da st'utilizatore?", diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index aaf50d67c5..20ef437337 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -386,7 +386,6 @@ "lists.search": "Hledejte mezi lidmi, které sledujete", "lists.subheading": "Vaše seznamy", "load_pending": "{count, plural, one {# nová položka} few {# nové položky} many {# nových položek} other {# nových položek}}", - "loading_indicator.label": "Načítání...", "media_gallery.toggle_visible": "{number, plural, one {Skrýt obrázek} few {Skrýt obrázky} many {Skrýt obrázky} other {Skrýt obrázky}}", "moved_to_account_banner.text": "Váš účet {disabledAccount} je momentálně deaktivován, protože jste se přesunul/a na {movedToAccount}.", "mute_modal.duration": "Trvání", diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index 183ab6955b..dcd5406d05 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -390,7 +390,6 @@ "lists.search": "Chwilio ymysg pobl rydych yn eu dilyn", "lists.subheading": "Eich rhestrau", "load_pending": "{count, plural, one {# eitem newydd} other {# eitem newydd}}", - "loading_indicator.label": "Llwytho...", "media_gallery.toggle_visible": "{number, plural, one {Cuddio delwedd} other {Cuddio delwedd}}", "moved_to_account_banner.text": "Ar hyn y bryd, mae eich cyfrif {disabledAccount} wedi ei analluogi am i chi symud i {movedToAccount}.", "mute_modal.duration": "Hyd", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index bb8b72bca4..33eda6f436 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -390,7 +390,7 @@ "lists.search": "Søg blandt personer, som følges", "lists.subheading": "Dine lister", "load_pending": "{count, plural, one {# nyt emne} other {# nye emner}}", - "loading_indicator.label": "Indlæser...", + "loading_indicator.label": "Indlæser…", "media_gallery.toggle_visible": "{number, plural, one {Skjul billede} other {Skjul billeder}}", "moved_to_account_banner.text": "Din konto {disabledAccount} er pt. deaktiveret, da du flyttede til {movedToAccount}.", "mute_modal.duration": "Varighed", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Ingen resultater tilgængelige pt. Prøv at bruge søgning eller gennemse siden for at finde personer at følge, eller forsøg igen senere.", "onboarding.follows.lead": "Man kurerer sin eget hjemme-feed. Jo flere personer man følger, des mere aktiv og interessant vil det være. Disse profiler kan være et godt udgangspunkt – de kan altid fjernes senere!", "onboarding.follows.title": "Populært på Mastodon", + "onboarding.profile.discoverable": "Fremhæv profil og indlæg i detekteringsalgoritmer", + "onboarding.profile.display_name": "Visningsnavn", + "onboarding.profile.display_name_hint": "Fulde navn eller dit sjove navn…", + "onboarding.profile.indexable": "Medtag offentlige indlæg i søgeresultater", + "onboarding.profile.lead": "Dette kan altid færdiggøres senere i indstillingerne, hvor endnu flere tilpasningsmuligheder forefindes.", + "onboarding.profile.note": "Bio", + "onboarding.profile.note_hint": "Man kan @omtale andre personer eller #hashtags…", + "onboarding.profile.save_and_continue": "Gem og fortsæt", + "onboarding.profile.title": "Profilopsætning", + "onboarding.profile.upload_avatar": "Upload profilbillede", + "onboarding.profile.upload_header": "Upload profiloverskrift", "onboarding.share.lead": "Lad folk vide, hvordan de kan finde dig på Mastodon!", "onboarding.share.message": "Jeg er {username} på #Mastodon! Følg mig på {url}", "onboarding.share.next_steps": "Mulige næste trin:", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index e4f7fe6cec..5c1ccf46d9 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -390,7 +390,7 @@ "lists.search": "Suche nach Leuten, denen du folgst", "lists.subheading": "Deine Listen", "load_pending": "{count, plural, one {# neuer Beitrag} other {# neue Beiträge}}", - "loading_indicator.label": "Wird geladen …", + "loading_indicator.label": "Wird geladen …", "media_gallery.toggle_visible": "{number, plural, one {Medium ausblenden} other {Medien ausblenden}}", "moved_to_account_banner.text": "Dein Konto {disabledAccount} ist derzeit deaktiviert, weil du zu {movedToAccount} umgezogen bist.", "mute_modal.duration": "Dauer", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Bedauerlicherweise können aktuell keine Ergebnisse angezeigt werden. Du kannst die Suche verwenden oder den Reiter „Entdecken“ auswählen, um neue Leute zum Folgen zu finden – oder du versuchst es später erneut.", "onboarding.follows.lead": "Deine Startseite ist der primäre Anlaufpunkt, um Mastodon zu erleben. Je mehr Profilen du folgst, umso aktiver und interessanter wird sie. Damit du direkt loslegen kannst, gibt es hier ein paar Vorschläge:", "onboarding.follows.title": "Personalisiere deine Startseite", + "onboarding.profile.discoverable": "Profil und Beiträge in Suchalgorithmen berücksichtigen", + "onboarding.profile.display_name": "Anzeigename", + "onboarding.profile.display_name_hint": "Dein richtiger Name oder dein Fantasiename …", + "onboarding.profile.indexable": "Öffentliche Beiträge in die Suchergebnisse einbeziehen", + "onboarding.profile.lead": "Du kannst das später in den Einstellungen vervollständigen, wo noch mehr Anpassungsmöglichkeiten zur Verfügung stehen.", + "onboarding.profile.note": "Über mich", + "onboarding.profile.note_hint": "Du kannst andere @Profile erwähnen oder #Hashtags verwenden …", + "onboarding.profile.save_and_continue": "Speichern und fortsetzen", + "onboarding.profile.title": "Profil einrichten", + "onboarding.profile.upload_avatar": "Profilbild hochladen", + "onboarding.profile.upload_header": "Titelbild hochladen", "onboarding.share.lead": "Lass die Leute wissen, wie sie dich auf Mastodon finden können!", "onboarding.share.message": "Ich bin {username} auf #Mastodon! Folge mir auf {url}", "onboarding.share.next_steps": "Mögliche nächste Schritte:", diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index d3be386b40..31806bcfb9 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -345,7 +345,6 @@ "lists.search": "Αναζήτησε μεταξύ των ανθρώπων που ακουλουθείς", "lists.subheading": "Οι λίστες σου", "load_pending": "{count, plural, one {# νέο στοιχείο} other {# νέα στοιχεία}}", - "loading_indicator.label": "Φορτώνει...", "media_gallery.toggle_visible": "{number, plural, one {Απόκρυψη εικόνας} other {Απόκρυψη εικόνων}}", "moved_to_account_banner.text": "Ο λογαριασμός σου {disabledAccount} είναι προσωρινά απενεργοποιημένος επειδή μεταφέρθηκες στον {movedToAccount}.", "mute_modal.duration": "Διάρκεια", diff --git a/app/javascript/mastodon/locales/en-GB.json b/app/javascript/mastodon/locales/en-GB.json index 20ed8937bc..d00782592e 100644 --- a/app/javascript/mastodon/locales/en-GB.json +++ b/app/javascript/mastodon/locales/en-GB.json @@ -389,7 +389,7 @@ "lists.search": "Search among people you follow", "lists.subheading": "Your lists", "load_pending": "{count, plural, one {# new item} other {# new items}}", - "loading_indicator.label": "Loading...", + "loading_indicator.label": "Loading…", "media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}", "moved_to_account_banner.text": "Your account {disabledAccount} is currently disabled because you moved to {movedToAccount}.", "mute_modal.duration": "Duration", @@ -478,6 +478,17 @@ "onboarding.follows.empty": "Unfortunately, no results can be shown right now. You can try using search or browsing the explore page to find people to follow, or try again later.", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.title": "Personalize your home feed", + "onboarding.profile.discoverable": "Feature profile and posts in discovery algorithms", + "onboarding.profile.display_name": "Display name", + "onboarding.profile.display_name_hint": "Your full name or your fun name…", + "onboarding.profile.indexable": "Include public posts in search results", + "onboarding.profile.lead": "You can always complete this later in the settings, where even more customisation options are available.", + "onboarding.profile.note": "Bio", + "onboarding.profile.note_hint": "You can @mention other people or #hashtags…", + "onboarding.profile.save_and_continue": "Save and continue", + "onboarding.profile.title": "Profile setup", + "onboarding.profile.upload_avatar": "Upload profile picture", + "onboarding.profile.upload_header": "Upload profile header", "onboarding.share.lead": "Let people know how they can find you on Mastodon!", "onboarding.share.message": "I'm {username} on #Mastodon! Come follow me at {url}", "onboarding.share.next_steps": "Possible next steps:", diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 0414460375..16941e2ca4 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -21,6 +21,7 @@ "account.blocked": "Blocked", "account.browse_more_on_origin_server": "Browse more on the original profile", "account.cancel_follow_request": "Cancel follow", + "account.copy": "Copy link to profile", "account.direct": "Privately mention @{name}", "account.disable_notifications": "Stop notifying me when @{name} posts", "account.domain_blocked": "Domain blocked", @@ -191,6 +192,7 @@ "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", "conversation.with": "With {names}", + "copy_icon_button.copied": "Copied to clipboard", "copypaste.copied": "Copied", "copypaste.copy_to_clipboard": "Copy to clipboard", "directory.federated": "From known fediverse", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index 6b4258a6bc..5679d5e415 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -365,7 +365,6 @@ "lists.search": "Serĉi inter la homoj, kiujn vi sekvas", "lists.subheading": "Viaj listoj", "load_pending": "{count,plural, one {# nova elemento} other {# novaj elementoj}}", - "loading_indicator.label": "Ŝargado…", "media_gallery.toggle_visible": "{number, plural, one {Kaŝi la bildon} other {Kaŝi la bildojn}}", "moved_to_account_banner.text": "Via konto {disabledAccount} estas malvalidigita ĉar vi movis ĝin al {movedToAccount}.", "mute_modal.duration": "Daŭro", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index 71d6e3119b..6803363695 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -390,7 +390,7 @@ "lists.search": "Buscar entre la gente que seguís", "lists.subheading": "Tus listas", "load_pending": "{count, plural, one {# elemento nuevo} other {# elementos nuevos}}", - "loading_indicator.label": "Cargando...", + "loading_indicator.label": "Cargando…", "media_gallery.toggle_visible": "Ocultar {number, plural, one {imagen} other {imágenes}}", "moved_to_account_banner.text": "Tu cuenta {disabledAccount} está actualmente deshabilitada porque te mudaste a {movedToAccount}.", "mute_modal.duration": "Duración", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Desafortunadamente, no se pueden mostrar resultados en este momento. Podés intentar usar la búsqueda o navegar por la página de exploración para encontrar cuentas a las que seguir, o intentarlo de nuevo más tarde.", "onboarding.follows.lead": "Tu línea temporal de inicio es la forma principal de experimentar Mastodon. Cuanta más cuentas sigás, más activa e interesante será. Para empezar, acá tenés algunas sugerencias:", "onboarding.follows.title": "Personalizá tu línea de tiempo principal", + "onboarding.profile.discoverable": "Destacar perfil y mensajes en algoritmos de descubrimiento", + "onboarding.profile.display_name": "Nombre para mostrar", + "onboarding.profile.display_name_hint": "Tu nombre completo o tu pseudónimo…", + "onboarding.profile.indexable": "Incluir mensajes públicos en resultados de búsqueda", + "onboarding.profile.lead": "Siempre podés completar esto más tarde en la configuración, donde hay disponibles más opciones de personalización.", + "onboarding.profile.note": "Biografía", + "onboarding.profile.note_hint": "Podés @mencionar otras cuentas o usar #etiquetas…", + "onboarding.profile.save_and_continue": "Guardar y continuar", + "onboarding.profile.title": "Configuración del perfil", + "onboarding.profile.upload_avatar": "Subir avatar", + "onboarding.profile.upload_header": "Subir cabecera", "onboarding.share.lead": "¡Decile a la gente cómo te pueden encontrar en Mastodon!", "onboarding.share.message": "¡En #Mastodon soy «{username}»! Podés seguirme desde {url}", "onboarding.share.next_steps": "Posibles próximos pasos:", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index aadc901f99..aa8a21edb5 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Desafortunadamente, no se pueden mostrar resultados en este momento. Puedes intentar usar la búsqueda o navegar por la página de exploración para encontrar gente a la que seguir, o inténtalo de nuevo más tarde.", "onboarding.follows.lead": "Tienes que personalizar tu inicio. Cuantas más personas sigas, más activo e interesante será. Estos perfiles pueden ser un buen punto de partida, ¡pero siempre puedes dejar de seguirlos más adelante!", "onboarding.follows.title": "Popular en Mastodon", + "onboarding.profile.discoverable": "Destacar el perfil y las publicaciones en el algoritmo de descubrimiento", + "onboarding.profile.display_name": "Nombre a mostrar", + "onboarding.profile.display_name_hint": "Tu nombre completo o tu apodo…", + "onboarding.profile.indexable": "Incluir publicaciones públicas en los resultados de búsqueda", + "onboarding.profile.lead": "Siempre puedes completar esto más tarde en los ajustes, donde hay aún más opciones de personalización disponibles.", + "onboarding.profile.note": "Biografía", + "onboarding.profile.note_hint": "Puedes @mencionar a otras personas o #hashtags…", + "onboarding.profile.save_and_continue": "Guardar y continuar", + "onboarding.profile.title": "Configuración del perfil", + "onboarding.profile.upload_avatar": "Subir foto de perfil", + "onboarding.profile.upload_header": "Subir foto de cabecera", "onboarding.share.lead": "¡Dile a la gente cómo te pueden encontrar en Mastodon!", "onboarding.share.message": "¡Soy {username} en #Mastodon! Ven a seguirme en {url}", "onboarding.share.next_steps": "Posibles siguientes pasos:", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index f3735d9685..5d1aa004b3 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -479,6 +479,7 @@ "onboarding.follows.empty": "Desafortunadamente, no se pueden mostrar resultados en este momento. Puedes intentar usar la búsqueda o navegar por la página de exploración para encontrar personas a las que seguir, o inténtalo de nuevo más tarde.", "onboarding.follows.lead": "Tu línea de inicio es la forma principal de experimentar Mastodon. Cuanta más personas sigas, más activa e interesante será. Para empezar, aquí hay algunas sugerencias:", "onboarding.follows.title": "Personaliza tu línea de inicio", + "onboarding.profile.display_name": "Nombre para mostrar", "onboarding.share.lead": "¡Cuéntale a otras personas cómo te pueden encontrar en Mastodon!", "onboarding.share.message": "¡Soy {username} en #Mastodon! Ven a seguirme en {url}", "onboarding.share.next_steps": "Posibles siguientes pasos:", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index c4182a073d..3b6d86a9dd 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -390,7 +390,6 @@ "lists.search": "Otsi enda jälgitavate inimeste hulgast", "lists.subheading": "Sinu nimekirjad", "load_pending": "{count, plural, one {# uus kirje} other {# uut kirjet}}", - "loading_indicator.label": "Laeb..", "media_gallery.toggle_visible": "{number, plural, one {Varja pilt} other {Varja pildid}}", "moved_to_account_banner.text": "Kontot {disabledAccount} ei ole praegu võimalik kasutada, sest kolisid kontole {movedToAccount}.", "mute_modal.duration": "Kestus", diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json index 419589aba7..88f70cffb0 100644 --- a/app/javascript/mastodon/locales/eu.json +++ b/app/javascript/mastodon/locales/eu.json @@ -390,7 +390,7 @@ "lists.search": "Bilatu jarraitzen dituzun pertsonen artean", "lists.subheading": "Zure zerrendak", "load_pending": "{count, plural, one {elementu berri #} other {# elementu berri}}", - "loading_indicator.label": "Kargatzen...", + "loading_indicator.label": "Kargatzen…", "media_gallery.toggle_visible": "Txandakatu ikusgaitasuna", "moved_to_account_banner.text": "Zure {disabledAccount} kontua desgaituta dago une honetan, {movedToAccount} kontura aldatu zinelako.", "mute_modal.duration": "Iraupena", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Zoritxarrez, ezin da emaitzik erakutsi orain. Bilaketa erabil dezakezu edo Arakatu orrian jendea bilatu jarraitzeko, edo saiatu geroago.", "onboarding.follows.lead": "Hasierako orria zuk pertsonalizatzen duzu. Gero eta jende gehiagori jarraitu, orduan eta aktibo eta interesgarriago izango da. Profil hauek egokiak izan daitezke hasteko, beti ere, geroago jarraitzeari utz diezazkiekezu!", "onboarding.follows.title": "Mastodonen pil-pilean", + "onboarding.profile.discoverable": "Ezagutarazi profila eta bidalketak bilaketa algoritmoetan", + "onboarding.profile.display_name": "Bistaratzeko izena", + "onboarding.profile.display_name_hint": "Zure izena edo ezizena…", + "onboarding.profile.indexable": "Gehitu argitalpen publikoak bilaketa-emaitzetan", + "onboarding.profile.lead": "Geroagoago bete daiteke konfigurazioan, non pertsonalizatzeko aukera gehiago dauden.", + "onboarding.profile.note": "Biografia", + "onboarding.profile.note_hint": "Beste pertsona batzuk @aipa ditzakezu edo #traolak erabili…", + "onboarding.profile.save_and_continue": "Gorde eta jarraitu", + "onboarding.profile.title": "Profilaren konfigurazioa", + "onboarding.profile.upload_avatar": "Igo profilaren irudia", + "onboarding.profile.upload_header": "Igo profilaren goiburua", "onboarding.share.lead": "Esan jendeari nola aurki zaitzaketen Mastodonen!", "onboarding.share.message": "{username} naiz #Mastodon-en! Jarrai nazazu hemen: {url}", "onboarding.share.next_steps": "Hurrengo urrats posibleak:", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index 246f218998..97dae30d43 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -390,7 +390,7 @@ "lists.search": "جست‌وجو بین کسانی که پی‌گرفته‌اید", "lists.subheading": "سیاهه‌هایتان", "load_pending": "{count, plural, one {# مورد جدید} other {# مورد جدید}}", - "loading_indicator.label": "بار کردن…", + "loading_indicator.label": "در حال بارگذاری…", "media_gallery.toggle_visible": "{number, plural, one {نهفتن تصویر} other {نهفتن تصاویر}}", "moved_to_account_banner.text": "حسابتان {disabledAccount} اکنون از کار افتاده؛ چرا که به {movedToAccount} منتقل شدید.", "mute_modal.duration": "مدت زمان", @@ -479,6 +479,13 @@ "onboarding.follows.empty": "متأسفانه هم‌اکنون نتیجه‌ای قابل نمایش نیست. می‌توانید استفاده از جست‌وجو یا مرور صفحهٔ کاوش را برای یافتن افرادی برای پی‌گیری آزموده یا دوباره تلاش کنید.", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.title": "Popular on Mastodon", + "onboarding.profile.discoverable": "معرفی نمایه و فرسته‌ها در الگوریتم‌های کشف", + "onboarding.profile.display_name": "نام نمایشی", + "onboarding.profile.display_name_hint": "نام کامل یا نام باحالتان…", + "onboarding.profile.note": "درباره شما", + "onboarding.profile.note_hint": "می‌توانید افراد دیگر را @نام‌بردن یا #برچسب بزنید…", + "onboarding.profile.save_and_continue": "ذخیره کن و ادامه بده", + "onboarding.profile.title": "تنظیم نمایه", "onboarding.share.lead": "بگذارید افراد بدانند چگونه می‌توانند در ماستادون بیابندتان!", "onboarding.share.message": "من {username} روی #ماستودون هستم! مرا در {url} پی‌بگیرید", "onboarding.share.next_steps": "گام‌های ممکن بعدی:", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index 9aa2e7355f..849a7f463c 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -390,7 +390,7 @@ "lists.search": "Etsi seuraamistasi henkilöistä", "lists.subheading": "Omat listasi", "load_pending": "{count, plural, one {# uusi kohde} other {# uutta kohdetta}}", - "loading_indicator.label": "Ladataan...", + "loading_indicator.label": "Ladataan…", "media_gallery.toggle_visible": "{number, plural, one {Piilota kuva} other {Piilota kuvat}}", "moved_to_account_banner.text": "Tilisi {disabledAccount} on tällä hetkellä poissa käytöstä, koska teit siirron tiliin {movedToAccount}.", "mute_modal.duration": "Kesto", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Valitettavasti tuloksia ei voida näyttää juuri nyt. Voit kokeilla hakua tai selata tutustumissivua löytääksesi seurattavaa tai yrittää myöhemmin uudelleen.", "onboarding.follows.lead": "Kokoat oman kotisyötteesi itse. Mitä enemmän ihmisiä seuraat, sitä aktiivisempi ja kiinnostavampi syöte on. Nämä profiilit voivat olla alkuun hyvä lähtökohta — voit aina lopettaa niiden seuraamisen myöhemmin!", "onboarding.follows.title": "Mukauta kotisyötettäsi", + "onboarding.profile.discoverable": "Pidä profiilia ja julkaisuja esillä löytämisalgoritmeissa", + "onboarding.profile.display_name": "Näyttönimi", + "onboarding.profile.display_name_hint": "Koko nimesi tai lempinimesi…", + "onboarding.profile.indexable": "Sisällytä julkiset julkaisut hakutuloksiin", + "onboarding.profile.lead": "Voit viimeistellä tämän milloin tahansa asetuksissa, jossa on saatavilla vielä enemmän mukautusvalintoja.", + "onboarding.profile.note": "Elämäkerta", + "onboarding.profile.note_hint": "Voit @mainita muita käyttäjiä tai #aihetunnisteita…", + "onboarding.profile.save_and_continue": "Tallenna ja jatka", + "onboarding.profile.title": "Profiilin määritys", + "onboarding.profile.upload_avatar": "Lataa profiilikuva", + "onboarding.profile.upload_header": "Lataa profiilin otsakekuva", "onboarding.share.lead": "Kerro ihmisille, kuinka he voivat löytää sinut Mastodonista!", "onboarding.share.message": "Olen {username} #Mastodon⁠issa! Seuraa minua osoitteessa {url}", "onboarding.share.next_steps": "Mahdolliset seuraavat vaiheet:", diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json index 42a1317db7..61c1287ea5 100644 --- a/app/javascript/mastodon/locales/fo.json +++ b/app/javascript/mastodon/locales/fo.json @@ -390,7 +390,6 @@ "lists.search": "Leita millum fólk, sum tú fylgir", "lists.subheading": "Tínir listar", "load_pending": "{count, plural, one {# nýtt evni} other {# nýggj evni}}", - "loading_indicator.label": "Innlesi...", "media_gallery.toggle_visible": "{number, plural, one {Fjal mynd} other {Fjal myndir}}", "moved_to_account_banner.text": "Konta tín {disabledAccount} er í løtuni óvirkin, tí tú flutti til {movedToAccount}.", "mute_modal.duration": "Tíðarbil", diff --git a/app/javascript/mastodon/locales/fr-QC.json b/app/javascript/mastodon/locales/fr-QC.json index a6dd91becf..e858882f84 100644 --- a/app/javascript/mastodon/locales/fr-QC.json +++ b/app/javascript/mastodon/locales/fr-QC.json @@ -390,7 +390,6 @@ "lists.search": "Rechercher parmi les gens que vous suivez", "lists.subheading": "Vos listes", "load_pending": "{count, plural, one {# nouvel élément} other {# nouveaux éléments}}", - "loading_indicator.label": "Chargement…", "media_gallery.toggle_visible": "{number, plural, one {Cacher l’image} other {Cacher les images}}", "moved_to_account_banner.text": "Votre compte {disabledAccount} est actuellement désactivé parce que vous avez déménagé sur {movedToAccount}.", "mute_modal.duration": "Durée", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 0d2ba2bb9b..a7bb4a12fe 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -390,7 +390,6 @@ "lists.search": "Rechercher parmi les gens que vous suivez", "lists.subheading": "Vos listes", "load_pending": "{count, plural, one {# nouvel élément} other {# nouveaux éléments}}", - "loading_indicator.label": "Chargement…", "media_gallery.toggle_visible": "{number, plural, one {Cacher l’image} other {Cacher les images}}", "moved_to_account_banner.text": "Votre compte {disabledAccount} est actuellement désactivé parce que vous l'avez déplacé à {movedToAccount}.", "mute_modal.duration": "Durée", diff --git a/app/javascript/mastodon/locales/fy.json b/app/javascript/mastodon/locales/fy.json index 9d3b416068..2128a045be 100644 --- a/app/javascript/mastodon/locales/fy.json +++ b/app/javascript/mastodon/locales/fy.json @@ -390,7 +390,6 @@ "lists.search": "Sykje nei minsken dy’t jo folgje", "lists.subheading": "Jo listen", "load_pending": "{count, plural, one {# nij item} other {# nije items}}", - "loading_indicator.label": "Lade…", "media_gallery.toggle_visible": "{number, plural, one {ôfbylding ferstopje} other {ôfbyldingen ferstopje}}", "moved_to_account_banner.text": "Omdat jo nei {movedToAccount} ferhuze binne is jo account {disabledAccount} op dit stuit útskeakele.", "mute_modal.duration": "Doer", diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json index 388a557e8d..ee6b44c884 100644 --- a/app/javascript/mastodon/locales/ga.json +++ b/app/javascript/mastodon/locales/ga.json @@ -316,7 +316,6 @@ "lists.replies_policy.title": "Taispeáin freagraí:", "lists.search": "Cuardaigh i measc daoine atá á leanúint agat", "lists.subheading": "Do liostaí", - "loading_indicator.label": "Ag lódáil...", "mute_modal.duration": "Tréimhse", "mute_modal.hide_notifications": "Cuir póstalacha ón t-úsáideoir seo i bhfolach?", "mute_modal.indefinite": "Gan téarma", diff --git a/app/javascript/mastodon/locales/gd.json b/app/javascript/mastodon/locales/gd.json index 4f485cfc55..91333c1a0a 100644 --- a/app/javascript/mastodon/locales/gd.json +++ b/app/javascript/mastodon/locales/gd.json @@ -389,7 +389,6 @@ "lists.search": "Lorg am measg nan daoine a leanas tu", "lists.subheading": "Na liostaichean agad", "load_pending": "{count, plural, one {# nì ùr} two {# nì ùr} few {# nithean ùra} other {# nì ùr}}", - "loading_indicator.label": "’Ga luchdadh…", "media_gallery.toggle_visible": "{number, plural, 1 {Falaich an dealbh} one {Falaich na dealbhan} two {Falaich na dealbhan} few {Falaich na dealbhan} other {Falaich na dealbhan}}", "moved_to_account_banner.text": "Tha an cunntas {disabledAccount} agad à comas on a rinn thu imrich gu {movedToAccount}.", "mute_modal.duration": "Faide", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index e79e549264..7d2c6dab95 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -390,7 +390,6 @@ "lists.search": "Procurar entre as persoas que segues", "lists.subheading": "As túas listaxes", "load_pending": "{count, plural, one {# novo elemento} other {# novos elementos}}", - "loading_indicator.label": "Estase a cargar...", "media_gallery.toggle_visible": "Agochar {number, plural, one {imaxe} other {imaxes}}", "moved_to_account_banner.text": "A túa conta {disabledAccount} está actualmente desactivada porque movéchela a {movedToAccount}.", "mute_modal.duration": "Duración", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index 485e8313ad..2e00091709 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -390,7 +390,7 @@ "lists.search": "חיפוש בין אנשים שאני עוקב\\ת אחריהם", "lists.subheading": "הרשימות שלך", "load_pending": "{count, plural, one {# פריט חדש} other {# פריטים חדשים}}", - "loading_indicator.label": "טוען...", + "loading_indicator.label": "בטעינה…", "media_gallery.toggle_visible": "{number, plural, one {להסתיר תמונה} two {להסתיר תמונותיים} many {להסתיר תמונות} other {להסתיר תמונות}}", "moved_to_account_banner.text": "חשבונך {disabledAccount} אינו פעיל כרגע עקב מעבר ל{movedToAccount}.", "mute_modal.duration": "משך הזמן", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "למצער, תוצאות לחיפושך אינן בנמצא. ניתן להשתמש בחיפוש או בדף החקירות לשם מציאת אנשים ולעקבם. אפשר גם לנסות שוב אחר כך.", "onboarding.follows.lead": "אתם אוצרים את הזרם הבייתי שלכם. ככל שתעקבו אחרי יותר אנשים, הוא יהיה עשיר ופעיל יותר. הנה כמה פרופילים להתחיל בהם - תמיד ניתן להפסיק מעקב אחריהם בהמשך!", "onboarding.follows.title": "פופולארי על מסטודון", + "onboarding.profile.discoverable": "הצגת פרופיל והודעות במסך התגליות", + "onboarding.profile.display_name": "שם להצגה", + "onboarding.profile.display_name_hint": "שמך המלא או כינוי הכיף שלך…", + "onboarding.profile.indexable": "הכללת הודעות ציבוריות בתוצאות החיפוש", + "onboarding.profile.lead": "תמיד ניתן להשלים זאת אחר כך בהגדרות, שם יש אפילו עוד אפשרויות להתאמה אישית.", + "onboarding.profile.note": "אודות", + "onboarding.profile.note_hint": "ניתן @לאזכר משתמשים אחרים או #תגיות…", + "onboarding.profile.save_and_continue": "לשמור ולהמשיך", + "onboarding.profile.title": "הגדרת פרופיל", + "onboarding.profile.upload_avatar": "העלאת תמונת פרופיל", + "onboarding.profile.upload_header": "העלאת כותרת פרופיל", "onboarding.share.lead": "כדאי להודיע לחברים היכן למצוא אותך במסטודון!", "onboarding.share.message": "אני {username} ברשת #מסטודון! בואו לעקוב אחרי בכתובת {url}", "onboarding.share.next_steps": "לאיפה להמשיך מכאן:", @@ -518,7 +529,7 @@ "privacy.private.short": "לעוקבים בלבד", "privacy.public.long": "גלוי לכל", "privacy.public.short": "פומבי", - "privacy.unlisted.long": "גלוי לכל, אבל מוסתר מאמצעי גילוי", + "privacy.unlisted.long": "גלוי לכל, אבל מוסתר מאמצעי תגלית", "privacy.unlisted.short": "לא רשום (לא לפיד הכללי)", "privacy_policy.last_updated": "עודכן לאחרונה {date}", "privacy_policy.title": "מדיניות פרטיות", diff --git a/app/javascript/mastodon/locales/hi.json b/app/javascript/mastodon/locales/hi.json index 71694db76a..f4473b7169 100644 --- a/app/javascript/mastodon/locales/hi.json +++ b/app/javascript/mastodon/locales/hi.json @@ -360,7 +360,6 @@ "lists.replies_policy.none": "कोई नहीं", "lists.replies_policy.title": "इसके जवाब दिखाएं:", "lists.subheading": "आपकी सूचियाँ", - "loading_indicator.label": "लोड हो रहा है...", "mute_modal.duration": "अवधि", "mute_modal.hide_notifications": "इस सभ्य की ओरसे आनेवाली सूचनाए शांत करे", "mute_modal.indefinite": "अनिश्चितकालीन", diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json index 16d25e7846..01524e553b 100644 --- a/app/javascript/mastodon/locales/hr.json +++ b/app/javascript/mastodon/locales/hr.json @@ -306,7 +306,6 @@ "lists.replies_policy.none": "Nitko", "lists.search": "Traži među praćenim ljudima", "lists.subheading": "Vaše liste", - "loading_indicator.label": "Učitavanje...", "media_gallery.toggle_visible": "Sakrij {number, plural, one {sliku} other {slike}}", "mute_modal.duration": "Trajanje", "mute_modal.hide_notifications": "Sakrij obavijesti ovog korisnika?", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index ca20271619..96fc720a41 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -390,7 +390,7 @@ "lists.search": "Keresés a követett személyek között", "lists.subheading": "Saját listák", "load_pending": "{count, plural, one {# új elem} other {# új elem}}", - "loading_indicator.label": "Betöltés...", + "loading_indicator.label": "Betöltés…", "media_gallery.toggle_visible": "{number, plural, one {Kép elrejtése} other {Képek elrejtése}}", "moved_to_account_banner.text": "A(z) {disabledAccount} fiókod jelenleg le van tiltva, mert átköltöztél ide: {movedToAccount}.", "mute_modal.duration": "Időtartam", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Sajnos jelenleg nem jeleníthető meg eredmény. Kipróbálhatod a keresést vagy böngészheted a felfedező oldalon a követni kívánt személyeket, vagy próbáld meg később.", "onboarding.follows.lead": "A saját hírfolyamod az elsődleges tapasztalás a Mastodonon. Minél több embert követsz, annál aktívabb és érdekesebb a dolog. Az induláshoz itt van néhány javaslat:", "onboarding.follows.title": "Népszerű a Mastodonon", + "onboarding.profile.discoverable": "Profil és bejegyzések szerepeltetése a felfedezési algoritmusokban", + "onboarding.profile.display_name": "Megjelenített név", + "onboarding.profile.display_name_hint": "Teljes név vagy becenév…", + "onboarding.profile.indexable": "Nyilvános bejegyzések is a keresési eredményekben", + "onboarding.profile.lead": "Ezt később bármikor elvégezhető a beállításoknál, ahol még több testreszabási lehetőség áll rendelkezésre.", + "onboarding.profile.note": "Biográfia", + "onboarding.profile.note_hint": "@említhetünk másokat vagy #hashtag elemeket…", + "onboarding.profile.save_and_continue": "Mentés és folytatás", + "onboarding.profile.title": "Profil beüzemelés", + "onboarding.profile.upload_avatar": "Profilkép feltöltése", + "onboarding.profile.upload_header": "Profil fejléc feltöltése", "onboarding.share.lead": "Tudassuk az emberekkel, hogyan találhatnak meg a Mastodonon!", "onboarding.share.message": "{username} vagyok a #Mastodon hálózaton! Kövess itt: {url}.", "onboarding.share.next_steps": "Lehetséges következő lépések:", diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json index 776991b014..f2548c7d3a 100644 --- a/app/javascript/mastodon/locales/hy.json +++ b/app/javascript/mastodon/locales/hy.json @@ -314,7 +314,6 @@ "lists.search": "Փնտրել քո հետեւած մարդկանց մէջ", "lists.subheading": "Քո ցանկերը", "load_pending": "{count, plural, one {# նոր նիւթ} other {# նոր նիւթ}}", - "loading_indicator.label": "Բեռնւում է…", "media_gallery.toggle_visible": "Ցուցադրել/թաքցնել", "mute_modal.duration": "Տեւողութիւն", "mute_modal.hide_notifications": "Թաքցնե՞լ ծանուցումներն այս օգտատիրոջից։", diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json index 76542cc52c..8ecf36125d 100644 --- a/app/javascript/mastodon/locales/id.json +++ b/app/javascript/mastodon/locales/id.json @@ -353,7 +353,6 @@ "lists.search": "Cari di antara orang yang Anda ikuti", "lists.subheading": "Daftar Anda", "load_pending": "{count, plural, other {# item baru}}", - "loading_indicator.label": "Tunggu sebentar...", "media_gallery.toggle_visible": "Tampil/Sembunyikan", "moved_to_account_banner.text": "Akun {disabledAccount} Anda kini dinonaktifkan karena Anda pindah ke {movedToAccount}.", "mute_modal.duration": "Durasi", diff --git a/app/javascript/mastodon/locales/ig.json b/app/javascript/mastodon/locales/ig.json index 201bebc05f..c24d28eea9 100644 --- a/app/javascript/mastodon/locales/ig.json +++ b/app/javascript/mastodon/locales/ig.json @@ -88,7 +88,6 @@ "lists.delete": "Hichapụ ndepụta", "lists.edit": "Dezie ndepụta", "lists.subheading": "Ndepụta gị", - "loading_indicator.label": "Na-adọnye...", "navigation_bar.about": "Maka", "navigation_bar.bookmarks": "Ebenrụtụakā", "navigation_bar.domain_blocks": "Hidden domains", diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json index cfe1b43445..552debdb50 100644 --- a/app/javascript/mastodon/locales/io.json +++ b/app/javascript/mastodon/locales/io.json @@ -383,7 +383,6 @@ "lists.search": "Trovez inter personi quon vu sequas", "lists.subheading": "Vua listi", "load_pending": "{count, plural, one {# nova kozo} other {# nova kozi}}", - "loading_indicator.label": "Kargante...", "media_gallery.toggle_visible": "Chanjar videbleso", "moved_to_account_banner.text": "Vua konto {disabledAccount} es nune desaktiva pro ke vu movis a {movedToAccount}.", "mute_modal.duration": "Durado", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index 0b6a8012ad..54123ae4c7 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -390,7 +390,7 @@ "lists.search": "Leita meðal þeirra sem þú fylgist með", "lists.subheading": "Listarnir þínir", "load_pending": "{count, plural, one {# nýtt atriði} other {# ný atriði}}", - "loading_indicator.label": "Hleð inn...", + "loading_indicator.label": "Hleð inn…", "media_gallery.toggle_visible": "Víxla sýnileika", "moved_to_account_banner.text": "Aðgangurinn þinn {disabledAccount} er óvirkur í augnablikinu vegna þess að þú fluttir þig yfir á {movedToAccount}.", "mute_modal.duration": "Lengd", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Því miður er ekki hægt að birta neinar niðurstöður í augnablikinu. Þú getur reynt að nota leitina eða skoðað könnunarsíðuna til að finna fólk til að fylgjast með, nú eða prófað aftur síðar.", "onboarding.follows.lead": "Þú ræktar heimastreymið þitt. Því fleira fólki sem þú fylgist með, því virkara og áhugaverðara verður það. Að fylgjast með þessum notendum gæti verið ágætt til að byrja með - þú getur alltaf hætt að fylgjast með þeim síðar!", "onboarding.follows.title": "Vinsælt á Mastodon", + "onboarding.profile.discoverable": "Hafa notandasnið og færslur með í reikniritum leitar", + "onboarding.profile.display_name": "Birtingarnafn", + "onboarding.profile.display_name_hint": "Fullt nafn þitt eða eitthvað til gamans…", + "onboarding.profile.indexable": "Hafa opinberar færslur með í leitarniðurstöðum", + "onboarding.profile.lead": "Þú getur alltaf klárað þetta seinna í stillingunum, þar sem enn fleiri möguleikar bjóðast á sérsníðingum.", + "onboarding.profile.note": "Æviágrip", + "onboarding.profile.note_hint": "Þú getur @minnst á annað fólk eða #myllumerki…", + "onboarding.profile.save_and_continue": "Vista og halda áfram", + "onboarding.profile.title": "Uppsetning notandasniðs", + "onboarding.profile.upload_avatar": "Sendu inn auðkennismynd", + "onboarding.profile.upload_header": "Sendu inn bakgrunnsmynd í haus notandasniðs", "onboarding.share.lead": "Láttu fólk vita hvernig það getur fundið þig á Mastodon!", "onboarding.share.message": "Ég heiti {username} á #Mastodon! Þú getur fylgst með mér á {url}", "onboarding.share.next_steps": "Möguleg næstu skref:", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index 8ad791bfef..284d7739c0 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -390,7 +390,7 @@ "lists.search": "Cerca tra le persone che segui", "lists.subheading": "Le tue liste", "load_pending": "{count, plural, one {# nuovo oggetto} other {# nuovi oggetti}}", - "loading_indicator.label": "Caricamento...", + "loading_indicator.label": "Caricamento…", "media_gallery.toggle_visible": "{number, plural, one {Nascondi immagine} other {Nascondi immagini}}", "moved_to_account_banner.text": "Il tuo profilo {disabledAccount} è correntemente disabilitato perché ti sei spostato a {movedToAccount}.", "mute_modal.duration": "Durata", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Sfortunatamente, nessun risultato può essere mostrato in questo momento. Puoi provare a utilizzare la ricerca o sfogliare la pagina di esplorazione per trovare persone da seguire, oppure riprova più tardi.", "onboarding.follows.lead": "La cronologia della tua home è gestita da te. Più persone segui, più attiva e interessante sarà. Questi profili possono essere un buon punto di partenza; puoi sempre smettere di seguirli in seguito!", "onboarding.follows.title": "Popolare su Mastodon", + "onboarding.profile.discoverable": "Include il profilo e i post negli algoritmi di scoperta", + "onboarding.profile.display_name": "Nome da visualizzare", + "onboarding.profile.display_name_hint": "Il tuo nome completo o il tuo nome divertente…", + "onboarding.profile.indexable": "Includi i post pubblici nei risultati di ricerca", + "onboarding.profile.lead": "Puoi sempre completarlo in un secondo momento nelle impostazioni, dove sono disponibili ancora più opzioni di personalizzazione.", + "onboarding.profile.note": "Biografia", + "onboarding.profile.note_hint": "Puoi @menzionare altre persone o #hashtags…", + "onboarding.profile.save_and_continue": "Salva e continua", + "onboarding.profile.title": "Configurazione del profilo", + "onboarding.profile.upload_avatar": "Carica l'immagine del profilo", + "onboarding.profile.upload_header": "Carica l'intestazione del profilo", "onboarding.share.lead": "Fai sapere alle persone come possono trovarti su Mastodon!", "onboarding.share.message": "Sono {username} su #Mastodon! Vieni a seguirmi su {url}", "onboarding.share.next_steps": "Possibili passaggi successivi:", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index 4cd7228c8c..f8c85b774e 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -390,7 +390,7 @@ "lists.search": "フォローしている人の中から検索", "lists.subheading": "あなたのリスト", "load_pending": "{count}件の新着", - "loading_indicator.label": "読み込み中...", + "loading_indicator.label": "", "media_gallery.toggle_visible": "{number, plural, one {画像を閉じる} other {画像を閉じる}}", "moved_to_account_banner.text": "あなたのアカウント『{disabledAccount}』は『{movedToAccount}』に移動したため現在無効になっています。", "mute_modal.duration": "ミュートする期間", diff --git a/app/javascript/mastodon/locales/ka.json b/app/javascript/mastodon/locales/ka.json index 256aa93f4a..875ac3c195 100644 --- a/app/javascript/mastodon/locales/ka.json +++ b/app/javascript/mastodon/locales/ka.json @@ -165,7 +165,6 @@ "lists.new.title_placeholder": "ახალი სიის სათაური", "lists.search": "ძებნა ადამიანებს შორის რომელთაც მიჰყვებით", "lists.subheading": "თქვენი სიები", - "loading_indicator.label": "იტვირთება...", "media_gallery.toggle_visible": "ხილვადობის ჩართვა", "mute_modal.hide_notifications": "დავმალოთ შეტყობინებები ამ მომხმარებლისგან?", "navigation_bar.blocks": "დაბლოკილი მომხმარებლები", diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json index 8f9576c263..e9d4b57de8 100644 --- a/app/javascript/mastodon/locales/kab.json +++ b/app/javascript/mastodon/locales/kab.json @@ -274,7 +274,6 @@ "lists.search": "Nadi gar yemdanen i teṭṭafaṛeḍ", "lists.subheading": "Tibdarin-ik·im", "load_pending": "{count, plural, one {# n uferdis amaynut} other {# n yiferdisen imaynuten}}", - "loading_indicator.label": "Yessalay-d…", "media_gallery.toggle_visible": "Ffer {number, plural, one {tugna} other {tugniwin}}", "mute_modal.duration": "Tanzagt", "mute_modal.hide_notifications": "Tebɣiḍ ad teffreḍ talɣutin n umseqdac-a?", diff --git a/app/javascript/mastodon/locales/kk.json b/app/javascript/mastodon/locales/kk.json index 6a4b2161b2..189d792e38 100644 --- a/app/javascript/mastodon/locales/kk.json +++ b/app/javascript/mastodon/locales/kk.json @@ -242,7 +242,6 @@ "lists.search": "Сіз іздеген адамдар арасында іздеу", "lists.subheading": "Тізімдеріңіз", "load_pending": "{count, plural, one {# жаңа нәрсе} other {# жаңа нәрсе}}", - "loading_indicator.label": "Жүктеу...", "media_gallery.toggle_visible": "Көрінуді қосу", "mute_modal.hide_notifications": "Бұл қолданушы ескертпелерін жасырамыз ба?", "navigation_bar.blocks": "Бұғатталғандар", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index 574d8e211b..1420be8e09 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -479,6 +479,17 @@ "onboarding.follows.empty": "안타깝지만 아직은 아무 것도 보여드릴 수 없습니다. 검색을 이용하거나 발견하기 페이지에서 팔로우 할 사람을 찾을 수 있습니다. 아니면 잠시 후에 다시 시도하세요.", "onboarding.follows.lead": "홈 피드는 마스토돈을 경험하는 주된 경로입니다. 더 많은 사람들을 팔로우 할수록 더 활발하고 흥미로워질 것입니다. 여기 시작을 위한 몇몇 추천을 드립니다:", "onboarding.follows.title": "내게 맞는 홈 피드 꾸미기", + "onboarding.profile.discoverable": "발견하기 알고리즘에 프로필과 게시물을 추천하기", + "onboarding.profile.display_name": "표시되는 이름", + "onboarding.profile.display_name_hint": "진짜 이름 또는 재미난 이름…", + "onboarding.profile.indexable": "공개 게시물을 검색 결과에 포함시키기", + "onboarding.profile.lead": "언제든지 나중에 설정 메뉴에서 마저 할 수 있고, 그곳에서 더 많은 맞춤 옵션을 고를 수 있습니다.", + "onboarding.profile.note": "자기소개", + "onboarding.profile.note_hint": "남을 @mention 하거나 #hashtag 태그를 달 수 있습니다…", + "onboarding.profile.save_and_continue": "저장 및 계속", + "onboarding.profile.title": "프로필 설정", + "onboarding.profile.upload_avatar": "프로필 사진 업로드", + "onboarding.profile.upload_header": "프로필 헤더 업로드", "onboarding.share.lead": "여러 사람에게 마스토돈에서 나를 찾을 수 있는 방법을 알려주세요!", "onboarding.share.message": "#마스토돈 이용하는 {username}입니다! {url} 에서 저를 팔로우 해보세요", "onboarding.share.next_steps": "할만한 다음 단계:", diff --git a/app/javascript/mastodon/locales/ku.json b/app/javascript/mastodon/locales/ku.json index 8c9aaf3e8c..b940542677 100644 --- a/app/javascript/mastodon/locales/ku.json +++ b/app/javascript/mastodon/locales/ku.json @@ -339,7 +339,6 @@ "lists.search": "Di navbera kesên ku te dişopînin bigere", "lists.subheading": "Lîsteyên te", "load_pending": "{count, plural, one {# hêmaneke nû} other {#hêmaneke nû}}", - "loading_indicator.label": "Tê barkirin...", "media_gallery.toggle_visible": "{number, plural, one {Wêneyê veşêre} other {Wêneyan veşêre}}", "moved_to_account_banner.text": "Ajimêrê te {disabledAccount} niha neçalak e ji ber ku te bar kir bo {movedToAccount}.", "mute_modal.duration": "Dem", diff --git a/app/javascript/mastodon/locales/kw.json b/app/javascript/mastodon/locales/kw.json index 6b46d82313..ca08ca836e 100644 --- a/app/javascript/mastodon/locales/kw.json +++ b/app/javascript/mastodon/locales/kw.json @@ -235,7 +235,6 @@ "lists.search": "Hwilas yn-mysk tus a holyewgh", "lists.subheading": "Agas rolyow", "load_pending": "{count, plural, one {# daklennowydh} other {# a daklennow nowydh}}", - "loading_indicator.label": "Ow karga...", "media_gallery.toggle_visible": "Hide {number, plural, one {aven} other {aven}}", "mute_modal.duration": "Duryans", "mute_modal.hide_notifications": "Kudha gwarnyansow a'n devnydhyer ma?", diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json index 5675799e77..21aa797b47 100644 --- a/app/javascript/mastodon/locales/lt.json +++ b/app/javascript/mastodon/locales/lt.json @@ -26,6 +26,7 @@ "account.domain_blocked": "Užblokuotas domenas", "account.edit_profile": "Redaguoti profilį", "account.enable_notifications": "Pranešti man, kai @{name} paskelbia", + "account.endorse": "Savybė profilyje", "account.featured_tags.last_status_at": "Paskutinį kartą paskelbta {date}", "account.featured_tags.last_status_never": "Nėra įrašų", "account.follow": "Sekti", @@ -191,6 +192,7 @@ "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search", "keyboard_shortcuts.up": "to move up in the list", "lightbox.close": "Uždaryti", + "loading_indicator.label": "Kraunama…", "media_gallery.toggle_visible": "{number, plural, one {Slėpti vaizdą} few {Slėpti vaizdus} many {Slėpti vaizdo} other {Slėpti vaizdų}}", "navigation_bar.compose": "Compose new toot", "navigation_bar.domain_blocks": "Hidden domains", @@ -217,6 +219,16 @@ "onboarding.actions.go_to_home": "Go to your home feed", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.title": "Popular on Mastodon", + "onboarding.profile.display_name": "Rodomas vardas", + "onboarding.profile.display_name_hint": "Tavo pilnas vardas arba linksmas vardas…", + "onboarding.profile.indexable": "Įtraukti viešus įrašus į paieškos rezultatus", + "onboarding.profile.lead": "Gali visada tai užbaigti vėliau nustatymuose, kur yra dar daugiau pritaikymo parinkčių.", + "onboarding.profile.note": "Biografija", + "onboarding.profile.note_hint": "Gali @paminėti kitus žmones arba #saitažodžius…", + "onboarding.profile.save_and_continue": "Išsaugoti ir tęsti", + "onboarding.profile.title": "Profilio konfigūravimas", + "onboarding.profile.upload_avatar": "Įkelti profilio nuotrauką", + "onboarding.profile.upload_header": "Įkelti profilio antraštę", "onboarding.share.message": "Aš {username} #Mastodon! Ateik sekti manęs adresu {url}", "onboarding.start.lead": "Dabar esi Mastodon dalis – unikalios decentralizuotos socialinės žiniasklaidos platformos, kurioje tu, o ne algoritmas, pats nustatai savo patirtį. Pradėkime tavo kelionę šioje naujoje socialinėje erdvėje:", "onboarding.start.skip": "Want to skip right ahead?", diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json index 5d681b8291..63ec6275ba 100644 --- a/app/javascript/mastodon/locales/lv.json +++ b/app/javascript/mastodon/locales/lv.json @@ -390,7 +390,6 @@ "lists.search": "Meklēt starp cilvēkiem, kuriem tu seko", "lists.subheading": "Tavi saraksti", "load_pending": "{count, plural, one {# jauna lieta} other {# jaunas lietas}}", - "loading_indicator.label": "Ielādē...", "media_gallery.toggle_visible": "{number, plural, one {Slēpt attēlu} other {Slēpt attēlus}}", "moved_to_account_banner.text": "Tavs konts {disabledAccount} pašlaik ir atspējots, jo pārcēlies uz kontu {movedToAccount}.", "mute_modal.duration": "Ilgums", diff --git a/app/javascript/mastodon/locales/ml.json b/app/javascript/mastodon/locales/ml.json index 6bf04ce758..b00cedc6fc 100644 --- a/app/javascript/mastodon/locales/ml.json +++ b/app/javascript/mastodon/locales/ml.json @@ -237,7 +237,6 @@ "lists.replies_policy.none": "ആരുമില്ല", "lists.replies_policy.title": "ഇതിനുള്ള മറുപടികൾ കാണിക്കുക:", "lists.subheading": "എന്റെ പട്ടികകൾ", - "loading_indicator.label": "ലോഡിംഗ്...", "mute_modal.duration": "കാലാവധി", "mute_modal.indefinite": "അനിശ്ചിതകാല", "navigation_bar.blocks": "തടയപ്പെട്ട ഉപയോക്താക്കൾ", diff --git a/app/javascript/mastodon/locales/mr.json b/app/javascript/mastodon/locales/mr.json index ef0efbdece..75b75375b7 100644 --- a/app/javascript/mastodon/locales/mr.json +++ b/app/javascript/mastodon/locales/mr.json @@ -196,7 +196,6 @@ "lists.search": "तुम्ही फॉलो करत असलेल्या लोकांमध्ये शोधा", "lists.subheading": "तुमच्या याद्या", "load_pending": "{count, plural, one {# new item} other {# new items}}", - "loading_indicator.label": "लोड करत आहे...", "navigation_bar.compose": "Compose new toot", "navigation_bar.domain_blocks": "Hidden domains", "navigation_bar.pins": "Pinned toots", diff --git a/app/javascript/mastodon/locales/ms.json b/app/javascript/mastodon/locales/ms.json index a3bbd0067d..724e07ae76 100644 --- a/app/javascript/mastodon/locales/ms.json +++ b/app/javascript/mastodon/locales/ms.json @@ -386,7 +386,6 @@ "lists.search": "Cari dalam kalangan orang yang anda ikuti", "lists.subheading": "Senarai anda", "load_pending": "{count, plural, one {# item baharu} other {# item baharu}}", - "loading_indicator.label": "Memuatkan...", "media_gallery.toggle_visible": "{number, plural, other {Sembunyikan imej}}", "moved_to_account_banner.text": "Akaun anda {disabledAccount} kini dinyahdayakan kerana anda berpindah ke {movedToAccount}.", "mute_modal.duration": "Tempoh", diff --git a/app/javascript/mastodon/locales/my.json b/app/javascript/mastodon/locales/my.json index 103f4e0f8d..4078a4c066 100644 --- a/app/javascript/mastodon/locales/my.json +++ b/app/javascript/mastodon/locales/my.json @@ -389,7 +389,6 @@ "lists.search": "မိမိဖောလိုးထားသူများမှရှာဖွေမည်", "lists.subheading": "သင့်၏စာရင်းများ", "load_pending": "{count, plural, one {# new item} other {# new items}}", - "loading_indicator.label": "လုပ်ဆောင်နေသည်…", "media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}", "moved_to_account_banner.text": "{movedToAccount} အကောင့်သို့ပြောင်းလဲထားသဖြင့် {disabledAccount} အကောင့်မှာပိတ်ထားသည်", "mute_modal.duration": "ကြာချိန်", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 131d2e4aa0..6f941999f6 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Helaas kunnen op dit moment geen resultaten worden getoond. Je kunt proberen te zoeken of op de verkenningspagina te bladeren om mensen te vinden die je kunt volgen, of probeer het later opnieuw.", "onboarding.follows.lead": "Jouw starttijdlijn is de belangrijkste manier om Mastodon te ervaren. Hoe meer mensen je volgt, hoe actiever en interessanter het zal zijn. Om te beginnen, zijn hier enkele suggesties:", "onboarding.follows.title": "Je starttijdlijn aan jouw wensen aanpassen", + "onboarding.profile.discoverable": "Profiel en berichten laten uitlichten in ontdekkingsalgoritmes", + "onboarding.profile.display_name": "Weergavenaam", + "onboarding.profile.display_name_hint": "Jouw volledige naam of een leuke bijnaam…", + "onboarding.profile.indexable": "Openbare berichten in zoekresultaten opnemen", + "onboarding.profile.lead": "Je kunt dit later altijd aanvullen in de instellingen, waar nog meer aanpassingsopties beschikbaar zijn.", + "onboarding.profile.note": "Biografie", + "onboarding.profile.note_hint": "Je kunt andere mensen @vermelden of #hashtags gebruiken…", + "onboarding.profile.save_and_continue": "Opslaan en doorgaan", + "onboarding.profile.title": "Profiel instellen", + "onboarding.profile.upload_avatar": "Profielfoto uploaden", + "onboarding.profile.upload_header": "Kop voor het profiel uploaden", "onboarding.share.lead": "Laat mensen weten hoe ze je kunnen vinden op Mastodon!", "onboarding.share.message": "Ik ben {username} op #Mastodon! Volg mij op {url}", "onboarding.share.next_steps": "Mogelijke volgende stappen:", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index aa30aef7d2..a3402d6608 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -390,7 +390,7 @@ "lists.search": "Søk blant folk du fylgjer", "lists.subheading": "Listene dine", "load_pending": "{count, plural, one {# nytt element} other {# nye element}}", - "loading_indicator.label": "Lastar...", + "loading_indicator.label": "Laster…", "media_gallery.toggle_visible": "{number, plural, one {Skjul bilete} other {Skjul bilete}}", "moved_to_account_banner.text": "Kontoen din, {disabledAccount} er for tida deaktivert fordi du har flytta til {movedToAccount}.", "mute_modal.duration": "Varigheit", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Me kan ikkje visa deg nokon resultat no. Du kan prøva å søkja eller bla gjennom utforsk-sida for å finna folk å fylgja, eller du kan prøva att seinare.", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.title": "Popular on Mastodon", + "onboarding.profile.discoverable": "Fremhevede profiler og innlegg i oppdagelsealgoritmer", + "onboarding.profile.display_name": "Visningsnavn", + "onboarding.profile.display_name_hint": "Ditt fulle navn eller ditt morsomme navn…", + "onboarding.profile.indexable": "Inkluder offentlige innlegg i søkeresultatene", + "onboarding.profile.lead": "Du kan alltid fullføre dette senere i innstillingene, der enda flere tilpasningsalternativer er tilgjengelige.", + "onboarding.profile.note": "Om meg", + "onboarding.profile.note_hint": "Du kan @nevne andre eller #emneknagger…", + "onboarding.profile.save_and_continue": "Lagre og fortsett", + "onboarding.profile.title": "Konfigurering av profil", + "onboarding.profile.upload_avatar": "Last opp profilbilde", + "onboarding.profile.upload_header": "Last opp profiltoppbilde", "onboarding.share.lead": "La folk vita korleis dei kan finna deg på Mastodon!", "onboarding.share.message": "Eg er {username} på #Mastodon! Du kan fylgja meg på {url}", "onboarding.share.next_steps": "Dette kan du gjera no:", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index 7421c780f5..fe3979f0fe 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -390,7 +390,7 @@ "lists.search": "Søk blant personer du følger", "lists.subheading": "Dine lister", "load_pending": "{count, plural,one {# ny gjenstand} other {# nye gjenstander}}", - "loading_indicator.label": "Laster...", + "loading_indicator.label": "Laster…", "media_gallery.toggle_visible": "Veksle synlighet", "moved_to_account_banner.text": "Din konto {disabledAccount} er for øyeblikket deaktivert fordi du flyttet til {movedToAccount}.", "mute_modal.duration": "Varighet", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Dessverre kan ingen resultater vises akkurat nå. Du kan prøve å bruke søk eller bla gjennom utforske-siden for å finne folk å følge, eller prøve igjen senere.", "onboarding.follows.lead": "Hjem-skjermen din er den viktigste måten å oppleve Mastodon på. Jo flere du følger, jo mer aktiv og interessant blir det. For å komme i gang, er her noen forslag:", "onboarding.follows.title": "Populært på Mastodon", + "onboarding.profile.discoverable": "Fremhevede profiler og innlegg i oppdagelsealgoritmer", + "onboarding.profile.display_name": "Visningsnavn", + "onboarding.profile.display_name_hint": "Ditt fulle navn eller ditt morsomme navn…", + "onboarding.profile.indexable": "Inkluder offentlige innlegg i søkeresultatene", + "onboarding.profile.lead": "Du kan alltid fullføre dette senere i innstillingene, der enda flere tilpasningsalternativer er tilgjengelige.", + "onboarding.profile.note": "Om meg", + "onboarding.profile.note_hint": "Du kan @nevne andre eller #emneknagger…", + "onboarding.profile.save_and_continue": "Lagre og fortsett", + "onboarding.profile.title": "Konfigurering av profil", + "onboarding.profile.upload_avatar": "Last opp profilbilde", + "onboarding.profile.upload_header": "Last opp profiltoppbilde", "onboarding.share.lead": "La folk vite hvordan de kan finne deg på Mastodon!", "onboarding.share.message": "Jeg er {username} på #Mastodon! Kom og følg meg på {url}", "onboarding.share.next_steps": "Mulige neste trinn:", diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json index 6b82654500..3812057fb0 100644 --- a/app/javascript/mastodon/locales/oc.json +++ b/app/javascript/mastodon/locales/oc.json @@ -340,7 +340,6 @@ "lists.search": "Cercar demest lo mond que seguètz", "lists.subheading": "Vòstras listas", "load_pending": "{count, plural, one {# nòu element} other {# nòu elements}}", - "loading_indicator.label": "Cargament…", "media_gallery.toggle_visible": "Modificar la visibilitat", "mute_modal.duration": "Durada", "mute_modal.hide_notifications": "Rescondre las notificacions d’aquesta persona ?", diff --git a/app/javascript/mastodon/locales/pa.json b/app/javascript/mastodon/locales/pa.json index 371f9622d2..7faf279719 100644 --- a/app/javascript/mastodon/locales/pa.json +++ b/app/javascript/mastodon/locales/pa.json @@ -122,7 +122,6 @@ "lightbox.next": "ਅਗਲੀ", "lightbox.previous": "ਪਿਛਲੀ", "lists.delete": "ਸੂਚੀ ਮਿਟਾਓ", - "loading_indicator.label": "ਲੋਡ ਹੋ ਰਿਹਾ ਹੈ...", "mute_modal.duration": "ਮਿਆਦ", "navigation_bar.about": "ਸਾਡੇ ਬਾਰੇ", "navigation_bar.bookmarks": "ਬੁੱਕਮਾਰਕ", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 643f78a884..a1cc0e26e6 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Niestety w tej chwili nie można przedstawić żadnych wyników. Możesz spróbować wyszukać lub przeglądać stronę, aby znaleźć osoby do śledzenia, lub spróbować ponownie później.", "onboarding.follows.lead": "Zarządasz swoim własnym kanałem. Im więcej ludzi śledzisz, tym bardziej aktywny i ciekawy będzie Twój kanał. Te profile mogą być dobrym punktem wyjścia— możesz przestać je obserwować w dowolnej chwili!", "onboarding.follows.title": "Popularne na Mastodonie", + "onboarding.profile.discoverable": "Udostępniaj profil i wpisy funkcjom odkrywania", + "onboarding.profile.display_name": "Nazwa wyświetlana", + "onboarding.profile.display_name_hint": "Twoje imię lub pseudonim…", + "onboarding.profile.indexable": "Pokaż publiczne wpisy w wynikach wyszukiwania", + "onboarding.profile.lead": "Możesz wypełnić te dane później w menu ustawień, gdzie dostępnych jest jeszcze więcej opcji.", + "onboarding.profile.note": "O mnie", + "onboarding.profile.note_hint": "Możesz @wspomnieć użytkowników albo #hasztagi…", + "onboarding.profile.save_and_continue": "Zapisz i kontynuuj", + "onboarding.profile.title": "Ustawienia profilu", + "onboarding.profile.upload_avatar": "Dodaj zdjęcie profilowe", + "onboarding.profile.upload_header": "Dodaj zdjęcie nagłówkowe", "onboarding.share.lead": "Daj znać ludziom, jak mogą cię znaleźć na Mastodonie!", "onboarding.share.message": "Jestem {username} na #Mastodon! Śledź mnie tutaj {url}", "onboarding.share.next_steps": "Możliwe dalsze kroki:", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index 9c09e2d719..7ce63e9b1a 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -390,7 +390,6 @@ "lists.search": "Procurar entre as pessoas que segue", "lists.subheading": "Suas listas", "load_pending": "{count, plural, one {# novo item} other {# novos items}}", - "loading_indicator.label": "Carregando...", "media_gallery.toggle_visible": "{number, plural, one {Ocultar mídia} other {Ocultar mídias}}", "moved_to_account_banner.text": "Sua conta {disabledAccount} está desativada porque você a moveu para {movedToAccount}.", "mute_modal.duration": "Duração", diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json index 988bec9b03..69e804878b 100644 --- a/app/javascript/mastodon/locales/pt-PT.json +++ b/app/javascript/mastodon/locales/pt-PT.json @@ -390,7 +390,7 @@ "lists.search": "Pesquisa entre as pessoas que segues", "lists.subheading": "As tuas listas", "load_pending": "{count, plural, one {# novo item} other {# novos itens}}", - "loading_indicator.label": "A carregar...", + "loading_indicator.label": "A carregar…", "media_gallery.toggle_visible": "Alternar visibilidade", "moved_to_account_banner.text": "A sua conta {disabledAccount} está, no momento, desativada, porque você migrou para {movedToAccount}.", "mute_modal.duration": "Duração", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Infelizmente, não é possível mostrar resultados neste momento. Pode tentar utilizar a pesquisa ou navegar na página \"Explorar\" para encontrar pessoas para seguir ou tentar novamente mais tarde.", "onboarding.follows.lead": "Você personaliza a sua própria página inicial. Quanto mais pessoas seguir, mais ativa e interessante ela será. Estes perfis podem ser um bom ponto de partida - pode sempre deixar de os seguir mais tarde!", "onboarding.follows.title": "Popular no Mastodon", + "onboarding.profile.discoverable": "Destacar perfil e publicações nos algoritmos de descoberta", + "onboarding.profile.display_name": "Nome a apresentar", + "onboarding.profile.display_name_hint": "O seu nome completo ou o seu nome divertido…", + "onboarding.profile.indexable": "Incluir publicações públicas nos resultados de pesquisa", + "onboarding.profile.lead": "Pode sempre completar isto mais tarde, nas configurações, onde ainda estão disponíveis mais opções de personalização.", + "onboarding.profile.note": "Bio", + "onboarding.profile.note_hint": "Pode @mencionar outras pessoas ou #hashtags…", + "onboarding.profile.save_and_continue": "Guardar e continuar", + "onboarding.profile.title": "Configuração do perfil", + "onboarding.profile.upload_avatar": "Carregar foto de perfil", + "onboarding.profile.upload_header": "Carregar cabeçalho do perfil", "onboarding.share.lead": "Deixe as pessoas saber como o podem encontrar no Mastodon!", "onboarding.share.message": "Eu sou {username} no #Mastodon! Venha seguir-me em {url}", "onboarding.share.next_steps": "Próximos passos possíveis:", diff --git a/app/javascript/mastodon/locales/ro.json b/app/javascript/mastodon/locales/ro.json index f0e84463b2..5355f9935a 100644 --- a/app/javascript/mastodon/locales/ro.json +++ b/app/javascript/mastodon/locales/ro.json @@ -353,7 +353,6 @@ "lists.search": "Caută printre persoanele la care ești abonat", "lists.subheading": "Listele tale", "load_pending": "{count, plural, one {# element nou} other {# elemente noi}}", - "loading_indicator.label": "Se încarcă...", "media_gallery.toggle_visible": "{number, plural, one {Ascunde imaginea} other {Ascunde imaginile}}", "moved_to_account_banner.text": "Contul tău {disabledAccount} este în acest moment dezactivat deoarece te-ai mutat la {movedToAccount}.", "mute_modal.duration": "Durata", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index 69db89dc86..5c98d906b6 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -389,7 +389,6 @@ "lists.search": "Искать среди подписок", "lists.subheading": "Ваши списки", "load_pending": "{count, plural, one {# новый элемент} few {# новых элемента} other {# новых элементов}}", - "loading_indicator.label": "Загрузка...", "media_gallery.toggle_visible": "Показать/скрыть {number, plural, =1 {изображение} other {изображения}}", "moved_to_account_banner.text": "Ваша учетная запись {disabledAccount} в настоящее время заморожена, потому что вы переехали на {movedToAccount}.", "mute_modal.duration": "Продолжительность", diff --git a/app/javascript/mastodon/locales/sa.json b/app/javascript/mastodon/locales/sa.json index cb92914e50..59379343b9 100644 --- a/app/javascript/mastodon/locales/sa.json +++ b/app/javascript/mastodon/locales/sa.json @@ -345,7 +345,6 @@ "lists.search": "त्वया अनुसारितजनेषु अन्विष्य", "lists.subheading": "तव सूचयः", "load_pending": "{count, plural, one {# नूतनवस्तु} other {# नूतनवस्तूनि}}", - "loading_indicator.label": "आरोपयति...", "media_gallery.toggle_visible": "{number, plural, one {चित्रं प्रच्छादय} other {चित्राणि प्रच्छादय}}", "moved_to_account_banner.text": "तव एकौण्ट् {disabledAccount} अधुना निष्कृतो यतोहि {movedToAccount} अस्मिन्त्वमसार्षीः।", "mute_modal.duration": "परिमाणम्", diff --git a/app/javascript/mastodon/locales/sc.json b/app/javascript/mastodon/locales/sc.json index 4528e161b6..59c834b950 100644 --- a/app/javascript/mastodon/locales/sc.json +++ b/app/javascript/mastodon/locales/sc.json @@ -263,7 +263,6 @@ "lists.search": "Chirca intre sa gente chi ses sighende", "lists.subheading": "Is listas tuas", "load_pending": "{count, plural, one {# elementu nou} other {# elementos noos}}", - "loading_indicator.label": "Carrighende...", "media_gallery.toggle_visible": "Cua {number, plural, one {immàgine} other {immàgines}}", "mute_modal.duration": "Durada", "mute_modal.hide_notifications": "Boles cuare is notìficas de custa persone?", diff --git a/app/javascript/mastodon/locales/sco.json b/app/javascript/mastodon/locales/sco.json index 9b8e6a215f..28dac9c2a2 100644 --- a/app/javascript/mastodon/locales/sco.json +++ b/app/javascript/mastodon/locales/sco.json @@ -330,7 +330,6 @@ "lists.search": "Seirch amang the fowk ye ken", "lists.subheading": "Yer lists", "load_pending": "{count, plural, one {# new item} other {# new items}}", - "loading_indicator.label": "Loadin...", "media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}", "moved_to_account_banner.text": "Yer accoont {disabledAccount} is disabilt the noo acause ye flittit tae {movedToAccount}.", "mute_modal.duration": "Lenth", diff --git a/app/javascript/mastodon/locales/si.json b/app/javascript/mastodon/locales/si.json index 7b26a9b488..835f699b82 100644 --- a/app/javascript/mastodon/locales/si.json +++ b/app/javascript/mastodon/locales/si.json @@ -261,7 +261,6 @@ "lists.replies_policy.none": "කිසිවෙක් නැත", "lists.replies_policy.title": "පිළිතුරු පෙන්වන්න:", "lists.subheading": "ඔබගේ ලැයිස්තු", - "loading_indicator.label": "පූරණය වෙමින්...", "mute_modal.duration": "පරාසය", "mute_modal.hide_notifications": "මෙම පුද්ගලයාගේ දැනුම්දීම් සඟවන්නද?", "navigation_bar.about": "පිළිබඳව", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index f2616b31c4..24186794bb 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -389,7 +389,6 @@ "lists.search": "Vyhľadávaj medzi užívateľmi, ktorých sleduješ", "lists.subheading": "Tvoje zoznamy", "load_pending": "{count, plural, one {# nová položka} other {# nových položiek}}", - "loading_indicator.label": "Načítam...", "media_gallery.toggle_visible": "Zapni/Vypni viditeľnosť", "moved_to_account_banner.text": "Vaše konto {disabledAccount} je momentálne zablokované, pretože ste sa presunuli na {movedToAccount}.", "mute_modal.duration": "Trvanie", diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json index f16a91d65a..d179a86562 100644 --- a/app/javascript/mastodon/locales/sl.json +++ b/app/javascript/mastodon/locales/sl.json @@ -390,7 +390,6 @@ "lists.search": "Iščite med ljudmi, katerim sledite", "lists.subheading": "Vaši seznami", "load_pending": "{count, plural, one {# nov element} two {# nova elementa} few {# novi elementi} other {# novih elementov}}", - "loading_indicator.label": "Nalaganje ...", "media_gallery.toggle_visible": "{number, plural,one {Skrij sliko} two {Skrij sliki} other {Skrij slike}}", "moved_to_account_banner.text": "Vaš račun {disabledAccount} je trenutno onemogočen, ker ste se prestavili na {movedToAccount}.", "mute_modal.duration": "Trajanje", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 8d54ef41b1..1417bed5fc 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Mjerisht, s’mund të shfaqen përfundime tani. Mund të provoni të përdorni kërkimin, ose të shfletoni faqen e eksplorimit, që të gjeni persona për ndjekje, ose të riprovoni më vonë.", "onboarding.follows.lead": "Ju kujdeseni për prurjen tuaj. Sa më tepër persona të tjerë të ndiqni, aq më aktive dhe interesante do të bëhet ajo. Këto profile mund të jenë një pikënisje e mirë—mundeni përherë të ndërpritni ndjekjen e tyre më vonë!", "onboarding.follows.title": "Popullore në Mastodon", + "onboarding.profile.discoverable": "Profilin dhe postimet bëji objekt të algoritmeve të zbulimit", + "onboarding.profile.display_name": "Emër në ekran", + "onboarding.profile.display_name_hint": "Emri juaj i plotë, ose ç’të doni…", + "onboarding.profile.indexable": "Përfshi postime publike në përfundime kërkimi", + "onboarding.profile.lead": "Këtë mund ta plotësoni përherë më vonë, te rregullimet, ku ka edhe më tepër mundësi përshtatjeje.", + "onboarding.profile.note": "Jetëshkrim", + "onboarding.profile.note_hint": "Mund të @përmendni persona të tjerë, ose #hashtagë…", + "onboarding.profile.save_and_continue": "Ruaje dhe vazhdo", + "onboarding.profile.title": "Udjisje profili", + "onboarding.profile.upload_avatar": "Ngarkoni foto profili", + "onboarding.profile.upload_header": "Ngarkoni krye profili", "onboarding.share.lead": "Bëjuni të ditur njerëzve se si mund t’ju gjejnë në Mastodon!", "onboarding.share.message": "Jam {username} në #Mastodon! Ejani dhe ndiqmëni te {url}", "onboarding.share.next_steps": "Hapa pasues të mundshëm:", diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json index aa948b1f0e..ea6e188cb7 100644 --- a/app/javascript/mastodon/locales/sr-Latn.json +++ b/app/javascript/mastodon/locales/sr-Latn.json @@ -390,7 +390,6 @@ "lists.search": "Pretraži među ljudima koje pratite", "lists.subheading": "Vaše liste", "load_pending": "{count, plural, one {# nova stavka} few {# nove stavke} other {# novih stavki}}", - "loading_indicator.label": "Učitavanje...", "media_gallery.toggle_visible": "{number, plural, one {Sakrij sliku} few {Sakrij slike} other {Sakrij slike}}", "moved_to_account_banner.text": "Vaš nalog {disabledAccount} je trenutno onemogućen jer ste prešli na {movedToAccount}.", "mute_modal.duration": "Trajanje", diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json index 9e67169272..b0a76b32ab 100644 --- a/app/javascript/mastodon/locales/sr.json +++ b/app/javascript/mastodon/locales/sr.json @@ -390,7 +390,6 @@ "lists.search": "Претражи међу људима које пратите", "lists.subheading": "Ваше листе", "load_pending": "{count, plural, one {# нова ставка} few {# нове ставке} other {# нових ставки}}", - "loading_indicator.label": "Учитавање...", "media_gallery.toggle_visible": "{number, plural, one {Сакриј слику} few {Сакриј слике} other {Сакриј слике}}", "moved_to_account_banner.text": "Ваш налог {disabledAccount} је тренутно онемогућен јер сте прешли на {movedToAccount}.", "mute_modal.duration": "Трајање", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index edf981e112..6f9f37ea12 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -390,7 +390,7 @@ "lists.search": "Sök bland personer du följer", "lists.subheading": "Dina listor", "load_pending": "{count, plural, one {# nytt objekt} other {# nya objekt}}", - "loading_indicator.label": "Laddar...", + "loading_indicator.label": "Laddar…", "media_gallery.toggle_visible": "Växla synlighet", "moved_to_account_banner.text": "Ditt konto {disabledAccount} är för närvarande inaktiverat eftersom du flyttat till {movedToAccount}.", "mute_modal.duration": "Varaktighet", @@ -479,6 +479,14 @@ "onboarding.follows.empty": "Tyvärr kan inga resultat visas just nu. Du kan prova att använda sökfunktionen eller utforska sidan för att hitta personer att följa, eller försök igen senare.", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.title": "Popular on Mastodon", + "onboarding.profile.display_name": "Visningsnamn", + "onboarding.profile.display_name_hint": "Fullständigt namn eller ditt roliga namn…", + "onboarding.profile.indexable": "Inkludera offentliga inlägg i sökresultaten", + "onboarding.profile.lead": "Du kan alltid slutföra detta senare i inställningarna, där ännu fler anpassningsalternativ finns tillgängliga.", + "onboarding.profile.note": "Bio", + "onboarding.profile.note_hint": "Du kan @nämna andra personer eller #hashtags…", + "onboarding.profile.save_and_continue": "Spara och fortsätt", + "onboarding.profile.upload_avatar": "Ladda upp profilbild", "onboarding.share.lead": "Låt folk veta hur de kan hitta dig på Mastodon!", "onboarding.share.message": "Jag är {username} på #Mastodon! Följ mig på {url}", "onboarding.share.next_steps": "Möjliga nästa steg:", diff --git a/app/javascript/mastodon/locales/ta.json b/app/javascript/mastodon/locales/ta.json index f62088f626..ce9042e62b 100644 --- a/app/javascript/mastodon/locales/ta.json +++ b/app/javascript/mastodon/locales/ta.json @@ -248,7 +248,6 @@ "lists.search": "நீங்கள் பின்தொடரும் நபர்கள் மத்தியில் தேடுதல்", "lists.subheading": "உங்கள் பட்டியல்கள்", "load_pending": "{count, plural,one {# புதியது}other {# புதியவை}}", - "loading_indicator.label": "ஏற்றுதல்...", "media_gallery.toggle_visible": "நிலைமாற்று தெரியும்", "mute_modal.hide_notifications": "இந்த பயனரின் அறிவிப்புகளை மறைக்கவா?", "navigation_bar.blocks": "தடுக்கப்பட்ட பயனர்கள்", diff --git a/app/javascript/mastodon/locales/te.json b/app/javascript/mastodon/locales/te.json index 6cf735991f..f21c0ef57a 100644 --- a/app/javascript/mastodon/locales/te.json +++ b/app/javascript/mastodon/locales/te.json @@ -180,7 +180,6 @@ "lists.new.title_placeholder": "కొత్త జాబితా శీర్షిక", "lists.search": "మీరు అనుసరించే వ్యక్తులలో శోధించండి", "lists.subheading": "మీ జాబితాలు", - "loading_indicator.label": "లోడ్ అవుతోంది...", "media_gallery.toggle_visible": "దృశ్యమానతను టోగుల్ చేయండి", "mute_modal.hide_notifications": "ఈ వినియోగదారు నుండి నోటిఫికేషన్లను దాచాలా?", "navigation_bar.blocks": "బ్లాక్ చేయబడిన వినియోగదారులు", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index 80f862cbe0..2166cd2dda 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -390,7 +390,7 @@ "lists.search": "ค้นหาในหมู่ผู้คนที่คุณติดตาม", "lists.subheading": "รายการของคุณ", "load_pending": "{count, plural, other {# รายการใหม่}}", - "loading_indicator.label": "กำลังโหลด...", + "loading_indicator.label": "กำลังโหลด…", "media_gallery.toggle_visible": "{number, plural, other {ซ่อนภาพ}}", "moved_to_account_banner.text": "มีการปิดใช้งานบัญชีของคุณ {disabledAccount} ในปัจจุบันเนื่องจากคุณได้ย้ายไปยัง {movedToAccount}", "mute_modal.duration": "ระยะเวลา", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "น่าเสียดาย ไม่สามารถแสดงผลลัพธ์ได้ในตอนนี้ คุณสามารถลองใช้การค้นหาหรือเรียกดูหน้าสำรวจเพื่อค้นหาผู้คนที่จะติดตาม หรือลองอีกครั้งในภายหลัง", "onboarding.follows.lead": "ฟีดหน้าแรกของคุณเป็นวิธีหลักในการสัมผัส Mastodon ยิ่งคุณติดตามผู้คนมากเท่าไร ฟีดหน้าแรกก็จะยิ่งมีการใช้งานและน่าสนใจมากขึ้นเท่านั้น เพื่อช่วยให้คุณเริ่มต้นใช้งาน นี่คือข้อเสนอแนะบางส่วน:", "onboarding.follows.title": "ปรับแต่งฟีดหน้าแรกของคุณ", + "onboarding.profile.discoverable": "แสดงโปรไฟล์และโพสต์ในอัลกอริทึมการค้นพบ", + "onboarding.profile.display_name": "ชื่อที่แสดง", + "onboarding.profile.display_name_hint": "ชื่อเต็มหรือชื่อแบบสนุกสนานของคุณ", + "onboarding.profile.indexable": "รวมโพสต์สาธารณะในผลลัพธ์การค้นหา", + "onboarding.profile.lead": "คุณสามารถกลับมาทำต่อได้เสมอในการตั้งค่า ซึ่งจะมีตัวเลือกในการปรับแต่งมากกว่า", + "onboarding.profile.note": "ชีวประวัติ", + "onboarding.profile.note_hint": "คุณสามารถ @กล่าวถึง ผู้คนอื่น ๆ หรือ #แฮชแท็ก", + "onboarding.profile.save_and_continue": "บันทึกและดำเนินการต่อ", + "onboarding.profile.title": "การตั้งค่าโปรไฟล์", + "onboarding.profile.upload_avatar": "อัปโหลดรูปโปรไฟล์", + "onboarding.profile.upload_header": "อัปโหลดรูปส่วนหัวโปรไฟล์", "onboarding.share.lead": "แจ้งให้ผู้คนทราบวิธีที่เขาสามารถค้นหาคุณใน Mastodon!", "onboarding.share.message": "ฉันคือ {username} ใน #Mastodon! มาติดตามฉันที่ {url}", "onboarding.share.next_steps": "ขั้นตอนถัดไปที่เป็นไปได้:", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 9ad2594930..505b16f4b0 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -390,7 +390,7 @@ "lists.search": "Takip ettiğiniz kişiler arasından arayın", "lists.subheading": "Listeleriniz", "load_pending": "{count, plural, one {# yeni öğe} other {# yeni öğe}}", - "loading_indicator.label": "Yükleniyor...", + "loading_indicator.label": "Yükleniyor…", "media_gallery.toggle_visible": "{number, plural, one {Resmi} other {Resimleri}} gizle", "moved_to_account_banner.text": "{disabledAccount} hesabınız, {movedToAccount} hesabına taşıdığınız için şu an devre dışı.", "mute_modal.duration": "Süre", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "Maalesef şu an bir sonuç gösterilemiyor. Takip edilecek kişileri bulmak için arama veya keşfet sayfasına gözatmayı kullanabilirsiniz veya daha sonra tekrar deneyin.", "onboarding.follows.lead": "Kendi ana akışınızı siz düzenliyorsunuz. Siz daha fazla insanı takip ettikçe, daha etkin ve ilgi çekici olacaktır. Bu profiller iyi bir başlangıç olabilir, isterseniz izlemeyi daha sonra bırakabilirsiniz:", "onboarding.follows.title": "Mastodon'da Popüler", + "onboarding.profile.discoverable": "Profil ve gönderileri keşif algoritmalarında kullan", + "onboarding.profile.display_name": "Görünen isim", + "onboarding.profile.display_name_hint": "Tam adınız veya kullanıcı adınız…", + "onboarding.profile.indexable": "Herkese açık gönderileri arama sonuçlarına ekle", + "onboarding.profile.lead": "Bunu her zaman daha sonra ayarlardan tamamlayabilirsiniz, hatta daha fazla özelleştirme seçeneğine de ulaşabilirsiniz.", + "onboarding.profile.note": "Kişisel bilgiler", + "onboarding.profile.note_hint": "Diğer insanlara @değinebilir veya #etiketler kullanabilirsiniz…", + "onboarding.profile.save_and_continue": "Kaydet ve ilerle", + "onboarding.profile.title": "Profilini ayarla", + "onboarding.profile.upload_avatar": "Profil resmi yükle", + "onboarding.profile.upload_header": "Profil başlığı yükle", "onboarding.share.lead": "Kullanıcılara Mastodon'da size nasıl ulaşabileceklerini ifade edin!", "onboarding.share.message": "#Mastodon'da kullanıcı adım {username}! Beni takip etmek için {url} bağlantısını kullanın", "onboarding.share.next_steps": "Olası sonraki adımlar:", diff --git a/app/javascript/mastodon/locales/tt.json b/app/javascript/mastodon/locales/tt.json index e84bc66cc5..6727f3e59a 100644 --- a/app/javascript/mastodon/locales/tt.json +++ b/app/javascript/mastodon/locales/tt.json @@ -314,7 +314,6 @@ "lists.replies_policy.none": "Һичкем", "lists.subheading": "Исемлегегегезләр", "load_pending": "{count, plural, one {# яңа элемент} other {# яңа элемент}}", - "loading_indicator.label": "Йөкләү...", "mute_modal.duration": "Дәвамлык", "mute_modal.indefinite": "Билгесез", "navigation_bar.about": "Проект турында", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 09fa58fbf9..8649d93103 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -390,7 +390,7 @@ "lists.search": "Шукати серед людей, на яких ви підписані", "lists.subheading": "Ваші списки", "load_pending": "{count, plural, one {# новий елемент} other {# нових елементів}}", - "loading_indicator.label": "Завантаження...", + "loading_indicator.label": "Завантаження…", "media_gallery.toggle_visible": "{number, plural, one {Приховати зображення} other {Приховати зображення}}", "moved_to_account_banner.text": "Ваш обліковий запис {disabledAccount} наразі вимкнений, оскільки вас перенесено до {movedToAccount}.", "mute_modal.duration": "Тривалість", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "На жаль, жоден результат не може бути показаний просто зараз. Ви можете спробувати скористатися пошуком або переглядом сторінки огляду, щоб знайти людей для слідкування або повторіть спробу пізніше.", "onboarding.follows.lead": "Ваша домашня стрічка - основний спосіб роботи Mastodon. Чим більше людей, які ви підписані, тим активнішою і цікавою. Ось деякі пропозиції на початок:", "onboarding.follows.title": "Персоналізуйте домашню стрічку", + "onboarding.profile.discoverable": "Враховувати профіль та дописи в алгоритмах пошуку", + "onboarding.profile.display_name": "Видиме ім'я", + "onboarding.profile.display_name_hint": "Ваше повне ім'я або ваш псевдонім…", + "onboarding.profile.indexable": "Включити загальнодоступні дописи в результати пошуку", + "onboarding.profile.lead": "Ви завжди можете завершити це пізніше в Налаштуваннях, де доступно ще більше опцій налаштування.", + "onboarding.profile.note": "Біографія", + "onboarding.profile.note_hint": "Ви можете @згадувати інших людей або #гештеґи…", + "onboarding.profile.save_and_continue": "Зберегти і продовжити", + "onboarding.profile.title": "Налаштування профілю", + "onboarding.profile.upload_avatar": "Завантажити зображення профілю", + "onboarding.profile.upload_header": "Завантажити заголовок профілю", "onboarding.share.lead": "Розкажіть людям про те, як вони можуть знайти вас на Mastodon!", "onboarding.share.message": "Я {username} на #Mastodon! Стежте за мною на {url}", "onboarding.share.next_steps": "Можливі такі кроки:", diff --git a/app/javascript/mastodon/locales/uz.json b/app/javascript/mastodon/locales/uz.json index afb4c4c4c2..026cc115c1 100644 --- a/app/javascript/mastodon/locales/uz.json +++ b/app/javascript/mastodon/locales/uz.json @@ -325,7 +325,6 @@ "lists.search": "Siz kuzatadigan odamlar orasidan qidiring", "lists.subheading": "Sizning ro'yxatlaringiz", "load_pending": "{count, plural, one {# yangi element} other {# yangi elementlar}}", - "loading_indicator.label": "Yuklanmoqda...", "media_gallery.toggle_visible": "{number, plural, one {Rasmni yashirish} other {Rasmlarni yashirish}}", "moved_to_account_banner.text": "{movedToAccount} hisobiga koʻchganingiz uchun {disabledAccount} hisobingiz hozirda oʻchirib qoʻyilgan.", "mute_modal.duration": "Davomiyligi", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index aa229eceb8..c98be2b746 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -390,7 +390,6 @@ "lists.search": "Tìm kiếm những người mà bạn quan tâm", "lists.subheading": "Danh sách của bạn", "load_pending": "{count, plural, one {# tút mới} other {# tút mới}}", - "loading_indicator.label": "Đang tải...", "media_gallery.toggle_visible": "{number, plural, other {Ẩn hình ảnh}}", "moved_to_account_banner.text": "Tài khoản {disabledAccount} của bạn hiện không khả dụng vì bạn đã chuyển sang {movedToAccount}.", "mute_modal.duration": "Thời hạn", diff --git a/app/javascript/mastodon/locales/zgh.json b/app/javascript/mastodon/locales/zgh.json index 7b19e0e6a7..5896a25b02 100644 --- a/app/javascript/mastodon/locales/zgh.json +++ b/app/javascript/mastodon/locales/zgh.json @@ -127,7 +127,6 @@ "lists.replies_policy.title": "ⵙⴽⵏ ⵜⵉⵔⴰⵔⵉⵏ ⵉ:", "lists.subheading": "ⵜⵉⵍⴳⴰⵎⵉⵏ ⵏⵏⴽ", "load_pending": "{count, plural, one {# ⵓⴼⵔⴷⵉⵙ ⴰⵎⴰⵢⵏⵓ} other {# ⵉⴼⵔⴷⴰⵙ ⵉⵎⴰⵢⵏⵓⵜⵏ}}", - "loading_indicator.label": "ⴰⵣⴷⴰⵎ...", "media_gallery.toggle_visible": "ⴼⴼⵔ {number, plural, one {ⵜⴰⵡⵍⴰⴼⵜ} other {ⵜⵉⵡⵍⴰⴼⵉⵏ}}", "navigation_bar.compose": "Compose new toot", "navigation_bar.domain_blocks": "Hidden domains", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index f830aa2985..cc6d8994d2 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -193,7 +193,7 @@ "conversation.with": "与 {names}", "copypaste.copied": "已复制", "copypaste.copy_to_clipboard": "复制到剪贴板", - "directory.federated": "来自已知联邦宇宙", + "directory.federated": "来自已知的联邦宇宙", "directory.local": "仅来自 {domain}", "directory.new_arrivals": "新来者", "directory.recently_active": "最近活跃", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "很抱歉,现在无法显示任何结果。您可以尝试使用搜索或浏览探索页面来查找要关注的人,或稍后再试。", "onboarding.follows.lead": "你管理你自己的家庭饲料。你关注的人越多,它将越活跃和有趣。 这些配置文件可能是一个很好的起点——你可以随时取消关注它们!", "onboarding.follows.title": "定制您的主页动态", + "onboarding.profile.discoverable": "在发现算法中展示您的个人资料和嘟文", + "onboarding.profile.display_name": "昵称", + "onboarding.profile.display_name_hint": "您的全名或昵称…", + "onboarding.profile.indexable": "将您的公开嘟文纳入搜索范围", + "onboarding.profile.lead": "您可以稍后在设置中完成此操作,设置中有更多的自定义选项。", + "onboarding.profile.note": "简介", + "onboarding.profile.note_hint": "您可以提及 @其他人 或 #标签…", + "onboarding.profile.save_and_continue": "保存并继续", + "onboarding.profile.title": "设置个人资料", + "onboarding.profile.upload_avatar": "上传头像", + "onboarding.profile.upload_header": "上传资料卡头图", "onboarding.share.lead": "让人们知道他们如何在Mastodon找到你!", "onboarding.share.message": "我是来自 #Mastodon 的 {username}!请在 {url} 关注我。", "onboarding.share.next_steps": "可能的下一步:", diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json index 7121a7d03e..ea932bc5a7 100644 --- a/app/javascript/mastodon/locales/zh-HK.json +++ b/app/javascript/mastodon/locales/zh-HK.json @@ -390,7 +390,7 @@ "lists.search": "從你關注的人搜索", "lists.subheading": "列表", "load_pending": "{count, plural, other {# 個新項目}}", - "loading_indicator.label": "載入中...", + "loading_indicator.label": "載入中…", "media_gallery.toggle_visible": "隱藏圖片", "moved_to_account_banner.text": "您的帳號 {disabledAccount} 目前已停用,因為您已搬家至 {movedToAccount}。", "mute_modal.duration": "時間", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "很遺憾,現在無法顯示任何結果。你可以嘗試搜尋或瀏覽探索頁面來找使用者來追蹤,或者稍後再試。", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.title": "Popular on Mastodon", + "onboarding.profile.discoverable": "在探索的演算法中展示個人檔案和帖文", + "onboarding.profile.display_name": "顯示名稱", + "onboarding.profile.display_name_hint": "你的全名或暱稱…", + "onboarding.profile.indexable": "將公開帖文納入搜尋結果中", + "onboarding.profile.lead": "你可以隨時在設定中完成此動作,那裏有更多自訂選項。", + "onboarding.profile.note": "簡介", + "onboarding.profile.note_hint": "你可以 @提及他人 或使用 #標籤…", + "onboarding.profile.save_and_continue": "儲存並繼續", + "onboarding.profile.title": "個人檔案設定", + "onboarding.profile.upload_avatar": "上載個人檔案頭像", + "onboarding.profile.upload_header": "上載個人檔案橫幅圖片", "onboarding.share.lead": "讓大家知道如何在 Mastodon 上找到你吧!", "onboarding.share.message": "我在 #Mastodon 的使用者名稱是 {username}!快來追蹤我吧 {url}", "onboarding.share.next_steps": "接下來你可以:", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 974096d2fa..4c52693cc3 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -390,7 +390,7 @@ "lists.search": "搜尋您跟隨的使用者", "lists.subheading": "您的列表", "load_pending": "{count, plural, one {# 個新項目} other {# 個新項目}}", - "loading_indicator.label": "讀取中...", + "loading_indicator.label": "正在載入...", "media_gallery.toggle_visible": "切換可見性", "moved_to_account_banner.text": "您的帳號 {disabledAccount} 目前已停用,因為您已搬家至 {movedToAccount}。", "mute_modal.duration": "持續時間", @@ -479,6 +479,17 @@ "onboarding.follows.empty": "很遺憾,目前未能顯示任何結果。您可以嘗試使用搜尋、瀏覽探索頁面以找尋人們跟隨、或稍候再試。", "onboarding.follows.lead": "您的首頁時間軸是 Mastodon 的核心體驗。若您跟隨更多人的話,它將會變得更活躍有趣。這些個人檔案也許是個好起點,您可以隨時取消跟隨他們!", "onboarding.follows.title": "客製化您的首頁時間軸", + "onboarding.profile.discoverable": "於探索演算法中推薦個人檔案及嘟文", + "onboarding.profile.display_name": "顯示名稱", + "onboarding.profile.display_name_hint": "完整名稱或暱稱...", + "onboarding.profile.indexable": "允許公開嘟文顯示於搜尋結果中", + "onboarding.profile.lead": "您隨時可以稍候於設定中完成此操作,將有更多自訂選項可使用。", + "onboarding.profile.note": "個人簡介", + "onboarding.profile.note_hint": "您可以 @mention 其他人或者使用 #主題標籤...", + "onboarding.profile.save_and_continue": "儲存並繼續", + "onboarding.profile.title": "個人檔案設定", + "onboarding.profile.upload_avatar": "上傳個人檔案大頭貼", + "onboarding.profile.upload_header": "上傳個人檔案封面圖片", "onboarding.share.lead": "讓其他人知道他們如何於 Mastodon 上面找到您!", "onboarding.share.message": "我是 #Mastodon 上的 {username}!歡迎於 {url} 跟隨我", "onboarding.share.next_steps": "可能的下一步:", diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 8543f2ee0f..add2456681 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -286,6 +286,17 @@ font-size: 12px; font-weight: 500; } + + &.copyable { + transition: all 300ms linear; + } + + &.copied { + border-color: $valid-value-color; + color: $valid-value-color; + transition: none; + background-color: rgba($valid-value-color, 0.15); + } } .text-icon-button { @@ -2288,8 +2299,7 @@ $ui-header-height: 55px; > .scrollable { background: $ui-base-color; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; + border-radius: 0 0 4px 4px; } } @@ -7278,6 +7288,7 @@ noscript { .account__header { overflow: hidden; + container: account-header / inline-size; &.inactive { opacity: 0.5; @@ -7373,6 +7384,16 @@ noscript { width: 24px; height: 24px; } + + &.copied { + border-color: $valid-value-color; + } + } + + @container account-header (max-width: 372px) { + .optional { + display: none; + } } } diff --git a/config/locales/be.yml b/config/locales/be.yml index 223b4d1dff..fa43373f6d 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -635,6 +635,7 @@ be: created_at: Створана delete_and_resolve: Выдаліць допісы forwarded: Пераслана + forwarded_replies_explanation: Гэтае паведамленне паступіла ад выдаленага карыстальніка і дакранаецца выдаленага змесціва. Яно было накіраванае вам, бо змесціва паведамлення з'яўляецца адказам аднаму з вашых карыстальнікаў. forwarded_to: Пераслана на %{domain} mark_as_resolved: Пазначыць як вырашаную mark_as_sensitive: Пазначыць як далікатны diff --git a/config/locales/bg.yml b/config/locales/bg.yml index 9da8343019..dfff7058dc 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -1368,6 +1368,7 @@ bg: '86400': 1 ден expires_in_prompt: Никога generate: Генериране на линк за покана + invalid: Тази покана не е валидна invited_by: 'Бяхте поканени от:' max_uses: one: 1 използване diff --git a/config/locales/da.yml b/config/locales/da.yml index 13010e1adf..7344d789ff 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -611,6 +611,7 @@ da: created_at: Anmeldt delete_and_resolve: Slet indlæg forwarded: Videresendt + forwarded_replies_explanation: Denne anmeldelse er fra en ekstern bruger og om eksternt indhold. Den er videresendt til dig, da det anmeldte indhold er som svar til en af dine brugere. forwarded_to: Videresendt til %{domain} mark_as_resolved: Markér som løst mark_as_sensitive: Markér som sensitiv diff --git a/config/locales/de.yml b/config/locales/de.yml index 81fa4b57f3..69309737d4 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -611,6 +611,7 @@ de: created_at: Gemeldet delete_and_resolve: Beiträge löschen forwarded: Weitergeleitet + forwarded_replies_explanation: Diese Meldung stammt von einem externen Profil und betrifft einen externen Inhalt. Der Inhalt wurde an Dich weitergeleitet, weil er eine Antwort auf ein bei Dir registriertes Profil ist. forwarded_to: Weitergeleitet an %{domain} mark_as_resolved: Als geklärt markieren mark_as_sensitive: Mit einer Inhaltswarnung versehen diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index 9175a1fc1a..88248d0986 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -611,6 +611,7 @@ es-AR: created_at: Denunciado delete_and_resolve: Eliminar mensajes forwarded: Reenviado + forwarded_replies_explanation: Esta denuncia es de un usuario remoto y sobre contenido remoto. Se te reenvió porque el contenido denunciado es en respuesta a uno de tus usuarios. forwarded_to: Reenviado a %{domain} mark_as_resolved: Marcar como resuelta mark_as_sensitive: Marcar como sensible diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index 75d329b0ae..4ecb666b07 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -611,6 +611,7 @@ es-MX: created_at: Denunciado delete_and_resolve: Eliminar publicaciones forwarded: Reenviado + forwarded_replies_explanation: Este reporte es de un usuario remoto y sobre contenido remoto. Se le ha enviado porque el contenido reportado es en respuesta a uno de sus usuarios. forwarded_to: Reenviado a %{domain} mark_as_resolved: Marcar como resuelto mark_as_sensitive: Marcar como sensible diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 4fe0179dfe..73442396fc 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -611,6 +611,7 @@ fi: created_at: Raportoitu delete_and_resolve: Poista julkaisut forwarded: Välitetty + forwarded_replies_explanation: Tämä raportti on etäkäyttäjältä ja koskee etäsisältöä. Se on välitetty sinulle, koska raportoitu sisältö on vastaus jollekin käyttäjällesi. forwarded_to: Välitetty %{domain} mark_as_resolved: Merkitse ratkaistuksi mark_as_sensitive: Merkitse arkaluonteiseksi @@ -1368,6 +1369,7 @@ fi: '86400': 1 vuorokausi expires_in_prompt: Ei koskaan generate: Luo + invalid: Tämä kutsu ei ole kelvollinen invited_by: 'Sinut kutsui:' max_uses: one: kertakäyttöinen diff --git a/config/locales/he.yml b/config/locales/he.yml index 11e5db4539..35dc99650c 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -635,6 +635,7 @@ he: created_at: מדווח delete_and_resolve: מחיקת הודעות forwarded: קודם + forwarded_replies_explanation: דווח זה הגיע מחשבון משתמש חיצוני על תוכן חיצוני. הוא הועבר אליך כיוון שהתוכן שדווח הוא בתשובה למשתמש.ת שלך. forwarded_to: קודם ל-%{domain} mark_as_resolved: סימון כפתור mark_as_sensitive: סימון כרגיש @@ -786,7 +787,7 @@ he: public_timelines: פידים פומביים publish_discovered_servers: פרסום שרתים שנתגלו publish_statistics: פרסום הסטטיסטיקות בפומבי - title: גילוי + title: תגליות trends: נושאים חמים domain_blocks: all: לכולם @@ -1048,7 +1049,7 @@ he: advanced_web_interface_hint: 'אם ברצונך לעשות שימוש במלוא רוחב המסך, ממשק הווב המתקדם מאפשר לך להגדיר עמודות רבות ושונות כדי לראות בו זמנית כמה מידע שתרצה/י: פיד הבית, התראות, פרהסיה ומספר כלשהו של רשימות ותגיות.' animations_and_accessibility: הנפשות ונגישות confirmation_dialogs: חלונות אישור - discovery: גילוי + discovery: תגליות localization: body: מסטודון מתורגם על ידי מתנדבים. guide_link: https://crowdin.com/project/mastodon @@ -1336,7 +1337,7 @@ he: deselect: בטל בחירה של הכל none: כלום order_by: מיין לפי - save_changes: שמור שינויים + save_changes: לשמור שינויים select_all_matching_items: many: בחר.י %{count} פריטים שתאמו לחיפוש שלך. one: בחר.י פריט %{count} שתאם לחיפוש שלך. @@ -1780,7 +1781,7 @@ he: keep_media_hint: לא מוחק את הודעותיך שמצורפים אליהן קבצי מדיה keep_pinned: שמור הודעות מוצמדות keep_pinned_hint: לא מוחק אף אחד מההודעות המוצמדות שלך - keep_polls: שמור סקרים + keep_polls: לשמור סקרים keep_polls_hint: לא מוחר אף אחד מהסקרים שלך keep_self_bookmark: שמור הודעות שסימנת keep_self_bookmark_hint: לא מוחק הודעות שסימנת @@ -1868,7 +1869,7 @@ he: disable: אינך יכול/ה יותר להשתמש בחשבונך, אבל הפרופיל ושאר המידע נשארו על עומדם. ניתן לבקש גיבוי של המידע, לשנות את הגדרות החשבון או למחוק אותו. mark_statuses_as_sensitive: כמה מהודעותיך סומנו כרגישות על ידי מנחי הקהילה של %{instance}. זה אומר שאנשים יצטרכו להקיש על המדיה בהודעות לפני שתופיע תצוגה מקדימה. ניתן לסמן את המידע כרגיש בעצמך בהודעותיך העתידיות. sensitive: מעתה ואילך כל קבצי המדיה שיועלו על ידך יסומנו כרגישים ויוסתרו מאחורי אזהרה. - silence: ניתן עדיין להשתמש בחשבונך אבל רק אנשים שכבר עוקבים אחריך יראו את הודעותיך בשרת זה, וייתכן שתוחרג/י מאמצעי גילוי משתמשים. עם זאת, אחרים יוכלו עדיין לעקוב אחריך. + silence: ניתן עדיין להשתמש בחשבונך אבל רק אנשים שכבר עוקבים אחריך יראו את הודעותיך בשרת זה, וייתכן שתוחרג/י ממסכי התגליות. עם זאת, אחרים יוכלו עדיין לעקוב אחריך. suspend: לא ניתן יותר להשתמש בחשבונך, ופרופילך וכל מידע אחר לא נגישים יותר. ניתן עדיין להתחבר על מנת לבקש גיבוי של המידע שלך עד שיוסר סופית בעוד כ-30 יום, אבל מידע מסויים ישמר על מנת לוודא שלא תחמוק/י מההשעיה. reason: 'סיבה:' statuses: 'הודעות מצוטטות:' diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 48f9d5b9d1..a0ff3061fc 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -611,6 +611,7 @@ hu: created_at: Jelentve delete_and_resolve: Bejegyzések törlése forwarded: Továbbítva + forwarded_replies_explanation: Ez a jelentés egy távoli felhasználótól származik, és távoli tartalomról szól. Azért lett neked továbbítva, mert a jelentett tartalom az egyik felhasználódnak küldött válasz. forwarded_to: 'Továbbítva ide: %{domain}' mark_as_resolved: Megjelölés megoldottként mark_as_sensitive: Érzékenynek jelölés diff --git a/config/locales/is.yml b/config/locales/is.yml index 390ce0ac03..a4706ee51a 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -611,6 +611,7 @@ is: created_at: Tilkynnt delete_and_resolve: Eyða færslum forwarded: Áframsent + forwarded_replies_explanation: Þessi kæra er frá fjartengdum notanda og er um fjartengt efni. Hún hefur verið framsend til þín þar sem kærða efnið er í svari til eins af notendunum þínum. forwarded_to: Áframsent á %{domain} mark_as_resolved: Merkja sem leyst mark_as_sensitive: Merkja sem viðkvæmt diff --git a/config/locales/it.yml b/config/locales/it.yml index f35e9e42b1..82bbf72518 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -611,6 +611,7 @@ it: created_at: Segnalato delete_and_resolve: Cancella post forwarded: Inoltrato + forwarded_replies_explanation: Questa segnalazione proviene da un utente remoto e tratta di contenuti remoti. È stato inoltrato a voi perché il contenuto riportato è in risposta a uno dei vostri utenti. forwarded_to: Inoltrato a %{domain} mark_as_resolved: Segna come risolto mark_as_sensitive: Segna come sensibile diff --git a/config/locales/ko.yml b/config/locales/ko.yml index fb193c75f6..e11081fcdf 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -601,6 +601,7 @@ ko: created_at: 신고 시각 delete_and_resolve: 게시물 삭제 forwarded: 전달됨 + forwarded_replies_explanation: 이 신고는 리모트 사용자가 리모트 컨텐츠에 대해 신고한 것입니다. 이것은 신고된 내용이 로컬 사용자에 대한 답글이기 때문에 첨부되었습니다. forwarded_to: "%{domain}에게 전달됨" mark_as_resolved: 해결로 표시 mark_as_sensitive: 민감함으로 설정 diff --git a/config/locales/lt.yml b/config/locales/lt.yml index 529eb5a44c..035b04462e 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -214,6 +214,7 @@ lt: comment: none: Nėra created_at: Reportuotas + forwarded_replies_explanation: Šis ataskaita yra iš nuotolinio naudotojo ir susijusi su nuotoliniu turiniu. Jis buvo persiųstas tau, nes turinys, apie kurį pranešta, yra atsakymas vienam iš tavo naudotojų. mark_as_resolved: Pažymėti kaip išsprestą mark_as_unresolved: Pažymėti kaip neišsprestą notes: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 94a1f29f7f..4147078d30 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -611,6 +611,7 @@ nl: created_at: Gerapporteerd op delete_and_resolve: Bericht verwijderen forwarded: Doorgestuurd + forwarded_replies_explanation: Dit rapport komt van een externe gebruiker en gaat over externe inhoud. Het is naar u doorgestuurd omdat de gerapporteerde inhoud een reactie is op een van uw gebruikers. forwarded_to: Doorgestuurd naar %{domain} mark_as_resolved: Markeer als opgelost mark_as_sensitive: Als gevoelig markeren diff --git a/config/locales/nn.yml b/config/locales/nn.yml index 4925d44632..09de24a672 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -611,6 +611,7 @@ nn: created_at: Rapportert delete_and_resolve: Slett innlegg forwarded: Videresendt + forwarded_replies_explanation: Denne rapporten er fra en ekstern bruker og handler om eksternt innhold. Den er videresendt til deg fordi det rapporterte innholdet svarer til en av brukerne dine. forwarded_to: Videresendt til %{domain} mark_as_resolved: Merk som løyst mark_as_sensitive: Marker som ømtolig diff --git a/config/locales/no.yml b/config/locales/no.yml index a1058bf9f2..3cf2df3a1b 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -611,6 +611,7 @@ created_at: Rapportert delete_and_resolve: Slettede innlegg forwarded: Videresendt + forwarded_replies_explanation: Denne rapporten er fra en ekstern bruker og handler om eksternt innhold. Den er videresendt til deg fordi det rapporterte innholdet svarer til en av brukerne dine. forwarded_to: Videresendt til %{domain} mark_as_resolved: Merk som løst mark_as_sensitive: Merk som følsomt diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 69b1aa0a9d..4ff81e11e0 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -635,6 +635,7 @@ pl: created_at: Zgłoszono delete_and_resolve: Usuń posty forwarded: Przekazano + forwarded_replies_explanation: Ten raport nadszedł od zdalnego użytkownika i dotyczy zdalnej treści. Został ci przekazany, bo raportowana treść jest odpowiedzią na jednego z twoich użytkowników. forwarded_to: Przekazano do %{domain} mark_as_resolved: Oznacz jako rozwiązane mark_as_sensitive: Oznacz jako wrażliwe diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index ce7479aa86..8e147ce4c3 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -611,6 +611,7 @@ pt-PT: created_at: Denunciado delete_and_resolve: Eliminar publicações forwarded: Encaminhado + forwarded_replies_explanation: Esta denúncia é de um utilizador remoto e sobre conteúdo remoto. Foi encaminhada para si porque o conteúdo denunciado é em resposta a um dos seus utilizadores. forwarded_to: Encaminhado para %{domain} mark_as_resolved: Marcar como resolvido mark_as_sensitive: Marcar como problemático diff --git a/config/locales/simple_form.fi.yml b/config/locales/simple_form.fi.yml index bada4c3d0f..29f2398a90 100644 --- a/config/locales/simple_form.fi.yml +++ b/config/locales/simple_form.fi.yml @@ -188,7 +188,7 @@ fi: email: Sähköpostiosoite expires_in: Vanhenee fields: Lisäkentät - header: Otsikkokuva + header: Otsakekuva honeypot: "%{label} (älä täytä)" inbox_url: Välittäjän postilaatikon URL-osoite irreversible: Pudota piilottamisen sijaan diff --git a/config/locales/simple_form.he.yml b/config/locales/simple_form.he.yml index 13ea8a0c4f..04b21cd1b0 100644 --- a/config/locales/simple_form.he.yml +++ b/config/locales/simple_form.he.yml @@ -85,7 +85,7 @@ he: mascot: בחירת ציור למנשק הווב המתקדם. media_cache_retention_period: קבצי מדיה שהורדו ימחקו אחרי מספר הימים שיצוינו אם נבחר מספר חיובי, או-אז יורדו שוב מחדש בהתאם לצורך. peers_api_enabled: רשימת השרתים ששרת זה פגש בפדיוורס. לא כולל מידע לגבי קשר ישיר עם שרת נתון, אלא רק שידוע לשרת זה על קיומו. מידע זה משמש שירותים האוספים סטטיסטיקות כלליות על הפדרציה. - profile_directory: מדריך הפרופילים מפרט את כל המשתמשים שביקשו להיות ניתנים לגילוי. + profile_directory: ספריית הפרופילים מציגה ברשימה את כל המשתמשים שביקשו להיות ניתנים לגילוי. require_invite_text: כאשר הרשמות דורשות אישור ידני, הפיכת טקסט ה"מדוע את/ה רוצה להצטרף" להכרחי במקום אופציונלי site_contact_email: מה היא הדרך ליצור איתך קשר לצורך תמיכה או לצורך תאימות עם החוק. site_contact_username: כיצד יכולים אחרים ליצור איתך קשר על רשת מסטודון. @@ -140,7 +140,7 @@ he: url: היעד שאליו יישלחו אירועים labels: account: - discoverable: חשיפת פרופיל משתמש והודעות לאלגוריתם של האתר + discoverable: הצג משתמש ופוסטים בעמוד התגליות fields: name: תווית value: תוכן @@ -188,7 +188,7 @@ he: email: כתובת דוא"ל expires_in: תפוגה לאחר fields: מטא-נתונים על הפרופיל - header: כותרת + header: תמונת נושא honeypot: "%{label} (לא למלא)" inbox_url: קישורית לתיבת ממסר irreversible: הסרה במקום הסתרה diff --git a/config/locales/simple_form.ko.yml b/config/locales/simple_form.ko.yml index 7b26561553..720012a310 100644 --- a/config/locales/simple_form.ko.yml +++ b/config/locales/simple_form.ko.yml @@ -4,7 +4,7 @@ ko: hints: account: discoverable: 내 공개 게시물과 프로필이 마스토돈의 다양한 추천 기능에 나타날 수 있고 프로필이 다른 사용자에게 제안될 수 있습니다 - display_name: 실명 혹은 별명. + display_name: 진짜 이름 또는 재미난 이름. fields: 홈페이지, 호칭, 나이, 뭐든지 적고 싶은 것들. indexable: 내 공개 게시물이 마스토돈의 검색 결과에 나타날 수 있습니다. 내 게시물과 상호작용했던 사람들은 이 설정과 관계 없이 그 게시물을 검색할 수 있습니다. note: '남을 @mention 하거나 #hashtag 태그를 달 수 있습니다.' @@ -195,7 +195,7 @@ ko: locale: 인터페이스 언어 max_uses: 사용 횟수 제한 new_password: 새로운 암호 입력 - note: 소개 + note: 자기소개 otp_attempt: 이중 인증 코드 password: 암호 phrase: 키워드 또는 문장 diff --git a/config/locales/sq.yml b/config/locales/sq.yml index bd01a80890..b6a7736dfb 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -1,18 +1,18 @@ --- sq: about: - about_mastodon_html: 'Rrjeti shoqëror i së ardhmes: Pa reklama, pa survejim nga korporata, konceptim etik dhe decentralizim! Jini zot i të dhënave tuaja, me Mastodon-in!' - contact_missing: I parregulluar + about_mastodon_html: 'Rrjeti social i së ardhmes: Pa reklama, pa sy vëzhguese nga korporata, etik dhe i decentralizuar! Merrni sërisht zotësinë e të dhënave tuaja, me Mastodon!' + contact_missing: E pacaktuar contact_unavailable: N/A - hosted_on: Mastodon i strehuar në %{domain} + hosted_on: Server Mastodon i strehuar në %{domain} title: Mbi accounts: follow: Ndiqeni followers: one: Ndjekës other: Ndjekës - following: Ndjekje - instance_actor_flash: Kjo llogari është një aktor virtual, i përdorur për të përfaqësuar vetë shërbyesin dhe jo ndonjë përdorues individual. Përdoret për qëllime federimi dhe s’duhet pezulluar. + following: Po ndjek + instance_actor_flash: Kjo llogari është një aktor virtual, i përdorur për të përfaqësuar vetë serverin dhe jo ndonjë përdorues. Përdoret për qëllime federimi dhe s’duhet pezulluar. last_active: aktiv së fundi link_verified_on: Pronësia e kësaj lidhjeje qe kontrolluar më %{date} nothing_here: S’ka gjë këtu! @@ -610,6 +610,7 @@ sq: created_at: Raportuar më delete_and_resolve: Fshiji postimet forwarded: U përcoll + forwarded_replies_explanation: Ky raportim është nga një përdorues i largët dhe rreth lënde të largët. Ju është përcjellë ngaqë lënda e raportuar gjendet në përgjigje ndaj njërit prej përdoruesve tuaj. forwarded_to: U përcoll te %{domain} mark_as_resolved: Vëri shenjë si i zgjidhur mark_as_sensitive: Vëri shenjë si rezervat @@ -925,6 +926,7 @@ sq: peaked_on_and_decaying: Kulmoi më %{date}, tani në rënie title: Hashtag-ë në modë trendable: Mund të shfaqet nën të modës + trending_rank: 'Trending #%{rank}' usable: Mund të përdoret usage_comparison: Përdorur %{today} herë sot, krahasuar me %{yesterday} dje used_by_over_week: diff --git a/config/locales/th.yml b/config/locales/th.yml index 6618998962..79d668d3e4 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -599,6 +599,7 @@ th: created_at: รายงานเมื่อ delete_and_resolve: ลบโพสต์ forwarded: ส่งต่อแล้ว + forwarded_replies_explanation: รายงานนี้มาจากผู้ใช้ระยะไกล และเป็นรายงานเกี่ยวกับเนื้อหาระยะไกล ซึ่งถูกส่งต่อมาหาคุณเนื่องจากเนื้อหาที่ถูกรายงานอยู่ในการตอบกลับไปยังหนึ่งในผู้ใช้ของคุณ forwarded_to: ส่งต่อไปยัง %{domain} แล้ว mark_as_resolved: ทำเครื่องหมายว่าแก้ปัญหาแล้ว mark_as_sensitive: ทำเครื่องหมายว่าละเอียดอ่อน diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 2261c647ba..e9eee14a1e 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -635,6 +635,7 @@ uk: created_at: Створено delete_and_resolve: Видалити дописи forwarded: Переслано + forwarded_replies_explanation: Цей звіт належить віддаленому користувачеві і про віддалений вміст. Контент був пересланий вам, тому що він містить повідомлення у відповідь одному з ваших користувачів. forwarded_to: Переслано до %{domain} mark_as_resolved: Позначити вирішеним mark_as_sensitive: Позначити делікатним diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index f13cedad6e..5dd0d2e612 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -599,6 +599,7 @@ zh-HK: created_at: 日期 delete_and_resolve: 刪除帖文 forwarded: 已轉寄 + forwarded_replies_explanation: 這份檢舉來自一位遠端使用者,並涉及遠端內容。之所以轉交給你,是因為被檢舉的內容是回覆你其中一位使用者。 forwarded_to: 已轉寄到 %{domain} mark_as_resolved: 標示為「已處理」 mark_as_sensitive: 標記為敏感內容 diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 7259afdbeb..2f65855fc0 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -70,7 +70,7 @@ zh-TW: enabled_msg: 成功解除 %{username} 帳號的凍結 followers: 跟隨者 follows: 正在跟隨 - header: 開頭 + header: 封面圖片 inbox_url: 收件匣 (Inbox) URL invite_request_text: 加入原因 invited_by: 邀請者 @@ -117,7 +117,7 @@ zh-TW: remote_suspension_irreversible: 此帳號之資料已被不可逆地刪除。 remote_suspension_reversible_hint_html: 這個帳號已於此伺服器被停權,所有資料將會於 %{date} 被刪除。於此之前,遠端伺服器可以完全回復此的帳號。如果您想即時刪除這個帳號的資料,您能於下面進行操作。 remove_avatar: 取消大頭貼 - remove_header: 移除開頭 + remove_header: 移除封面圖片 removed_avatar_msg: 已成功刪除 %{username} 的大頭貼 removed_header_msg: 已成功刪除 %{username} 的封面圖片 resend_confirmation: @@ -599,6 +599,7 @@ zh-TW: created_at: 日期 delete_and_resolve: 刪除嘟文 forwarded: 已轉寄 + forwarded_replies_explanation: 此報告來自聯邦宇宙中非本伺服器帳號,關於非本伺服器內容。此報告轉發給您,因為報告之內容是回覆給您的伺服器上某位使用者。 forwarded_to: 轉寄到 %{domain} mark_as_resolved: 標記為「已解決」 mark_as_sensitive: 標記為敏感內容 diff --git a/spec/controllers/statuses_controller_spec.rb b/spec/controllers/statuses_controller_spec.rb index 8b715824b8..fe40ee6de1 100644 --- a/spec/controllers/statuses_controller_spec.rb +++ b/spec/controllers/statuses_controller_spec.rb @@ -57,11 +57,14 @@ describe StatusesController do let(:format) { 'html' } it 'renders status successfully', :aggregate_failures do - expect(response).to have_http_status(200) - expect(response.headers['Link'].to_s).to include 'activity+json' - expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' - expect(response.headers['Cache-Control']).to include 'public' - expect(response).to render_template(:show) + expect(response) + .to have_http_status(200) + .and render_template(:show) + expect(response.headers).to include( + 'Vary' => 'Accept, Accept-Language, Cookie', + 'Cache-Control' => include('public'), + 'Link' => satisfy { |header| header.to_s.include?('activity+json') } + ) expect(response.body).to include status.text end end @@ -72,12 +75,15 @@ describe StatusesController do it_behaves_like 'cacheable response', expects_vary: 'Accept, Accept-Language, Cookie' it 'renders ActivityPub Note object successfully', :aggregate_failures do - expect(response).to have_http_status(200) - expect(response.headers['Link'].to_s).to include 'activity+json' - expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' - expect(response.headers['Content-Type']).to include 'application/activity+json' - json = body_as_json - expect(json[:content]).to include status.text + expect(response) + .to have_http_status(200) + expect(response.headers).to include( + 'Vary' => 'Accept, Accept-Language, Cookie', + 'Content-Type' => include('application/activity+json'), + 'Link' => satisfy { |header| header.to_s.include?('activity+json') } + ) + expect(body_as_json) + .to include(content: include(status.text)) end end end @@ -157,11 +163,14 @@ describe StatusesController do let(:format) { 'html' } it 'renders status successfully', :aggregate_failures do - expect(response).to have_http_status(200) - expect(response.headers['Link'].to_s).to include 'activity+json' - expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' - expect(response.headers['Cache-Control']).to include 'private' - expect(response).to render_template(:show) + expect(response) + .to have_http_status(200) + .and render_template(:show) + expect(response.headers).to include( + 'Vary' => 'Accept, Accept-Language, Cookie', + 'Cache-Control' => include('private'), + 'Link' => satisfy { |header| header.to_s.include?('activity+json') } + ) expect(response.body).to include status.text end end @@ -170,13 +179,16 @@ describe StatusesController do let(:format) { 'json' } it 'renders ActivityPub Note object successfully', :aggregate_failures do - expect(response).to have_http_status(200) - expect(response.headers['Link'].to_s).to include 'activity+json' - expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' - expect(response.headers['Cache-Control']).to include 'private' - expect(response.headers['Content-Type']).to include 'application/activity+json' - json = body_as_json - expect(json[:content]).to include status.text + expect(response) + .to have_http_status(200) + expect(response.headers).to include( + 'Vary' => 'Accept, Accept-Language, Cookie', + 'Cache-Control' => include('private'), + 'Content-Type' => include('application/activity+json'), + 'Link' => satisfy { |header| header.to_s.include?('activity+json') } + ) + expect(body_as_json) + .to include(content: include(status.text)) end end end @@ -194,11 +206,15 @@ describe StatusesController do let(:format) { 'html' } it 'renders status successfully', :aggregate_failures do - expect(response).to have_http_status(200) - expect(response.headers['Link'].to_s).to include 'activity+json' - expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' - expect(response.headers['Cache-Control']).to include 'private' - expect(response).to render_template(:show) + expect(response) + .to have_http_status(200) + .and render_template(:show) + + expect(response.headers).to include( + 'Vary' => 'Accept, Accept-Language, Cookie', + 'Cache-Control' => include('private'), + 'Link' => satisfy { |header| header.to_s.include?('activity+json') } + ) expect(response.body).to include status.text end end @@ -207,13 +223,16 @@ describe StatusesController do let(:format) { 'json' } it 'renders ActivityPub Note object successfully', :aggregate_failures do - expect(response).to have_http_status(200) - expect(response.headers['Link'].to_s).to include 'activity+json' - expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' - expect(response.headers['Cache-Control']).to include 'private' - expect(response.headers['Content-Type']).to include 'application/activity+json' - json = body_as_json - expect(json[:content]).to include status.text + expect(response) + .to have_http_status(200) + expect(response.headers).to include( + 'Vary' => 'Accept, Accept-Language, Cookie', + 'Cache-Control' => include('private'), + 'Content-Type' => include('application/activity+json'), + 'Link' => satisfy { |header| header.to_s.include?('activity+json') } + ) + expect(body_as_json) + .to include(content: include(status.text)) end end end @@ -254,11 +273,14 @@ describe StatusesController do let(:format) { 'html' } it 'renders status successfully', :aggregate_failures do - expect(response).to have_http_status(200) - expect(response.headers['Link'].to_s).to include 'activity+json' - expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' - expect(response.headers['Cache-Control']).to include 'private' - expect(response).to render_template(:show) + expect(response) + .to have_http_status(200) + .and render_template(:show) + expect(response.headers).to include( + 'Vary' => 'Accept, Accept-Language, Cookie', + 'Cache-Control' => include('private'), + 'Link' => satisfy { |header| header.to_s.include?('activity+json') } + ) expect(response.body).to include status.text end end @@ -267,13 +289,16 @@ describe StatusesController do let(:format) { 'json' } it 'renders ActivityPub Note object successfully' do - expect(response).to have_http_status(200) - expect(response.headers['Link'].to_s).to include 'activity+json' - expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' - expect(response.headers['Cache-Control']).to include 'private' - expect(response.headers['Content-Type']).to include 'application/activity+json' - json = body_as_json - expect(json[:content]).to include status.text + expect(response) + .to have_http_status(200) + expect(response.headers).to include( + 'Vary' => 'Accept, Accept-Language, Cookie', + 'Cache-Control' => include('private'), + 'Content-Type' => include('application/activity+json'), + 'Link' => satisfy { |header| header.to_s.include?('activity+json') } + ) + expect(body_as_json) + .to include(content: include(status.text)) end end end @@ -340,11 +365,14 @@ describe StatusesController do let(:format) { 'html' } it 'renders status successfully', :aggregate_failures do - expect(response).to have_http_status(200) - expect(response.headers['Link'].to_s).to include 'activity+json' - expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' - expect(response.headers['Cache-Control']).to include 'private' - expect(response).to render_template(:show) + expect(response) + .to have_http_status(200) + .and render_template(:show) + expect(response.headers).to include( + 'Vary' => 'Accept, Accept-Language, Cookie', + 'Cache-Control' => include('private'), + 'Link' => satisfy { |header| header.to_s.include?('activity+json') } + ) expect(response.body).to include status.text end end @@ -355,12 +383,15 @@ describe StatusesController do it_behaves_like 'cacheable response', expects_vary: 'Accept, Accept-Language, Cookie' it 'renders ActivityPub Note object successfully', :aggregate_failures do - expect(response).to have_http_status(200) - expect(response.headers['Link'].to_s).to include 'activity+json' - expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' - expect(response.headers['Content-Type']).to include 'application/activity+json' - json = body_as_json - expect(json[:content]).to include status.text + expect(response) + .to have_http_status(200) + expect(response.headers).to include( + 'Vary' => 'Accept, Accept-Language, Cookie', + 'Content-Type' => include('application/activity+json'), + 'Link' => satisfy { |header| header.to_s.include?('activity+json') } + ) + expect(body_as_json) + .to include(content: include(status.text)) end end end @@ -378,11 +409,14 @@ describe StatusesController do let(:format) { 'html' } it 'renders status successfully', :aggregate_failures do - expect(response).to have_http_status(200) - expect(response.headers['Link'].to_s).to include 'activity+json' - expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' - expect(response.headers['Cache-Control']).to include 'private' - expect(response).to render_template(:show) + expect(response) + .to have_http_status(200) + .and render_template(:show) + expect(response.headers).to include( + 'Vary' => 'Accept, Accept-Language, Cookie', + 'Cache-Control' => include('private'), + 'Link' => satisfy { |header| header.to_s.include?('activity+json') } + ) expect(response.body).to include status.text end end @@ -391,13 +425,17 @@ describe StatusesController do let(:format) { 'json' } it 'renders ActivityPub Note object successfully' do - expect(response).to have_http_status(200) - expect(response.headers['Link'].to_s).to include 'activity+json' - expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' - expect(response.headers['Cache-Control']).to include 'private' - expect(response.headers['Content-Type']).to include 'application/activity+json' - json = body_as_json - expect(json[:content]).to include status.text + expect(response) + .to have_http_status(200) + expect(response.headers).to include( + 'Vary' => 'Accept, Accept-Language, Cookie', + 'Cache-Control' => include('private'), + 'Content-Type' => include('application/activity+json'), + 'Link' => satisfy { |header| header.to_s.include?('activity+json') } + ) + + expect(body_as_json) + .to include(content: include(status.text)) end end end @@ -438,11 +476,14 @@ describe StatusesController do let(:format) { 'html' } it 'renders status successfully', :aggregate_failures do - expect(response).to have_http_status(200) - expect(response.headers['Link'].to_s).to include 'activity+json' - expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' - expect(response.headers['Cache-Control']).to include 'private' - expect(response).to render_template(:show) + expect(response) + .to have_http_status(200) + .and render_template(:show) + expect(response.headers).to include( + 'Vary' => 'Accept, Accept-Language, Cookie', + 'Cache-Control' => include('private'), + 'Link' => satisfy { |header| header.to_s.include?('activity+json') } + ) expect(response.body).to include status.text end end @@ -451,13 +492,16 @@ describe StatusesController do let(:format) { 'json' } it 'renders ActivityPub Note object', :aggregate_failures do - expect(response).to have_http_status(200) - expect(response.headers['Link'].to_s).to include 'activity+json' - expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' - expect(response.headers['Cache-Control']).to include 'private' - expect(response.headers['Content-Type']).to include 'application/activity+json' - json = body_as_json - expect(json[:content]).to include status.text + expect(response) + .to have_http_status(200) + expect(response.headers).to include( + 'Vary' => 'Accept, Accept-Language, Cookie', + 'Cache-Control' => include('private'), + 'Content-Type' => include('application/activity+json'), + 'Link' => satisfy { |header| header.to_s.include?('activity+json') } + ) + expect(body_as_json) + .to include(content: include(status.text)) end end end @@ -732,11 +776,14 @@ describe StatusesController do end it 'renders status successfully', :aggregate_failures do - expect(response).to have_http_status(200) - expect(response.headers['Link'].to_s).to include 'activity+json' - expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' - expect(response.headers['Cache-Control']).to include 'public' - expect(response).to render_template(:embed) + expect(response) + .to have_http_status(200) + .and render_template(:embed) + expect(response.headers).to include( + 'Vary' => 'Accept, Accept-Language, Cookie', + 'Cache-Control' => include('public'), + 'Link' => satisfy { |header| header.to_s.include?('activity+json') } + ) expect(response.body).to include status.text end end diff --git a/spec/controllers/well_known/host_meta_controller_spec.rb b/spec/controllers/well_known/host_meta_controller_spec.rb deleted file mode 100644 index 4bd161cd9d..0000000000 --- a/spec/controllers/well_known/host_meta_controller_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe WellKnown::HostMetaController do - render_views - - describe 'GET #show' do - it 'returns http success' do - get :show, format: :xml - - expect(response).to have_http_status(200) - expect(response.media_type).to eq 'application/xrd+xml' - expect(response.body).to eq <<~XML - - - - - XML - end - end -end diff --git a/spec/controllers/well_known/node_info_controller_spec.rb b/spec/controllers/well_known/node_info_controller_spec.rb deleted file mode 100644 index 6ec34afd04..0000000000 --- a/spec/controllers/well_known/node_info_controller_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe WellKnown::NodeInfoController do - render_views - - describe 'GET #index' do - it 'returns json document pointing to node info' do - get :index - - expect(response).to have_http_status(200) - expect(response.media_type).to eq 'application/json' - - json = body_as_json - - expect(json[:links]).to be_an Array - expect(json[:links][0][:rel]).to eq 'http://nodeinfo.diaspora.software/ns/schema/2.0' - expect(json[:links][0][:href]).to include 'nodeinfo/2.0' - end - end - - describe 'GET #show' do - it 'returns json document with node info properties' do - get :show - - expect(response).to have_http_status(200) - expect(response.media_type).to eq 'application/json' - - json = body_as_json - foo = { 'foo' => 0 } - - expect(foo).to_not match_json_schema('nodeinfo_2.0') - expect(json).to match_json_schema('nodeinfo_2.0') - expect(json[:version]).to eq '2.0' - expect(json[:usage]).to be_a Hash - expect(json[:software]).to be_a Hash - expect(json[:protocols]).to be_an Array - end - end -end diff --git a/spec/controllers/well_known/webfinger_controller_spec.rb b/spec/controllers/well_known/webfinger_controller_spec.rb deleted file mode 100644 index 6610f4d138..0000000000 --- a/spec/controllers/well_known/webfinger_controller_spec.rb +++ /dev/null @@ -1,235 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe WellKnown::WebfingerController do - include RoutingHelper - - render_views - - describe 'GET #show' do - subject(:perform_show!) do - get :show, params: { resource: resource }, format: :json - end - - let(:alternate_domains) { [] } - let(:alice) { Fabricate(:account, username: 'alice') } - let(:resource) { nil } - - around do |example| - tmp = Rails.configuration.x.alternate_domains - Rails.configuration.x.alternate_domains = alternate_domains - example.run - Rails.configuration.x.alternate_domains = tmp - end - - shared_examples 'a successful response' do - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'does not set a Vary header' do - expect(response.headers['Vary']).to be_nil - end - - it 'returns application/jrd+json' do - expect(response.media_type).to eq 'application/jrd+json' - end - - it 'returns links for the account' do - json = body_as_json - expect(json[:subject]).to eq 'acct:alice@cb6e6126.ngrok.io' - expect(json[:aliases]).to include('https://cb6e6126.ngrok.io/@alice', 'https://cb6e6126.ngrok.io/users/alice') - end - end - - context 'when an account exists' do - let(:resource) { alice.to_webfinger_s } - - before do - perform_show! - end - - it_behaves_like 'a successful response' - end - - context 'when an account is temporarily suspended' do - let(:resource) { alice.to_webfinger_s } - - before do - alice.suspend! - perform_show! - end - - it_behaves_like 'a successful response' - end - - context 'when an account is permanently suspended or deleted' do - let(:resource) { alice.to_webfinger_s } - - before do - alice.suspend! - alice.deletion_request.destroy - perform_show! - end - - it 'returns http gone' do - expect(response).to have_http_status(410) - end - end - - context 'when an account is not found' do - let(:resource) { 'acct:not@existing.com' } - - before do - perform_show! - end - - it 'returns http not found' do - expect(response).to have_http_status(404) - end - end - - context 'with an alternate domain' do - let(:alternate_domains) { ['foo.org'] } - - before do - perform_show! - end - - context 'when an account exists' do - let(:resource) do - username, = alice.to_webfinger_s.split('@') - "#{username}@foo.org" - end - - it_behaves_like 'a successful response' - end - - context 'when the domain is wrong' do - let(:resource) do - username, = alice.to_webfinger_s.split('@') - "#{username}@bar.org" - end - - it 'returns http not found' do - expect(response).to have_http_status(404) - end - end - end - - context 'when the old name scheme is used to query the instance actor' do - let(:resource) do - "#{Rails.configuration.x.local_domain}@#{Rails.configuration.x.local_domain}" - end - - before do - perform_show! - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'does not set a Vary header' do - expect(response.headers['Vary']).to be_nil - end - - it 'returns application/jrd+json' do - expect(response.media_type).to eq 'application/jrd+json' - end - - it 'returns links for the internal account' do - json = body_as_json - expect(json[:subject]).to eq 'acct:mastodon.internal@cb6e6126.ngrok.io' - expect(json[:aliases]).to eq ['https://cb6e6126.ngrok.io/actor'] - end - end - - context 'with no resource parameter' do - let(:resource) { nil } - - before do - perform_show! - end - - it 'returns http bad request' do - expect(response).to have_http_status(400) - end - end - - context 'with a nonsense parameter' do - let(:resource) { 'df/:dfkj' } - - before do - perform_show! - end - - it 'returns http bad request' do - expect(response).to have_http_status(400) - end - end - - context 'when an account has an avatar' do - let(:alice) { Fabricate(:account, username: 'alice', avatar: attachment_fixture('attachment.jpg')) } - let(:resource) { alice.to_webfinger_s } - - it 'returns avatar in response' do - perform_show! - - avatar_link = get_avatar_link(body_as_json) - expect(avatar_link).to_not be_nil - expect(avatar_link[:type]).to eq alice.avatar.content_type - expect(avatar_link[:href]).to eq full_asset_url(alice.avatar) - end - - context 'with limited federation mode' do - before do - allow(Rails.configuration.x).to receive(:limited_federation_mode).and_return(true) - end - - it 'does not return avatar in response' do - perform_show! - - avatar_link = get_avatar_link(body_as_json) - expect(avatar_link).to be_nil - end - end - - context 'when enabling DISALLOW_UNAUTHENTICATED_API_ACCESS' do - around do |example| - ClimateControl.modify DISALLOW_UNAUTHENTICATED_API_ACCESS: 'true' do - example.run - end - end - - it 'does not return avatar in response' do - perform_show! - - avatar_link = get_avatar_link(body_as_json) - expect(avatar_link).to be_nil - end - end - end - - context 'when an account does not have an avatar' do - let(:alice) { Fabricate(:account, username: 'alice', avatar: nil) } - let(:resource) { alice.to_webfinger_s } - - before do - perform_show! - end - - it 'does not return avatar in response' do - avatar_link = get_avatar_link(body_as_json) - expect(avatar_link).to be_nil - end - end - end - - private - - def get_avatar_link(json) - json[:links].find { |link| link[:rel] == 'http://webfinger.net/rel/avatar' } - end -end diff --git a/spec/fabricators/account_deletion_request_fabricator.rb b/spec/fabricators/account_deletion_request_fabricator.rb new file mode 100644 index 0000000000..3d3d373988 --- /dev/null +++ b/spec/fabricators/account_deletion_request_fabricator.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +Fabricator(:account_deletion_request) do + account +end diff --git a/spec/fabricators/import_fabricator.rb b/spec/fabricators/import_fabricator.rb new file mode 100644 index 0000000000..4951bb9a4d --- /dev/null +++ b/spec/fabricators/import_fabricator.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +Fabricator(:import) do + account + type :following + data { attachment_fixture('imports.txt') } +end diff --git a/spec/presenters/account_relationships_presenter_spec.rb b/spec/presenters/account_relationships_presenter_spec.rb index 5c2ba54e00..5b05ac8001 100644 --- a/spec/presenters/account_relationships_presenter_spec.rb +++ b/spec/presenters/account_relationships_presenter_spec.rb @@ -23,12 +23,14 @@ RSpec.describe AccountRelationshipsPresenter do let(:options) { {} } it 'sets default maps' do - expect(presenter.following).to eq default_map - expect(presenter.followed_by).to eq default_map - expect(presenter.blocking).to eq default_map - expect(presenter.muting).to eq default_map - expect(presenter.requested).to eq default_map - expect(presenter.domain_blocking).to eq default_map + expect(presenter).to have_attributes( + following: default_map, + followed_by: default_map, + blocking: default_map, + muting: default_map, + requested: default_map, + domain_blocking: default_map + ) end end diff --git a/spec/presenters/familiar_followers_presenter_spec.rb b/spec/presenters/familiar_followers_presenter_spec.rb index c21ffd36ec..853babb84b 100644 --- a/spec/presenters/familiar_followers_presenter_spec.rb +++ b/spec/presenters/familiar_followers_presenter_spec.rb @@ -22,9 +22,12 @@ RSpec.describe FamiliarFollowersPresenter do it 'returns followers you follow' do result = subject.accounts.first - expect(result).to_not be_nil - expect(result.id).to eq requested_accounts.first.id - expect(result.accounts).to contain_exactly(familiar_follower) + expect(result) + .to be_present + .and have_attributes( + id: requested_accounts.first.id, + accounts: contain_exactly(familiar_follower) + ) end context 'when requested account hides followers' do @@ -35,9 +38,12 @@ RSpec.describe FamiliarFollowersPresenter do it 'does not return followers you follow' do result = subject.accounts.first - expect(result).to_not be_nil - expect(result.id).to eq requested_accounts.first.id - expect(result.accounts).to be_empty + expect(result) + .to be_present + .and have_attributes( + id: requested_accounts.first.id, + accounts: be_empty + ) end end @@ -49,9 +55,12 @@ RSpec.describe FamiliarFollowersPresenter do it 'does not return followers you follow' do result = subject.accounts.first - expect(result).to_not be_nil - expect(result.id).to eq requested_accounts.first.id - expect(result.accounts).to be_empty + expect(result) + .to be_present + .and have_attributes( + id: requested_accounts.first.id, + accounts: be_empty + ) end end end diff --git a/spec/presenters/status_relationships_presenter_spec.rb b/spec/presenters/status_relationships_presenter_spec.rb index 7746c8cd78..af6a93b82b 100644 --- a/spec/presenters/status_relationships_presenter_spec.rb +++ b/spec/presenters/status_relationships_presenter_spec.rb @@ -22,11 +22,13 @@ RSpec.describe StatusRelationshipsPresenter do let(:options) { {} } it 'sets default maps' do - expect(presenter.reblogs_map).to eq default_map - expect(presenter.favourites_map).to eq default_map - expect(presenter.bookmarks_map).to eq default_map - expect(presenter.mutes_map).to eq default_map - expect(presenter.pins_map).to eq default_map + expect(presenter).to have_attributes( + reblogs_map: eq(default_map), + favourites_map: eq(default_map), + bookmarks_map: eq(default_map), + mutes_map: eq(default_map), + pins_map: eq(default_map) + ) end end @@ -80,18 +82,30 @@ RSpec.describe StatusRelationshipsPresenter do it 'sets @filters_map to filter top-level status' do matched_filters = presenter.filters_map[statuses[0].id] - expect(matched_filters.size).to eq 1 - expect(matched_filters[0].filter.title).to eq 'filter1' - expect(matched_filters[0].keyword_matches).to eq ['banned'] + expect(matched_filters) + .to be_an(Array) + .and have_attributes(size: 1) + .and contain_exactly( + have_attributes( + filter: have_attributes(title: 'filter1'), + keyword_matches: contain_exactly('banned') + ) + ) end it 'sets @filters_map to filter reblogged status' do matched_filters = presenter.filters_map[statuses[1].reblog_of_id] - expect(matched_filters.size).to eq 1 - expect(matched_filters[0].filter.title).to eq 'filter1' - expect(matched_filters[0].keyword_matches).to eq ['irrelevant'] + expect(matched_filters) + .to be_an(Array) + .and have_attributes(size: 1) + .and contain_exactly( + have_attributes( + filter: have_attributes(title: 'filter1'), + keyword_matches: contain_exactly('irrelevant') + ) + ) end end @@ -107,18 +121,30 @@ RSpec.describe StatusRelationshipsPresenter do it 'sets @filters_map to filter top-level status' do matched_filters = presenter.filters_map[statuses[0].id] - expect(matched_filters.size).to eq 1 - expect(matched_filters[0].filter.title).to eq 'filter1' - expect(matched_filters[0].status_matches).to eq [statuses[0].id] + expect(matched_filters) + .to be_an(Array) + .and have_attributes(size: 1) + .and contain_exactly( + have_attributes( + filter: have_attributes(title: 'filter1'), + status_matches: contain_exactly(statuses.first.id) + ) + ) end it 'sets @filters_map to filter reblogged status' do matched_filters = presenter.filters_map[statuses[1].reblog_of_id] - expect(matched_filters.size).to eq 1 - expect(matched_filters[0].filter.title).to eq 'filter1' - expect(matched_filters[0].status_matches).to eq [statuses[1].reblog_of_id] + expect(matched_filters) + .to be_an(Array) + .and have_attributes(size: 1) + .and contain_exactly( + have_attributes( + filter: have_attributes(title: 'filter1'), + status_matches: contain_exactly(statuses.second.reblog_of_id) + ) + ) end end end diff --git a/spec/requests/api/v1/accounts/relationships_spec.rb b/spec/requests/api/v1/accounts/relationships_spec.rb index 5011352c6b..e06ffdfae9 100644 --- a/spec/requests/api/v1/accounts/relationships_spec.rb +++ b/spec/requests/api/v1/accounts/relationships_spec.rb @@ -27,12 +27,16 @@ describe 'GET /api/v1/accounts/relationships' do it 'returns JSON with correct data', :aggregate_failures do subject - json = body_as_json - - expect(response).to have_http_status(200) - expect(json).to be_a Enumerable - expect(json.first[:following]).to be true - expect(json.first[:followed_by]).to be false + expect(response) + .to have_http_status(200) + expect(body_as_json) + .to be_an(Enumerable) + .and have_attributes( + first: include( + following: true, + followed_by: false + ) + ) end end @@ -40,18 +44,19 @@ describe 'GET /api/v1/accounts/relationships' do let(:params) { { id: [simon.id, lewis.id, bob.id] } } context 'when there is returned JSON data' do - let(:json) { body_as_json } - context 'with default parameters' do it 'returns an enumerable json with correct elements, excluding suspended accounts', :aggregate_failures do subject - expect(response).to have_http_status(200) - expect(json).to be_a Enumerable - expect(json.size).to eq 2 - - expect_simon_item_one - expect_lewis_item_two + expect(response) + .to have_http_status(200) + expect(body_as_json) + .to be_an(Enumerable) + .and have_attributes( + size: 2, + first: include(simon_item), + second: include(lewis_item) + ) end end @@ -61,62 +66,75 @@ describe 'GET /api/v1/accounts/relationships' do it 'returns an enumerable json with correct elements, including suspended accounts', :aggregate_failures do subject - expect(response).to have_http_status(200) - expect(json).to be_a Enumerable - expect(json.size).to eq 3 - - expect_simon_item_one - expect_lewis_item_two - expect_bob_item_three + expect(response) + .to have_http_status(200) + expect(body_as_json) + .to be_an(Enumerable) + .and have_attributes( + size: 3, + first: include(simon_item), + second: include(lewis_item), + third: include(bob_item) + ) end end - def expect_simon_item_one - expect(json.first[:id]).to eq simon.id.to_s - expect(json.first[:following]).to be true - expect(json.first[:showing_reblogs]).to be true - expect(json.first[:followed_by]).to be false - expect(json.first[:muting]).to be false - expect(json.first[:requested]).to be false - expect(json.first[:domain_blocking]).to be false + def simon_item + { + id: simon.id.to_s, + following: true, + showing_reblogs: true, + followed_by: false, + muting: false, + requested: false, + domain_blocking: false, + } end - def expect_lewis_item_two - expect(json.second[:id]).to eq lewis.id.to_s - expect(json.second[:following]).to be false - expect(json.second[:showing_reblogs]).to be false - expect(json.second[:followed_by]).to be true - expect(json.second[:muting]).to be false - expect(json.second[:requested]).to be false - expect(json.second[:domain_blocking]).to be false + def lewis_item + { + id: lewis.id.to_s, + following: false, + showing_reblogs: false, + followed_by: true, + muting: false, + requested: false, + domain_blocking: false, + + } end - def expect_bob_item_three - expect(json.third[:id]).to eq bob.id.to_s - expect(json.third[:following]).to be false - expect(json.third[:showing_reblogs]).to be false - expect(json.third[:followed_by]).to be false - expect(json.third[:muting]).to be false - expect(json.third[:requested]).to be false - expect(json.third[:domain_blocking]).to be false + def bob_item + { + id: bob.id.to_s, + following: false, + showing_reblogs: false, + followed_by: false, + muting: false, + requested: false, + domain_blocking: false, + + } end end it 'returns JSON with correct data on previously cached requests' do # Initial request including multiple accounts in params get '/api/v1/accounts/relationships', headers: headers, params: { id: [simon.id, lewis.id] } - expect(body_as_json.size).to eq(2) + expect(body_as_json) + .to have_attributes(size: 2) # Subsequent request with different id, should override cache from first request get '/api/v1/accounts/relationships', headers: headers, params: { id: [simon.id] } - expect(response).to have_http_status(200) + expect(response) + .to have_http_status(200) expect(body_as_json) .to be_an(Enumerable) .and have_attributes( size: 1, - first: hash_including( + first: include( following: true, showing_reblogs: true ) @@ -129,13 +147,17 @@ describe 'GET /api/v1/accounts/relationships' do get '/api/v1/accounts/relationships', headers: headers, params: { id: [simon.id] } - expect(response).to have_http_status(200) + expect(response) + .to have_http_status(200) - json = body_as_json - - expect(json).to be_a Enumerable - expect(json.first[:following]).to be false - expect(json.first[:showing_reblogs]).to be false + expect(body_as_json) + .to be_an(Enumerable) + .and have_attributes( + first: include( + following: false, + showing_reblogs: false + ) + ) end end end diff --git a/spec/requests/host_meta_request_spec.rb b/spec/requests/host_meta_request_spec.rb deleted file mode 100644 index ec26ecba7d..0000000000 --- a/spec/requests/host_meta_request_spec.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe 'The host_meta route' do - describe 'requested without accepts headers' do - it 'returns an xml response' do - get host_meta_url - - expect(response).to have_http_status(200) - expect(response.media_type).to eq 'application/xrd+xml' - end - end -end diff --git a/spec/requests/webfinger_request_spec.rb b/spec/requests/webfinger_request_spec.rb deleted file mode 100644 index 68a1478bed..0000000000 --- a/spec/requests/webfinger_request_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe 'The webfinger route' do - let(:alice) { Fabricate(:account, username: 'alice') } - - describe 'requested with standard accepts headers' do - it 'returns a json response' do - get webfinger_url(resource: alice.to_webfinger_s) - - expect(response).to have_http_status(200) - expect(response.media_type).to eq 'application/jrd+json' - end - end - - describe 'asking for json format' do - it 'returns a json response for json format' do - get webfinger_url(resource: alice.to_webfinger_s, format: :json) - - expect(response).to have_http_status(200) - expect(response.media_type).to eq 'application/jrd+json' - end - - it 'returns a json response for json accept header' do - headers = { 'HTTP_ACCEPT' => 'application/jrd+json' } - get webfinger_url(resource: alice.to_webfinger_s), headers: headers - - expect(response).to have_http_status(200) - expect(response.media_type).to eq 'application/jrd+json' - end - end -end diff --git a/spec/requests/well_known/host_meta_spec.rb b/spec/requests/well_known/host_meta_spec.rb new file mode 100644 index 0000000000..ca10a51a01 --- /dev/null +++ b/spec/requests/well_known/host_meta_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'The /.well-known/host-meta request' do + it 'returns http success with valid XML response' do + get '/.well-known/host-meta' + + expect(response) + .to have_http_status(200) + .and have_attributes( + media_type: 'application/xrd+xml', + body: host_meta_xml_template + ) + end + + private + + def host_meta_xml_template + <<~XML + + + + + XML + end +end diff --git a/spec/requests/well_known/node_info_spec.rb b/spec/requests/well_known/node_info_spec.rb new file mode 100644 index 0000000000..0934b0fde6 --- /dev/null +++ b/spec/requests/well_known/node_info_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'The well-known node-info endpoints' do + describe 'The /.well-known/node-info endpoint' do + it 'returns JSON document pointing to node info' do + get '/.well-known/nodeinfo' + + expect(response) + .to have_http_status(200) + .and have_attributes( + media_type: 'application/json' + ) + + expect(body_as_json).to include( + links: be_an(Array).and( + contain_exactly( + include( + rel: 'http://nodeinfo.diaspora.software/ns/schema/2.0', + href: include('nodeinfo/2.0') + ) + ) + ) + ) + end + end + + describe 'The /nodeinfo/2.0 endpoint' do + it 'returns JSON document with node info properties' do + get '/nodeinfo/2.0' + + expect(response) + .to have_http_status(200) + .and have_attributes( + media_type: 'application/json' + ) + + expect(non_matching_hash) + .to_not match_json_schema('nodeinfo_2.0') + + expect(body_as_json) + .to match_json_schema('nodeinfo_2.0') + .and include( + version: '2.0', + usage: be_a(Hash), + software: be_a(Hash), + protocols: be_a(Array) + ) + end + + private + + def non_matching_hash + { 'foo' => 0 } + end + end +end diff --git a/spec/requests/well_known/webfinger_spec.rb b/spec/requests/well_known/webfinger_spec.rb new file mode 100644 index 0000000000..779f1bba59 --- /dev/null +++ b/spec/requests/well_known/webfinger_spec.rb @@ -0,0 +1,255 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'The /.well-known/webfinger endpoint' do + subject(:perform_request!) { get webfinger_url(resource: resource) } + + let(:alternate_domains) { [] } + let(:alice) { Fabricate(:account, username: 'alice') } + let(:resource) { nil } + + around do |example| + tmp = Rails.configuration.x.alternate_domains + Rails.configuration.x.alternate_domains = alternate_domains + example.run + Rails.configuration.x.alternate_domains = tmp + end + + shared_examples 'a successful response' do + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'sets only a Vary Origin header' do + expect(response.headers['Vary']).to eq('Origin') + end + + it 'returns application/jrd+json' do + expect(response.media_type).to eq 'application/jrd+json' + end + + it 'returns links for the account' do + json = body_as_json + expect(json[:subject]).to eq 'acct:alice@cb6e6126.ngrok.io' + expect(json[:aliases]).to include('https://cb6e6126.ngrok.io/@alice', 'https://cb6e6126.ngrok.io/users/alice') + end + end + + context 'when an account exists' do + let(:resource) { alice.to_webfinger_s } + + before do + perform_request! + end + + it_behaves_like 'a successful response' + end + + context 'when an account is temporarily suspended' do + let(:resource) { alice.to_webfinger_s } + + before do + alice.suspend! + perform_request! + end + + it_behaves_like 'a successful response' + end + + context 'when an account is permanently suspended or deleted' do + let(:resource) { alice.to_webfinger_s } + + before do + alice.suspend! + alice.deletion_request.destroy + perform_request! + end + + it 'returns http gone' do + expect(response).to have_http_status(410) + end + end + + context 'when an account is not found' do + let(:resource) { 'acct:not@existing.com' } + + before do + perform_request! + end + + it 'returns http not found' do + expect(response).to have_http_status(404) + end + end + + context 'with an alternate domain' do + let(:alternate_domains) { ['foo.org'] } + + before do + perform_request! + end + + context 'when an account exists' do + let(:resource) do + username, = alice.to_webfinger_s.split('@') + "#{username}@foo.org" + end + + it_behaves_like 'a successful response' + end + + context 'when the domain is wrong' do + let(:resource) do + username, = alice.to_webfinger_s.split('@') + "#{username}@bar.org" + end + + it 'returns http not found' do + expect(response).to have_http_status(404) + end + end + end + + context 'when the old name scheme is used to query the instance actor' do + let(:resource) do + "#{Rails.configuration.x.local_domain}@#{Rails.configuration.x.local_domain}" + end + + before do + perform_request! + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'sets only a Vary Origin header' do + expect(response.headers['Vary']).to eq('Origin') + end + + it 'returns application/jrd+json' do + expect(response.media_type).to eq 'application/jrd+json' + end + + it 'returns links for the internal account' do + json = body_as_json + expect(json[:subject]).to eq 'acct:mastodon.internal@cb6e6126.ngrok.io' + expect(json[:aliases]).to eq ['https://cb6e6126.ngrok.io/actor'] + end + end + + context 'with no resource parameter' do + let(:resource) { nil } + + before do + perform_request! + end + + it 'returns http bad request' do + expect(response).to have_http_status(400) + end + end + + context 'with a nonsense parameter' do + let(:resource) { 'df/:dfkj' } + + before do + perform_request! + end + + it 'returns http bad request' do + expect(response).to have_http_status(400) + end + end + + context 'when an account has an avatar' do + let(:alice) { Fabricate(:account, username: 'alice', avatar: attachment_fixture('attachment.jpg')) } + let(:resource) { alice.to_webfinger_s } + + it 'returns avatar in response' do + perform_request! + + avatar_link = get_avatar_link(body_as_json) + expect(avatar_link).to_not be_nil + expect(avatar_link[:type]).to eq alice.avatar.content_type + expect(avatar_link[:href]).to eq Addressable::URI.new(host: Rails.configuration.x.local_domain, path: alice.avatar.to_s, scheme: 'https').to_s + end + + context 'with limited federation mode' do + before do + allow(Rails.configuration.x).to receive(:limited_federation_mode).and_return(true) + end + + it 'does not return avatar in response' do + perform_request! + + avatar_link = get_avatar_link(body_as_json) + expect(avatar_link).to be_nil + end + end + + context 'when enabling DISALLOW_UNAUTHENTICATED_API_ACCESS' do + around do |example| + ClimateControl.modify DISALLOW_UNAUTHENTICATED_API_ACCESS: 'true' do + example.run + end + end + + it 'does not return avatar in response' do + perform_request! + + avatar_link = get_avatar_link(body_as_json) + expect(avatar_link).to be_nil + end + end + end + + context 'when an account does not have an avatar' do + let(:alice) { Fabricate(:account, username: 'alice', avatar: nil) } + let(:resource) { alice.to_webfinger_s } + + before do + perform_request! + end + + it 'does not return avatar in response' do + avatar_link = get_avatar_link(body_as_json) + expect(avatar_link).to be_nil + end + end + + context 'with different headers' do + describe 'requested with standard accepts headers' do + it 'returns a json response' do + get webfinger_url(resource: alice.to_webfinger_s) + + expect(response).to have_http_status(200) + expect(response.media_type).to eq 'application/jrd+json' + end + end + + describe 'asking for json format' do + it 'returns a json response for json format' do + get webfinger_url(resource: alice.to_webfinger_s, format: :json) + + expect(response).to have_http_status(200) + expect(response.media_type).to eq 'application/jrd+json' + end + + it 'returns a json response for json accept header' do + headers = { 'HTTP_ACCEPT' => 'application/jrd+json' } + get webfinger_url(resource: alice.to_webfinger_s), headers: headers + + expect(response).to have_http_status(200) + expect(response.media_type).to eq 'application/jrd+json' + end + end + end + + private + + def get_avatar_link(json) + json[:links].find { |link| link[:rel] == 'http://webfinger.net/rel/avatar' } + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0bb4f88cf9..dc60976d05 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,28 +1,7 @@ # frozen_string_literal: true -if ENV['DISABLE_SIMPLECOV'] != 'true' - require 'simplecov' - - if ENV['CI'] - require 'simplecov-lcov' - SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true - SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter - else - SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter - end - SimpleCov.start 'rails' do - enable_coverage :branch - enable_coverage_for_eval - - add_filter 'lib/linter' - add_group 'Policies', 'app/policies' - add_group 'Presenters', 'app/presenters' - add_group 'Serializers', 'app/serializers' - add_group 'Services', 'app/services' - add_group 'Validators', 'app/validators' - - add_group 'Libraries', 'lib' - end +unless ENV['DISABLE_SIMPLECOV'] == 'true' + require 'simplecov' # Configuration details loaded from .simplecov end RSpec.configure do |config| diff --git a/spec/workers/account_refresh_worker_spec.rb b/spec/workers/account_refresh_worker_spec.rb new file mode 100644 index 0000000000..361d69aa0a --- /dev/null +++ b/spec/workers/account_refresh_worker_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe AccountRefreshWorker do + let(:worker) { described_class.new } + let(:service) { instance_double(ResolveAccountService, call: true) } + + describe '#perform' do + before do + allow(ResolveAccountService).to receive(:new).and_return(service) + end + + context 'when account does not exist' do + it 'returns immediately without processing' do + worker.perform(123_123_123) + + expect(service).to_not have_received(:call) + end + end + + context 'when account exists' do + context 'when account does not need refreshing' do + let(:account) { Fabricate(:account, last_webfingered_at: recent_webfinger_at) } + + it 'returns immediately without processing' do + worker.perform(account.id) + + expect(service).to_not have_received(:call) + end + end + + context 'when account needs refreshing' do + let(:account) { Fabricate(:account, last_webfingered_at: outdated_webfinger_at) } + + it 'schedules an account update' do + worker.perform(account.id) + + expect(service).to have_received(:call) + end + end + + def recent_webfinger_at + (Account::BACKGROUND_REFRESH_INTERVAL - 3.days).ago + end + + def outdated_webfinger_at + (Account::BACKGROUND_REFRESH_INTERVAL + 3.days).ago + end + end + end +end diff --git a/spec/workers/activitypub/post_upgrade_worker_spec.rb b/spec/workers/activitypub/post_upgrade_worker_spec.rb new file mode 100644 index 0000000000..08de150ad9 --- /dev/null +++ b/spec/workers/activitypub/post_upgrade_worker_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe ActivityPub::PostUpgradeWorker do + let(:worker) { described_class.new } + + describe '#perform' do + let(:domain) { 'host.example' } + + it 'updates relevant values' do + account = Fabricate(:account, domain: domain, last_webfingered_at: 1.day.ago, protocol: :ostatus) + worker.perform(domain) + + expect(account.reload.last_webfingered_at).to be_nil + end + end +end diff --git a/spec/workers/activitypub/synchronize_featured_tags_collection_worker_spec.rb b/spec/workers/activitypub/synchronize_featured_tags_collection_worker_spec.rb new file mode 100644 index 0000000000..8cf13cb900 --- /dev/null +++ b/spec/workers/activitypub/synchronize_featured_tags_collection_worker_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe ActivityPub::SynchronizeFeaturedTagsCollectionWorker do + let(:worker) { described_class.new } + let(:service) { instance_double(ActivityPub::FetchFeaturedTagsCollectionService, call: true) } + + describe '#perform' do + before do + allow(ActivityPub::FetchFeaturedTagsCollectionService).to receive(:new).and_return(service) + end + + let(:account) { Fabricate(:account) } + let(:url) { 'https://host.example' } + + it 'sends the account and url to the service' do + worker.perform(account.id, url) + + expect(service).to have_received(:call).with(account, url) + end + + it 'returns true for non-existent record' do + result = worker.perform(123_123_123, url) + + expect(result).to be(true) + end + end +end diff --git a/spec/workers/admin/suspension_worker_spec.rb b/spec/workers/admin/suspension_worker_spec.rb new file mode 100644 index 0000000000..da12037edc --- /dev/null +++ b/spec/workers/admin/suspension_worker_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::SuspensionWorker do + let(:worker) { described_class.new } + let(:service) { instance_double(SuspendAccountService, call: true) } + + describe '#perform' do + before do + allow(SuspendAccountService).to receive(:new).and_return(service) + end + + let(:account) { Fabricate(:account) } + + it 'sends the account to the service' do + worker.perform(account.id) + + expect(service).to have_received(:call).with(account) + end + + it 'returns true for non-existent record' do + result = worker.perform(123_123_123) + + expect(result).to be(true) + end + end +end diff --git a/spec/workers/after_account_domain_block_worker_spec.rb b/spec/workers/after_account_domain_block_worker_spec.rb new file mode 100644 index 0000000000..54a113a2b3 --- /dev/null +++ b/spec/workers/after_account_domain_block_worker_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe AfterAccountDomainBlockWorker do + let(:worker) { described_class.new } + let(:service) { instance_double(AfterBlockDomainFromAccountService, call: true) } + + describe '#perform' do + before do + allow(AfterBlockDomainFromAccountService).to receive(:new).and_return(service) + end + + let(:account) { Fabricate(:account) } + let(:domain) { 'host.example' } + + it 'sends the account and domain to the service' do + worker.perform(account.id, domain) + + expect(service).to have_received(:call).with(account, domain) + end + + it 'returns true for non-existent record' do + result = worker.perform(123_123_123, domain) + + expect(result).to be(true) + end + end +end diff --git a/spec/workers/backup_worker_spec.rb b/spec/workers/backup_worker_spec.rb new file mode 100644 index 0000000000..1a169513e9 --- /dev/null +++ b/spec/workers/backup_worker_spec.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe BackupWorker do + let(:worker) { described_class.new } + let(:service) { instance_double(BackupService, call: true) } + + describe '#perform' do + before do + allow(BackupService).to receive(:new).and_return(service) + end + + let(:backup) { Fabricate(:backup) } + let!(:other_backup) { Fabricate(:backup, user: backup.user) } + + it 'sends the backup to the service and removes other backups' do + expect do + worker.perform(backup.id) + end.to change(UserMailer.deliveries, :size).by(1) + + expect(service).to have_received(:call).with(backup) + expect { other_backup.reload }.to raise_error(ActiveRecord::RecordNotFound) + end + + context 'when sidekiq retries are exhausted' do + it 'destroys the backup' do + described_class.within_sidekiq_retries_exhausted_block({ 'args' => [backup.id] }) do + worker.perform(backup.id) + end + + expect { backup.reload }.to raise_error(ActiveRecord::RecordNotFound) + end + end + end +end diff --git a/spec/workers/delete_mute_worker_spec.rb b/spec/workers/delete_mute_worker_spec.rb new file mode 100644 index 0000000000..1fc84491c3 --- /dev/null +++ b/spec/workers/delete_mute_worker_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe DeleteMuteWorker do + let(:worker) { described_class.new } + let(:service) { instance_double(UnmuteService, call: true) } + + describe '#perform' do + before do + allow(UnmuteService).to receive(:new).and_return(service) + end + + context 'with an expired mute' do + let(:mute) { Fabricate(:mute, expires_at: 1.day.ago) } + + it 'sends the mute to the service' do + worker.perform(mute.id) + + expect(service).to have_received(:call).with(mute.account, mute.target_account) + end + end + + context 'with an unexpired mute' do + let(:mute) { Fabricate(:mute, expires_at: 1.day.from_now) } + + it 'does not send the mute to the service' do + worker.perform(mute.id) + + expect(service).to_not have_received(:call) + end + end + + context 'with a non-existent mute' do + it 'does not send the mute to the service' do + worker.perform(123_123_123) + + expect(service).to_not have_received(:call) + end + end + end +end diff --git a/spec/workers/feed_insert_worker_spec.rb b/spec/workers/feed_insert_worker_spec.rb index 97c73c5999..e9484879ff 100644 --- a/spec/workers/feed_insert_worker_spec.rb +++ b/spec/workers/feed_insert_worker_spec.rb @@ -8,6 +8,7 @@ describe FeedInsertWorker do describe 'perform' do let(:follower) { Fabricate(:account) } let(:status) { Fabricate(:status) } + let(:list) { Fabricate(:list) } context 'when there are no records' do it 'skips push with missing status' do @@ -42,11 +43,29 @@ describe FeedInsertWorker do it 'pushes the status onto the home timeline without filter' do instance = instance_double(FeedManager, push_to_home: nil, filter?: false) allow(FeedManager).to receive(:instance).and_return(instance) - result = subject.perform(status.id, follower.id) + result = subject.perform(status.id, follower.id, :home) expect(result).to be_nil expect(instance).to have_received(:push_to_home).with(follower, status, update: nil) end + + it 'pushes the status onto the tags timeline without filter' do + instance = instance_double(FeedManager, push_to_home: nil, filter?: false) + allow(FeedManager).to receive(:instance).and_return(instance) + result = subject.perform(status.id, follower.id, :tags) + + expect(result).to be_nil + expect(instance).to have_received(:push_to_home).with(follower, status, update: nil) + end + + it 'pushes the status onto the list timeline without filter' do + instance = instance_double(FeedManager, push_to_list: nil, filter?: false) + allow(FeedManager).to receive(:instance).and_return(instance) + result = subject.perform(status.id, list.id, :list) + + expect(result).to be_nil + expect(instance).to have_received(:push_to_list).with(list, status, update: nil) + end end end end diff --git a/spec/workers/import_worker_spec.rb b/spec/workers/import_worker_spec.rb new file mode 100644 index 0000000000..4095a5d354 --- /dev/null +++ b/spec/workers/import_worker_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe ImportWorker do + let(:worker) { described_class.new } + let(:service) { instance_double(ImportService, call: true) } + + describe '#perform' do + before do + allow(ImportService).to receive(:new).and_return(service) + end + + let(:import) { Fabricate(:import) } + + it 'sends the import to the service' do + worker.perform(import.id) + + expect(service).to have_received(:call).with(import) + expect { import.reload }.to raise_error(ActiveRecord::RecordNotFound) + end + end +end diff --git a/spec/workers/move_worker_spec.rb b/spec/workers/move_worker_spec.rb index efad92c047..774296fda4 100644 --- a/spec/workers/move_worker_spec.rb +++ b/spec/workers/move_worker_spec.rb @@ -35,17 +35,16 @@ describe MoveWorker do context 'when user notes are short enough' do it 'copies user note with prelude' do subject.perform(source_account.id, target_account.id) - expect(AccountNote.find_by(account: account_note.account, target_account: target_account).comment).to include(source_account.acct) - expect(AccountNote.find_by(account: account_note.account, target_account: target_account).comment).to include(account_note.comment) + expect(relevant_account_note.comment) + .to include(source_account.acct, account_note.comment) end it 'merges user notes when needed' do new_account_note = AccountNote.create!(account: account_note.account, target_account: target_account, comment: 'new note prior to move') subject.perform(source_account.id, target_account.id) - expect(AccountNote.find_by(account: account_note.account, target_account: target_account).comment).to include(source_account.acct) - expect(AccountNote.find_by(account: account_note.account, target_account: target_account).comment).to include(account_note.comment) - expect(AccountNote.find_by(account: account_note.account, target_account: target_account).comment).to include(new_account_note.comment) + expect(relevant_account_note.comment) + .to include(source_account.acct, account_note.comment, new_account_note.comment) end end @@ -54,16 +53,24 @@ describe MoveWorker do it 'copies user note without prelude' do subject.perform(source_account.id, target_account.id) - expect(AccountNote.find_by(account: account_note.account, target_account: target_account).comment).to include(account_note.comment) + expect(relevant_account_note.comment) + .to include(account_note.comment) end it 'keeps user notes unchanged' do new_account_note = AccountNote.create!(account: account_note.account, target_account: target_account, comment: 'new note prior to move') subject.perform(source_account.id, target_account.id) - expect(AccountNote.find_by(account: account_note.account, target_account: target_account).comment).to include(new_account_note.comment) + expect(relevant_account_note.comment) + .to include(new_account_note.comment) end end + + private + + def relevant_account_note + AccountNote.find_by(account: account_note.account, target_account: target_account) + end end shared_examples 'block and mute handling' do @@ -71,10 +78,19 @@ describe MoveWorker do subject.perform(source_account.id, target_account.id) expect(block_service).to have_received(:call).with(blocking_account, target_account) - expect(AccountNote.find_by(account: blocking_account, target_account: target_account).comment).to include(source_account.acct) - expect(muting_account.muting?(target_account)).to be true - expect(AccountNote.find_by(account: muting_account, target_account: target_account).comment).to include(source_account.acct) + + expect( + [note_account_comment, mute_account_comment] + ).to all include(source_account.acct) + end + + def note_account_comment + AccountNote.find_by(account: blocking_account, target_account: target_account).comment + end + + def mute_account_comment + AccountNote.find_by(account: muting_account, target_account: target_account).comment end end diff --git a/spec/workers/post_process_media_worker_spec.rb b/spec/workers/post_process_media_worker_spec.rb index 33072704bf..828da5244f 100644 --- a/spec/workers/post_process_media_worker_spec.rb +++ b/spec/workers/post_process_media_worker_spec.rb @@ -2,12 +2,38 @@ require 'rails_helper' -describe PostProcessMediaWorker do +describe PostProcessMediaWorker, :paperclip_processing do let(:worker) { described_class.new } - describe 'perform' do - it 'runs without error for missing record' do - expect { worker.perform(nil) }.to_not raise_error + describe '#perform' do + let(:media_attachment) { Fabricate(:media_attachment) } + + it 'reprocesses and updates the media attachment' do + worker.perform(media_attachment.id) + + expect(media_attachment.processing).to eq('complete') + end + + it 'returns true for non-existent record' do + result = worker.perform(123_123_123) + + expect(result).to be(true) + end + + context 'when sidekiq retries are exhausted' do + it 'sets state to failed' do + described_class.within_sidekiq_retries_exhausted_block({ 'args' => [media_attachment.id] }) do + worker.perform(media_attachment.id) + end + + expect(media_attachment.reload.processing).to eq('failed') + end + + it 'returns true for non-existent record' do + described_class.within_sidekiq_retries_exhausted_block({ 'args' => [123_123_123] }) do + expect(worker.perform(123_123_123)).to be(true) + end + end end end end diff --git a/spec/workers/publish_announcement_reaction_worker_spec.rb b/spec/workers/publish_announcement_reaction_worker_spec.rb new file mode 100644 index 0000000000..91668b5ada --- /dev/null +++ b/spec/workers/publish_announcement_reaction_worker_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe PublishAnnouncementReactionWorker do + let(:worker) { described_class.new } + + describe '#perform' do + before { Fabricate(:account, user: Fabricate(:user, current_sign_in_at: 1.hour.ago)) } + + let(:announcement) { Fabricate(:announcement) } + let(:name) { 'name value' } + + it 'sends the announcement and name to the service when subscribed' do + allow(redis).to receive(:exists?).and_return(true) + allow(redis).to receive(:publish) + + worker.perform(announcement.id, name) + + expect(redis).to have_received(:publish) + end + + it 'does not send the announcement and name to the service when not subscribed' do + allow(redis).to receive(:exists?).and_return(false) + allow(redis).to receive(:publish) + + worker.perform(announcement.id, name) + + expect(redis).to_not have_received(:publish) + end + + it 'returns true for non-existent record' do + result = worker.perform(123_123_123, name) + + expect(result).to be(true) + end + end +end diff --git a/spec/workers/redownload_avatar_worker_spec.rb b/spec/workers/redownload_avatar_worker_spec.rb index b44ae9f035..4ab368e12f 100644 --- a/spec/workers/redownload_avatar_worker_spec.rb +++ b/spec/workers/redownload_avatar_worker_spec.rb @@ -5,9 +5,48 @@ require 'rails_helper' describe RedownloadAvatarWorker do let(:worker) { described_class.new } - describe 'perform' do - it 'runs without error for missing record' do - expect { worker.perform(nil) }.to_not raise_error + describe '#perform' do + it 'returns nil for non-existent record' do + result = worker.perform(123_123_123) + + expect(result).to be_nil + end + + it 'returns nil for suspended account' do + account = Fabricate(:account, suspended_at: 10.days.ago) + + expect(worker.perform(account.id)).to be_nil + end + + it 'returns nil with a domain block' do + account = Fabricate(:account, domain: 'host.example') + Fabricate(:domain_block, domain: account.domain, reject_media: true) + + expect(worker.perform(account.id)).to be_nil + end + + it 'returns nil without an avatar remote url' do + account = Fabricate(:account, avatar_remote_url: '') + + expect(worker.perform(account.id)).to be_nil + end + + it 'returns nil when avatar file name is present' do + stub_request(:get, 'https://example.host/file').to_return request_fixture('avatar.txt') + account = Fabricate(:account, avatar_remote_url: 'https://example.host/file', avatar_file_name: 'test.jpg') + + expect(worker.perform(account.id)).to be_nil + end + + it 'reprocesses a remote avatar' do + stub_request(:get, 'https://example.host/file').to_return request_fixture('avatar.txt') + account = Fabricate(:account, avatar_remote_url: 'https://example.host/file') + account.update_column(:avatar_file_name, nil) # rubocop:disable Rails/SkipsModelValidations + + result = worker.perform(account.id) + + expect(result).to be(true) + expect(account.reload.avatar_file_name).to_not be_nil end end end diff --git a/spec/workers/redownload_header_worker_spec.rb b/spec/workers/redownload_header_worker_spec.rb index 767ae7a5ab..3b6f497bb8 100644 --- a/spec/workers/redownload_header_worker_spec.rb +++ b/spec/workers/redownload_header_worker_spec.rb @@ -5,9 +5,48 @@ require 'rails_helper' describe RedownloadHeaderWorker do let(:worker) { described_class.new } - describe 'perform' do - it 'runs without error for missing record' do - expect { worker.perform(nil) }.to_not raise_error + describe '#perform' do + it 'returns nil for non-existent record' do + result = worker.perform(123_123_123) + + expect(result).to be_nil + end + + it 'returns nil for suspended account' do + account = Fabricate(:account, suspended_at: 10.days.ago) + + expect(worker.perform(account.id)).to be_nil + end + + it 'returns nil with a domain block' do + account = Fabricate(:account, domain: 'host.example') + Fabricate(:domain_block, domain: account.domain, reject_media: true) + + expect(worker.perform(account.id)).to be_nil + end + + it 'returns nil without an header remote url' do + account = Fabricate(:account, header_remote_url: '') + + expect(worker.perform(account.id)).to be_nil + end + + it 'returns nil when header file name is present' do + stub_request(:get, 'https://example.host/file').to_return request_fixture('avatar.txt') + account = Fabricate(:account, header_remote_url: 'https://example.host/file', header_file_name: 'test.jpg') + + expect(worker.perform(account.id)).to be_nil + end + + it 'reprocesses a remote header' do + stub_request(:get, 'https://example.host/file').to_return request_fixture('avatar.txt') + account = Fabricate(:account, header_remote_url: 'https://example.host/file') + account.update_column(:header_file_name, nil) # rubocop:disable Rails/SkipsModelValidations + + result = worker.perform(account.id) + + expect(result).to be(true) + expect(account.reload.header_file_name).to_not be_nil end end end diff --git a/spec/workers/redownload_media_worker_spec.rb b/spec/workers/redownload_media_worker_spec.rb new file mode 100644 index 0000000000..cd561d148b --- /dev/null +++ b/spec/workers/redownload_media_worker_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe RedownloadMediaWorker do + let(:worker) { described_class.new } + + describe '#perform' do + it 'returns nil for non-existent record' do + result = worker.perform(123_123_123) + + expect(result).to be_nil + end + + it 'returns nil without a remote_url' do + media_attachment = Fabricate(:media_attachment, remote_url: '') + + result = worker.perform(media_attachment.id) + + expect(result).to be_nil + end + + context 'with a valid remote url' do + let(:url) { 'https://example.host/file.txt' } + + before { stub_request(:get, url).to_return(status: 200) } + + it 'processes downloads for valid record' do + media_attachment = Fabricate(:media_attachment, remote_url: url) + + worker.perform(media_attachment.id) + + expect(a_request(:get, url)).to have_been_made + end + end + end +end diff --git a/spec/workers/removal_worker_spec.rb b/spec/workers/removal_worker_spec.rb new file mode 100644 index 0000000000..5071e882b6 --- /dev/null +++ b/spec/workers/removal_worker_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe RemovalWorker do + let(:worker) { described_class.new } + let(:service) { instance_double(RemoveStatusService, call: true) } + + describe '#perform' do + before do + allow(RemoveStatusService).to receive(:new).and_return(service) + end + + let(:status) { Fabricate(:status) } + + it 'sends the status to the service' do + worker.perform(status.id) + + expect(service).to have_received(:call).with(status) + end + + it 'returns true for non-existent record' do + result = worker.perform(123_123_123) + + expect(result).to be(true) + end + end +end diff --git a/spec/workers/scheduler/self_destruct_scheduler_spec.rb b/spec/workers/scheduler/self_destruct_scheduler_spec.rb new file mode 100644 index 0000000000..2bf5783571 --- /dev/null +++ b/spec/workers/scheduler/self_destruct_scheduler_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Scheduler::SelfDestructScheduler do + let(:worker) { described_class.new } + + describe '#perform' do + let!(:account) { Fabricate(:account, domain: nil, suspended_at: nil) } + + context 'when not in self destruct mode' do + before do + allow(SelfDestructHelper).to receive(:self_destruct?).and_return(false) + end + + it 'returns without processing' do + worker.perform + + expect(account.reload.suspended_at).to be_nil + end + end + + context 'when in self-destruct mode' do + before do + allow(SelfDestructHelper).to receive(:self_destruct?).and_return(true) + end + + context 'when sidekiq is overwhelmed' do + before do + stats = instance_double(Sidekiq::Stats, enqueued: described_class::MAX_ENQUEUED**2) + allow(Sidekiq::Stats).to receive(:new).and_return(stats) + end + + it 'returns without processing' do + worker.perform + + expect(account.reload.suspended_at).to be_nil + end + end + + context 'when sidekiq is operational' do + it 'suspends local non-suspended accounts' do + worker.perform + + expect(account.reload.suspended_at).to_not be_nil + end + + it 'suspends local suspended accounts marked for deletion' do + account.update(suspended_at: 10.days.ago) + deletion_request = Fabricate(:account_deletion_request, account: account) + + worker.perform + + expect(account.reload.suspended_at).to be > 1.day.ago + expect { deletion_request.reload }.to raise_error(ActiveRecord::RecordNotFound) + end + end + end + end +end diff --git a/spec/workers/webhooks/delivery_worker_spec.rb b/spec/workers/webhooks/delivery_worker_spec.rb index daf8a3e285..6a5483d1d4 100644 --- a/spec/workers/webhooks/delivery_worker_spec.rb +++ b/spec/workers/webhooks/delivery_worker_spec.rb @@ -5,9 +5,21 @@ require 'rails_helper' describe Webhooks::DeliveryWorker do let(:worker) { described_class.new } - describe 'perform' do - it 'runs without error' do - expect { worker.perform(nil, nil) }.to_not raise_error + describe '#perform' do + let(:webhook) { Fabricate(:webhook) } + + it 'reprocesses and updates the webhook' do + stub_request(:post, webhook.url).to_return(status: 200, body: '') + + worker.perform(webhook.id, 'body') + + expect(a_request(:post, webhook.url)).to have_been_made.at_least_once + end + + it 'returns true for non-existent record' do + result = worker.perform(123_123_123, '') + + expect(result).to be(true) end end end diff --git a/yarn.lock b/yarn.lock index 8dd3509327..d480bb1a06 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2553,9 +2553,9 @@ __metadata: linkType: soft "@material-symbols/svg-600@npm:^0.14.0": - version: 0.14.0 - resolution: "@material-symbols/svg-600@npm:0.14.0" - checksum: e6547a9a0b2072f4109f2e4e0863367ea2507efce740c427a8544100db02ffff52f33608aac1a355f4977e2c0b2ce6cdd6bfee9177bb13cee0b28418f948b5a5 + version: 0.14.1 + resolution: "@material-symbols/svg-600@npm:0.14.1" + checksum: fb5252285bbeccc45a4b131e8b165470b5b57e146bc7ea586eb82e580037d1218f6dad5fee4e6822c357041ff547f34c9c7432cce0a811b14f7e41d8ae23009b languageName: node linkType: hard @@ -13801,17 +13801,17 @@ __metadata: linkType: hard "react-redux-loading-bar@npm:^5.0.4": - version: 5.0.4 - resolution: "react-redux-loading-bar@npm:5.0.4" + version: 5.0.5 + resolution: "react-redux-loading-bar@npm:5.0.5" dependencies: prop-types: "npm:^15.7.2" react-lifecycles-compat: "npm:^3.0.4" peerDependencies: react: ^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 react-dom: ^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 - react-redux: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - redux: ^3.0.0 || ^4.0.0 - checksum: 11eea2ef6dfae232e278eceb83d07f9f57a2ece3ef23ce888dccf24964b669c9ee83a6db12b1f3c757b5b3410f7a7ccda96a4b4216c4ad9b42bf831ccea7a4a2 + react-redux: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + redux: ^3.0.0 || ^4.0.0 || ^5.0.0 + checksum: 0dbac046c5b8b6bd209ccfc25ccc55dc9158cd737b42b68fd1900dfe46a59c9c7e2b0082d8901b749e7cf2d7e23074590aae74f350a814f205105f47895a6214 languageName: node linkType: hard @@ -17038,8 +17038,8 @@ __metadata: linkType: hard "webpack-bundle-analyzer@npm:^4.8.0": - version: 4.10.0 - resolution: "webpack-bundle-analyzer@npm:4.10.0" + version: 4.10.1 + resolution: "webpack-bundle-analyzer@npm:4.10.1" dependencies: "@discoveryjs/json-ext": "npm:0.5.7" acorn: "npm:^8.0.4" @@ -17056,7 +17056,7 @@ __metadata: ws: "npm:^7.3.1" bin: webpack-bundle-analyzer: lib/bin/analyzer.js - checksum: f812a8d3c0198ce518baf742bff656526f3eae69fb7a64c7f0c9cff202f6fb3380cabf3baaae965b8d6ffbbb6fb802eacb373fca03a596a38b01b84cfb2e8329 + checksum: 6a94c8f6aa03296fb2eb00d6ad3b27bd5c551590fd253772bc61debf3177414d42701014079d4f85c74ba1ca685ae9f0cb4063812b58c21f294d108e9908e5cd languageName: node linkType: hard