From c1542643f55ecf5a5d19298e16aa1ca1b8619d1f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 14:23:00 +0200 Subject: [PATCH 01/19] fix(deps): update dependency sass to v1.92.0 (#36001) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3f5b751a36..289b41f670 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11957,8 +11957,8 @@ __metadata: linkType: hard "sass@npm:^1.62.1": - version: 1.91.0 - resolution: "sass@npm:1.91.0" + version: 1.92.0 + resolution: "sass@npm:1.92.0" dependencies: "@parcel/watcher": "npm:^2.4.1" chokidar: "npm:^4.0.0" @@ -11969,7 +11969,7 @@ __metadata: optional: true bin: sass: sass.js - checksum: 10c0/5be1c98f7a618cb5f90b62f63d2aa0f78f9bf369c93ec7cd9880752a26b0ead19aa63cc341e8a26ce6c74d080baa5705f1685dff52fe6a3f28a7828ae50182b6 + checksum: 10c0/bdff9fa6988620e2a81962efdd016e3894d19934cfadc105cf41db767f59dd47afd8ff32840e612ef700cb67e19d9e83c108f1724eb8f0bef56c4877dbe6f14d languageName: node linkType: hard From bc952ebde914e9dfd9ab4d88f4b994388ac90bef Mon Sep 17 00:00:00 2001 From: diondiondion Date: Wed, 3 Sep 2025 14:34:29 +0200 Subject: [PATCH 02/19] Add new plain (text-only) button variant (#36002) --- .../components/button/button.stories.tsx | 17 +++++++++ .../mastodon/components/button/index.tsx | 3 ++ .../styles/mastodon/components.scss | 35 +++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/app/javascript/mastodon/components/button/button.stories.tsx b/app/javascript/mastodon/components/button/button.stories.tsx index 4bcb9edbb8..6827097c50 100644 --- a/app/javascript/mastodon/components/button/button.stories.tsx +++ b/app/javascript/mastodon/components/button/button.stories.tsx @@ -8,6 +8,7 @@ const meta = { component: Button, args: { secondary: false, + plain: false, compact: false, dangerous: false, disabled: false, @@ -57,6 +58,14 @@ export const Secondary: Story = { play: buttonTest, }; +export const Plain: Story = { + args: { + plain: true, + children: 'Plain button', + }, + play: buttonTest, +}; + export const Compact: Story = { args: { compact: true, @@ -101,6 +110,14 @@ export const SecondaryDisabled: Story = { play: disabledButtonTest, }; +export const PlainDisabled: Story = { + args: { + ...Plain.args, + disabled: true, + }, + play: disabledButtonTest, +}; + const loadingButtonTest: Story['play'] = async ({ args, canvas, diff --git a/app/javascript/mastodon/components/button/index.tsx b/app/javascript/mastodon/components/button/index.tsx index 6d2a37cf85..f940c07d05 100644 --- a/app/javascript/mastodon/components/button/index.tsx +++ b/app/javascript/mastodon/components/button/index.tsx @@ -9,6 +9,7 @@ interface BaseProps extends Omit, 'children'> { block?: boolean; secondary?: boolean; + plain?: boolean; compact?: boolean; dangerous?: boolean; loading?: boolean; @@ -35,6 +36,7 @@ export const Button: React.FC = ({ disabled, block, secondary, + plain, compact, dangerous, loading, @@ -62,6 +64,7 @@ export const Button: React.FC = ({ + )} + + + )} + + )} + + ); +}; diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index f2f23e60fa..6bff9ed594 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -768,6 +768,9 @@ "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "today", + "remove_quote_hint.button_label": "Got it", + "remove_quote_hint.message": "You can do so from the {icon} options menu.", + "remove_quote_hint.title": "Want to remove your quoted post?", "reply_indicator.attachments": "{count, plural, one {# attachment} other {# attachments}}", "reply_indicator.cancel": "Cancel", "reply_indicator.poll": "Poll", diff --git a/app/javascript/mastodon/reducers/settings.js b/app/javascript/mastodon/reducers/settings.js index cea8949f23..43cf4e5342 100644 --- a/app/javascript/mastodon/reducers/settings.js +++ b/app/javascript/mastodon/reducers/settings.js @@ -117,6 +117,7 @@ const initialState = ImmutableMap({ 'explore/links': false, 'explore/statuses': false, 'explore/tags': false, + 'notifications/remove_quote_hint': false, }), }); diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 80f8e5cb02..1b5867e8b9 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -471,8 +471,8 @@ } } -body > [data-popper-placement] { - z-index: 3; +[data-popper-placement] { + z-index: 9999; } .invisible { @@ -7127,7 +7127,8 @@ a.status-card { cursor: default; } -.media-gallery__alt__popover { +.info-tooltip { + color: $white; background: color.change($black, $alpha: 0.65); backdrop-filter: $backdrop-blur-filter; border-radius: 4px; @@ -7139,20 +7140,36 @@ a.status-card { max-height: 30em; overflow-y: auto; + &--solid { + color: var(--nested-card-text); + background: + /* This is a bit of a silly hack for layering two background colours + * since --nested-card-background is too transparent for a tooltip */ + linear-gradient( + var(--nested-card-background), + var(--nested-card-background) + ), + linear-gradient(var(--background-color), var(--background-color)); + border: var(--nested-card-border); + } + h4 { font-size: 15px; line-height: 20px; font-weight: 500; - color: $white; margin-bottom: 8px; } p { font-size: 15px; line-height: 20px; - color: color.change($white, $alpha: 0.85); + opacity: 0.85; white-space: pre-line; } + + .button { + margin-block-start: 8px; + } } .attachment-list { From 0d93801bde372bf2b26660dd1caf254bd77396bc Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 5 Sep 2025 10:07:59 +0200 Subject: [PATCH 10/19] Fix missing `beforeUnload` confirmation when a poll is being authored (#36030) --- app/javascript/mastodon/features/ui/index.jsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/javascript/mastodon/features/ui/index.jsx b/app/javascript/mastodon/features/ui/index.jsx index 79f7f8c3b2..a420279ca4 100644 --- a/app/javascript/mastodon/features/ui/index.jsx +++ b/app/javascript/mastodon/features/ui/index.jsx @@ -92,8 +92,7 @@ const messages = defineMessages({ const mapStateToProps = state => ({ layout: state.getIn(['meta', 'layout']), isComposing: state.getIn(['compose', 'is_composing']), - hasComposingText: state.getIn(['compose', 'text']).trim().length !== 0, - hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0, + hasComposingContents: state.getIn(['compose', 'text']).trim().length !== 0 || state.getIn(['compose', 'media_attachments']).size > 0 || state.getIn(['compose', 'poll']) !== null, canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < state.getIn(['server', 'server', 'configuration', 'statuses', 'max_media_attachments']), firstLaunch: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION, newAccount: !state.getIn(['accounts', me, 'note']) && !state.getIn(['accounts', me, 'bot']) && state.getIn(['accounts', me, 'following_count'], 0) === 0 && state.getIn(['accounts', me, 'statuses_count'], 0) === 0, @@ -241,8 +240,7 @@ class UI extends PureComponent { dispatch: PropTypes.func.isRequired, children: PropTypes.node, isComposing: PropTypes.bool, - hasComposingText: PropTypes.bool, - hasMediaAttachments: PropTypes.bool, + hasComposingContents: PropTypes.bool, canUploadMore: PropTypes.bool, intl: PropTypes.object.isRequired, layout: PropTypes.string.isRequired, @@ -257,11 +255,11 @@ class UI extends PureComponent { }; handleBeforeUnload = e => { - const { intl, dispatch, isComposing, hasComposingText, hasMediaAttachments } = this.props; + const { intl, dispatch, isComposing, hasComposingContents } = this.props; dispatch(synchronouslySubmitMarkers()); - if (isComposing && (hasComposingText || hasMediaAttachments)) { + if (isComposing && hasComposingContents) { e.preventDefault(); // Setting returnValue to any string causes confirmation dialog. // Many browsers no longer display this text to users, From dd6bd681eab5122df18484f80b7cbdff05a0b6e2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 5 Sep 2025 10:14:25 +0200 Subject: [PATCH 11/19] New Crowdin Translations (automated) (#36029) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/br.json | 59 +++++++++++++++++----- app/javascript/mastodon/locales/cs.json | 5 ++ app/javascript/mastodon/locales/da.json | 1 + app/javascript/mastodon/locales/de.json | 3 ++ app/javascript/mastodon/locales/eo.json | 9 ++++ app/javascript/mastodon/locales/es-AR.json | 3 ++ app/javascript/mastodon/locales/es-MX.json | 3 ++ app/javascript/mastodon/locales/es.json | 3 ++ app/javascript/mastodon/locales/et.json | 5 ++ app/javascript/mastodon/locales/fi.json | 3 ++ app/javascript/mastodon/locales/gl.json | 3 ++ app/javascript/mastodon/locales/he.json | 3 ++ app/javascript/mastodon/locales/is.json | 3 ++ app/javascript/mastodon/locales/nl.json | 3 ++ app/javascript/mastodon/locales/vi.json | 3 ++ app/javascript/mastodon/locales/zh-CN.json | 3 ++ app/javascript/mastodon/locales/zh-TW.json | 3 ++ config/locales/br.yml | 22 ++++++-- config/locales/cy.yml | 3 ++ config/locales/simple_form.br.yml | 8 +-- 20 files changed, 129 insertions(+), 19 deletions(-) diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json index 941712a501..c6fceba7b7 100644 --- a/app/javascript/mastodon/locales/br.json +++ b/app/javascript/mastodon/locales/br.json @@ -29,6 +29,8 @@ "account.endorse": "Lakaat war-wel war ar profil", "account.familiar_followers_one": "Heuilhet gant {name1}", "account.familiar_followers_two": "Heuilhet gant {name1} ha {name2}", + "account.featured.accounts": "Profiloù", + "account.featured.hashtags": "Gerioù-klik", "account.featured_tags.last_status_at": "Toud diwezhañ : {date}", "account.featured_tags.last_status_never": "Embannadur ebet", "account.follow": "Heuliañ", @@ -39,6 +41,7 @@ "account.followers_you_know_counter": "{counter} a anavezit", "account.following": "Koumanantoù", "account.follows.empty": "An implijer·ez-mañ na heul den ebet.", + "account.follows_you": "Ho heuilh", "account.go_to_profile": "Gwelet ar profil", "account.hide_reblogs": "Kuzh skignadennoù gant @{name}", "account.in_memoriam": "E koun.", @@ -89,7 +92,10 @@ "alt_text_modal.done": "Graet", "announcement.announcement": "Kemennad", "annual_report.summary.followers.followers": "heulier", + "annual_report.summary.followers.total": "{count} en holl", "annual_report.summary.highlighted_post.possessive": "{name}", + "annual_report.summary.most_used_app.most_used_app": "arload muiañ implijet", + "annual_report.summary.most_used_hashtag.most_used_hashtag": "ar gerioù-klik implijet ar muiañ", "annual_report.summary.most_used_hashtag.none": "Hini ebet", "annual_report.summary.new_posts.new_posts": "toudoù nevez", "attachments_list.unprocessed": "(ket meret)", @@ -149,7 +155,7 @@ "compose.saved.body": "Enrollet.", "compose_form.direct_message_warning_learn_more": "Gouzout hiroc'h", "compose_form.encryption_warning": "Toudoù war Mastodon na vezont ket sifret penn-da-benn. Na rannit ket titouroù kizidik dre Mastodon.", - "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", + "compose_form.hashtag_warning": "Ne vo ket listennet an toud-mañ dindan gerioù-klik ebet dre m'eo anlistennet. N'eus nemet an toudoù foran a c'hall bezañ klasket dre c'her-klik.", "compose_form.lock_disclaimer": "N'eo ket {locked} ho kont. An holl a c'hal ho heuliañ evit gwelet ho toudoù prevez.", "compose_form.lock_disclaimer.lock": "prennet", "compose_form.placeholder": "Petra emaoc'h o soñjal e-barzh ?", @@ -168,6 +174,7 @@ "confirmations.block.confirm": "Stankañ", "confirmations.delete.confirm": "Dilemel", "confirmations.delete.message": "Ha sur oc'h e fell deoc'h dilemel an toud-mañ ?", + "confirmations.delete.title": "Dilemel an toud?", "confirmations.delete_list.confirm": "Dilemel", "confirmations.delete_list.message": "Ha sur eo hoc'h eus c'hoant da zilemel ar roll-mañ da vat ?", "confirmations.delete_list.title": "Dilemel al listenn?", @@ -176,10 +183,14 @@ "confirmations.follow_to_list.title": "Heuliañ an implijer·ez?", "confirmations.logout.confirm": "Digevreañ", "confirmations.logout.message": "Ha sur oc'h e fell deoc'h digevreañ ?", + "confirmations.logout.title": "Digevreañ?", "confirmations.mute.confirm": "Kuzhat", "confirmations.redraft.confirm": "Diverkañ ha skrivañ en-dro", "confirmations.unfollow.confirm": "Diheuliañ", "confirmations.unfollow.message": "Ha sur oc'h e fell deoc'h paouez da heuliañ {name} ?", + "confirmations.unfollow.title": "Paouez da heuliañ an implijer·ez?", + "content_warning.hide": "Kuzhat an embannadur", + "content_warning.show": "Diskwel memes tra", "content_warning.show_more": "Diskouez muioc'h", "conversation.delete": "Dilemel ar gaozeadenn", "conversation.mark_as_read": "Merkañ evel lennet", @@ -224,8 +235,8 @@ "empty_column.domain_blocks": "N'eus domani kuzh ebet c'hoazh.", "empty_column.explore_statuses": "N'eus tuadur ebet evit c'hoazh. Distroit diwezhatoc'h !", "empty_column.follow_requests": "N'ho peus reked heuliañ ebet c'hoazh. Pa vo resevet unan e teuio war wel amañ.", - "empty_column.followed_tags": "N'emaoc'h oc'h heuliañ hashtag ebet evit poent. Pa vioc'h e vo d'o gwelet amañ.", - "empty_column.hashtag": "N'eus netra en hashtag-mañ c'hoazh.", + "empty_column.followed_tags": "N'emaoc'h oc'h heuliañ ger-klik ebet evit poent. Pa vioc'h e vo d'o gwelet amañ.", + "empty_column.hashtag": "N'eus netra er ger-klik-mañ c'hoazh.", "empty_column.home": "Goullo eo ho red-amzer degemer! Kit da weladenniñ {public} pe implijit ar c'hlask evit kregiñ ganti ha kejañ gant implijer·ien·ezed all.", "empty_column.list": "Goullo eo al listenn-mañ evit c'hoazh. Pa vo embannet toudoù nevez gant e izili e teuint war wel amañ.", "empty_column.mutes": "N'ho peus kuzhet implijer ebet c'hoazh.", @@ -241,7 +252,7 @@ "explore.title": "Diouzh ar c'hiz", "explore.trending_links": "Keleier", "explore.trending_statuses": "Embannadurioù", - "explore.trending_tags": "Hashtagoù", + "explore.trending_tags": "Gerioù-klik", "featured_carousel.next": "War-raok", "featured_carousel.post": "Embannadenn", "featured_carousel.previous": "War-gil", @@ -269,7 +280,8 @@ "follow_suggestions.friends_of_friends_longer": "Diouzh ar c'hiz e-touez an dud heuliet ganeoc'h", "follow_suggestions.popular_suggestion_longer": "Diouzh ar c'hiz war {domain}", "follow_suggestions.view_all": "Gwelet pep tra", - "followed_tags": "Hashtagoù o heuliañ", + "follow_suggestions.who_to_follow": "Piv heuliañ", + "followed_tags": "Gerioù-klik o heuliañ", "footer.about": "Diwar-benn", "footer.directory": "Kavlec'h ar profiloù", "footer.get_app": "Pellgargañ an arload", @@ -281,19 +293,23 @@ "generic.saved": "Enrollet", "getting_started.heading": "Loc'hañ", "hashtag.admin_moderation": "Digeriñ an etrefas evezhiañ evit #{name}", + "hashtag.browse": "Furchal dre an toudoù gant #{hashtag}", + "hashtag.browse_from_account": "Furchal dre an toudoù gant @{name} gant #{hashtag}", "hashtag.column_header.tag_mode.all": "ha(g) {additional}", "hashtag.column_header.tag_mode.any": "pe {additional}", "hashtag.column_header.tag_mode.none": "hep {additional}", "hashtag.column_settings.select.no_options_message": "N'eus bet kavet ali ebet", - "hashtag.column_settings.select.placeholder": "Ouzhpennañ hashtagoù…", + "hashtag.column_settings.select.placeholder": "Ouzhpennañ gerioù-klik…", "hashtag.column_settings.tag_mode.all": "An holl anezho", "hashtag.column_settings.tag_mode.any": "Unan e mesk anezho", "hashtag.column_settings.tag_mode.none": "Hini ebet anezho", "hashtag.column_settings.tag_toggle": "Endelc'her gerioù-alc'hwez ouzhpenn evit ar bannad-mañ", "hashtag.counter_by_uses": "{count, plural, one {{counter} embannadur} other {{counter} embannadur}}", "hashtag.counter_by_uses_today": "{count, plural, one {{counter} embannadur} other {{counter} embannadur}} hiziv", + "hashtag.feature": "Lakaat war-wel war ar profil", "hashtag.follow": "Heuliañ ar ger-klik", - "hashtag.unfollow": "Paouez heuliañ an hashtag", + "hashtag.mute": "Kuzhat #{hashtag}", + "hashtag.unfollow": "Diheuliañ ar ger-klik", "hashtags.and_other": "…{count, plural, one {hag # all} other {ha # all}}", "home.column_settings.show_quotes": "Diskouez an arroudennoù", "home.column_settings.show_reblogs": "Diskouez ar skignadennoù", @@ -302,12 +318,14 @@ "home.pending_critical_update.body": "Hizivait ho servijer Mastodon kerkent ha ma c'hallit mar plij!", "home.pending_critical_update.link": "Gwelet an hizivadennoù", "home.show_announcements": "Diskouez ar c'hemennoù", + "interaction_modal.go": "Mont di", "interaction_modal.on_another_server": "War ur servijer all", "interaction_modal.on_this_server": "War ar servijer-mañ", "interaction_modal.title.favourite": "Ouzhpennañ embannadur {name} d'ar re vuiañ-karet", "interaction_modal.title.follow": "Heuliañ {name}", "interaction_modal.title.reblog": "Skignañ toud {name}", "interaction_modal.title.reply": "Respont da doud {name}", + "interaction_modal.username_prompt": "D.s. {example}", "intervals.full.days": "{number, plural, one {# devezh} other{# a zevezhioù}}", "intervals.full.hours": "{number, plural, one {# eurvezh} other{# eurvezh}}", "intervals.full.minutes": "{number, plural, one {# munut} other{# a vunutoù}}", @@ -345,12 +363,14 @@ "keyboard_shortcuts.toot": "Kregiñ gant un toud nevez", "keyboard_shortcuts.unfocus": "Difokus an dachenn testenn/klask", "keyboard_shortcuts.up": "Pignat er roll", + "learn_more_link.got_it": "Mat eo", "lightbox.close": "Serriñ", "lightbox.next": "Da-heul", "lightbox.previous": "A-raok", - "limited_account_hint.action": "Diskouez an aelad memes tra", + "limited_account_hint.action": "Diskouez ar profil memes tra", "limited_account_hint.title": "Kuzhet eo bet ar profil-mañ gant an evezhierien eus {domain}.", "link_preview.author": "Gant {name}", + "link_preview.more_from_author": "Muioc'h gant {name}", "lists.add_member": "Ouzhpennañ", "lists.add_to_list": "Ouzhpennañ d'al listenn", "lists.create": "Krouiñ", @@ -359,13 +379,19 @@ "lists.done": "Graet", "lists.edit": "Kemmañ al listenn", "lists.list_name": "Anv al listenn", + "lists.new_list_name": "Anv nevez al listenn", + "lists.no_lists_yet": "Listenn ebet c'hoazh.", "lists.replies_policy.followed": "Pep implijer.ez heuliet", "lists.replies_policy.list": "Izili ar roll", "lists.replies_policy.none": "Den ebet", + "lists.save": "Enrollañ", + "lists.search": "Klask", "load_pending": "{count, plural, one {# dra nevez} other {# dra nevez}}", "loading_indicator.label": "O kargañ…", + "media_gallery.hide": "Kuzhat", "navigation_bar.about": "Diwar-benn", "navigation_bar.account_settings": "Ger-tremen ha surentez", + "navigation_bar.administration": "Merañ", "navigation_bar.automated_deletion": "Dilemel an embannadenn ent-emgefreek", "navigation_bar.blocks": "Implijer·ezed·ien berzet", "navigation_bar.bookmarks": "Sinedoù", @@ -374,11 +400,12 @@ "navigation_bar.favourites": "Muiañ-karet", "navigation_bar.filters": "Gerioù kuzhet", "navigation_bar.follow_requests": "Pedadoù heuliañ", - "navigation_bar.followed_tags": "Hashtagoù o heuliañ", + "navigation_bar.followed_tags": "Gerioù-klik o heuliañ", "navigation_bar.follows_and_followers": "Heuliadennoù ha heulier·ezed·ien", "navigation_bar.import_export": "Enporzhiañ hag ezporzhiañ", "navigation_bar.lists": "Listennoù", "navigation_bar.logout": "Digennaskañ", + "navigation_bar.moderation": "Habaskadur", "navigation_bar.more": "Muioc'h", "navigation_bar.mutes": "Implijer·ion·ezed kuzhet", "navigation_bar.preferences": "Gwellvezioù", @@ -391,6 +418,8 @@ "notification.follow.name_and_others": "{name} {count, plural, one {hag # den all} two {ha # zen all} few {ha # den all} many {ha # den all} other {ha # den all}} zo o heuliañ ac'hanoc'h", "notification.follow_request": "Gant {name} eo bet goulennet ho heuliañ", "notification.label.reply": "Respont", + "notification.mention": "Meneg", + "notification.mentioned_you": "Gant {name} oc'h bet meneget", "notification.moderation-warning.learn_more": "Gouzout hiroc'h", "notification.own_poll": "Echu eo ho sontadeg", "notification.reblog": "Gant {name} eo bet skignet ho toud", @@ -447,7 +476,7 @@ "onboarding.profile.display_name": "Anv diskouezet", "onboarding.profile.display_name_hint": "Hoc'h anv klok pe hoc'h anv fentus…", "onboarding.profile.note": "Berr-ha-berr", - "onboarding.profile.note_hint": "Gallout a rit @menegiñ tud all pe #hashtagoù…", + "onboarding.profile.note_hint": "Gallout a rit @menegiñ tud all pe #gerioù-klik…", "onboarding.profile.save_and_continue": "Enrollañ ha kenderc'hel", "onboarding.profile.upload_avatar": "Enporzhiañ ur skeudenn profil", "password_confirmation.mismatching": "Disheñvel eo an daou c'her-termen-se", @@ -480,6 +509,7 @@ "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}eil", "relative_time.today": "hiziv", + "remove_quote_hint.button_label": "Mat eo", "reply_indicator.cancel": "Nullañ", "reply_indicator.poll": "Sontadeg", "report.block": "Stankañ", @@ -528,7 +558,7 @@ "search.placeholder": "Klask", "search.quick_action.account_search": "Profiloù a glot gant {x}", "search.quick_action.go_to_account": "Mont d'ar profil {x}", - "search.quick_action.go_to_hashtag": "Mont d'an hashtag {x}", + "search.quick_action.go_to_hashtag": "Mont d'ar ger-klik {x}", "search.quick_action.open_url": "Digeriñ an URL e-barzh Mastodon", "search.quick_action.status_search": "Embannadurioù a glot gant {x}", "search.search_or_paste": "Klask pe pegañ un URL", @@ -541,7 +571,7 @@ "search_popout.user": "implijer·ez", "search_results.accounts": "Profiloù", "search_results.all": "Pep tra", - "search_results.hashtags": "Hashtagoù", + "search_results.hashtags": "Gerioù-klik", "search_results.no_results": "Disoc'h ebet.", "search_results.see_all": "Gwelet pep tra", "search_results.statuses": "Toudoù", @@ -607,6 +637,7 @@ "subscribed_languages.save": "Enrollañ ar cheñchamantoù", "subscribed_languages.target": "Cheñch ar yezhoù koumanantet evit {target}", "tabs_bar.home": "Degemer", + "tabs_bar.menu": "Lañser", "tabs_bar.notifications": "Kemennoù", "tabs_bar.publish": "Embannadenn nevez", "tabs_bar.search": "Klask", @@ -638,6 +669,8 @@ "video.hide": "Kuzhat ar video", "video.pause": "Paouez", "video.play": "Lenn", + "visibility_modal.privacy_label": "Gwelusted", "visibility_modal.quote_followers": "Tud koumanantet hepken", - "visibility_modal.quote_public": "Pep den" + "visibility_modal.quote_public": "Pep den", + "visibility_modal.save": "Enrollañ" } diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index a59ab6702f..f8bda8f735 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -768,6 +768,9 @@ "relative_time.minutes": "{number} m", "relative_time.seconds": "{number} s", "relative_time.today": "dnes", + "remove_quote_hint.button_label": "Chápu", + "remove_quote_hint.message": "Můžete to udělat z {icon} nabídky možností.", + "remove_quote_hint.title": "Chcete odstranit citovaný příspěvek?", "reply_indicator.attachments": "{count, plural, one {{counter} příloha} few {{counter} přílohy} other {{counter} příloh}}", "reply_indicator.cancel": "Zrušit", "reply_indicator.poll": "Anketa", @@ -863,6 +866,7 @@ "status.block": "Blokovat @{name}", "status.bookmark": "Přidat do záložek", "status.cancel_reblog_private": "Zrušit boostnutí", + "status.cannot_quote": "Citování je na tomo příspěvku zakázáno", "status.cannot_reblog": "Tento příspěvek nemůže být boostnutý", "status.context.load_new_replies": "K dispozici jsou nové odpovědi", "status.context.loading": "Hledání dalších odpovědí", @@ -988,6 +992,7 @@ "visibility_modal.header": "Viditelnost a interakce", "visibility_modal.helper.direct_quoting": "Soukromé zmínky, které jsou vytvořeny na Mastodonu, nemohou být citovány ostatními.", "visibility_modal.helper.privacy_editing": "Publikované příspěvky nemohou změnit svou viditelnost.", + "visibility_modal.helper.privacy_private_self_quote": "Citace vlastních soukromých příspěvků nelze zveřejnit.", "visibility_modal.helper.private_quoting": "Příspěvky pouze pro sledující, které jsou vytvořeny na Mastodonu, nemohou být citovány ostatními.", "visibility_modal.helper.unlisted_quoting": "Když vás lidé citují, jejich příspěvek bude v časové ose populárních příspěvků také skryt.", "visibility_modal.instructions": "Nastavte, kdo bude moci interagovat s tímto příspěvkem. Tyto nastavení též můžete změnit pro všechny budoucí příspěvky v Nastavení > Výchozí nastavení příspěvků.", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index 71f808a118..cf10facdbf 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -768,6 +768,7 @@ "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "i dag", + "remove_quote_hint.button_label": "Forstået", "reply_indicator.attachments": "{count, plural, one {# vedhæftning} other {# vedhæftninger}}", "reply_indicator.cancel": "Afbryd", "reply_indicator.poll": "Afstemning", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 905fc668e8..e869b49ac6 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -768,6 +768,9 @@ "relative_time.minutes": "{number} Min.", "relative_time.seconds": "{number} Sek.", "relative_time.today": "heute", + "remove_quote_hint.button_label": "Verstanden", + "remove_quote_hint.message": "Klicke dafür im Beitrag auf „{icon} Mehr“.", + "remove_quote_hint.title": "Möchtest du aus dem zitierten Beitrag entfernt werden?", "reply_indicator.attachments": "{count, plural, one {# Anhang} other {# Anhänge}}", "reply_indicator.cancel": "Abbrechen", "reply_indicator.poll": "Umfrage", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index ca0f341a80..aedf92cfa3 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -30,6 +30,8 @@ "account.edit_profile": "Redakti la profilon", "account.enable_notifications": "Sciigu min kiam @{name} afiŝos", "account.endorse": "Montri en profilo", + "account.familiar_followers_one": "Sekvita de {name1}", + "account.familiar_followers_two": "Sekvita de {name1} kaj {name2}", "account.featured": "Montrita", "account.featured.accounts": "Profiloj", "account.featured.hashtags": "Kradvortoj", @@ -305,6 +307,7 @@ "emoji_button.search_results": "Serĉaj rezultoj", "emoji_button.symbols": "Simboloj", "emoji_button.travel": "Vojaĝoj kaj lokoj", + "empty_column.account_featured.me": "Vi ankoraŭ nenion prezentis. Ĉu vi sciis, ke vi povas prezenti viajn plej ofte uzatajn kradvortojn, kaj eĉ la kontojn de viaj amikoj sur via profilo?", "empty_column.account_featured_other.unknown": "Ĉi tiu konto ankoraŭ ne montris ion ajn.", "empty_column.account_hides_collections": "Ĉi tiu uzanto elektis ne disponebligi ĉi tiu informon", "empty_column.account_suspended": "Konto suspendita", @@ -338,6 +341,7 @@ "explore.trending_links": "Novaĵoj", "explore.trending_statuses": "Afiŝoj", "explore.trending_tags": "Kradvortoj", + "featured_carousel.header": "{count, plural, one {Alpinglita afiŝo} other {Alpinglitaj afiŝoj}}", "featured_carousel.next": "Antaŭen", "featured_carousel.post": "Afiŝi", "featured_carousel.previous": "Malantaŭen", @@ -751,6 +755,9 @@ "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "hodiaŭ", + "remove_quote_hint.button_label": "Komprenite", + "remove_quote_hint.message": "Vi povas fari tion el la menuo de opcioj {icon}.", + "remove_quote_hint.title": "Ĉu vi volas forigi vian cititan afiŝon?", "reply_indicator.attachments": "{count, plural, one {# aldonaĵo} other {# aldonaĵoj}}", "reply_indicator.cancel": "Nuligi", "reply_indicator.poll": "Balotenketo", @@ -846,6 +853,7 @@ "status.block": "Bloki @{name}", "status.bookmark": "Aldoni al la legosignoj", "status.cancel_reblog_private": "Ne plu diskonigi", + "status.cannot_quote": "Citaĵoj estas malebligitaj en ĉi tiu afiŝo", "status.cannot_reblog": "Ĉi tiun afiŝon ne eblas diskonigi", "status.context.load_new_replies": "Disponeblaj novaj respondoj", "status.context.loading": "Serĉante pliajn respondojn", @@ -971,6 +979,7 @@ "visibility_modal.helper.privacy_editing": "Publikigitaj afiŝoj ne povas ŝanĝi sian videblon.", "visibility_modal.helper.private_quoting": "Afiŝoj nur por sekvantoj verkitaj ĉe Mastodon ne povas esti cititaj de aliaj.", "visibility_modal.helper.unlisted_quoting": "Kiam homoj citas vin, ilia afiŝo ankaŭ estos kaŝita de tendencaj templinioj.", + "visibility_modal.privacy_label": "Videbleco", "visibility_modal.quote_followers": "Nur sekvantoj", "visibility_modal.quote_label": "Kiu povas citi", "visibility_modal.quote_nobody": "Nur mi", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index 7aa7a9b4ee..a51d8092c2 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -768,6 +768,9 @@ "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "hoy", + "remove_quote_hint.button_label": "Entendido", + "remove_quote_hint.message": "Podés hacerlo desde el menú de opciones {icon}.", + "remove_quote_hint.title": "¿Querés eliminar tu mensaje citado?", "reply_indicator.attachments": "{count, plural,one {# adjunto} other {# adjuntos}}", "reply_indicator.cancel": "Cancelar", "reply_indicator.poll": "Encuesta", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index 7f764d0cd3..e6e5ece97e 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -768,6 +768,9 @@ "relative_time.minutes": "{number} m", "relative_time.seconds": "{number} s", "relative_time.today": "hoy", + "remove_quote_hint.button_label": "Entendido", + "remove_quote_hint.message": "Puedes hacerlo desde el menú de opciones {icon}.", + "remove_quote_hint.title": "¿Quieres eliminar tu publicación citada?", "reply_indicator.attachments": "{count, plural, one {# adjunto} other {# adjuntos}}", "reply_indicator.cancel": "Cancelar", "reply_indicator.poll": "Encuesta", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 4f1464e6cc..a46592221a 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -768,6 +768,9 @@ "relative_time.minutes": "{number} m", "relative_time.seconds": "{number} s", "relative_time.today": "hoy", + "remove_quote_hint.button_label": "Entendido", + "remove_quote_hint.message": "Puedes hacerlo desde el menú de opciones {icon}.", + "remove_quote_hint.title": "¿Quieres eliminar tu publicación citada?", "reply_indicator.attachments": "{count, plural, one {# adjunto} other {# adjuntos}}", "reply_indicator.cancel": "Cancelar", "reply_indicator.poll": "Encuesta", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index 7fa3ca5fb2..700f9c4bc8 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -863,6 +863,7 @@ "status.block": "Blokeeri @{name}", "status.bookmark": "Järjehoidja", "status.cancel_reblog_private": "Lõpeta jagamine", + "status.cannot_quote": "Selle postituse tsiteerimine pole lubatud", "status.cannot_reblog": "Seda postitust ei saa jagada", "status.context.load_new_replies": "Leidub uusi vastuseid", "status.context.loading": "Kontrollin täiendavate vastuste olemasolu", @@ -988,9 +989,13 @@ "visibility_modal.header": "Nähtavus ja kasutus", "visibility_modal.helper.direct_quoting": "Ainult mainituile mõeldud Mastodoni postitusi ei saa teiste poolt tsiteerida.", "visibility_modal.helper.privacy_editing": "Avaldatud postitused ei saa muuta oma nähtavust.", + "visibility_modal.helper.privacy_private_self_quote": "Privaatsete postituste tsiteerimist oma enda poolt pole võimalik teha avalikuks.", "visibility_modal.helper.private_quoting": "Ainult jälgijatele mõeldud Mastodoni postitusi ei saa teiste poolt tsiteerida.", "visibility_modal.helper.unlisted_quoting": "Kui teised kasutajad sind tsiteerivad, siis nende postitused peidetakse ajajoonelt, mis näitavad populaarsust koguvaid postitusi.", + "visibility_modal.instructions": "Halda seda, kes võivad antud postitusega suhestuda. Lisaks võid kõikide tulevaste postituste seadistusi muuta valikust Eelistused > Postituse vaikeseadistused.", + "visibility_modal.privacy_label": "Nähtavus", "visibility_modal.quote_followers": "Ainult jälgijad", + "visibility_modal.quote_label": "Kes võivad tsiteerida", "visibility_modal.quote_nobody": "Ainult mina", "visibility_modal.quote_public": "Kõik", "visibility_modal.save": "Salvesta" diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index 22599858fb..b48520ebd3 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -768,6 +768,9 @@ "relative_time.minutes": "{number} min", "relative_time.seconds": "{number} s", "relative_time.today": "tänään", + "remove_quote_hint.button_label": "Selvä", + "remove_quote_hint.message": "Voit tehdä sen {icon}-valikosta.", + "remove_quote_hint.title": "Haluatko poistaa lainatun julkaisusi?", "reply_indicator.attachments": "{count, plural, one {# liite} other {# liitettä}}", "reply_indicator.cancel": "Peruuta", "reply_indicator.poll": "Äänestys", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index 0b8ede0613..4e6bbfacd3 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -768,6 +768,9 @@ "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "hoxe", + "remove_quote_hint.button_label": "Entendido", + "remove_quote_hint.message": "Pódelo facer desde o {icon} menú de opcións.", + "remove_quote_hint.title": "Queres eliminar a publicación citada?", "reply_indicator.attachments": "{count, plural, one {# adxunto} other {# adxuntos}}", "reply_indicator.cancel": "Desbotar", "reply_indicator.poll": "Enquisa", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index ed03d4d757..7418a78784 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -768,6 +768,9 @@ "relative_time.minutes": "{number} דקות", "relative_time.seconds": "{number} שניות", "relative_time.today": "היום", + "remove_quote_hint.button_label": "הבנתי", + "remove_quote_hint.message": "ניתן לעשות זאת מתפריט האפשרויות {icon}", + "remove_quote_hint.title": "להסיר את ההודעה המצוטטת?", "reply_indicator.attachments": "{count, plural,one {# קובץ מצורף}other {# קבצים מצורפים}}", "reply_indicator.cancel": "ביטול", "reply_indicator.poll": "משאל", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index 967006e239..2f583f3334 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -768,6 +768,9 @@ "relative_time.minutes": "{number}mín", "relative_time.seconds": "{number}sek", "relative_time.today": "í dag", + "remove_quote_hint.button_label": "Náði því", + "remove_quote_hint.message": "Þú getur gert það úr {icon} valmyndinni.", + "remove_quote_hint.title": "Viltu fjarlægja tilvitnuðu færsluna þína?", "reply_indicator.attachments": "{count, plural, one {# viðhengi} other {# viðhengi}}", "reply_indicator.cancel": "Hætta við", "reply_indicator.poll": "Könnun", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index d762191b71..55c2b2423d 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -768,6 +768,9 @@ "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "vandaag", + "remove_quote_hint.button_label": "Begrepen", + "remove_quote_hint.message": "Je kunt dit doen vanuit het {icon} optiesmenu.", + "remove_quote_hint.title": "Wil je jouw geciteerd bericht verwijderen?", "reply_indicator.attachments": "{count, plural, one {# bijlage} other {# bijlagen}}", "reply_indicator.cancel": "Annuleren", "reply_indicator.poll": "Peiling", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index 2c5fe289b7..35f2545cdb 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -768,6 +768,9 @@ "relative_time.minutes": "{number} phút", "relative_time.seconds": "{number}s", "relative_time.today": "hôm nay", + "remove_quote_hint.button_label": "Đã hiểu", + "remove_quote_hint.message": "Bạn cũng có thể làm trong menu tùy chọn {icon}", + "remove_quote_hint.title": "Gỡ tút mà bạn đã trích dẫn?", "reply_indicator.attachments": "{count, plural, other {# tập tin đính kèm}}", "reply_indicator.cancel": "Hủy bỏ", "reply_indicator.poll": "Vốt", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index bfb436e049..713147428f 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -768,6 +768,9 @@ "relative_time.minutes": "{number} 分钟前", "relative_time.seconds": "{number} 秒前", "relative_time.today": "今天", + "remove_quote_hint.button_label": "明白了", + "remove_quote_hint.message": "你可以通过 {icon} 选项菜单进行此操作。", + "remove_quote_hint.title": "是否需要删除你的引用嘟文?", "reply_indicator.attachments": "{count, plural, other {# 个附件}}", "reply_indicator.cancel": "取消", "reply_indicator.poll": "投票", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 10481b5e86..ee360d63bf 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -768,6 +768,9 @@ "relative_time.minutes": "{number} 分鐘前", "relative_time.seconds": "{number} 秒", "relative_time.today": "今天", + "remove_quote_hint.button_label": "了解", + "remove_quote_hint.message": "您能自 {icon} 選單完成此操作。", + "remove_quote_hint.title": "是否想要移除您的引用嘟文?", "reply_indicator.attachments": "{count, plural, other {# 個附加檔案}}", "reply_indicator.cancel": "取消", "reply_indicator.poll": "投票", diff --git a/config/locales/br.yml b/config/locales/br.yml index 38794dd75d..75e22a9530 100644 --- a/config/locales/br.yml +++ b/config/locales/br.yml @@ -63,6 +63,7 @@ br: all: Pep tra local: Lec'hel remote: A-bell + title: Lec'hiadur media_attachments: Restroù media stag moderation: active: Oberiant @@ -180,6 +181,7 @@ br: name: Anv registrations: confirm: Kadarnaat + save: Enrollañ status: Statud follow_recommendations: status: Statud @@ -260,6 +262,7 @@ br: title: Disklêriadennoù unresolved: Andiskoulmet updated_at: Nevesaet + view_profile: Gwelet ar profil roles: categories: devops: DevOps @@ -287,6 +290,7 @@ br: danger_zone: Takad dañjer discovery: privacy: Buhez prevez + profile_directory: Kavlec'h ar profiloù title: Dizoloadur trends: Luskadoù domain_blocks: @@ -310,6 +314,10 @@ br: strikes: actions: delete_statuses: Dilamet eo bet toudoù %{target} gant %{name} + tags: + title: Gerioù-klik + terms_of_service: + save_draft: Enrollañ ar brouilhed trends: allow: Aotren approved: Aprouet @@ -324,7 +332,7 @@ br: dashboard: tag_uses_measure: implijoù hollek not_usable: N'haller ket en implijout - title: Hashtagoù diouzh ar c'hiz + title: Gerioù-klik diouzh ar c'hiz warning_presets: add_new: Ouzhpenniñ unan nevez delete: Dilemel @@ -342,7 +350,7 @@ br: none: ur c'hemenn diwall new_trends: new_trending_tags: - title: Hashtagoù diouzh ar c'hiz + title: Gerioù-klik diouzh ar c'hiz appearance: discovery: Dizoloadur localization: @@ -350,6 +358,7 @@ br: guide_link: https://crowdin.com/project/mastodon application_mailer: view: 'Sellet :' + view_profile: Gwelet ar profil view_status: Gwelet ar c'hannad auth: delete_account: Dilemel ar gont @@ -396,6 +405,8 @@ br: created_at: Deiziad title_actions: none: Diwall + edit_profile: + other: All emoji_styles: auto: Emgefreek twemoji: Twemoji @@ -422,6 +433,8 @@ br: other: "%{count} a gannadoù" two: "%{count} gannad" title: Siloù + new: + save: Enrollañ ar sil nevez statuses: index: title: Toudoù silet @@ -547,7 +560,7 @@ br: back: Distreiñ da vMastodon development: Diorren edit_profile: Kemmañ ar profil - featured_tags: Hashtagoù pennañ + featured_tags: Gerioù-klik pennañ import: Enporzhiañ import_and_export: Enporzhiañ hag ezporzhiañ preferences: Gwellvezioù @@ -609,6 +622,9 @@ br: edit_profile_title: Personelaat ho profil feature_action: Gouzout hiroc'h follow_action: Heuliañ + hashtags_title: Gerioù-klik diouzh ar c'hiz + hashtags_view_more: Gwelet muioc'h a c'herioù-klik diouzh ar c'hiz + share_title: Rannit ho kont Mastodon sign_in_action: Kevreañ subject: Donemat e Mastodon title: Degemer mat e bourzh, %{name}! diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 3d590069af..917b401d2e 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -1894,6 +1894,9 @@ cy: self_vote: Nid oes modd i chi bleidleisio yn eich polau eich hun too_few_options: rhaid cael mwy nag un eitem too_many_options: ni all gynnwys mwy na %{max} eitem + vote: Pleidleisio + posting_defaults: + explanation: Bydd y gosodiadau hyn yn cael eu defnyddio fel rhagosodiadau pan fyddwch chi'n creu postiadau newydd, ond gallwch chi eu golygu fesul postiad o fewn y cyfansoddwr. preferences: other: Arall posting_defaults: Rhagosodiadau postio diff --git a/config/locales/simple_form.br.yml b/config/locales/simple_form.br.yml index b415640eb0..c0a2fb38a4 100644 --- a/config/locales/simple_form.br.yml +++ b/config/locales/simple_form.br.yml @@ -2,6 +2,8 @@ br: simple_form: hints: + account: + note: 'Gallout a rit @menegiñ tud all pe #gerioù-klik.' defaults: avatar: WEBP, PNG, GIF pe JPG. Bihanoc'h eget %{size}. A vo izelaet betek %{dimensions}px header: WEBP, PNG, GIF pe JPG. Bihanoc'h eget %{size}. A vo izelaet betek %{dimensions}px @@ -56,7 +58,7 @@ br: username: Anv whole_word: Ger a-bezh featured_tag: - name: Hashtag + name: Ger-klik invite: comment: Evezhiadenn invite_request: @@ -71,8 +73,8 @@ br: hint: Titouroù ouzhpenn text: Reolenn tag: - name: Hashtag - trendable: Aotren an hashtag-mañ da zont war wel dindan tuadurioù + name: Ger-klik + trendable: Aotren ar ger-klik-mañ da zont war wel dindan tuadurioù user: role: Roll time_zone: Gwerzhid eur From 497bfbc48381a2e13be4fc13247973d8e1b53ff3 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 5 Sep 2025 10:14:34 +0200 Subject: [PATCH 12/19] Fix source string for visibility dropdown hint (#36031) --- app/javascript/mastodon/locales/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 6bff9ed594..213b93bca5 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -991,7 +991,7 @@ "visibility_modal.button_title": "Set visibility", "visibility_modal.header": "Visibility and interaction", "visibility_modal.helper.direct_quoting": "Private mentions authored on Mastodon can't be quoted by others.", - "visibility_modal.helper.privacy_editing": "Published posts cannot change their visibility.", + "visibility_modal.helper.privacy_editing": "Visibility can't be changed after a post is published.", "visibility_modal.helper.privacy_private_self_quote": "Self-quotes of private posts cannot be made public.", "visibility_modal.helper.private_quoting": "Follower-only posts authored on Mastodon can't be quoted by others.", "visibility_modal.helper.unlisted_quoting": "When people quote you, their post will also be hidden from trending timelines.", From 279405f2a7ad8f12245d61ef913ae5698f86b9ac Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 5 Sep 2025 10:34:14 +0200 Subject: [PATCH 13/19] Fix incorrect change of `unlisted` source strings (#36033) --- config/locales/en.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index ebbb72fb07..7a9cb9f506 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -367,7 +367,7 @@ en: title: Custom emojis uncategorized: Uncategorized unlist: Unlist - unlisted: Quiet public + unlisted: Unlisted update_failed_msg: Could not update that emoji updated_msg: Emoji successfully updated! upload: Upload @@ -1923,7 +1923,7 @@ en: private_long: Only show to followers public: Public public_long: Anyone on and off Mastodon - unlisted: Unlisted + unlisted: Quiet public unlisted_long: Hidden from Mastodon search results, trending, and public timelines statuses_cleanup: enabled: Automatically delete old posts From 9a2be25199dd74bd72a12ce45012627b4ff26703 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 5 Sep 2025 10:51:49 +0200 Subject: [PATCH 14/19] Fix missing `beforeUnload` confirmation when a quote post is being authored (#36034) --- app/javascript/mastodon/features/ui/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/ui/index.jsx b/app/javascript/mastodon/features/ui/index.jsx index a420279ca4..0583bf99c5 100644 --- a/app/javascript/mastodon/features/ui/index.jsx +++ b/app/javascript/mastodon/features/ui/index.jsx @@ -92,7 +92,7 @@ const messages = defineMessages({ const mapStateToProps = state => ({ layout: state.getIn(['meta', 'layout']), isComposing: state.getIn(['compose', 'is_composing']), - hasComposingContents: state.getIn(['compose', 'text']).trim().length !== 0 || state.getIn(['compose', 'media_attachments']).size > 0 || state.getIn(['compose', 'poll']) !== null, + hasComposingContents: state.getIn(['compose', 'text']).trim().length !== 0 || state.getIn(['compose', 'media_attachments']).size > 0 || state.getIn(['compose', 'poll']) !== null || state.getIn(['compose', 'quoted_status_id']) !== null, canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < state.getIn(['server', 'server', 'configuration', 'statuses', 'max_media_attachments']), firstLaunch: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION, newAccount: !state.getIn(['accounts', me, 'note']) && !state.getIn(['accounts', me, 'bot']) && state.getIn(['accounts', me, 'following_count'], 0) === 0 && state.getIn(['accounts', me, 'statuses_count'], 0) === 0, From de09e33c922ed326e075524b8bb862720f9b1816 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 5 Sep 2025 10:59:16 +0200 Subject: [PATCH 15/19] =?UTF-8?q?Change=20=E2=80=9CBoost=20with=20original?= =?UTF-8?q?=20visibility=E2=80=9D=20to=20=E2=80=9CShare=20again=20with=20y?= =?UTF-8?q?our=20followers=E2=80=9D=20(#36035)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/javascript/mastodon/components/status/reblog_button.tsx | 2 +- .../mastodon/features/picture_in_picture/components/footer.tsx | 2 +- app/javascript/mastodon/locales/en.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/javascript/mastodon/components/status/reblog_button.tsx b/app/javascript/mastodon/components/status/reblog_button.tsx index afc208e032..079ca5d7c8 100644 --- a/app/javascript/mastodon/components/status/reblog_button.tsx +++ b/app/javascript/mastodon/components/status/reblog_button.tsx @@ -69,7 +69,7 @@ const messages = defineMessages({ }, reblog_private: { id: 'status.reblog_private', - defaultMessage: 'Boost with original visibility', + defaultMessage: 'Share again with your followers', }, reblog_cannot: { id: 'status.cannot_reblog', diff --git a/app/javascript/mastodon/features/picture_in_picture/components/footer.tsx b/app/javascript/mastodon/features/picture_in_picture/components/footer.tsx index 919a41cbae..ddcc386ad8 100644 --- a/app/javascript/mastodon/features/picture_in_picture/components/footer.tsx +++ b/app/javascript/mastodon/features/picture_in_picture/components/footer.tsx @@ -33,7 +33,7 @@ const messages = defineMessages({ reblog: { id: 'status.reblog', defaultMessage: 'Boost' }, reblog_private: { id: 'status.reblog_private', - defaultMessage: 'Boost with original visibility', + defaultMessage: 'Share again with your followers', }, cancel_reblog_private: { id: 'status.cancel_reblog_private', diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 213b93bca5..1acbe9089f 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -913,7 +913,7 @@ "status.read_more": "Read more", "status.reblog": "Boost", "status.reblog_or_quote": "Boost or quote", - "status.reblog_private": "Boost with original visibility", + "status.reblog_private": "Share again with your followers", "status.reblogged_by": "{name} boosted", "status.reblogs": "{count, plural, one {boost} other {boosts}}", "status.reblogs.empty": "No one has boosted this post yet. When someone does, they will show up here.", From 350a8028518faf2658a4ddd94cb42cab3dcbb4bc Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 5 Sep 2025 08:29:11 -0400 Subject: [PATCH 16/19] Remove unused `_index` iterator in admin partial (#36018) --- app/views/admin/shared/_status_attachments.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/shared/_status_attachments.html.haml b/app/views/admin/shared/_status_attachments.html.haml index 24af2b5f7d..d34a4221db 100644 --- a/app/views/admin/shared/_status_attachments.html.haml +++ b/app/views/admin/shared/_status_attachments.html.haml @@ -1,7 +1,7 @@ - if status.with_poll? .poll %ul - - status.preloadable_poll.options.each_with_index do |option, _index| + - status.preloadable_poll.options.each do |option| %li %label.poll__option.disabled<> - if status.preloadable_poll.multiple? From 3efba15b3c8f55de132efc6b0653ffd39fde7237 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 5 Sep 2025 08:30:18 -0400 Subject: [PATCH 17/19] Use `pluck` on `DomainAllow.allowed_domains` for export (#36019) --- .../admin/export_domain_allows_controller.rb | 4 +-- app/models/domain_allow.rb | 2 +- .../export_domain_allows_controller_spec.rb | 17 ----------- spec/models/domain_allow_spec.rb | 15 ++++++++++ .../admin/export_domain_allows_spec.rb | 28 +++++++++++++++++-- 5 files changed, 44 insertions(+), 22 deletions(-) diff --git a/app/controllers/admin/export_domain_allows_controller.rb b/app/controllers/admin/export_domain_allows_controller.rb index ca88c6525e..d1a2ea5bbf 100644 --- a/app/controllers/admin/export_domain_allows_controller.rb +++ b/app/controllers/admin/export_domain_allows_controller.rb @@ -49,8 +49,8 @@ module Admin def export_data CSV.generate(headers: export_headers, write_headers: true) do |content| - DomainAllow.allowed_domains.each do |instance| - content << [instance.domain] + DomainAllow.allowed_domains.each do |domain| + content << [domain] end end end diff --git a/app/models/domain_allow.rb b/app/models/domain_allow.rb index 47ada7ac23..8eab3164e5 100644 --- a/app/models/domain_allow.rb +++ b/app/models/domain_allow.rb @@ -27,7 +27,7 @@ class DomainAllow < ApplicationRecord end def allowed_domains - select(:domain) + pluck(:domain) end def rule_for(domain) diff --git a/spec/controllers/admin/export_domain_allows_controller_spec.rb b/spec/controllers/admin/export_domain_allows_controller_spec.rb index dcb1f55a99..7879a5e181 100644 --- a/spec/controllers/admin/export_domain_allows_controller_spec.rb +++ b/spec/controllers/admin/export_domain_allows_controller_spec.rb @@ -17,17 +17,6 @@ RSpec.describe Admin::ExportDomainAllowsController do end end - describe 'GET #export' do - it 'renders instances' do - Fabricate(:domain_allow, domain: 'good.domain') - Fabricate(:domain_allow, domain: 'better.domain') - - get :export, params: { format: :csv } - expect(response).to have_http_status(200) - expect(response.body).to eq(domain_allows_csv_file) - end - end - describe 'POST #import' do it 'allows imported domains' do post :import, params: { admin_import: { data: fixture_file_upload('domain_allows.csv') } } @@ -50,10 +39,4 @@ RSpec.describe Admin::ExportDomainAllowsController do expect(flash[:error]).to eq(I18n.t('admin.export_domain_allows.no_file')) end end - - private - - def domain_allows_csv_file - File.read(File.join(file_fixture_path, 'domain_allows.csv')) - end end diff --git a/spec/models/domain_allow_spec.rb b/spec/models/domain_allow_spec.rb index fbb324657e..0c69aaff8d 100644 --- a/spec/models/domain_allow_spec.rb +++ b/spec/models/domain_allow_spec.rb @@ -12,4 +12,19 @@ RSpec.describe DomainAllow do it { is_expected.to_not allow_value('xn--r9j5b5b').for(:domain) } end end + + describe '.allowed_domains' do + subject { described_class.allowed_domains } + + context 'without domain allows' do + it { is_expected.to be_an(Array).and(be_empty) } + end + + context 'with domain allows' do + let!(:allowed_domain) { Fabricate :domain_allow } + let!(:other_allowed_domain) { Fabricate :domain_allow } + + it { is_expected.to contain_exactly(allowed_domain.domain, other_allowed_domain.domain) } + end + end end diff --git a/spec/requests/admin/export_domain_allows_spec.rb b/spec/requests/admin/export_domain_allows_spec.rb index 761c39984e..dd1a55a022 100644 --- a/spec/requests/admin/export_domain_allows_spec.rb +++ b/spec/requests/admin/export_domain_allows_spec.rb @@ -3,9 +3,9 @@ require 'rails_helper' RSpec.describe 'Admin Export Domain Allows' do - describe 'POST /admin/export_domain_allows/import' do - before { sign_in Fabricate(:admin_user) } + before { sign_in Fabricate(:admin_user) } + describe 'POST /admin/export_domain_allows/import' do it 'gracefully handles invalid nested params' do post import_admin_export_domain_allows_path(admin_import: 'invalid') @@ -13,4 +13,28 @@ RSpec.describe 'Admin Export Domain Allows' do .to redirect_to(admin_instances_path) end end + + describe 'GET /admin/export_domain_allows/export.csv' do + before do + Fabricate(:domain_allow, domain: 'good.domain') + Fabricate(:domain_allow, domain: 'better.domain') + end + + it 'returns CSV response with instance domain values' do + get export_admin_export_domain_allows_path(format: :csv) + + expect(response) + .to have_http_status(200) + expect(response.body) + .to eq(domain_allows_csv_file) + expect(response.media_type) + .to eq('text/csv') + end + end + + private + + def domain_allows_csv_file + File.read(File.join(file_fixture_path, 'domain_allows.csv')) + end end From 05a655f33ebe3f6f591f341561469edd9142561f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 5 Sep 2025 08:44:09 -0400 Subject: [PATCH 18/19] Convert age verification controller to system specs (#36026) --- .../auth/registrations_controller_spec.rb | 36 ------------ spec/requests/api/v1/accounts_spec.rb | 29 ++++++++-- spec/system/auth/registrations_spec.rb | 58 +++++++++++++++++++ 3 files changed, 83 insertions(+), 40 deletions(-) create mode 100644 spec/system/auth/registrations_spec.rb diff --git a/spec/controllers/auth/registrations_controller_spec.rb b/spec/controllers/auth/registrations_controller_spec.rb index a110717166..04c2d5dbbb 100644 --- a/spec/controllers/auth/registrations_controller_spec.rb +++ b/spec/controllers/auth/registrations_controller_spec.rb @@ -342,42 +342,6 @@ RSpec.describe Auth::RegistrationsController do end end - context 'when age verification is enabled' do - subject { post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' }.merge(date_of_birth) } } - - before do - Setting.min_age = 16 - end - - let(:date_of_birth) { {} } - - context 'when date of birth is below age limit' do - let(:date_of_birth) { 13.years.ago.then { |date| { 'date_of_birth(1i)': date.day.to_s, 'date_of_birth(2i)': date.month.to_s, 'date_of_birth(3i)': date.year.to_s } } } - - it 'does not create user' do - subject - user = User.find_by(email: 'test@example.com') - expect(user).to be_nil - end - end - - context 'when date of birth is above age limit' do - let(:date_of_birth) { 17.years.ago.then { |date| { 'date_of_birth(1i)': date.day.to_s, 'date_of_birth(2i)': date.month.to_s, 'date_of_birth(3i)': date.year.to_s } } } - - it 'redirects to setup and creates user' do - subject - - expect(response).to redirect_to auth_setup_path - - expect(User.find_by(email: 'test@example.com')) - .to be_present - .and have_attributes( - age_verified_at: not_eq(nil) - ) - end - end - end - it_behaves_like 'registration mode based responses', :create end diff --git a/spec/requests/api/v1/accounts_spec.rb b/spec/requests/api/v1/accounts_spec.rb index a040174d38..0e64915baf 100644 --- a/spec/requests/api/v1/accounts_spec.rb +++ b/spec/requests/api/v1/accounts_spec.rb @@ -110,9 +110,12 @@ RSpec.describe '/api/v1/accounts' do let(:date_of_birth) { 13.years.ago.strftime('%d.%m.%Y') } it 'returns http unprocessable entity' do - subject + expect { subject } + .to not_change(User, :count) + .and not_change(Account, :count) - expect(response).to have_http_status(422) + expect(response) + .to have_http_status(422) expect(response.content_type) .to start_with('application/json') end @@ -122,9 +125,27 @@ RSpec.describe '/api/v1/accounts' do let(:date_of_birth) { 17.years.ago.strftime('%d.%m.%Y') } it 'creates a user', :aggregate_failures do - subject + expect { subject } + .to change(User, :count).by(1) + .and change(Account, :count).by(1) - expect(response).to have_http_status(200) + expect(response) + .to have_http_status(200) + expect(response.content_type) + .to start_with('application/json') + end + end + + context 'when date of birth is over age limit in ISO-8601 format' do + let(:date_of_birth) { 17.years.ago.to_date.iso8601 } + + it 'creates a user', :aggregate_failures do + expect { subject } + .to change(User, :count).by(1) + .and change(Account, :count).by(1) + + expect(response) + .to have_http_status(200) expect(response.content_type) .to start_with('application/json') end diff --git a/spec/system/auth/registrations_spec.rb b/spec/system/auth/registrations_spec.rb new file mode 100644 index 0000000000..4c08bf47ee --- /dev/null +++ b/spec/system/auth/registrations_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Auth Registration' do + context 'when age verification is enabled' do + before { Setting.min_age = 16 } + + context 'when date of birth is below age limit' do + let(:date_of_birth) { 13.years.ago } + + it 'does not create user record and displays errors' do + visit new_user_registration_path + expect(page) + .to have_title(I18n.t('auth.register')) + + expect { fill_in_and_submit_form } + .to not_change(User, :count) + expect(page) + .to have_content(/error below/) + end + end + + context 'when date of birth is above age limit' do + let(:date_of_birth) { 17.years.ago } + + it 'creates user and marks as verified' do + visit new_user_registration_path + expect(page) + .to have_title(I18n.t('auth.register')) + + expect { fill_in_and_submit_form } + .to change(User, :count).by(1) + expect(User.last) + .to have_attributes(email: 'test@example.com', age_verified_at: be_present) + expect(page) + .to have_content(I18n.t('auth.setup.title')) + end + end + + def fill_in_and_submit_form + # Avoid the registration spam check + travel_to 10.seconds.from_now + + fill_in 'user_account_attributes_username', with: 'test' + fill_in 'user_email', with: 'test@example.com' + fill_in 'user_password', with: 'Test.123.Pass' + fill_in 'user_password_confirmation', with: 'Test.123.Pass' + check 'user_agreement' + + find('input[aria-label="Day"]').fill_in with: date_of_birth.day + find('input[autocomplete="bday-month"]').fill_in with: date_of_birth.month + find('input[autocomplete="bday-year"]').fill_in with: date_of_birth.year + + click_on I18n.t('auth.register') + end + end +end From 1b664cf20dbb696cf16a42efcf59ab186cb211eb Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 5 Sep 2025 08:56:15 -0400 Subject: [PATCH 19/19] Relay reset delivery tracker model spec and callback (#36027) --- app/models/relay.rb | 8 ++++++-- spec/models/relay_spec.rb | 13 +++++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/app/models/relay.rb b/app/models/relay.rb index 813a861c68..8a9524e9b3 100644 --- a/app/models/relay.rb +++ b/app/models/relay.rb @@ -34,7 +34,7 @@ class Relay < ApplicationRecord payload = Oj.dump(follow_activity(activity_id)) update!(state: :pending, follow_activity_id: activity_id) - DeliveryFailureTracker.reset!(inbox_url) + reset_delivery_tracker ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url) end @@ -43,12 +43,16 @@ class Relay < ApplicationRecord payload = Oj.dump(unfollow_activity(activity_id)) update!(state: :idle, follow_activity_id: nil) - DeliveryFailureTracker.reset!(inbox_url) + reset_delivery_tracker ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url) end private + def reset_delivery_tracker + DeliveryFailureTracker.reset!(inbox_url) + end + def follow_activity(activity_id) { '@context': ActivityPub::TagManager::CONTEXT, diff --git a/spec/models/relay_spec.rb b/spec/models/relay_spec.rb index 9c917e2d2e..03758ca6a8 100644 --- a/spec/models/relay_spec.rb +++ b/spec/models/relay_spec.rb @@ -33,7 +33,7 @@ RSpec.describe Relay do describe 'Callbacks' do describe 'Ensure disabled on destroy' do - before { stub_delivery_worker } + before { stub_services } context 'when relay is enabled' do let(:relay) { Fabricate :relay, state: :accepted } @@ -71,7 +71,7 @@ RSpec.describe Relay do describe '#disable' do let(:relay) { Fabricate :relay, state: :accepted, follow_activity_id: 'https://host.example/123' } - before { stub_delivery_worker } + before { stub_services } it 'changes state to idle and removes the activity id' do expect { relay.disable! } @@ -79,13 +79,15 @@ RSpec.describe Relay do .and change { relay.reload.follow_activity_id }.to(be_nil) expect(ActivityPub::DeliveryWorker) .to have_received(:perform_async).with(match('Undo'), Account.representative.id, relay.inbox_url) + expect(DeliveryFailureTracker) + .to have_received(:reset!).with(relay.inbox_url) end end describe '#enable' do let(:relay) { Fabricate :relay, state: :idle, follow_activity_id: '' } - before { stub_delivery_worker } + before { stub_services } it 'changes state to pending and populates the activity id' do expect { relay.enable! } @@ -93,10 +95,13 @@ RSpec.describe Relay do .and change { relay.reload.follow_activity_id }.to(be_present) expect(ActivityPub::DeliveryWorker) .to have_received(:perform_async).with(match('Follow'), Account.representative.id, relay.inbox_url) + expect(DeliveryFailureTracker) + .to have_received(:reset!).with(relay.inbox_url) end end - def stub_delivery_worker + def stub_services allow(ActivityPub::DeliveryWorker).to receive(:perform_async) + allow(DeliveryFailureTracker).to receive(:reset!) end end