diff options
12 files changed, 90 insertions, 11 deletions
diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js index 572f34fa0..0af0935e6 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.js +++ b/app/javascript/flavours/glitch/features/account/components/header.js @@ -66,6 +66,15 @@ class Header extends ImmutablePureComponent { identity_props: ImmutablePropTypes.list, onFollow: PropTypes.func.isRequired, onBlock: PropTypes.func.isRequired, + onMention: PropTypes.func.isRequired, + onDirect: PropTypes.func.isRequired, + onReport: PropTypes.func.isRequired, + onReblogToggle: PropTypes.func.isRequired, + onMute: PropTypes.func.isRequired, + onBlockDomain: PropTypes.func.isRequired, + onUnblockDomain: PropTypes.func.isRequired, + onEndorseToggle: PropTypes.func.isRequired, + onAddToList: PropTypes.func.isRequired, onEditAccountNote: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, domain: PropTypes.string.isRequired, diff --git a/app/javascript/flavours/glitch/features/account_timeline/components/header.js b/app/javascript/flavours/glitch/features/account_timeline/components/header.js index 1bab05c72..8195735a1 100644 --- a/app/javascript/flavours/glitch/features/account_timeline/components/header.js +++ b/app/javascript/flavours/glitch/features/account_timeline/components/header.js @@ -24,7 +24,6 @@ export default class Header extends ImmutablePureComponent { onUnblockDomain: PropTypes.func.isRequired, onEndorseToggle: PropTypes.func.isRequired, onAddToList: PropTypes.func.isRequired, - onEditAccountNote: PropTypes.func.isRequired, hideTabs: PropTypes.bool, domain: PropTypes.string.isRequired, }; diff --git a/app/javascript/flavours/glitch/features/audio/index.js b/app/javascript/flavours/glitch/features/audio/index.js index 4e85e3c58..33e67fcbe 100644 --- a/app/javascript/flavours/glitch/features/audio/index.js +++ b/app/javascript/flavours/glitch/features/audio/index.js @@ -254,8 +254,9 @@ class Audio extends React.PureComponent { } _initAudioContext () { - const context = new AudioContext(); - const source = context.createMediaElementSource(this.audio); + const AudioContext = window.AudioContext || window.webkitAudioContext; + const context = new AudioContext(); + const source = context.createMediaElementSource(this.audio); this.visualizer.setAudioContext(context, source); source.connect(context.destination); diff --git a/app/javascript/flavours/glitch/features/compose/containers/warning_container.js b/app/javascript/flavours/glitch/features/compose/containers/warning_container.js index b9b0a2644..ea970c61f 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/warning_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/warning_container.js @@ -6,7 +6,22 @@ import { FormattedMessage } from 'react-intl'; import { me } from 'flavours/glitch/util/initial_state'; import { profileLink, termsLink } from 'flavours/glitch/util/backend_links'; -const APPROX_HASHTAG_RE = /(?:^|[^\/\)\w])#(\w*[a-zA-Z·]\w*)/i; +const HASHTAG_SEPARATORS = "_\\u00b7\\u200c"; +const ALPHA = '\\p{L}\\p{M}'; +const WORD = '\\p{L}\\p{M}\\p{N}\\p{Pc}'; +const APPROX_HASHTAG_RE = new RegExp( + '(?:^|[^\\/\\)\\w])#((' + + '[' + WORD + '_]' + + '[' + WORD + HASHTAG_SEPARATORS + ']*' + + '[' + ALPHA + HASHTAG_SEPARATORS + ']' + + '[' + WORD + HASHTAG_SEPARATORS +']*' + + '[' + WORD + '_]' + + ')|(' + + '[' + WORD + '_]*' + + '[' + ALPHA + ']' + + '[' + WORD + '_]*' + + '))', 'iu' +); const mapStateToProps = state => ({ needsLockWarning: state.getIn(['compose', 'privacy']) === 'private' && !state.getIn(['accounts', me, 'locked']), diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js index 9613b0b9e..61ecf045d 100644 --- a/app/javascript/mastodon/features/account/components/header.js +++ b/app/javascript/mastodon/features/account/components/header.js @@ -66,6 +66,16 @@ class Header extends ImmutablePureComponent { identity_props: ImmutablePropTypes.list, onFollow: PropTypes.func.isRequired, onBlock: PropTypes.func.isRequired, + onMention: PropTypes.func.isRequired, + onDirect: PropTypes.func.isRequired, + onReport: PropTypes.func.isRequired, + onReblogToggle: PropTypes.func.isRequired, + onMute: PropTypes.func.isRequired, + onBlockDomain: PropTypes.func.isRequired, + onUnblockDomain: PropTypes.func.isRequired, + onEndorseToggle: PropTypes.func.isRequired, + onAddToList: PropTypes.func.isRequired, + onEditAccountNote: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, domain: PropTypes.string.isRequired, }; diff --git a/app/javascript/mastodon/features/account_timeline/components/header.js b/app/javascript/mastodon/features/account_timeline/components/header.js index 4e1b27466..abb15edcc 100644 --- a/app/javascript/mastodon/features/account_timeline/components/header.js +++ b/app/javascript/mastodon/features/account_timeline/components/header.js @@ -23,7 +23,6 @@ export default class Header extends ImmutablePureComponent { onUnblockDomain: PropTypes.func.isRequired, onEndorseToggle: PropTypes.func.isRequired, onAddToList: PropTypes.func.isRequired, - onEditAccountNote: PropTypes.func.isRequired, hideTabs: PropTypes.bool, domain: PropTypes.string.isRequired, }; diff --git a/app/javascript/mastodon/features/audio/index.js b/app/javascript/mastodon/features/audio/index.js index 1ab1c3117..a4e00ba96 100644 --- a/app/javascript/mastodon/features/audio/index.js +++ b/app/javascript/mastodon/features/audio/index.js @@ -269,8 +269,9 @@ class Audio extends React.PureComponent { } _initAudioContext () { - const context = new AudioContext(); - const source = context.createMediaElementSource(this.audio); + const AudioContext = window.AudioContext || window.webkitAudioContext; + const context = new AudioContext(); + const source = context.createMediaElementSource(this.audio); this.visualizer.setAudioContext(context, source); source.connect(context.destination); diff --git a/app/javascript/mastodon/features/compose/containers/warning_container.js b/app/javascript/mastodon/features/compose/containers/warning_container.js index 8200a319f..947d20c5a 100644 --- a/app/javascript/mastodon/features/compose/containers/warning_container.js +++ b/app/javascript/mastodon/features/compose/containers/warning_container.js @@ -5,7 +5,22 @@ import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import { me } from '../../../initial_state'; -const APPROX_HASHTAG_RE = /(?:^|[^\/\)\w])#(\w*[a-zA-Z·]\w*)/i; +const HASHTAG_SEPARATORS = "_\\u00b7\\u200c"; +const ALPHA = '\\p{L}\\p{M}'; +const WORD = '\\p{L}\\p{M}\\p{N}\\p{Pc}'; +const APPROX_HASHTAG_RE = new RegExp( + '(?:^|[^\\/\\)\\w])#((' + + '[' + WORD + '_]' + + '[' + WORD + HASHTAG_SEPARATORS + ']*' + + '[' + ALPHA + HASHTAG_SEPARATORS + ']' + + '[' + WORD + HASHTAG_SEPARATORS +']*' + + '[' + WORD + '_]' + + ')|(' + + '[' + WORD + '_]*' + + '[' + ALPHA + ']' + + '[' + WORD + '_]*' + + '))', 'iu' +); const mapStateToProps = state => ({ needsLockWarning: state.getIn(['compose', 'privacy']) === 'private' && !state.getIn(['accounts', me, 'locked']), diff --git a/app/javascript/styles/mastodon/boost.scss b/app/javascript/styles/mastodon/boost.scss index 3489428f8..4b6c9b82e 100644 --- a/app/javascript/styles/mastodon/boost.scss +++ b/app/javascript/styles/mastodon/boost.scss @@ -15,5 +15,8 @@ button.icon-button i.fa-retweet { } button.icon-button.disabled i.fa-retweet { - background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' height='209' width='22'><path d='M 18.972656 1.2011719 C 18.829825 1.1881782 18.685932 1.2302188 18.572266 1.3300781 L 15.990234 3.5996094 C 15.58109 3.6070661 15.297269 3.609375 14.730469 3.609375 L 7.0996094 3.609375 L 9.4199219 6.4609375 L 9.4492188 6.5195312 L 12.664062 6.5195312 L 6.5761719 11.867188 C 6.5674697 11.818249 6.5507813 11.773891 6.5507812 11.720703 L 6.5507812 9.0195312 L 9.0507812 9.0195312 C 9.4207813 9.0495313 9.6792188 8.54 9.4492188 8.25 L 5.5 3.3496094 C 5.38 3.1796094 5.1607031 3.1003906 4.9707031 3.1503906 L 4.9707031 3.1601562 C 4.8707031 3.1901563 4.8 3.2598438 4.75 3.3398438 L 0.80078125 8.2402344 C 0.60078125 8.5402344 0.8292187 9.0190625 1.1992188 9.0390625 L 3.5996094 9.0390625 L 3.5996094 11.720703 C 3.5996094 13.045739 3.5690668 13.895038 3.6503906 14.4375 L 2.6152344 15.347656 C 2.3879011 15.547375 2.3754917 15.901081 2.5859375 16.140625 L 3.1464844 16.78125 C 3.3569308 17.020794 3.7101667 17.053234 3.9375 16.853516 L 19.892578 2.8359375 C 20.119911 2.6362188 20.134275 2.282513 19.923828 2.0429688 L 19.361328 1.4023438 C 19.256105 1.282572 19.115488 1.2141655 18.972656 1.2011719 z M 18.410156 6.7753906 L 15.419922 9.4042969 L 15.419922 9.9394531 L 14.810547 9.9394531 L 13.148438 11.400391 L 16.539062 15.640625 C 16.719062 15.890625 17.140313 15.890625 17.320312 15.640625 L 21.259766 10.740234 C 21.519766 10.460234 21.260625 9.9094531 20.890625 9.9394531 L 18.400391 9.9394531 L 18.400391 7.2402344 C 18.400391 7.0470074 18.407711 6.9489682 18.410156 6.7753906 z M 11.966797 12.439453 L 8.6679688 15.339844 L 14.919922 15.339844 L 12.619141 12.5 C 12.589141 12.48 12.590313 12.459453 12.570312 12.439453 L 11.966797 12.439453 z' fill='#{hex-color(darken($action-button-color, 13%))}' stroke-width='0'/></svg>"); + &, + &:hover { + background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' height='209' width='22'><path d='M 18.972656 1.2011719 C 18.829825 1.1881782 18.685932 1.2302188 18.572266 1.3300781 L 15.990234 3.5996094 C 15.58109 3.6070661 15.297269 3.609375 14.730469 3.609375 L 7.0996094 3.609375 L 9.4199219 6.4609375 L 9.4492188 6.5195312 L 12.664062 6.5195312 L 6.5761719 11.867188 C 6.5674697 11.818249 6.5507813 11.773891 6.5507812 11.720703 L 6.5507812 9.0195312 L 9.0507812 9.0195312 C 9.4207813 9.0495313 9.6792188 8.54 9.4492188 8.25 L 5.5 3.3496094 C 5.38 3.1796094 5.1607031 3.1003906 4.9707031 3.1503906 L 4.9707031 3.1601562 C 4.8707031 3.1901563 4.8 3.2598438 4.75 3.3398438 L 0.80078125 8.2402344 C 0.60078125 8.5402344 0.8292187 9.0190625 1.1992188 9.0390625 L 3.5996094 9.0390625 L 3.5996094 11.720703 C 3.5996094 13.045739 3.5690668 13.895038 3.6503906 14.4375 L 2.6152344 15.347656 C 2.3879011 15.547375 2.3754917 15.901081 2.5859375 16.140625 L 3.1464844 16.78125 C 3.3569308 17.020794 3.7101667 17.053234 3.9375 16.853516 L 19.892578 2.8359375 C 20.119911 2.6362188 20.134275 2.282513 19.923828 2.0429688 L 19.361328 1.4023438 C 19.256105 1.282572 19.115488 1.2141655 18.972656 1.2011719 z M 18.410156 6.7753906 L 15.419922 9.4042969 L 15.419922 9.9394531 L 14.810547 9.9394531 L 13.148438 11.400391 L 16.539062 15.640625 C 16.719062 15.890625 17.140313 15.890625 17.320312 15.640625 L 21.259766 10.740234 C 21.519766 10.460234 21.260625 9.9094531 20.890625 9.9394531 L 18.400391 9.9394531 L 18.400391 7.2402344 C 18.400391 7.0470074 18.407711 6.9489682 18.410156 6.7753906 z M 11.966797 12.439453 L 8.6679688 15.339844 L 14.919922 15.339844 L 12.619141 12.5 C 12.589141 12.48 12.590313 12.459453 12.570312 12.439453 L 11.966797 12.439453 z' fill='#{hex-color(darken($action-button-color, 13%))}' stroke-width='0'/></svg>"); + } } diff --git a/chart/values.yaml.template b/chart/values.yaml.template index 694bc4d42..ff680b81f 100644 --- a/chart/values.yaml.template +++ b/chart/values.yaml.template @@ -4,7 +4,7 @@ image: repository: tootsuite/mastodon pullPolicy: Always # https://hub.docker.com/r/tootsuite/mastodon/tags - tag: v3.1.5 + tag: v3.2.0 # alternatively, use `latest` for the latest release or `edge` for the image # built from the most recent commit # diff --git a/lib/paperclip/response_with_limit_adapter.rb b/lib/paperclip/response_with_limit_adapter.rb index 7d897b8d6..8711b1349 100644 --- a/lib/paperclip/response_with_limit_adapter.rb +++ b/lib/paperclip/response_with_limit_adapter.rb @@ -19,7 +19,7 @@ module Paperclip @original_filename = filename_from_content_disposition || filename_from_path || 'data' @size = @target.response.content_length @tempfile = copy_to_tempfile(@target) - @content_type = @target.response.mime_type || ContentTypeDetector.new(@tempfile.path).detect + @content_type = ContentTypeDetector.new(@tempfile.path).detect end def copy_to_tempfile(source) diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb index 2ac4acc12..51e0b8caf 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -18,6 +18,7 @@ RSpec.describe ActivityPub::Activity::Create do stub_request(:get, 'http://example.com/attachment.png').to_return(request_fixture('avatar.txt')) stub_request(:get, 'http://example.com/emoji.png').to_return(body: attachment_fixture('emojo.png')) + stub_request(:get, 'http://example.com/emojib.png').to_return(body: attachment_fixture('emojo.png'), headers: { 'Content-Type' => 'application/octet-stream' }) end describe '#perform' do @@ -451,6 +452,32 @@ RSpec.describe ActivityPub::Activity::Create do end end + context 'with emojis served with invalid content-type' do + let(:object_json) do + { + id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, + type: 'Note', + content: 'Lorem ipsum :tinkong:', + tag: [ + { + type: 'Emoji', + icon: { + url: 'http://example.com/emojib.png', + }, + name: 'tinkong', + }, + ], + } + end + + it 'creates status' do + status = sender.statuses.first + + expect(status).to_not be_nil + expect(status.emojis.map(&:shortcode)).to include('tinkong') + end + end + context 'with emojis missing name' do let(:object_json) do { |