From d02aa274be0b003e096cbd2c2d2427aafcfac88a Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Fri, 14 Apr 2023 05:01:23 -0400 Subject: [PATCH 1/4] typo: collapsable -> collapsible (#24521) --- app/javascript/mastodon/components/status.jsx | 2 +- app/javascript/mastodon/components/status_content.jsx | 6 +++--- .../features/direct_timeline/components/conversation.jsx | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/javascript/mastodon/components/status.jsx b/app/javascript/mastodon/components/status.jsx index 923dc892df..60a77a39c3 100644 --- a/app/javascript/mastodon/components/status.jsx +++ b/app/javascript/mastodon/components/status.jsx @@ -541,7 +541,7 @@ class Status extends ImmutablePureComponent { expanded={!status.get('hidden')} onExpandedToggle={this.handleExpandedToggle} onTranslate={this.handleTranslate} - collapsable + collapsible onCollapsedToggle={this.handleCollapsedToggle} /> diff --git a/app/javascript/mastodon/components/status_content.jsx b/app/javascript/mastodon/components/status_content.jsx index fb953b9dd8..60f820bc52 100644 --- a/app/javascript/mastodon/components/status_content.jsx +++ b/app/javascript/mastodon/components/status_content.jsx @@ -65,7 +65,7 @@ class StatusContent extends React.PureComponent { onExpandedToggle: PropTypes.func, onTranslate: PropTypes.func, onClick: PropTypes.func, - collapsable: PropTypes.bool, + collapsible: PropTypes.bool, onCollapsedToggle: PropTypes.func, languages: ImmutablePropTypes.map, intl: PropTypes.object, @@ -112,10 +112,10 @@ class StatusContent extends React.PureComponent { } if (status.get('collapsed', null) === null && onCollapsedToggle) { - const { collapsable, onClick } = this.props; + const { collapsible, onClick } = this.props; const collapsed = - collapsable + collapsible && onClick && node.clientHeight > MAX_HEIGHT && status.get('spoiler_text').length === 0; diff --git a/app/javascript/mastodon/features/direct_timeline/components/conversation.jsx b/app/javascript/mastodon/features/direct_timeline/components/conversation.jsx index d0dbffe659..11f2790bff 100644 --- a/app/javascript/mastodon/features/direct_timeline/components/conversation.jsx +++ b/app/javascript/mastodon/features/direct_timeline/components/conversation.jsx @@ -165,7 +165,7 @@ class Conversation extends ImmutablePureComponent { onClick={this.handleClick} expanded={!lastStatus.get('hidden')} onExpandedToggle={this.handleShowMore} - collapsable + collapsible /> {lastStatus.get('media_attachments').size > 0 && ( From b0800d602e69892f93d72880a642c9b5274aa84b Mon Sep 17 00:00:00 2001 From: Daniel M Brasil Date: Fri, 14 Apr 2023 09:41:15 -0300 Subject: [PATCH 2/4] tootctl: add --approve option to tootctl accounts create (#24533) --- lib/mastodon/accounts_cli.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/mastodon/accounts_cli.rb b/lib/mastodon/accounts_cli.rb index a6532541e0..1601a6cd37 100644 --- a/lib/mastodon/accounts_cli.rb +++ b/lib/mastodon/accounts_cli.rb @@ -57,6 +57,7 @@ module Mastodon option :role option :reattach, type: :boolean option :force, type: :boolean + option :approve, type: :boolean desc 'create USERNAME', 'Create a new user account' long_desc <<-LONG_DESC Create a new user account with a given USERNAME and an @@ -72,6 +73,8 @@ module Mastodon account is still in use by someone else, you can supply the --force option to delete the old record and reattach the username to the new account anyway. + + With the --approve option, the account will be approved. LONG_DESC def create(username) role_id = nil @@ -89,7 +92,7 @@ module Mastodon account = Account.new(username: username) password = SecureRandom.hex - user = User.new(email: options[:email], password: password, agreement: true, approved: true, role_id: role_id, confirmed_at: options[:confirmed] ? Time.now.utc : nil, bypass_invite_request_check: true) + user = User.new(email: options[:email], password: password, agreement: true, role_id: role_id, confirmed_at: options[:confirmed] ? Time.now.utc : nil, bypass_invite_request_check: true) if options[:reattach] account = Account.find_local(username) || Account.new(username: username) @@ -112,6 +115,8 @@ module Mastodon user.confirm! end + user.approve! if options[:approve] + say('OK', :green) say("New password: #{password}") else From 10f0de42129d17fd28fc6ff92b77d49156b0185b Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 14 Apr 2023 08:42:10 -0400 Subject: [PATCH 3/4] Refactor race condition reblog service spec (#24526) --- spec/services/reblog_service_spec.rb | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/spec/services/reblog_service_spec.rb b/spec/services/reblog_service_spec.rb index fdf5ec923c..2ad6d30f6b 100644 --- a/spec/services/reblog_service_spec.rb +++ b/spec/services/reblog_service_spec.rb @@ -35,13 +35,25 @@ RSpec.describe ReblogService, type: :service do end context 'when the reblogged status is discarded in the meantime' do - let(:status) { Fabricate(:status, account: alice, visibility: :public) } + let(:status) { Fabricate(:status, account: alice, visibility: :public, text: 'discard-status-text') } + # Add a callback to discard the status being reblogged after the + # validations pass but before the database commit is executed. before do - # Update the in-database attribute without reflecting the change in - # the object. This cannot simulate all race conditions, but it is - # pretty close. - Status.where(id: status.id).update_all(deleted_at: Time.now.utc) # rubocop:disable Rails/SkipsModelValidations + Status.class_eval do + before_save :discard_status + def discard_status + Status + .where(id: reblog_of_id) + .where(text: 'discard-status-text') + .update_all(deleted_at: Time.now.utc) # rubocop:disable Rails/SkipsModelValidations + end + end + end + + # Remove race condition simulating `discard_status` callback. + after do + Status._save_callbacks.delete(:discard_status) end it 'raises an exception' do From f05fb51ecb34fd5ef86fad861e16cfc959fe0b27 Mon Sep 17 00:00:00 2001 From: Ivan Rodriguez <104603218+IRod22@users.noreply.github.com> Date: Fri, 14 Apr 2023 10:29:09 -0500 Subject: [PATCH 4/4] Fix status title for statuses without text (#24359) --- app/javascript/mastodon/features/status/index.jsx | 10 ++++++---- app/javascript/mastodon/locales/defaultMessages.json | 4 ++++ app/javascript/mastodon/locales/en.json | 1 + app/javascript/mastodon/locales/es-MX.json | 1 + 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/javascript/mastodon/features/status/index.jsx b/app/javascript/mastodon/features/status/index.jsx index b547741f78..900b19c315 100644 --- a/app/javascript/mastodon/features/status/index.jsx +++ b/app/javascript/mastodon/features/status/index.jsx @@ -69,6 +69,7 @@ const messages = defineMessages({ redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.' }, revealAll: { id: 'status.show_more_all', defaultMessage: 'Show more for all' }, hideAll: { id: 'status.show_less_all', defaultMessage: 'Show less for all' }, + statusTitleWithAttachments: { id: 'status.title.with_attachments', defaultMessage: '{user} posted {attachmentCount, plural, one {an attachment} other {{attachmentCount} attachments}}' }, detailedStatus: { id: 'status.detailed_status', defaultMessage: 'Detailed conversation view' }, replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' }, replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' }, @@ -166,13 +167,14 @@ const truncate = (str, num) => { } }; -const titleFromStatus = status => { +const titleFromStatus = (intl, status) => { const displayName = status.getIn(['account', 'display_name']); const username = status.getIn(['account', 'username']); - const prefix = displayName.trim().length === 0 ? username : displayName; + const user = displayName.trim().length === 0 ? username : displayName; const text = status.get('search_index'); + const attachmentCount = status.get('media_attachments').size; - return `${prefix}: "${truncate(text, 30)}"`; + return text ? `${user}: "${truncate(text, 30)}"` : intl.formatMessage(messages.statusTitleWithAttachments, { user, attachmentCount }); }; class Status extends ImmutablePureComponent { @@ -670,7 +672,7 @@ class Status extends ImmutablePureComponent { - {titleFromStatus(status)} + {titleFromStatus(intl, status)} diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index 1351945eb8..4f06d585ab 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -3732,6 +3732,10 @@ "defaultMessage": "Show less for all", "id": "status.show_less_all" }, + { + "defaultMessage": "{user} posted {attachmentCount, plural, one {an attachment} other {{attachmentCount} attachments}}", + "id": "status.title.with_attachments" + }, { "defaultMessage": "Detailed conversation view", "id": "status.detailed_status" diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index ae2d5a9996..e29ec24408 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -598,6 +598,7 @@ "status.show_more": "Show more", "status.show_more_all": "Show more for all", "status.show_original": "Show original", + "status.title.with_attachments": "{user} posted {attachmentCount, plural, one {an attachment} other {{attachmentCount} attachments}}", "status.translate": "Translate", "status.translated_from_with": "Translated from {lang} using {provider}", "status.uncached_media_warning": "Not available", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index 0085563d27..8869768237 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -597,6 +597,7 @@ "status.show_more": "Mostrar más", "status.show_more_all": "Mostrar más para todo", "status.show_original": "Mostrar original", + "status.title.with_attachments": "{user} publicó {attachmentCount, plural, one {un archivo adjunto} other {{attachmentCount} archivos adjuntos}}", "status.translate": "Traducir", "status.translated_from_with": "Traducido del {lang} usando {provider}", "status.uncached_media_warning": "No disponible",