From 8e24c4801d27eb31b0c86cd9a6e758edfdbb19b1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Jan 2025 09:27:27 +0100 Subject: [PATCH 01/10] Update dependency opentelemetry-instrumentation-rails to v0.35.1 (#33767) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index fcbe74b9c0..8547e4fba1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -530,7 +530,7 @@ GEM opentelemetry-instrumentation-rack (0.26.0) opentelemetry-api (~> 1.0) opentelemetry-instrumentation-base (~> 0.23.0) - opentelemetry-instrumentation-rails (0.35.0) + opentelemetry-instrumentation-rails (0.35.1) opentelemetry-api (~> 1.0) opentelemetry-instrumentation-action_mailer (~> 0.4.0) opentelemetry-instrumentation-action_pack (~> 0.11.0) From 9c85825ac6f080f21d03fc219249c13c440b79a8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 29 Jan 2025 09:38:53 +0100 Subject: [PATCH 02/10] New Crowdin Translations (automated) (#33766) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/sk.json | 4 ++++ config/locales/nn.yml | 1 + 2 files changed, 5 insertions(+) diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index 2bb214b887..5e7385bdc4 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -86,6 +86,9 @@ "alert.unexpected.message": "Vyskytla sa nečakaná chyba.", "alert.unexpected.title": "Ups!", "alt_text_badge.title": "Alternatívny popis", + "alt_text_modal.add_text_from_image": "Pridaj text z obrázka", + "alt_text_modal.cancel": "Zrušiť", + "alt_text_modal.done": "Hotovo", "announcement.announcement": "Oznámenie", "annual_report.summary.archetype.oracle": "Veštec", "annual_report.summary.followers.followers": "sledovatelia", @@ -378,6 +381,7 @@ "ignore_notifications_modal.not_followers_title": "Nevšímať si oznámenia od ľudí, ktorí ťa nenasledujú?", "ignore_notifications_modal.not_following_title": "Nevšímať si oznámenia od ľudí, ktorých nenasleduješ?", "ignore_notifications_modal.private_mentions_title": "Nevšímať si oznámenia o nevyžiadaných súkromných spomínaniach?", + "info_button.label": "Pomoc", "interaction_modal.action.favourite": "Pre pokračovanie si musíš obľúbiť zo svojho účtu.", "interaction_modal.action.follow": "Pre pokračovanie musíš nasledovať zo svojho účtu.", "interaction_modal.action.reply": "Pre pokračovanie musíš odpovedať s tvojho účtu.", diff --git a/config/locales/nn.yml b/config/locales/nn.yml index 2f652a646c..b7982e93ca 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -1209,6 +1209,7 @@ nn: too_fast: Skjemaet ble sendt inn for raskt, prøv på nytt. use_security_key: Bruk sikkerhetsnøkkel user_agreement_html: Eg godtek bruksvilkåra og personvernvllkåra + user_privacy_agreement_html: Eg har lese og godtar personvernerklæringa author_attribution: example_title: Eksempeltekst hint_html: Skriv du nyhende eller blogginnlegg utanfor Mastodon? Her kan du kontrollera korleis du blir kreditert når artiklane dine blir delte på Mastodon. From bd481204b539348858d30bca845882d9d07f518c Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 29 Jan 2025 09:42:20 +0100 Subject: [PATCH 03/10] Fix missing timeout options in `Request` class (#33769) --- app/lib/request.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/lib/request.rb b/app/lib/request.rb index 4e86cc2fdf..4e0ba77833 100644 --- a/app/lib/request.rb +++ b/app/lib/request.rb @@ -81,8 +81,11 @@ class Request max_hops: 3, on_redirect: ->(response, request) { re_sign_on_redirect(response, request) }, }, + }.merge(options).merge( socket_class: use_proxy? || @allow_local ? ProxySocket : Socket, - }.merge(options) + timeout_class: PerOperationWithDeadline, + timeout_options: TIMEOUT + ) @options = @options.merge(proxy_url) if use_proxy? @headers = {} From 82183d8a79979a738304c73f6808794d6f5d442f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 29 Jan 2025 09:46:04 +0100 Subject: [PATCH 04/10] Add loading indicator to timeline gap indicators in web UI (#33762) --- .../mastodon/components/load_gap.tsx | 14 +++++++++++--- .../styles/mastodon/components.scss | 19 ++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/app/javascript/mastodon/components/load_gap.tsx b/app/javascript/mastodon/components/load_gap.tsx index 544b5e1461..6cbdee6ce5 100644 --- a/app/javascript/mastodon/components/load_gap.tsx +++ b/app/javascript/mastodon/components/load_gap.tsx @@ -1,9 +1,10 @@ -import { useCallback } from 'react'; +import { useCallback, useState } from 'react'; import { useIntl, defineMessages } from 'react-intl'; import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; import { Icon } from 'mastodon/components/icon'; +import { LoadingIndicator } from 'mastodon/components/loading_indicator'; const messages = defineMessages({ load_more: { id: 'status.load_more', defaultMessage: 'Load more' }, @@ -17,10 +18,12 @@ interface Props { export const LoadGap = ({ disabled, param, onClick }: Props) => { const intl = useIntl(); + const [loading, setLoading] = useState(false); const handleClick = useCallback(() => { + setLoading(true); onClick(param); - }, [param, onClick]); + }, [setLoading, param, onClick]); return ( ); }; diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index ed23a88d41..75c38d91f2 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -4028,23 +4028,27 @@ a.status-card { } .load-more { - display: block; + display: flex; + align-items: center; + justify-content: center; color: $dark-text-color; background-color: transparent; border: 0; font-size: inherit; - text-align: center; line-height: inherit; - margin: 0; + width: 100%; padding: 15px; box-sizing: border-box; - width: 100%; - clear: both; text-decoration: none; &:hover { background: var(--on-surface-color); } + + .icon { + width: 22px; + height: 22px; + } } .load-gap { @@ -4421,6 +4425,7 @@ a.status-card { justify-content: center; } +.load-more .loading-indicator, .button .loading-indicator { position: static; transform: none; @@ -4432,6 +4437,10 @@ a.status-card { } } +.load-more .loading-indicator .circular-progress { + color: lighten($ui-base-color, 26%); +} + .circular-progress { color: lighten($ui-base-color, 26%); animation: 1.4s linear 0s infinite normal none running simple-rotate; From 85668becdee8eb91bd999a5a58d01979c532e1c0 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 29 Jan 2025 10:26:06 +0100 Subject: [PATCH 05/10] Change language detection debouncing behavior to refresh at least once every 1.5 seconds (#33770) --- .../mastodon/features/compose/util/language_detection.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/compose/util/language_detection.js b/app/javascript/mastodon/features/compose/util/language_detection.js index b3be07d516..ed22a2bd9c 100644 --- a/app/javascript/mastodon/features/compose/util/language_detection.js +++ b/app/javascript/mastodon/features/compose/util/language_detection.js @@ -73,4 +73,4 @@ const guessLanguage = (text) => { export const debouncedGuess = debounce((text, setGuess) => { setGuess(guessLanguage(text)); -}, 500, { leading: true, trailing: true }); \ No newline at end of file +}, 500, { maxWait: 1500, leading: true, trailing: true }); From 51bbca7723806d55f9013a50b3f9b007feba573a Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 29 Jan 2025 11:15:32 +0100 Subject: [PATCH 06/10] =?UTF-8?q?Fix=20=E2=80=9Cx=E2=80=9D=20hotkey=20not?= =?UTF-8?q?=20working=20on=20boosted=20filtered=20posts=20(#33758)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/javascript/mastodon/components/status.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/components/status.jsx b/app/javascript/mastodon/components/status.jsx index fb1fcb87fe..f44b0f0535 100644 --- a/app/javascript/mastodon/components/status.jsx +++ b/app/javascript/mastodon/components/status.jsx @@ -333,7 +333,7 @@ class Status extends ImmutablePureComponent { const { onToggleHidden } = this.props; const status = this._properStatus(); - if (status.get('matched_filters')) { + if (this.props.status.get('matched_filters')) { const expandedBecauseOfCW = !status.get('hidden') || status.get('spoiler_text').length === 0; const expandedBecauseOfFilter = this.state.showDespiteFilter; From 6aa565b3191b9f0181206e72b0881232aa40cbf9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 29 Jan 2025 11:36:24 +0100 Subject: [PATCH 07/10] Fix missing button styles on some forms (#33771) --- app/views/admin/invites/_invite.html.haml | 2 +- app/views/invites/_invite.html.haml | 2 +- app/views/mail_subscriptions/show.html.haml | 3 ++- app/views/oauth/authorizations/new.html.haml | 5 +++-- app/views/oauth/authorizations/show.html.haml | 2 +- app/views/settings/verifications/show.html.haml | 4 ++-- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/app/views/admin/invites/_invite.html.haml b/app/views/admin/invites/_invite.html.haml index e3e5d32542..fcaf5fc616 100644 --- a/app/views/admin/invites/_invite.html.haml +++ b/app/views/admin/invites/_invite.html.haml @@ -3,7 +3,7 @@ .input-copy .input-copy__wrapper = copyable_input value: public_invite_url(invite_code: invite.code) - %button{ type: :button }= t('generic.copy') + %button.button{ type: :button }= t('generic.copy') %td .name-tag diff --git a/app/views/invites/_invite.html.haml b/app/views/invites/_invite.html.haml index 7c94062de4..88479c4cad 100644 --- a/app/views/invites/_invite.html.haml +++ b/app/views/invites/_invite.html.haml @@ -3,7 +3,7 @@ .input-copy .input-copy__wrapper = copyable_input value: public_invite_url(invite_code: invite.code) - %button{ type: :button }= t('generic.copy') + %button.button{ type: :button }= t('generic.copy') - if invite.valid_for_use? %td diff --git a/app/views/mail_subscriptions/show.html.haml b/app/views/mail_subscriptions/show.html.haml index a09dacc4d3..78de486457 100644 --- a/app/views/mail_subscriptions/show.html.haml +++ b/app/views/mail_subscriptions/show.html.haml @@ -16,4 +16,5 @@ = form.hidden_field :type, value: params[:type] = form.button t('mail_subscriptions.unsubscribe.action'), - type: :submit + type: :submit, + class: 'btn' diff --git a/app/views/oauth/authorizations/new.html.haml b/app/views/oauth/authorizations/new.html.haml index ca9d12a676..17228d3cae 100644 --- a/app/views/oauth/authorizations/new.html.haml +++ b/app/views/oauth/authorizations/new.html.haml @@ -35,7 +35,8 @@ = form.hidden_field :scope, value: @pre_auth.scope = form.button t('doorkeeper.authorizations.buttons.authorize'), - type: :submit + type: :submit, + class: 'btn' = form_with url: oauth_authorization_path, method: :delete do |form| = form.hidden_field :client_id, @@ -52,4 +53,4 @@ value: @pre_auth.scope = form.button t('doorkeeper.authorizations.buttons.deny'), type: :submit, - class: 'negative' + class: 'btn negative' diff --git a/app/views/oauth/authorizations/show.html.haml b/app/views/oauth/authorizations/show.html.haml index bdff336368..f014a1052f 100644 --- a/app/views/oauth/authorizations/show.html.haml +++ b/app/views/oauth/authorizations/show.html.haml @@ -4,4 +4,4 @@ .input-copy .input-copy__wrapper = copyable_input value: params[:code], class: 'oauth-code' - %button{ type: :button }= t('generic.copy') + %button.button{ type: :button }= t('generic.copy') diff --git a/app/views/settings/verifications/show.html.haml b/app/views/settings/verifications/show.html.haml index c569843793..0243e3b806 100644 --- a/app/views/settings/verifications/show.html.haml +++ b/app/views/settings/verifications/show.html.haml @@ -17,7 +17,7 @@ .input-copy.lead .input-copy__wrapper = copyable_input value: link_to('Mastodon', ActivityPub::TagManager.instance.url_for(@account), rel: :me) - %button{ type: :button }= t('generic.copy') + %button.button{ type: :button }= t('generic.copy') %p.lead= t('verification.extra_instructions_html') @@ -60,7 +60,7 @@ .input-copy.lead .input-copy__wrapper = copyable_input value: tag.meta(name: 'fediverse:creator', content: "@#{@account.local_username_and_domain}") - %button{ type: :button }= t('generic.copy') + %button.button{ type: :button }= t('generic.copy') %p.lead= t('author_attribution.then_instructions') From 2beab34ca405a0beb3ea9f5ab684779dc2eb6374 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 29 Jan 2025 05:54:20 -0500 Subject: [PATCH 08/10] Convert `admin/email_domain_blocks` controller -> system spec (#33759) --- .../email_domain_blocks_controller_spec.rb | 68 ------------------- spec/support/domain_helpers.rb | 19 ++++++ spec/system/admin/email_domain_blocks_spec.rb | 37 ++++++++++ 3 files changed, 56 insertions(+), 68 deletions(-) delete mode 100644 spec/controllers/admin/email_domain_blocks_controller_spec.rb diff --git a/spec/controllers/admin/email_domain_blocks_controller_spec.rb b/spec/controllers/admin/email_domain_blocks_controller_spec.rb deleted file mode 100644 index f274c01281..0000000000 --- a/spec/controllers/admin/email_domain_blocks_controller_spec.rb +++ /dev/null @@ -1,68 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Admin::EmailDomainBlocksController do - render_views - - before do - sign_in Fabricate(:admin_user), scope: :user - end - - describe 'GET #index' do - around do |example| - default_per_page = EmailDomainBlock.default_per_page - EmailDomainBlock.paginates_per 2 - example.run - EmailDomainBlock.paginates_per default_per_page - end - - it 'returns http success' do - 2.times { Fabricate(:email_domain_block) } - Fabricate(:email_domain_block, allow_with_approval: true) - get :index, params: { page: 2 } - expect(response).to have_http_status(200) - end - end - - describe 'GET #new' do - it 'returns http success' do - get :new - expect(response).to have_http_status(200) - end - end - - describe 'POST #create' do - context 'when resolve button is pressed' do - before do - resolver = instance_double(Resolv::DNS) - - allow(resolver).to receive(:getresources) - .with('example.com', Resolv::DNS::Resource::IN::MX) - .and_return([]) - allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([]) - allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([]) - allow(resolver).to receive(:timeouts=).and_return(nil) - allow(Resolv::DNS).to receive(:open).and_yield(resolver) - - post :create, params: { email_domain_block: { domain: 'example.com' } } - end - - it 'renders new template' do - expect(response).to render_template(:new) - end - end - - context 'when save button is pressed' do - before do - post :create, params: { email_domain_block: { domain: 'example.com' }, save: '' } - end - - it 'blocks the domain and redirects to email domain blocks' do - expect(EmailDomainBlock.find_by(domain: 'example.com')).to_not be_nil - - expect(response).to redirect_to(admin_email_domain_blocks_path) - end - end - end -end diff --git a/spec/support/domain_helpers.rb b/spec/support/domain_helpers.rb index 9977702099..051cdaa7d2 100644 --- a/spec/support/domain_helpers.rb +++ b/spec/support/domain_helpers.rb @@ -28,6 +28,25 @@ module DomainHelpers .and_yield(resolver) end + def configure_dns(domain:, results:) + resolver = instance_double(Resolv::DNS, :timeouts= => nil) + + allow(resolver).to receive(:getresources) + .with(domain, Resolv::DNS::Resource::IN::MX) + .and_return(results) + allow(resolver) + .to receive(:getresources) + .with(domain, Resolv::DNS::Resource::IN::A) + .and_return(results) + allow(resolver) + .to receive(:getresources) + .with(domain, Resolv::DNS::Resource::IN::AAAA) + .and_return(results) + allow(Resolv::DNS) + .to receive(:open) + .and_yield(resolver) + end + private def double_mx(exchange) diff --git a/spec/system/admin/email_domain_blocks_spec.rb b/spec/system/admin/email_domain_blocks_spec.rb index 807cfb3768..e88811ac49 100644 --- a/spec/system/admin/email_domain_blocks_spec.rb +++ b/spec/system/admin/email_domain_blocks_spec.rb @@ -7,6 +7,43 @@ RSpec.describe 'Admin::EmailDomainBlocks' do before { sign_in current_user } + describe 'Managing email domain blocks' do + before { configure_dns(domain: 'example.com', results: []) } + + let!(:email_domain_block) { Fabricate :email_domain_block } + + it 'views and creates new blocks' do + visit admin_email_domain_blocks_path + expect(page) + .to have_content(I18n.t('admin.email_domain_blocks.title')) + .and have_content(email_domain_block.domain) + + click_on I18n.t('admin.email_domain_blocks.add_new') + expect(page) + .to have_content(I18n.t('admin.email_domain_blocks.new.title')) + + fill_in I18n.t('admin.email_domain_blocks.domain'), with: 'example.com' + expect { submit_resolve } + .to_not change(EmailDomainBlock, :count) + expect(page) + .to have_content(I18n.t('admin.email_domain_blocks.new.title')) + + expect { submit_create } + .to change(EmailDomainBlock.where(domain: 'example.com'), :count).by(1) + expect(page) + .to have_content(I18n.t('admin.email_domain_blocks.title')) + .and have_content(I18n.t('admin.email_domain_blocks.created_msg')) + end + + def submit_resolve + click_on I18n.t('admin.email_domain_blocks.new.resolve') + end + + def submit_create + click_on I18n.t('admin.email_domain_blocks.new.create') + end + end + describe 'Performing batch updates' do before do visit admin_email_domain_blocks_path From 2c97a5914857558c037924dfd511afdee65a6b76 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 29 Jan 2025 09:46:04 +0100 Subject: [PATCH 09/10] [Glitch] Add loading indicator to timeline gap indicators in web UI Port 82183d8a79979a738304c73f6808794d6f5d442f to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/components/load_gap.tsx | 14 +++++++++++--- .../flavours/glitch/styles/components.scss | 19 ++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/app/javascript/flavours/glitch/components/load_gap.tsx b/app/javascript/flavours/glitch/components/load_gap.tsx index 1870185c29..6237056488 100644 --- a/app/javascript/flavours/glitch/components/load_gap.tsx +++ b/app/javascript/flavours/glitch/components/load_gap.tsx @@ -1,9 +1,10 @@ -import { useCallback } from 'react'; +import { useCallback, useState } from 'react'; import { useIntl, defineMessages } from 'react-intl'; import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; import { Icon } from 'flavours/glitch/components/icon'; +import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator'; const messages = defineMessages({ load_more: { id: 'status.load_more', defaultMessage: 'Load more' }, @@ -17,10 +18,12 @@ interface Props { export const LoadGap = ({ disabled, param, onClick }: Props) => { const intl = useIntl(); + const [loading, setLoading] = useState(false); const handleClick = useCallback(() => { + setLoading(true); onClick(param); - }, [param, onClick]); + }, [setLoading, param, onClick]); return ( ); }; diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss index 52f4490d76..9778d87dd8 100644 --- a/app/javascript/flavours/glitch/styles/components.scss +++ b/app/javascript/flavours/glitch/styles/components.scss @@ -4105,23 +4105,27 @@ a.status-card { } .load-more { - display: block; + display: flex; + align-items: center; + justify-content: center; color: $dark-text-color; background-color: transparent; border: 0; font-size: inherit; - text-align: center; line-height: inherit; - margin: 0; + width: 100%; padding: 15px; box-sizing: border-box; - width: 100%; - clear: both; text-decoration: none; &:hover { background: var(--on-surface-color); } + + .icon { + width: 22px; + height: 22px; + } } .load-gap { @@ -4643,6 +4647,7 @@ a.status-card { justify-content: center; } +.load-more .loading-indicator, .button .loading-indicator { position: static; transform: none; @@ -4654,6 +4659,10 @@ a.status-card { } } +.load-more .loading-indicator .circular-progress { + color: lighten($ui-base-color, 26%); +} + .circular-progress { color: lighten($ui-base-color, 26%); animation: 1.4s linear 0s infinite normal none running simple-rotate; From 73f599a99ef5609974b48ea03bebabbca22acf0f Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 29 Jan 2025 10:26:06 +0100 Subject: [PATCH 10/10] [Glitch] Change language detection debouncing behavior to refresh at least once every 1.5 seconds Port 85668becdee8eb91bd999a5a58d01979c532e1c0 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/features/compose/util/language_detection.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/features/compose/util/language_detection.js b/app/javascript/flavours/glitch/features/compose/util/language_detection.js index b3be07d516..ed22a2bd9c 100644 --- a/app/javascript/flavours/glitch/features/compose/util/language_detection.js +++ b/app/javascript/flavours/glitch/features/compose/util/language_detection.js @@ -73,4 +73,4 @@ const guessLanguage = (text) => { export const debouncedGuess = debounce((text, setGuess) => { setGuess(guessLanguage(text)); -}, 500, { leading: true, trailing: true }); \ No newline at end of file +}, 500, { maxWait: 1500, leading: true, trailing: true });