mirror of
https://github.com/mastodon/mastodon.git
synced 2024-12-25 10:17:47 +00:00
Merge pull request #1616 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes
This commit is contained in:
commit
44fd66f0c6
|
@ -124,8 +124,8 @@ class ColumnHeader extends React.PureComponent {
|
||||||
|
|
||||||
moveButtons = (
|
moveButtons = (
|
||||||
<div key='move-buttons' className='column-header__setting-arrows'>
|
<div key='move-buttons' className='column-header__setting-arrows'>
|
||||||
<button title={formatMessage(messages.moveLeft)} aria-label={formatMessage(messages.moveLeft)} className='text-btn column-header__setting-btn' onClick={this.handleMoveLeft}><Icon id='chevron-left' /></button>
|
<button title={formatMessage(messages.moveLeft)} aria-label={formatMessage(messages.moveLeft)} className='icon-button column-header__setting-btn' onClick={this.handleMoveLeft}><Icon id='chevron-left' /></button>
|
||||||
<button title={formatMessage(messages.moveRight)} aria-label={formatMessage(messages.moveRight)} className='text-btn column-header__setting-btn' onClick={this.handleMoveRight}><Icon id='chevron-right' /></button>
|
<button title={formatMessage(messages.moveRight)} aria-label={formatMessage(messages.moveRight)} className='icon-button column-header__setting-btn' onClick={this.handleMoveRight}><Icon id='chevron-right' /></button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (multiColumn && this.props.onPin) {
|
} else if (multiColumn && this.props.onPin) {
|
||||||
|
@ -146,8 +146,8 @@ class ColumnHeader extends React.PureComponent {
|
||||||
];
|
];
|
||||||
|
|
||||||
if (multiColumn) {
|
if (multiColumn) {
|
||||||
collapsedContent.push(moveButtons);
|
|
||||||
collapsedContent.push(pinButton);
|
collapsedContent.push(pinButton);
|
||||||
|
collapsedContent.push(moveButtons);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (children || (multiColumn && this.props.onPin)) {
|
if (children || (multiColumn && this.props.onPin)) {
|
||||||
|
|
|
@ -437,12 +437,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.column-header__setting-btn {
|
.column-header__setting-btn {
|
||||||
&:hover {
|
&:hover,
|
||||||
|
&:focus {
|
||||||
color: $darker-text-color;
|
color: $darker-text-color;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.column-header__collapsible__extra + .column-header__setting-btn {
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.column-header__permission-btn {
|
.column-header__permission-btn {
|
||||||
display: inline;
|
display: inline;
|
||||||
font-weight: inherit;
|
font-weight: inherit;
|
||||||
|
@ -453,10 +458,15 @@
|
||||||
float: right;
|
float: right;
|
||||||
|
|
||||||
.column-header__setting-btn {
|
.column-header__setting-btn {
|
||||||
padding: 0 10px;
|
padding: 5px;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-right: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
padding-right: 0;
|
padding-left: 7px;
|
||||||
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -829,7 +829,7 @@
|
||||||
transition: background-color 0.2s ease;
|
transition: background-color 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-toggle:hover:not(.react-toggle--disabled) .react-toggle-track {
|
.react-toggle:is(:hover, :focus-within):not(.react-toggle--disabled) .react-toggle-track {
|
||||||
background-color: darken($ui-base-color, 10%);
|
background-color: darken($ui-base-color, 10%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,7 +837,7 @@
|
||||||
background-color: $ui-highlight-color;
|
background-color: $ui-highlight-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-toggle--checked:hover:not(.react-toggle--disabled) .react-toggle-track {
|
.react-toggle--checked:is(:hover, :focus-within):not(.react-toggle--disabled) .react-toggle-track {
|
||||||
background-color: lighten($ui-highlight-color, 10%);
|
background-color: lighten($ui-highlight-color, 10%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,20 @@ body.rtl {
|
||||||
|
|
||||||
.column-header__setting-arrows {
|
.column-header__setting-arrows {
|
||||||
float: left;
|
float: left;
|
||||||
|
|
||||||
|
.column-header__setting-btn {
|
||||||
|
&:first-child {
|
||||||
|
padding-left: 7px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
padding-right: 7px;
|
||||||
|
padding-left: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.setting-toggle__label {
|
.setting-toggle__label {
|
||||||
|
@ -428,11 +442,6 @@ body.rtl {
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.column-header__setting-arrows .column-header__setting-btn:last-child {
|
|
||||||
padding-left: 0;
|
|
||||||
padding-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simple_form .input.radio_buttons .radio > label input {
|
.simple_form .input.radio_buttons .radio > label input {
|
||||||
left: auto;
|
left: auto;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
|
|
@ -119,8 +119,8 @@ class ColumnHeader extends React.PureComponent {
|
||||||
|
|
||||||
moveButtons = (
|
moveButtons = (
|
||||||
<div key='move-buttons' className='column-header__setting-arrows'>
|
<div key='move-buttons' className='column-header__setting-arrows'>
|
||||||
<button title={formatMessage(messages.moveLeft)} aria-label={formatMessage(messages.moveLeft)} className='text-btn column-header__setting-btn' onClick={this.handleMoveLeft}><Icon id='chevron-left' /></button>
|
<button title={formatMessage(messages.moveLeft)} aria-label={formatMessage(messages.moveLeft)} className='icon-button column-header__setting-btn' onClick={this.handleMoveLeft}><Icon id='chevron-left' /></button>
|
||||||
<button title={formatMessage(messages.moveRight)} aria-label={formatMessage(messages.moveRight)} className='text-btn column-header__setting-btn' onClick={this.handleMoveRight}><Icon id='chevron-right' /></button>
|
<button title={formatMessage(messages.moveRight)} aria-label={formatMessage(messages.moveRight)} className='icon-button column-header__setting-btn' onClick={this.handleMoveRight}><Icon id='chevron-right' /></button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (multiColumn && this.props.onPin) {
|
} else if (multiColumn && this.props.onPin) {
|
||||||
|
@ -141,8 +141,8 @@ class ColumnHeader extends React.PureComponent {
|
||||||
];
|
];
|
||||||
|
|
||||||
if (multiColumn) {
|
if (multiColumn) {
|
||||||
collapsedContent.push(moveButtons);
|
|
||||||
collapsedContent.push(pinButton);
|
collapsedContent.push(pinButton);
|
||||||
|
collapsedContent.push(moveButtons);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (children || (multiColumn && this.props.onPin)) {
|
if (children || (multiColumn && this.props.onPin)) {
|
||||||
|
|
|
@ -2822,7 +2822,7 @@ a.account__display-name {
|
||||||
transition: background-color 0.2s ease;
|
transition: background-color 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-toggle:hover:not(.react-toggle--disabled) .react-toggle-track {
|
.react-toggle:is(:hover, :focus-within):not(.react-toggle--disabled) .react-toggle-track {
|
||||||
background-color: darken($ui-base-color, 10%);
|
background-color: darken($ui-base-color, 10%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2830,7 +2830,7 @@ a.account__display-name {
|
||||||
background-color: $ui-highlight-color;
|
background-color: $ui-highlight-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-toggle--checked:hover:not(.react-toggle--disabled) .react-toggle-track {
|
.react-toggle--checked:is(:hover, :focus-within):not(.react-toggle--disabled) .react-toggle-track {
|
||||||
background-color: lighten($ui-highlight-color, 10%);
|
background-color: lighten($ui-highlight-color, 10%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3548,12 +3548,17 @@ a.status-card.compact:hover {
|
||||||
}
|
}
|
||||||
|
|
||||||
.column-header__setting-btn {
|
.column-header__setting-btn {
|
||||||
&:hover {
|
&:hover,
|
||||||
|
&:focus {
|
||||||
color: $darker-text-color;
|
color: $darker-text-color;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.column-header__collapsible__extra + .column-header__setting-btn {
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.column-header__permission-btn {
|
.column-header__permission-btn {
|
||||||
display: inline;
|
display: inline;
|
||||||
font-weight: inherit;
|
font-weight: inherit;
|
||||||
|
@ -3564,10 +3569,15 @@ a.status-card.compact:hover {
|
||||||
float: right;
|
float: right;
|
||||||
|
|
||||||
.column-header__setting-btn {
|
.column-header__setting-btn {
|
||||||
padding: 0 10px;
|
padding: 5px;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-right: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
padding-right: 0;
|
padding-left: 7px;
|
||||||
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,20 @@ body.rtl {
|
||||||
|
|
||||||
.column-header__setting-arrows {
|
.column-header__setting-arrows {
|
||||||
float: left;
|
float: left;
|
||||||
|
|
||||||
|
.column-header__setting-btn {
|
||||||
|
&:first-child {
|
||||||
|
padding-left: 7px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
padding-right: 7px;
|
||||||
|
padding-left: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.setting-toggle__label {
|
.setting-toggle__label {
|
||||||
|
@ -451,11 +465,6 @@ body.rtl {
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.column-header__setting-arrows .column-header__setting-btn:last-child {
|
|
||||||
padding-left: 0;
|
|
||||||
padding-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simple_form .input.radio_buttons .radio > label input {
|
.simple_form .input.radio_buttons .radio > label input {
|
||||||
left: auto;
|
left: auto;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
|
|
@ -167,12 +167,11 @@ class MediaAttachment < ApplicationRecord
|
||||||
processors: ->(f) { file_processors f },
|
processors: ->(f) { file_processors f },
|
||||||
convert_options: GLOBAL_CONVERT_OPTIONS
|
convert_options: GLOBAL_CONVERT_OPTIONS
|
||||||
|
|
||||||
before_file_post_process :set_type_and_extension
|
before_file_validate :set_type_and_extension
|
||||||
before_file_post_process :check_video_dimensions
|
before_file_validate :check_video_dimensions
|
||||||
|
|
||||||
validates_attachment_content_type :file, content_type: IMAGE_MIME_TYPES + VIDEO_MIME_TYPES + AUDIO_MIME_TYPES
|
validates_attachment_content_type :file, content_type: IMAGE_MIME_TYPES + VIDEO_MIME_TYPES + AUDIO_MIME_TYPES
|
||||||
validates_attachment_size :file, less_than: IMAGE_LIMIT, unless: :larger_media_format?
|
validates_attachment_size :file, less_than: ->(m) { m.larger_media_format? ? VIDEO_LIMIT : IMAGE_LIMIT }
|
||||||
validates_attachment_size :file, less_than: VIDEO_LIMIT, if: :larger_media_format?
|
|
||||||
remotable_attachment :file, VIDEO_LIMIT, suppress_errors: false, download_on_assign: false, attribute_name: :remote_url
|
remotable_attachment :file, VIDEO_LIMIT, suppress_errors: false, download_on_assign: false, attribute_name: :remote_url
|
||||||
|
|
||||||
has_attached_file :thumbnail,
|
has_attached_file :thumbnail,
|
||||||
|
|
|
@ -181,4 +181,32 @@ RSpec.describe MediaAttachment, type: :model do
|
||||||
expect(media.description.size).to be <= 1_500
|
expect(media.description.size).to be <= 1_500
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'size limit validation' do
|
||||||
|
it 'rejects video files that are too large' do
|
||||||
|
stub_const 'MediaAttachment::IMAGE_LIMIT', 100.megabytes
|
||||||
|
stub_const 'MediaAttachment::VIDEO_LIMIT', 1.kilobyte
|
||||||
|
expect { MediaAttachment.create!(account: Fabricate(:account), file: attachment_fixture('attachment.webm')) }.to raise_error(ActiveRecord::RecordInvalid)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'accepts video files that are small enough' do
|
||||||
|
stub_const 'MediaAttachment::IMAGE_LIMIT', 1.kilobyte
|
||||||
|
stub_const 'MediaAttachment::VIDEO_LIMIT', 100.megabytes
|
||||||
|
media = MediaAttachment.create!(account: Fabricate(:account), file: attachment_fixture('attachment.webm'))
|
||||||
|
expect(media.valid?).to be true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'rejects image files that are too large' do
|
||||||
|
stub_const 'MediaAttachment::IMAGE_LIMIT', 1.kilobyte
|
||||||
|
stub_const 'MediaAttachment::VIDEO_LIMIT', 100.megabytes
|
||||||
|
expect { MediaAttachment.create!(account: Fabricate(:account), file: attachment_fixture('attachment.jpg')) }.to raise_error(ActiveRecord::RecordInvalid)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'accepts image files that are small enough' do
|
||||||
|
stub_const 'MediaAttachment::IMAGE_LIMIT', 100.megabytes
|
||||||
|
stub_const 'MediaAttachment::VIDEO_LIMIT', 1.kilobyte
|
||||||
|
media = MediaAttachment.create!(account: Fabricate(:account), file: attachment_fixture('attachment.jpg'))
|
||||||
|
expect(media.valid?).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue