From 183fc9d3cbc891be17a1c4be8b262250f9dbb545 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2019 01:31:27 +0900 Subject: Bump react-select from 2.4.4 to 3.0.5 (#11930) * Bump react-select from 2.4.4 to 3.0.5 Bumps [react-select](https://github.com/JedWatson/react-select) from 2.4.4 to 3.0.5. - [Release notes](https://github.com/JedWatson/react-select/releases) - [Changelog](https://github.com/JedWatson/react-select/blob/master/.sweet-changelogs.js) - [Commits](https://github.com/JedWatson/react-select/commits) Signed-off-by: dependabot-preview[bot] * Change import path for react-select --- .../mastodon/features/hashtag_timeline/components/column_settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js index cdc138c8b..9c39b158a 100644 --- a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js +++ b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import Toggle from 'react-toggle'; -import AsyncSelect from 'react-select/lib/Async'; +import AsyncSelect from 'react-select/async'; const messages = defineMessages({ placeholder: { id: 'hashtag.column_settings.select.placeholder', defaultMessage: 'Enter hashtags…' }, -- cgit From fccf83e1f2ecd4e23f7b1faee5330976d17da7b8 Mon Sep 17 00:00:00 2001 From: BSKY Date: Fri, 25 Oct 2019 05:44:42 +0900 Subject: Add noopener and/or noreferrer (#12202) --- app/javascript/mastodon/components/attachment_list.js | 4 ++-- app/javascript/mastodon/components/dropdown_menu.js | 2 +- app/javascript/mastodon/components/error_boundary.js | 2 +- app/javascript/mastodon/components/media_gallery.js | 3 ++- app/javascript/mastodon/components/status.js | 4 ++-- app/javascript/mastodon/components/status_content.js | 2 +- .../mastodon/features/account/components/header.js | 6 +++--- .../features/account_gallery/components/media_item.js | 14 +++++++------- app/javascript/mastodon/features/status/components/card.js | 6 +++--- .../mastodon/features/status/components/detailed_status.js | 4 ++-- .../mastodon/features/ui/components/actions_modal.js | 4 ++-- .../mastodon/features/ui/components/boost_modal.js | 2 +- .../mastodon/features/ui/components/link_footer.js | 2 +- app/lib/formatter.rb | 2 +- app/lib/sanitize_config.rb | 2 +- app/views/about/show.html.haml | 2 +- app/views/accounts/_moved.html.haml | 2 +- app/views/admin/reports/_status.html.haml | 2 +- app/views/admin/tags/show.html.haml | 2 +- app/views/application/_card.html.haml | 2 +- app/views/oauth/authorized_applications/index.html.haml | 2 +- app/views/statuses/_detailed_status.html.haml | 4 ++-- app/views/statuses/_simple_status.html.haml | 4 ++-- spec/fixtures/xml/mastodon.atom | 4 ++-- spec/lib/sanitize_config_spec.rb | 2 +- spec/services/fetch_link_card_service_spec.rb | 2 +- spec/services/verify_link_service_spec.rb | 4 ++-- 27 files changed, 46 insertions(+), 45 deletions(-) (limited to 'app') diff --git a/app/javascript/mastodon/components/attachment_list.js b/app/javascript/mastodon/components/attachment_list.js index 5dfa1464c..ebd696583 100644 --- a/app/javascript/mastodon/components/attachment_list.js +++ b/app/javascript/mastodon/components/attachment_list.js @@ -25,7 +25,7 @@ export default class AttachmentList extends ImmutablePureComponent { return (
  • - {filename(displayUrl)} + {filename(displayUrl)}
  • ); })} @@ -46,7 +46,7 @@ export default class AttachmentList extends ImmutablePureComponent { return (
  • - {filename(displayUrl)} + {filename(displayUrl)}
  • ); })} diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js index d423378c1..a4f262285 100644 --- a/app/javascript/mastodon/components/dropdown_menu.js +++ b/app/javascript/mastodon/components/dropdown_menu.js @@ -143,7 +143,7 @@ class DropdownMenu extends React.PureComponent { return (
  • - + {text}
  • diff --git a/app/javascript/mastodon/components/error_boundary.js b/app/javascript/mastodon/components/error_boundary.js index 82543e118..800b1c270 100644 --- a/app/javascript/mastodon/components/error_boundary.js +++ b/app/javascript/mastodon/components/error_boundary.js @@ -58,7 +58,7 @@ export default class ErrorBoundary extends React.PureComponent {

    -

    Mastodon v{version} · ·

    +

    Mastodon v{version} · ·

    ); diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js index e8dd79af9..b8fca8bcb 100644 --- a/app/javascript/mastodon/components/media_gallery.js +++ b/app/javascript/mastodon/components/media_gallery.js @@ -159,7 +159,7 @@ class Item extends React.PureComponent { if (attachment.get('type') === 'unknown') { return (
    - +
    @@ -187,6 +187,7 @@ class Item extends React.PureComponent { href={attachment.get('remote_url') || originalUrl} onClick={this.handleClick} target='_blank' + rel='noopener noreferrer' >
    - + - +
    {statusAvatar}
    diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js index 4ce9ec49f..d13091325 100644 --- a/app/javascript/mastodon/components/status_content.js +++ b/app/javascript/mastodon/components/status_content.js @@ -59,7 +59,7 @@ export default class StatusContent extends React.PureComponent { } link.setAttribute('target', '_blank'); - link.setAttribute('rel', 'noopener'); + link.setAttribute('rel', 'noopener noreferrer'); } if ( diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js index ac97bad71..dbb567e85 100644 --- a/app/javascript/mastodon/features/account/components/header.js +++ b/app/javascript/mastodon/features/account/components/header.js @@ -253,7 +253,7 @@ class Header extends ImmutablePureComponent {
    - + @@ -282,10 +282,10 @@ class Header extends ImmutablePureComponent {
    - + - +
    ))} diff --git a/app/javascript/mastodon/features/account_gallery/components/media_item.js b/app/javascript/mastodon/features/account_gallery/components/media_item.js index b6eec2243..617a45d16 100644 --- a/app/javascript/mastodon/features/account_gallery/components/media_item.js +++ b/app/javascript/mastodon/features/account_gallery/components/media_item.js @@ -1,12 +1,12 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; +import { decode } from 'blurhash'; +import classNames from 'classnames'; import Icon from 'mastodon/components/icon'; import { autoPlayGif, displayMedia } from 'mastodon/initial_state'; -import classNames from 'classnames'; -import { decode } from 'blurhash'; import { isIOS } from 'mastodon/is_mobile'; +import PropTypes from 'prop-types'; +import React from 'react'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import ImmutablePureComponent from 'react-immutable-pure-component'; export default class MediaItem extends ImmutablePureComponent { @@ -151,7 +151,7 @@ export default class MediaItem extends ImmutablePureComponent { return (
    - + {visible && thumbnail} {!visible && icon} diff --git a/app/javascript/mastodon/features/status/components/card.js b/app/javascript/mastodon/features/status/components/card.js index 0eff54411..2993fe29a 100644 --- a/app/javascript/mastodon/features/status/components/card.js +++ b/app/javascript/mastodon/features/status/components/card.js @@ -148,7 +148,7 @@ export default class Card extends React.PureComponent { const horizontal = (!compact && card.get('width') > card.get('height') && (card.get('width') + 100 >= width)) || card.get('type') !== 'link' || embedded; const interactive = card.get('type') !== 'link'; const className = classnames('status-card', { horizontal, compact, interactive }); - const title = interactive ? {card.get('title')} : {card.get('title')}; + const title = interactive ? {card.get('title')} : {card.get('title')}; const ratio = card.get('width') / card.get('height'); const height = (compact && !embedded) ? (width / (16 / 9)) : (width / ratio); @@ -180,7 +180,7 @@ export default class Card extends React.PureComponent {
    - {horizontal && } + {horizontal && }
    @@ -208,7 +208,7 @@ export default class Card extends React.PureComponent { } return ( - + {embed} {description} diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js index e97f18f08..d5bc82735 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.js +++ b/app/javascript/mastodon/features/status/components/detailed_status.js @@ -156,7 +156,7 @@ export default class DetailedStatus extends ImmutablePureComponent { } if (status.get('application')) { - applicationLink = · {status.getIn(['application', 'name'])}; + applicationLink = · {status.getIn(['application', 'name'])}; } if (status.get('visibility') === 'direct') { @@ -220,7 +220,7 @@ export default class DetailedStatus extends ImmutablePureComponent { {media}
    - + {applicationLink} · {reblogLink} · {favouriteLink}
    diff --git a/app/javascript/mastodon/features/ui/components/actions_modal.js b/app/javascript/mastodon/features/ui/components/actions_modal.js index 00280f7a6..875b2b75d 100644 --- a/app/javascript/mastodon/features/ui/components/actions_modal.js +++ b/app/javascript/mastodon/features/ui/components/actions_modal.js @@ -26,7 +26,7 @@ export default class ActionsModal extends ImmutablePureComponent { return (
  • - + {icon && }
    {text}
    @@ -42,7 +42,7 @@ export default class ActionsModal extends ImmutablePureComponent {
    diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.js b/app/javascript/mastodon/features/ui/components/boost_modal.js index 70f4a1282..0e79005f0 100644 --- a/app/javascript/mastodon/features/ui/components/boost_modal.js +++ b/app/javascript/mastodon/features/ui/components/boost_modal.js @@ -61,7 +61,7 @@ class BoostModal extends ImmutablePureComponent {
    diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index 990b9f63e..6ba327614 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -251,7 +251,7 @@ class Formatter def link_to_url(entity, options = {}) url = Addressable::URI.parse(entity[:url]) - html_attrs = { target: '_blank', rel: 'nofollow noopener' } + html_attrs = { target: '_blank', rel: 'nofollow noopener noreferrer' } html_attrs[:rel] = "me #{html_attrs[:rel]}" if options[:me] diff --git a/app/lib/sanitize_config.rb b/app/lib/sanitize_config.rb index aba8ce9f6..77045155e 100644 --- a/app/lib/sanitize_config.rb +++ b/app/lib/sanitize_config.rb @@ -45,7 +45,7 @@ class Sanitize add_attributes: { 'a' => { - 'rel' => 'nofollow noopener', + 'rel' => 'nofollow noopener noreferrer', 'target' => '_blank', }, }, diff --git a/app/views/about/show.html.haml b/app/views/about/show.html.haml index 80f4cd828..e0ec98ec9 100644 --- a/app/views/about/show.html.haml +++ b/app/views/about/show.html.haml @@ -38,7 +38,7 @@ %small= t('about.browse_public_posts') .directory__tag - = link_to 'https://joinmastodon.org/apps', target: '_blank', rel: 'noopener' do + = link_to 'https://joinmastodon.org/apps', target: '_blank', rel: 'noopener noreferrer' do %h4 = fa_icon 'tablet fw' = t('about.get_apps') diff --git a/app/views/accounts/_moved.html.haml b/app/views/accounts/_moved.html.haml index 02fd7bf42..a82f277b1 100644 --- a/app/views/accounts/_moved.html.haml +++ b/app/views/accounts/_moved.html.haml @@ -6,7 +6,7 @@ = t('accounts.moved_html', name: content_tag(:bdi, content_tag(:strong, display_name(account, custom_emojify: true), class: :emojify)), new_profile_link: link_to(content_tag(:strong, safe_join(['@', content_tag(:span, moved_to_account.acct)])), ActivityPub::TagManager.instance.url_for(moved_to_account), class: 'mention')) .moved-account-widget__card - = link_to ActivityPub::TagManager.instance.url_for(moved_to_account), class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'me noopener' do + = link_to ActivityPub::TagManager.instance.url_for(moved_to_account), class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'me noopener noreferrer' do .detailed-status__display-avatar .account__avatar-overlay .account__avatar-overlay-base{ style: "background-image: url('#{moved_to_account.avatar.url(:original)}')" } diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml index 6facc0a56..425d315e1 100644 --- a/app/views/admin/reports/_status.html.haml +++ b/app/views/admin/reports/_status.html.haml @@ -19,7 +19,7 @@ = react_component :media_gallery, height: 343, sensitive: !current_account&.user&.show_all_media? && status.proper.sensitive? || current_account&.user&.hide_all_media?, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.proper.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } .detailed-status__meta - = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener' do + = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener noreferrer' do %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at) - if status.discarded? · diff --git a/app/views/admin/tags/show.html.haml b/app/views/admin/tags/show.html.haml index 5799e5973..c9a147587 100644 --- a/app/views/admin/tags/show.html.haml +++ b/app/views/admin/tags/show.html.haml @@ -3,7 +3,7 @@ .dashboard__counters %div - = link_to tag_url(@tag), target: '_blank', rel: 'noopener' do + = link_to tag_url(@tag), target: '_blank', rel: 'noopener noreferrer' do .dashboard__counters__num= number_with_delimiter @accounts_today .dashboard__counters__label= t 'admin.tags.accounts_today' %div diff --git a/app/views/application/_card.html.haml b/app/views/application/_card.html.haml index 8719ce484..808dce514 100644 --- a/app/views/application/_card.html.haml +++ b/app/views/application/_card.html.haml @@ -1,7 +1,7 @@ - account_url = local_assigns[:admin] ? admin_account_path(account.id) : ActivityPub::TagManager.instance.url_for(account) .card.h-card - = link_to account_url, target: '_blank', rel: 'noopener' do + = link_to account_url, target: '_blank', rel: 'noopener noreferrer' do .card__img = image_tag account.header.url, alt: '' .card__bar diff --git a/app/views/oauth/authorized_applications/index.html.haml b/app/views/oauth/authorized_applications/index.html.haml index 7203d758d..7b77108a9 100644 --- a/app/views/oauth/authorized_applications/index.html.haml +++ b/app/views/oauth/authorized_applications/index.html.haml @@ -16,7 +16,7 @@ - if application.website.blank? = application.name - else - = link_to application.name, application.website, target: '_blank', rel: 'noopener' + = link_to application.name, application.website, target: '_blank', rel: 'noopener noreferrer' %th!= application.scopes.map { |scope| t(scope, scope: [:doorkeeper, :scopes]) }.join(', ') %td= l application.created_at %td diff --git a/app/views/statuses/_detailed_status.html.haml b/app/views/statuses/_detailed_status.html.haml index 5cee84ada..3fa52d3f2 100644 --- a/app/views/statuses/_detailed_status.html.haml +++ b/app/views/statuses/_detailed_status.html.haml @@ -44,14 +44,14 @@ .detailed-status__meta %data.dt-published{ value: status.created_at.to_time.iso8601 } - = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime u-url u-uid', target: stream_link_target, rel: 'noopener' do + = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime u-url u-uid', target: stream_link_target, rel: 'noopener noreferrer' do %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at) · - if status.application && @account.user&.setting_show_application - if status.application.website.blank? %strong.detailed-status__application= status.application.name - else - = link_to status.application.name, status.application.website, class: 'detailed-status__application', target: '_blank', rel: 'noopener' + = link_to status.application.name, status.application.website, class: 'detailed-status__application', target: '_blank', rel: 'noopener noreferrer' · = link_to remote_interaction_path(status, type: :reply), class: 'modal-button detailed-status__link' do - if status.in_reply_to_id.nil? diff --git a/app/views/statuses/_simple_status.html.haml b/app/views/statuses/_simple_status.html.haml index a68fe1022..edcfbba2b 100644 --- a/app/views/statuses/_simple_status.html.haml +++ b/app/views/statuses/_simple_status.html.haml @@ -1,11 +1,11 @@ .status .status__info - = link_to ActivityPub::TagManager.instance.url_for(status), class: 'status__relative-time u-url u-uid', target: stream_link_target, rel: 'noopener' do + = link_to ActivityPub::TagManager.instance.url_for(status), class: 'status__relative-time u-url u-uid', target: stream_link_target, rel: 'noopener noreferrer' do %time.time-ago{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at) %data.dt-published{ value: status.created_at.to_time.iso8601 } .p-author.h-card - = link_to ActivityPub::TagManager.instance.url_for(status.account), class: 'status__display-name u-url', target: stream_link_target, rel: 'noopener' do + = link_to ActivityPub::TagManager.instance.url_for(status.account), class: 'status__display-name u-url', target: stream_link_target, rel: 'noopener noreferrer' do .status__avatar %div - if current_account&.user&.setting_auto_play_gif || autoplay diff --git a/spec/fixtures/xml/mastodon.atom b/spec/fixtures/xml/mastodon.atom index 9ece3bc2e..92921a938 100644 --- a/spec/fixtures/xml/mastodon.atom +++ b/spec/fixtures/xml/mastodon.atom @@ -123,7 +123,7 @@ 2016-10-10T00:41:31Z 2016-10-10T00:41:31Z Social media needs MOAR cats! http://kickass.zone/media/3 - <p>Social media needs MOAR cats! <a rel="nofollow noopener" href="http://kickass.zone/media/3">http://kickass.zone/media/3</a></p> + <p>Social media needs MOAR cats! <a rel="nofollow noopener noreferrer" href="http://kickass.zone/media/3">http://kickass.zone/media/3</a></p> http://activitystrea.ms/schema/1.0/post @@ -135,7 +135,7 @@ 2016-10-10T00:38:39Z 2016-10-10T00:38:39Z http://kickass.zone/media/2 - <p><a rel="nofollow noopener" href="http://kickass.zone/media/2">http://kickass.zone/media/2</a></p> + <p><a rel="nofollow noopener noreferrer" href="http://kickass.zone/media/2">http://kickass.zone/media/2</a></p> http://activitystrea.ms/schema/1.0/post diff --git a/spec/lib/sanitize_config_spec.rb b/spec/lib/sanitize_config_spec.rb index 54bd8693c..feb86af35 100644 --- a/spec/lib/sanitize_config_spec.rb +++ b/spec/lib/sanitize_config_spec.rb @@ -24,7 +24,7 @@ describe Sanitize::Config do end it 'keep links in lists' do - expect(Sanitize.fragment('

    Check out:

    ', subject)).to eq '

    Check out:

    joinmastodon.org
    Bar

    ' + expect(Sanitize.fragment('

    Check out:

    ', subject)).to eq '

    Check out:

    joinmastodon.org
    Bar

    ' end end end diff --git a/spec/services/fetch_link_card_service_spec.rb b/spec/services/fetch_link_card_service_spec.rb index 9761c5f06..3c8f6f578 100644 --- a/spec/services/fetch_link_card_service_spec.rb +++ b/spec/services/fetch_link_card_service_spec.rb @@ -80,7 +80,7 @@ RSpec.describe FetchLinkCardService, type: :service do end context 'in a remote status' do - let(:status) { Fabricate(:status, account: Fabricate(:account, domain: 'example.com'), text: 'Habt ihr ein paar gute Links zu #Wannacry herumfliegen? Ich will mal unter
    https://github.com/qbi/WannaCry was sammeln. !security ') } + let(:status) { Fabricate(:status, account: Fabricate(:account, domain: 'example.com'), text: 'Habt ihr ein paar gute Links zu #Wannacry herumfliegen? Ich will mal unter
    https://github.com/qbi/WannaCry was sammeln. !security ') } it 'parses out URLs' do expect(a_request(:get, 'https://github.com/qbi/WannaCry')).to have_been_made.at_least_once diff --git a/spec/services/verify_link_service_spec.rb b/spec/services/verify_link_service_spec.rb index 2edcdb75f..3fc88e60e 100644 --- a/spec/services/verify_link_service_spec.rb +++ b/spec/services/verify_link_service_spec.rb @@ -28,12 +28,12 @@ RSpec.describe VerifyLinkService, type: :service do end end - context 'when a link contains an back' do + context 'when a link contains an back' do let(:html) do <<-HTML - Follow me on Mastodon + Follow me on Mastodon HTML end -- cgit From bd684e25d9ddb77e396e28a39ff221e9db28e608 Mon Sep 17 00:00:00 2001 From: ThibG Date: Thu, 24 Oct 2019 22:45:35 +0200 Subject: Fix incoming federation in whitelist mode (#12185) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … posting to the AP inbox required a logged-in local user… --- app/controllers/activitypub/inboxes_controller.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'app') diff --git a/app/controllers/activitypub/inboxes_controller.rb b/app/controllers/activitypub/inboxes_controller.rb index bcfc1e6d4..291eec19a 100644 --- a/app/controllers/activitypub/inboxes_controller.rb +++ b/app/controllers/activitypub/inboxes_controller.rb @@ -7,6 +7,7 @@ class ActivityPub::InboxesController < ActivityPub::BaseController before_action :skip_unknown_actor_delete before_action :require_signature! + skip_before_action :authenticate_user! def create upgrade_account -- cgit From d2919f7e94a22971fb368f614ecccce2b055d231 Mon Sep 17 00:00:00 2001 From: puckipedia Date: Thu, 24 Oct 2019 20:45:43 +0000 Subject: Allow Accept/Reject with a non-embedded object (#12199) Some ActivityPub servers refuse to embed remote objects into their own output. This is because they are not the authoritative source for these objects, and as such embedding them is always a waste of space. The follow request and follow models contain a URI, so this can be used to match them. --- app/lib/activitypub/activity.rb | 8 ++++++++ app/lib/activitypub/activity/accept.rb | 9 +++++---- app/lib/activitypub/activity/reject.rb | 10 ++++++---- 3 files changed, 19 insertions(+), 8 deletions(-) (limited to 'app') diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb index a4a9baaee..5cd48a6ae 100644 --- a/app/lib/activitypub/activity.rb +++ b/app/lib/activitypub/activity.rb @@ -153,6 +153,14 @@ class ActivityPub::Activity fetch_remote_original_status end + def follow_request_from_object + @follow_request ||= FollowRequest.find_by(target_account: @account, uri: object_uri) unless object_uri.nil? + end + + def follow_from_object + @follow ||= Follow.find_by(target_account: @account, uri: object_uri) unless object_uri.nil? + end + def fetch_remote_original_status if object_uri.start_with?('http') return if ActivityPub::TagManager.instance.local_uri?(object_uri) diff --git a/app/lib/activitypub/activity/accept.rb b/app/lib/activitypub/activity/accept.rb index 348ee0d1c..7010ff43e 100644 --- a/app/lib/activitypub/activity/accept.rb +++ b/app/lib/activitypub/activity/accept.rb @@ -2,17 +2,18 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity def perform + return accept_follow_for_relay if relay_follow? + return follow_request_from_object.authorize! unless follow_request_from_object.nil? + case @object['type'] when 'Follow' - accept_follow + accept_embedded_follow end end private - def accept_follow - return accept_follow_for_relay if relay_follow? - + def accept_embedded_follow target_account = account_from_uri(target_uri) return if target_account.nil? || !target_account.local? diff --git a/app/lib/activitypub/activity/reject.rb b/app/lib/activitypub/activity/reject.rb index dba21fb9a..8d771ed81 100644 --- a/app/lib/activitypub/activity/reject.rb +++ b/app/lib/activitypub/activity/reject.rb @@ -2,17 +2,19 @@ class ActivityPub::Activity::Reject < ActivityPub::Activity def perform + return reject_follow_for_relay if relay_follow? + return follow_request_from_object.reject! unless follow_request_from_object.nil? + return UnfollowService.new.call(follow_from_object.target_account, @account) unless follow_from_object.nil? + case @object['type'] when 'Follow' - reject_follow + reject_embedded_follow end end private - def reject_follow - return reject_follow_for_relay if relay_follow? - + def reject_embedded_follow target_account = account_from_uri(target_uri) return if target_account.nil? || !target_account.local? -- cgit From 9762fe382c76fdff5281a94f484191a92d09eac7 Mon Sep 17 00:00:00 2001 From: nightpool Date: Thu, 24 Oct 2019 16:46:15 -0400 Subject: microformat mentions can have an implicit property (#12189) See the first example here: http://microformats.org/wiki/microformats2#hyperlinked_person --- app/services/fetch_link_card_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb index f0b1169db..640c60fd4 100644 --- a/app/services/fetch_link_card_service.rb +++ b/app/services/fetch_link_card_service.rb @@ -84,7 +84,7 @@ class FetchLinkCardService < BaseService def skip_link?(a) # Avoid links for hashtags and mentions (microformats) - a['rel']&.include?('tag') || a['class']&.include?('u-url') || mention_link?(a) + a['rel']&.include?('tag') || a['class']&.match?(/u-url|h-card/) || mention_link?(a) end def attempt_oembed -- cgit From aa884e04848a6c06dbf7c27ae7a3fcc7d379792d Mon Sep 17 00:00:00 2001 From: ThibG Date: Thu, 24 Oct 2019 22:46:59 +0200 Subject: Fix batch actions being hidden from mobile view (#12183) On mobile, batch actions are hidden from the settings/admin interface, but there are several places those actions can only be performed through batch actions. This may not look great, but at least it makes the actions available again. --- app/javascript/styles/mastodon/tables.scss | 17 ++++++++--------- app/views/admin/tags/index.html.haml | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'app') diff --git a/app/javascript/styles/mastodon/tables.scss b/app/javascript/styles/mastodon/tables.scss index 5a6e10aa4..62f5554ff 100644 --- a/app/javascript/styles/mastodon/tables.scss +++ b/app/javascript/styles/mastodon/tables.scss @@ -149,10 +149,6 @@ a.table-action-link { margin-top: 0; } } - - @media screen and (max-width: $no-gap-breakpoint) { - display: none; - } } &__actions, @@ -174,10 +170,6 @@ a.table-action-link { text-align: right; padding-right: 16px - 5px; } - - @media screen and (max-width: $no-gap-breakpoint) { - display: none; - } } &__form { @@ -198,7 +190,7 @@ a.table-action-link { background: darken($ui-base-color, 4%); @media screen and (max-width: $no-gap-breakpoint) { - &:first-child { + .optional &:first-child { border-top: 1px solid darken($ui-base-color, 8%); } } @@ -264,6 +256,13 @@ a.table-action-link { } } + &.optional .batch-table__toolbar, + &.optional .batch-table__row__select { + @media screen and (max-width: $no-gap-breakpoint) { + display: none; + } + } + .status__content { padding-top: 0; diff --git a/app/views/admin/tags/index.html.haml b/app/views/admin/tags/index.html.haml index 8b1182dbb..b29991328 100644 --- a/app/views/admin/tags/index.html.haml +++ b/app/views/admin/tags/index.html.haml @@ -48,7 +48,7 @@ - Admin::FilterHelper::TAGS_FILTERS.each do |key| = hidden_field_tag key, params[key] if params[key].present? - .batch-table + .batch-table.optional .batch-table__toolbar %label.batch-table__toolbar__select.batch-checkbox-all = check_box_tag :batch_checkbox_all, nil, false -- cgit From 547a5bac9d9c909b306933596bc121b63809d772 Mon Sep 17 00:00:00 2001 From: Hinaloe Date: Fri, 25 Oct 2019 05:47:37 +0900 Subject: don't show outline of full-screen video (#12176) --- app/javascript/styles/mastodon/components.scss | 1 + 1 file changed, 1 insertion(+) (limited to 'app') diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 86425c47c..0fe86bf16 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -5194,6 +5194,7 @@ a.status-card.compact:hover { max-height: 100% !important; width: 100% !important; height: 100% !important; + outline: 0; } } -- cgit From 3a929dbedd31ea67723746bdf387e22e66e247cd Mon Sep 17 00:00:00 2001 From: ThibG Date: Thu, 24 Oct 2019 22:47:48 +0200 Subject: Replace fav icon animation with CSS (#12175) Fixes #12151 --- app/javascript/mastodon/components/icon_button.js | 84 ++++++++++------------- app/javascript/styles/mastodon/components.scss | 58 ++++++++++++++++ 2 files changed, 96 insertions(+), 46 deletions(-) (limited to 'app') diff --git a/app/javascript/mastodon/components/icon_button.js b/app/javascript/mastodon/components/icon_button.js index 401675052..fd715bc3c 100644 --- a/app/javascript/mastodon/components/icon_button.js +++ b/app/javascript/mastodon/components/icon_button.js @@ -1,6 +1,4 @@ import React from 'react'; -import Motion from '../features/ui/util/optional_motion'; -import spring from 'react-motion/lib/spring'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import Icon from 'mastodon/components/icon'; @@ -37,6 +35,21 @@ export default class IconButton extends React.PureComponent { tabIndex: '0', }; + state = { + activate: false, + deactivate: false, + } + + componentWillReceiveProps (nextProps) { + if (!nextProps.animate) return; + + if (this.props.active && !nextProps.active) { + this.setState({ activate: false, deactivate: true }); + } else if (!this.props.active && nextProps.active) { + this.setState({ activate: true, deactivate: false }); + } + } + handleClick = (e) => { e.preventDefault(); @@ -75,7 +88,6 @@ export default class IconButton extends React.PureComponent { const { active, - animate, className, disabled, expanded, @@ -87,57 +99,37 @@ export default class IconButton extends React.PureComponent { title, } = this.props; + const { + activate, + deactivate, + } = this.state; + const classes = classNames(className, 'icon-button', { active, disabled, inverted, + activate, + deactivate, overlayed: overlay, }); - if (!animate) { - // Perf optimization: avoid unnecessary components unless - // we actually need to animate. - return ( - - ); - } - return ( - - {({ rotate }) => ( - - )} - + ); } diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 0fe86bf16..52fe3bed0 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -1591,6 +1591,20 @@ a.account__display-name { color: $gold-star; } +.no-reduce-motion .icon-button.star-icon { + &.activate { + & > .fa-star { + animation: spring-rotate-in 1s linear; + } + } + + &.deactivate { + & > .fa-star { + animation: spring-rotate-out 1s linear; + } + } +} + .notification__display-name { color: inherit; font-weight: 500; @@ -3373,6 +3387,50 @@ a.status-card.compact:hover { animation: loader-figure 1.15s infinite cubic-bezier(0.215, 0.61, 0.355, 1); } +@keyframes spring-rotate-in { + 0% { + transform: rotate(0deg); + } + + 30% { + transform: rotate(-484.8deg); + } + + 60% { + transform: rotate(-316.7deg); + } + + 90% { + transform: rotate(-375deg); + } + + 100% { + transform: rotate(-360deg); + } +} + +@keyframes spring-rotate-out { + 0% { + transform: rotate(-360deg); + } + + 30% { + transform: rotate(124.8deg); + } + + 60% { + transform: rotate(-43.27deg); + } + + 90% { + transform: rotate(15deg); + } + + 100% { + transform: rotate(0deg); + } +} + @keyframes loader-figure { 0% { width: 0; -- cgit From 488dd0ff7a41584424f871841457affae11390e5 Mon Sep 17 00:00:00 2001 From: Hugo Gameiro Date: Thu, 24 Oct 2019 21:47:58 +0100 Subject: remove audio metadata (#12171) --- app/models/media_attachment.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'app') diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index 9c6c04556..137377422 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -87,6 +87,7 @@ class MediaAttachment < ApplicationRecord convert_options: { output: { 'loglevel' => 'fatal', + 'map_metadata' => '-1', 'q:a' => 2, }, }, -- cgit From f4be89e24d3849de4b543faa37493474e2ee8e02 Mon Sep 17 00:00:00 2001 From: umonaca <53662960+umonaca@users.noreply.github.com> Date: Thu, 24 Oct 2019 16:48:11 -0400 Subject: Improve swipe experience (#12168) --- app/javascript/mastodon/features/ui/components/columns_area.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.js index 8a4e89b3d..f31425c70 100644 --- a/app/javascript/mastodon/features/ui/components/columns_area.js +++ b/app/javascript/mastodon/features/ui/components/columns_area.js @@ -182,7 +182,7 @@ class ColumnsArea extends ImmutablePureComponent { const floatingActionButton = shouldHideFAB(this.context.router.history.location.pathname) ? null : ; const content = columnIndex !== -1 ? ( - + {links.map(this.renderView)} ) : ( -- cgit From bcf694dce7536d29ede3c0865b00cb84f348b5e1 Mon Sep 17 00:00:00 2001 From: ThibG Date: Thu, 24 Oct 2019 22:49:12 +0200 Subject: Fix volume slider in chromium 🤷 (#12158) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #12156 --- app/javascript/mastodon/features/audio/index.js | 1 + app/javascript/mastodon/features/video/index.js | 1 + 2 files changed, 2 insertions(+) (limited to 'app') diff --git a/app/javascript/mastodon/features/audio/index.js b/app/javascript/mastodon/features/audio/index.js index 95e5675f3..d3b309f0f 100644 --- a/app/javascript/mastodon/features/audio/index.js +++ b/app/javascript/mastodon/features/audio/index.js @@ -202,6 +202,7 @@ class Audio extends React.PureComponent {
    +  
    +  
    Date: Thu, 24 Oct 2019 22:49:26 +0200 Subject: Add link to search for users connected from the same IP address (#12157) * Add link to search for users connected from the same IP address Fixes #11949 * Fix missing cell in admin account view table --- app/views/admin/accounts/show.html.haml | 3 +++ config/locales/en.yml | 1 + 2 files changed, 4 insertions(+) (limited to 'app') diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index 40a936e86..9f1e3816b 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -143,12 +143,15 @@ %th= t('admin.accounts.most_recent_ip') %td= @account.user_current_sign_in_ip %td + - if @account.user_current_sign_in_ip + = table_link_to 'search', t('admin.accounts.search_same_ip'), admin_accounts_path(ip: @account.user_current_sign_in_ip) %tr %th= t('admin.accounts.most_recent_activity') %td - if @account.user_current_sign_in_at %time.formatted{ datetime: @account.user_current_sign_in_at.iso8601, title: l(@account.user_current_sign_in_at) }= l @account.user_current_sign_in_at + %td - if @account.user&.invited? %tr diff --git a/config/locales/en.yml b/config/locales/en.yml index be66b6c6c..458524c3d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -175,6 +175,7 @@ en: user: User salmon_url: Salmon URL search: Search + search_same_ip: Other users with the same IP shared_inbox_url: Shared inbox URL show: created_reports: Made reports -- cgit From a9530e29a2813ed8cf4c8f13fe60dd9fad245466 Mon Sep 17 00:00:00 2001 From: Nima Boscarino Date: Thu, 24 Oct 2019 13:49:45 -0700 Subject: Unliking a post updates like count on front end (#12140) * return the new favourites_count when unfavouriting a status * Remove trailing whitespace * revert changes to favourites_controller * Decrease favourites_count through statuses reducer * styling fix * Fix missing trailing comma --- app/javascript/mastodon/reducers/statuses.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'app') diff --git a/app/javascript/mastodon/reducers/statuses.js b/app/javascript/mastodon/reducers/statuses.js index 885cc221c..372673bc0 100644 --- a/app/javascript/mastodon/reducers/statuses.js +++ b/app/javascript/mastodon/reducers/statuses.js @@ -3,6 +3,7 @@ import { REBLOG_FAIL, FAVOURITE_REQUEST, FAVOURITE_FAIL, + UNFAVOURITE_SUCCESS, } from '../actions/interactions'; import { STATUS_MUTE_SUCCESS, @@ -37,6 +38,9 @@ export default function statuses(state = initialState, action) { return importStatuses(state, action.statuses); case FAVOURITE_REQUEST: return state.setIn([action.status.get('id'), 'favourited'], true); + case UNFAVOURITE_SUCCESS: + const favouritesCount = action.status.get('favourites_count'); + return state.setIn([action.status.get('id'), 'favourites_count'], favouritesCount - 1); case FAVOURITE_FAIL: return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'favourited'], false); case REBLOG_REQUEST: -- cgit From a6269b2f83e3eed1a8ab545f5756cd7b582075f5 Mon Sep 17 00:00:00 2001 From: Takeshi Umeda Date: Fri, 25 Oct 2019 05:50:09 +0900 Subject: Split AccountsHelper from StatusesHelper (#12078) --- app/helpers/accounts_helper.rb | 106 +++++++++++++++++++++ app/helpers/statuses_helper.rb | 103 -------------------- app/mailers/admin_mailer.rb | 2 +- app/mailers/notification_mailer.rb | 1 + app/mailers/user_mailer.rb | 2 +- app/serializers/rss/account_serializer.rb | 2 +- app/serializers/rss/tag_serializer.rb | 1 - spec/helpers/accounts_helper_spec.rb | 67 +++++++++++++ .../admin/account_moderation_notes_helper_spec.rb | 2 +- spec/helpers/statuses_helper_spec.rb | 54 ----------- 10 files changed, 178 insertions(+), 162 deletions(-) create mode 100644 app/helpers/accounts_helper.rb create mode 100644 spec/helpers/accounts_helper_spec.rb (limited to 'app') diff --git a/app/helpers/accounts_helper.rb b/app/helpers/accounts_helper.rb new file mode 100644 index 000000000..5b060a181 --- /dev/null +++ b/app/helpers/accounts_helper.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +module AccountsHelper + def display_name(account, **options) + if options[:custom_emojify] + Formatter.instance.format_display_name(account, options) + else + account.display_name.presence || account.username + end + end + + def acct(account) + if account.local? + "@#{account.acct}@#{Rails.configuration.x.local_domain}" + else + "@#{account.acct}" + end + end + + def account_action_button(account) + if user_signed_in? + if account.id == current_user.account_id + link_to settings_profile_url, class: 'button logo-button' do + safe_join([svg_logo, t('settings.edit_profile')]) + end + elsif current_account.following?(account) || current_account.requested?(account) + link_to account_unfollow_path(account), class: 'button logo-button button--destructive', data: { method: :post } do + safe_join([svg_logo, t('accounts.unfollow')]) + end + elsif !(account.memorial? || account.moved?) + link_to account_follow_path(account), class: "button logo-button#{account.blocking?(current_account) ? ' disabled' : ''}", data: { method: :post } do + safe_join([svg_logo, t('accounts.follow')]) + end + end + elsif !(account.memorial? || account.moved?) + link_to account_remote_follow_path(account), class: 'button logo-button modal-button', target: '_new' do + safe_join([svg_logo, t('accounts.follow')]) + end + end + end + + def minimal_account_action_button(account) + if user_signed_in? + return if account.id == current_user.account_id + + if current_account.following?(account) || current_account.requested?(account) + link_to account_unfollow_path(account), class: 'icon-button active', data: { method: :post }, title: t('accounts.unfollow') do + fa_icon('user-times fw') + end + elsif !(account.memorial? || account.moved?) + link_to account_follow_path(account), class: "icon-button#{account.blocking?(current_account) ? ' disabled' : ''}", data: { method: :post }, title: t('accounts.follow') do + fa_icon('user-plus fw') + end + end + elsif !(account.memorial? || account.moved?) + link_to account_remote_follow_path(account), class: 'icon-button modal-button', target: '_new', title: t('accounts.follow') do + fa_icon('user-plus fw') + end + end + end + + def account_badge(account, all: false) + if account.bot? + content_tag(:div, content_tag(:div, t('accounts.roles.bot'), class: 'account-role bot'), class: 'roles') + elsif (Setting.show_staff_badge && account.user_staff?) || all + content_tag(:div, class: 'roles') do + if all && !account.user_staff? + content_tag(:div, t('admin.accounts.roles.user'), class: 'account-role') + elsif account.user_admin? + content_tag(:div, t('accounts.roles.admin'), class: 'account-role admin') + elsif account.user_moderator? + content_tag(:div, t('accounts.roles.moderator'), class: 'account-role moderator') + end + end + end + end + + def account_description(account) + prepend_str = [ + [ + number_to_human(account.statuses_count, strip_insignificant_zeros: true), + I18n.t('accounts.posts', count: account.statuses_count), + ].join(' '), + + [ + number_to_human(account.following_count, strip_insignificant_zeros: true), + I18n.t('accounts.following', count: account.following_count), + ].join(' '), + + [ + number_to_human(account.followers_count, strip_insignificant_zeros: true), + I18n.t('accounts.followers', count: account.followers_count), + ].join(' '), + ].join(', ') + + [prepend_str, account.note].join(' · ') + end + + def svg_logo + content_tag(:svg, tag(:use, 'xlink:href' => '#mastodon-svg-logo'), 'viewBox' => '0 0 216.4144 232.00976') + end + + def svg_logo_full + content_tag(:svg, tag(:use, 'xlink:href' => '#mastodon-svg-logo-full'), 'viewBox' => '0 0 713.35878 175.8678') + end +end diff --git a/app/helpers/statuses_helper.rb b/app/helpers/statuses_helper.rb index 8380b3c42..866a9902c 100644 --- a/app/helpers/statuses_helper.rb +++ b/app/helpers/statuses_helper.rb @@ -4,80 +4,6 @@ module StatusesHelper EMBEDDED_CONTROLLER = 'statuses' EMBEDDED_ACTION = 'embed' - def display_name(account, **options) - if options[:custom_emojify] - Formatter.instance.format_display_name(account, options) - else - account.display_name.presence || account.username - end - end - - def account_action_button(account) - if user_signed_in? - if account.id == current_user.account_id - link_to settings_profile_url, class: 'button logo-button' do - safe_join([svg_logo, t('settings.edit_profile')]) - end - elsif current_account.following?(account) || current_account.requested?(account) - link_to account_unfollow_path(account), class: 'button logo-button button--destructive', data: { method: :post } do - safe_join([svg_logo, t('accounts.unfollow')]) - end - elsif !(account.memorial? || account.moved?) - link_to account_follow_path(account), class: "button logo-button#{account.blocking?(current_account) ? ' disabled' : ''}", data: { method: :post } do - safe_join([svg_logo, t('accounts.follow')]) - end - end - elsif !(account.memorial? || account.moved?) - link_to account_remote_follow_path(account), class: 'button logo-button modal-button', target: '_new' do - safe_join([svg_logo, t('accounts.follow')]) - end - end - end - - def minimal_account_action_button(account) - if user_signed_in? - return if account.id == current_user.account_id - - if current_account.following?(account) || current_account.requested?(account) - link_to account_unfollow_path(account), class: 'icon-button active', data: { method: :post }, title: t('accounts.unfollow') do - fa_icon('user-times fw') - end - elsif !(account.memorial? || account.moved?) - link_to account_follow_path(account), class: "icon-button#{account.blocking?(current_account) ? ' disabled' : ''}", data: { method: :post }, title: t('accounts.follow') do - fa_icon('user-plus fw') - end - end - elsif !(account.memorial? || account.moved?) - link_to account_remote_follow_path(account), class: 'icon-button modal-button', target: '_new', title: t('accounts.follow') do - fa_icon('user-plus fw') - end - end - end - - def svg_logo - content_tag(:svg, tag(:use, 'xlink:href' => '#mastodon-svg-logo'), 'viewBox' => '0 0 216.4144 232.00976') - end - - def svg_logo_full - content_tag(:svg, tag(:use, 'xlink:href' => '#mastodon-svg-logo-full'), 'viewBox' => '0 0 713.35878 175.8678') - end - - def account_badge(account, all: false) - if account.bot? - content_tag(:div, content_tag(:div, t('accounts.roles.bot'), class: 'account-role bot'), class: 'roles') - elsif (Setting.show_staff_badge && account.user_staff?) || all - content_tag(:div, class: 'roles') do - if all && !account.user_staff? - content_tag(:div, t('admin.accounts.roles.user'), class: 'account-role') - elsif account.user_admin? - content_tag(:div, t('accounts.roles.admin'), class: 'account-role admin') - elsif account.user_moderator? - content_tag(:div, t('accounts.roles.moderator'), class: 'account-role moderator') - end - end - end - end - def link_to_more(url) link_to t('statuses.show_more'), url, class: 'load-more load-gap' end @@ -88,27 +14,6 @@ module StatusesHelper end end - def account_description(account) - prepend_str = [ - [ - number_to_human(account.statuses_count, strip_insignificant_zeros: true), - I18n.t('accounts.posts', count: account.statuses_count), - ].join(' '), - - [ - number_to_human(account.following_count, strip_insignificant_zeros: true), - I18n.t('accounts.following', count: account.following_count), - ].join(' '), - - [ - number_to_human(account.followers_count, strip_insignificant_zeros: true), - I18n.t('accounts.followers', count: account.followers_count), - ].join(' '), - ].join(', ') - - [prepend_str, account.note].join(' · ') - end - def media_summary(status) attachments = { image: 0, video: 0 } @@ -154,14 +59,6 @@ module StatusesHelper embedded_view? ? '_blank' : nil end - def acct(account) - if account.local? - "@#{account.acct}@#{Rails.configuration.x.local_domain}" - else - "@#{account.acct}" - end - end - def style_classes(status, is_predecessor, is_successor, include_threads) classes = ['entry'] classes << 'entry-predecessor' if is_predecessor diff --git a/app/mailers/admin_mailer.rb b/app/mailers/admin_mailer.rb index 8abce5f05..11fd09e30 100644 --- a/app/mailers/admin_mailer.rb +++ b/app/mailers/admin_mailer.rb @@ -3,7 +3,7 @@ class AdminMailer < ApplicationMailer layout 'plain_mailer' - helper :statuses + helper :accounts def new_report(recipient, report) @report = report diff --git a/app/mailers/notification_mailer.rb b/app/mailers/notification_mailer.rb index 723d901fc..9d8a7886c 100644 --- a/app/mailers/notification_mailer.rb +++ b/app/mailers/notification_mailer.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true class NotificationMailer < ApplicationMailer + helper :accounts helper :statuses add_template_helper RoutingHelper diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 6b81f6873..c30bec80b 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -3,9 +3,9 @@ class UserMailer < Devise::Mailer layout 'mailer' + helper :accounts helper :application helper :instance - helper :statuses add_template_helper RoutingHelper diff --git a/app/serializers/rss/account_serializer.rb b/app/serializers/rss/account_serializer.rb index e39b2b372..ee972ff96 100644 --- a/app/serializers/rss/account_serializer.rb +++ b/app/serializers/rss/account_serializer.rb @@ -2,7 +2,7 @@ class RSS::AccountSerializer include ActionView::Helpers::NumberHelper - include StatusesHelper + include AccountsHelper include RoutingHelper def render(account, statuses, tag) diff --git a/app/serializers/rss/tag_serializer.rb b/app/serializers/rss/tag_serializer.rb index 6737fb2c9..ea26189a2 100644 --- a/app/serializers/rss/tag_serializer.rb +++ b/app/serializers/rss/tag_serializer.rb @@ -3,7 +3,6 @@ class RSS::TagSerializer include ActionView::Helpers::NumberHelper include ActionView::Helpers::SanitizeHelper - include StatusesHelper include RoutingHelper def render(tag, statuses) diff --git a/spec/helpers/accounts_helper_spec.rb b/spec/helpers/accounts_helper_spec.rb new file mode 100644 index 000000000..2b35b23b7 --- /dev/null +++ b/spec/helpers/accounts_helper_spec.rb @@ -0,0 +1,67 @@ +require 'rails_helper' + +RSpec.describe AccountsHelper, type: :helper do + def set_not_embedded_view + params[:controller] = "not_#{StatusesHelper::EMBEDDED_CONTROLLER}" + params[:action] = "not_#{StatusesHelper::EMBEDDED_ACTION}" + end + + def set_embedded_view + params[:controller] = StatusesHelper::EMBEDDED_CONTROLLER + params[:action] = StatusesHelper::EMBEDDED_ACTION + end + + describe '#display_name' do + it 'uses the display name when it exists' do + account = Account.new(display_name: "Display", username: "Username") + + expect(helper.display_name(account)).to eq "Display" + end + + it 'uses the username when display name is nil' do + account = Account.new(display_name: nil, username: "Username") + + expect(helper.display_name(account)).to eq "Username" + end + end + + describe '#acct' do + it 'is fully qualified for embedded local accounts' do + allow(Rails.configuration.x).to receive(:local_domain).and_return('local_domain') + set_embedded_view + account = Account.new(domain: nil, username: 'user') + + acct = helper.acct(account) + + expect(acct).to eq '@user@local_domain' + end + + it 'is fully qualified for embedded foreign accounts' do + set_embedded_view + account = Account.new(domain: 'foreign_server.com', username: 'user') + + acct = helper.acct(account) + + expect(acct).to eq '@user@foreign_server.com' + end + + it 'is fully qualified for non embedded foreign accounts' do + set_not_embedded_view + account = Account.new(domain: 'foreign_server.com', username: 'user') + + acct = helper.acct(account) + + expect(acct).to eq '@user@foreign_server.com' + end + + it 'is fully qualified for non embedded local accounts' do + allow(Rails.configuration.x).to receive(:local_domain).and_return('local_domain') + set_not_embedded_view + account = Account.new(domain: nil, username: 'user') + + acct = helper.acct(account) + + expect(acct).to eq '@user@local_domain' + end + end +end diff --git a/spec/helpers/admin/account_moderation_notes_helper_spec.rb b/spec/helpers/admin/account_moderation_notes_helper_spec.rb index ddfe8b46f..622ce8806 100644 --- a/spec/helpers/admin/account_moderation_notes_helper_spec.rb +++ b/spec/helpers/admin/account_moderation_notes_helper_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe Admin::AccountModerationNotesHelper, type: :helper do - include StatusesHelper + include AccountsHelper describe '#admin_account_link_to' do context 'account is nil' do diff --git a/spec/helpers/statuses_helper_spec.rb b/spec/helpers/statuses_helper_spec.rb index 510955a2f..940ff072e 100644 --- a/spec/helpers/statuses_helper_spec.rb +++ b/spec/helpers/statuses_helper_spec.rb @@ -1,20 +1,6 @@ require 'rails_helper' RSpec.describe StatusesHelper, type: :helper do - describe '#display_name' do - it 'uses the display name when it exists' do - account = Account.new(display_name: "Display", username: "Username") - - expect(helper.display_name(account)).to eq "Display" - end - - it 'uses the username when display name is nil' do - account = Account.new(display_name: nil, username: "Username") - - expect(helper.display_name(account)).to eq "Username" - end - end - describe '#stream_link_target' do it 'returns nil if it is not an embedded view' do set_not_embedded_view @@ -29,46 +15,6 @@ RSpec.describe StatusesHelper, type: :helper do end end - describe '#acct' do - it 'is fully qualified for embedded local accounts' do - allow(Rails.configuration.x).to receive(:local_domain).and_return('local_domain') - set_embedded_view - account = Account.new(domain: nil, username: 'user') - - acct = helper.acct(account) - - expect(acct).to eq '@user@local_domain' - end - - it 'is fully qualified for embedded foreign accounts' do - set_embedded_view - account = Account.new(domain: 'foreign_server.com', username: 'user') - - acct = helper.acct(account) - - expect(acct).to eq '@user@foreign_server.com' - end - - it 'is fully qualified for non embedded foreign accounts' do - set_not_embedded_view - account = Account.new(domain: 'foreign_server.com', username: 'user') - - acct = helper.acct(account) - - expect(acct).to eq '@user@foreign_server.com' - end - - it 'is fully qualified for non embedded local accounts' do - allow(Rails.configuration.x).to receive(:local_domain).and_return('local_domain') - set_not_embedded_view - account = Account.new(domain: nil, username: 'user') - - acct = helper.acct(account) - - expect(acct).to eq '@user@local_domain' - end - end - def set_not_embedded_view params[:controller] = "not_#{StatusesHelper::EMBEDDED_CONTROLLER}" params[:action] = "not_#{StatusesHelper::EMBEDDED_ACTION}" -- cgit From 48f75b86aed816ef5afaaae64416dbeaa14e4fda Mon Sep 17 00:00:00 2001 From: Faye Duxovni Date: Thu, 24 Oct 2019 16:51:41 -0400 Subject: Add setting for whether to crop images in unexpanded toots (#12126) --- app/controllers/settings/preferences_controller.rb | 1 + app/javascript/mastodon/components/media_gallery.js | 16 ++++++++-------- app/javascript/mastodon/initial_state.js | 1 + app/lib/user_settings_decorator.rb | 5 +++++ app/models/user.rb | 2 +- app/serializers/initial_state_serializer.rb | 2 ++ app/views/settings/preferences/appearance/show.html.haml | 5 +++++ config/locales/en.yml | 1 + config/locales/simple_form.en.yml | 1 + config/settings.yml | 1 + 10 files changed, 26 insertions(+), 9 deletions(-) (limited to 'app') diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb index edf29947b..bac9b329d 100644 --- a/app/controllers/settings/preferences_controller.rb +++ b/app/controllers/settings/preferences_controller.rb @@ -57,6 +57,7 @@ class Settings::PreferencesController < Settings::BaseController :setting_use_blurhash, :setting_use_pending_items, :setting_trends, + :setting_crop_images, notification_emails: %i(follow follow_request reblog favourite mention digest report pending_account trending_tag), interactions: %i(must_be_follower must_be_following must_be_following_dm) ) diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js index b8fca8bcb..12b7e5b66 100644 --- a/app/javascript/mastodon/components/media_gallery.js +++ b/app/javascript/mastodon/components/media_gallery.js @@ -6,7 +6,7 @@ import IconButton from './icon_button'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { isIOS } from '../is_mobile'; import classNames from 'classnames'; -import { autoPlayGif, displayMedia, useBlurhash } from '../initial_state'; +import { autoPlayGif, cropImages, displayMedia, useBlurhash } from '../initial_state'; import { decode } from 'blurhash'; const messages = defineMessages({ @@ -281,7 +281,7 @@ class MediaGallery extends React.PureComponent { } handleRef = (node) => { - if (node /*&& this.isStandaloneEligible()*/) { + if (node) { // offsetWidth triggers a layout, so only calculate when we need to if (this.props.cacheWidth) this.props.cacheWidth(node.offsetWidth); @@ -291,13 +291,13 @@ class MediaGallery extends React.PureComponent { } } - isStandaloneEligible() { - const { media, standalone } = this.props; - return standalone && media.size === 1 && media.getIn([0, 'meta', 'small', 'aspect']); + isFullSizeEligible() { + const { media } = this.props; + return media.size === 1 && media.getIn([0, 'meta', 'small', 'aspect']); } render () { - const { media, intl, sensitive, height, defaultWidth } = this.props; + const { media, intl, sensitive, height, defaultWidth, standalone } = this.props; const { visible } = this.state; const width = this.state.width || defaultWidth; @@ -306,7 +306,7 @@ class MediaGallery extends React.PureComponent { const style = {}; - if (this.isStandaloneEligible()) { + if (this.isFullSizeEligible() && (standalone || !cropImages)) { if (width) { style.height = width / this.props.media.getIn([0, 'meta', 'small', 'aspect']); } @@ -319,7 +319,7 @@ class MediaGallery extends React.PureComponent { const size = media.take(4).size; const uncached = media.every(attachment => attachment.get('type') === 'unknown'); - if (this.isStandaloneEligible()) { + if (standalone && this.isFullSizeEligible()) { children = ; } else { children = media.take(4).map((attachment, i) => ); diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js index 56fb58546..1134c55db 100644 --- a/app/javascript/mastodon/initial_state.js +++ b/app/javascript/mastodon/initial_state.js @@ -24,5 +24,6 @@ export const useBlurhash = getMeta('use_blurhash'); export const usePendingItems = getMeta('use_pending_items'); export const showTrends = getMeta('trends'); export const title = getMeta('title'); +export const cropImages = getMeta('crop_images'); export default initialState; diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb index 3568a3e11..fa8255faa 100644 --- a/app/lib/user_settings_decorator.rb +++ b/app/lib/user_settings_decorator.rb @@ -37,6 +37,7 @@ class UserSettingsDecorator user.settings['use_blurhash'] = use_blurhash_preference if change?('setting_use_blurhash') user.settings['use_pending_items'] = use_pending_items_preference if change?('setting_use_pending_items') user.settings['trends'] = trends_preference if change?('setting_trends') + user.settings['crop_images'] = crop_images_preference if change?('setting_crop_images') end def merged_notification_emails @@ -127,6 +128,10 @@ class UserSettingsDecorator boolean_cast_setting 'setting_trends' end + def crop_images_preference + boolean_cast_setting 'setting_crop_images' + end + def boolean_cast_setting(key) ActiveModel::Type::Boolean.new.cast(settings[key]) end diff --git a/app/models/user.rb b/app/models/user.rb index 9a19a53b3..7147a9a31 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -108,7 +108,7 @@ class User < ApplicationRecord delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :delete_modal, :reduce_motion, :system_font_ui, :noindex, :theme, :display_media, :hide_network, :expand_spoilers, :default_language, :aggregate_reblogs, :show_application, - :advanced_layout, :use_blurhash, :use_pending_items, :trends, + :advanced_layout, :use_blurhash, :use_pending_items, :trends, :crop_images, to: :settings, prefix: :setting, allow_nil: false attr_reader :invite_code diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index fb53ea314..392fc891a 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -38,11 +38,13 @@ class InitialStateSerializer < ActiveModel::Serializer store[:use_pending_items] = object.current_account.user.setting_use_pending_items store[:is_staff] = object.current_account.user.staff? store[:trends] = Setting.trends && object.current_account.user.setting_trends + store[:crop_images] = object.current_account.user.setting_crop_images else store[:auto_play_gif] = Setting.auto_play_gif store[:display_media] = Setting.display_media store[:reduce_motion] = Setting.reduce_motion store[:use_blurhash] = Setting.use_blurhash + store[:crop_images] = Setting.crop_images end store diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml index d6ee1933f..9ed83fb93 100644 --- a/app/views/settings/preferences/appearance/show.html.haml +++ b/app/views/settings/preferences/appearance/show.html.haml @@ -25,6 +25,11 @@ = f.input :setting_reduce_motion, as: :boolean, wrapper: :with_label = f.input :setting_system_font_ui, as: :boolean, wrapper: :with_label + %h4= t 'appearance.toot_layout' + + .fields-group + = f.input :setting_crop_images, as: :boolean, wrapper: :with_label + %h4= t 'appearance.discovery' .fields-group diff --git a/config/locales/en.yml b/config/locales/en.yml index 458524c3d..6fc191e1a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -576,6 +576,7 @@ en: confirmation_dialogs: Confirmation dialogs discovery: Discovery sensitive_content: Sensitive content + toot_layout: Toot layout application_mailer: notification_preferences: Change e-mail preferences salutation: "%{name}," diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index dc39ec926..65951b73b 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -113,6 +113,7 @@ en: setting_aggregate_reblogs: Group boosts in timelines setting_auto_play_gif: Auto-play animated GIFs setting_boost_modal: Show confirmation dialog before boosting + setting_crop_images: Crop images in non-expanded toots to 16x9 setting_default_language: Posting language setting_default_privacy: Posting privacy setting_default_sensitive: Always mark media as sensitive diff --git a/config/settings.yml b/config/settings.yml index bd2f65b5e..f66e3922e 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -36,6 +36,7 @@ defaults: &defaults use_pending_items: false trends: true trendable_by_default: false + crop_images: true notification_emails: follow: false reblog: false -- cgit From 9b36f62df63003419cb2ca08e77f2fa69fed91ad Mon Sep 17 00:00:00 2001 From: Nima Boscarino Date: Fri, 25 Oct 2019 02:48:20 -0700 Subject: Add download button to audio and video players (#12179) * Add download button for audio player * Add download button for video player * fix padding for download button in Audio component --- app/javascript/mastodon/features/audio/index.js | 9 +++++++++ app/javascript/mastodon/features/video/index.js | 7 +++++++ app/javascript/mastodon/locales/defaultMessages.json | 4 ++++ app/javascript/styles/mastodon/components.scss | 4 ++++ 4 files changed, 24 insertions(+) (limited to 'app') diff --git a/app/javascript/mastodon/features/audio/index.js b/app/javascript/mastodon/features/audio/index.js index d3b309f0f..1b4cdbb4f 100644 --- a/app/javascript/mastodon/features/audio/index.js +++ b/app/javascript/mastodon/features/audio/index.js @@ -12,6 +12,7 @@ const messages = defineMessages({ pause: { id: 'video.pause', defaultMessage: 'Pause' }, mute: { id: 'video.mute', defaultMessage: 'Mute sound' }, unmute: { id: 'video.unmute', defaultMessage: 'Unmute sound' }, + download: { id: 'video.download', defaultMessage: 'Download file' }, }); export default @injectIntl @@ -218,6 +219,14 @@ class Audio extends React.PureComponent { {formatTime(this.state.duration || Math.floor(this.props.duration))}
    + +
    + +
    diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js index 07051ddf3..7ca477d35 100644 --- a/app/javascript/mastodon/features/video/index.js +++ b/app/javascript/mastodon/features/video/index.js @@ -19,6 +19,7 @@ const messages = defineMessages({ close: { id: 'video.close', defaultMessage: 'Close video' }, fullscreen: { id: 'video.fullscreen', defaultMessage: 'Full screen' }, exit_fullscreen: { id: 'video.exit_fullscreen', defaultMessage: 'Exit full screen' }, + download: { id: 'video.download', defaultMessage: 'Download file' }, }); export const formatTime = secondsNum => { @@ -494,7 +495,13 @@ class Video extends React.PureComponent { {(!onCloseVideo && !editable) && } {(!fullscreen && onOpenVideo) && } {onCloseVideo && } + +
    diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index 8ab40ce3c..4778ed56f 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -776,6 +776,10 @@ { "defaultMessage": "Unmute sound", "id": "video.unmute" + }, + { + "defaultMessage": "Download file", + "id": "video.download" } ], "path": "app/javascript/mastodon/features/audio/index.json" diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 52fe3bed0..417e8c899 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -5330,6 +5330,10 @@ a.status-card.compact:hover { display: flex; justify-content: space-between; padding-bottom: 10px; + + .video-player__download__icon { + color: inherit; + } } &__buttons { -- cgit