diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js index baa98e98fe..e9b657424e 100644 --- a/app/javascript/flavours/glitch/actions/compose.js +++ b/app/javascript/flavours/glitch/actions/compose.js @@ -266,7 +266,7 @@ export function doodleSet(options) { export function uploadCompose(files) { return function (dispatch, getState) { - const uploadLimit = 4; + const uploadLimit = 20; const media = getState().getIn(['compose', 'media_attachments']); const pending = getState().getIn(['compose', 'pending_media_attachments']); const progress = new Array(files.length).fill(0); @@ -285,7 +285,7 @@ export function uploadCompose(files) { dispatch(uploadComposeRequest()); for (const [i, f] of Array.from(files).entries()) { - if (media.size + i > 3) break; + if (media.size + i > 19) break; resizeImage(f).then(file => { const data = new FormData(); diff --git a/app/javascript/flavours/glitch/components/media_gallery.js b/app/javascript/flavours/glitch/components/media_gallery.js index 68195ea807..a0c1531cc4 100644 --- a/app/javascript/flavours/glitch/components/media_gallery.js +++ b/app/javascript/flavours/glitch/components/media_gallery.js @@ -101,52 +101,45 @@ class Item extends React.PureComponent { render () { const { attachment, index, size, standalone, letterbox, displayWidth, visible } = this.props; - let width = 50; + let width = 100; let height = 100; let top = 'auto'; let left = 'auto'; let bottom = 'auto'; let right = 'auto'; - if (size === 1) { - width = 100; - } + let root = Math.sqrt(size); + let numCols = Math.ceil(root); + let numRows = Math.ceil(size / numCols); - if (size === 4 || (size === 3 && index > 0)) { - height = 50; + let col = index % numCols; + let row = Math.floor(index / numCols); + if(row === numRows - 1) { + width = 100 / (1 + ((size - 1) % numCols)); + } else { + width = 100 / numCols; } - - if (size === 2) { - if (index === 0) { + height = 100 / numRows; + + if(numCols > 1) { + if(col === 0) { right = '2px'; + } else if(col === numCols - 1) { + left = '2px';; } else { left = '2px'; - } - } else if (size === 3) { - if (index === 0) { right = '2px'; - } else if (index > 0) { - left = '2px'; } + } - if (index === 1) { + if(numRows > 1) { + if(row === 0) { bottom = '2px'; - } else if (index > 1) { + } else if(row === numRows - 1) { top = '2px'; - } - } else if (size === 4) { - if (index === 0 || index === 2) { - right = '2px'; - } - - if (index === 1 || index === 3) { - left = '2px'; - } - - if (index < 2) { - bottom = '2px'; } else { top = '2px'; + bottom = '2px'; } } @@ -154,7 +147,7 @@ class Item extends React.PureComponent { if (attachment.get('type') === 'unknown') { return ( -
+
+
attachment.get('type') === 'unknown'); const width = this.state.width || defaultWidth; @@ -366,7 +359,7 @@ class MediaGallery extends React.PureComponent { if (this.isStandaloneEligible()) { children = ; } else { - children = media.take(4).map((attachment, i) => ); + children = media.take(20).map((attachment, i) => ); // Attachment limit patch } if (uncached) { diff --git a/app/javascript/flavours/glitch/features/compose/containers/options_container.js b/app/javascript/flavours/glitch/features/compose/containers/options_container.js index c792aa5827..78012d69ab 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/options_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/options_container.js @@ -17,7 +17,7 @@ function mapStateToProps (state) { acceptContentTypes: state.getIn(['media_attachments', 'accept_content_types']).toArray().join(','), resetFileKey: state.getIn(['compose', 'resetFileKey']), hasPoll: !!poll, - allowMedia: !poll && (media ? media.size + pending_media < 4 && !media.some(item => ['video', 'audio'].includes(item.get('type'))) : pending_media < 4), + allowMedia: !poll && (media ? media.size + pending_media < 20 && !media.some(item => ['video', 'audio'].includes(item.get('type'))) : pending_media < 20), hasMedia: media && !!media.size, allowPoll: !(media && !!media.size), showContentTypeChoice: state.getIn(['local_settings', 'show_content_type_choice']), diff --git a/app/javascript/flavours/glitch/features/ui/index.js b/app/javascript/flavours/glitch/features/ui/index.js index 7ca1adf7cc..b6224e30e6 100644 --- a/app/javascript/flavours/glitch/features/ui/index.js +++ b/app/javascript/flavours/glitch/features/ui/index.js @@ -68,7 +68,7 @@ const messages = defineMessages({ const mapStateToProps = state => ({ hasComposingText: state.getIn(['compose', 'text']).trim().length !== 0, hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0, - canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < 4, + canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < 20, layout: state.getIn(['local_settings', 'layout']), isWide: state.getIn(['local_settings', 'stretch']), navbarUnder: state.getIn(['local_settings', 'navbar_under']), diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index f3129f8d9e..4962ba07e2 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -230,7 +230,7 @@ export function submitComposeFail(error) { export function uploadCompose(files) { return function (dispatch, getState) { - const uploadLimit = 4; + const uploadLimit = 20; // attachment limit patch const media = getState().getIn(['compose', 'media_attachments']); const pending = getState().getIn(['compose', 'pending_media_attachments']); const progress = new Array(files.length).fill(0); @@ -249,7 +249,7 @@ export function uploadCompose(files) { dispatch(uploadComposeRequest()); for (const [i, f] of Array.from(files).entries()) { - if (media.size + i > 3) break; + if (media.size + i > 19) break; // attachment limit patch resizeImage(f).then(file => { const data = new FormData(); diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js index 2e7ce2e608..344e046de6 100644 --- a/app/javascript/mastodon/components/media_gallery.js +++ b/app/javascript/mastodon/components/media_gallery.js @@ -87,46 +87,47 @@ class Item extends React.PureComponent { let left = 'auto'; let bottom = 'auto'; let right = 'auto'; - - if (size === 1) { - width = 100; - } - - if (size === 4 || (size === 3 && index > 0)) { - height = 50; + + let root = Math.sqrt(size); + let numCols = Math.ceil(root); + let numRows = Math.ceil(size / numCols); + + let row = Math.floor(index / numCols); + if(row === numRows - 1) { + width = 100 / (1 + ((size - 1) % numCols)); + } else { + width = 100 / numCols; + } + height = 100 / numRows; + + let col = index % numCols; + let row = Math.floor(index / numCols); + if(row === numRows - 1) { + width = 100 / (1 + ((size - 1) % numCols)); + } else { + width = 100 / numCols; } - - if (size === 2) { - if (index === 0) { + height = 100 / numRows; + + if(numCols > 1) { + if(col === 0) { right = '2px'; + } else if(col === numCols - 1) { + left = '2px';; } else { left = '2px'; - } - } else if (size === 3) { - if (index === 0) { right = '2px'; - } else if (index > 0) { - left = '2px'; } + } - if (index === 1) { + if(numRows > 1) { + if(row === 0) { bottom = '2px'; - } else if (index > 1) { + } else if(row === numRows - 1) { top = '2px'; - } - } else if (size === 4) { - if (index === 0 || index === 2) { - right = '2px'; - } - - if (index === 1 || index === 3) { - left = '2px'; - } - - if (index < 2) { - bottom = '2px'; } else { top = '2px'; + bottom = '2px'; } } @@ -134,7 +135,7 @@ class Item extends React.PureComponent { if (attachment.get('type') === 'unknown') { return ( -
+
+
attachment.get('type') === 'unknown'); if (standalone && this.isFullSizeEligible()) { children = ; } else { - children = media.take(4).map((attachment, i) => ); + children = media.take(20).map((attachment, i) => ); } if (uncached) { diff --git a/app/javascript/mastodon/features/compose/containers/upload_button_container.js b/app/javascript/mastodon/features/compose/containers/upload_button_container.js index 221b98e310..45e327805f 100644 --- a/app/javascript/mastodon/features/compose/containers/upload_button_container.js +++ b/app/javascript/mastodon/features/compose/containers/upload_button_container.js @@ -3,7 +3,7 @@ import UploadButton from '../components/upload_button'; import { uploadCompose } from '../../../actions/compose'; const mapStateToProps = state => ({ - disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size + state.getIn(['compose', 'pending_media_attachments']) > 3 || state.getIn(['compose', 'media_attachments']).some(m => ['video', 'audio'].includes(m.get('type')))), + disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size + state.getIn(['compose', 'pending_media_attachments']) > 19 || state.getIn(['compose', 'media_attachments']).some(m => ['video', 'audio'].includes(m.get('type')))), unavailable: state.getIn(['compose', 'poll']) !== null, resetFileKey: state.getIn(['compose', 'resetFileKey']), }); diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index 3feffa6564..39cf55be6f 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -69,7 +69,7 @@ const mapStateToProps = state => ({ isComposing: state.getIn(['compose', 'is_composing']), hasComposingText: state.getIn(['compose', 'text']).trim().length !== 0, hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0, - canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < 4, + canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < 20, dropdownMenuIsOpen: state.getIn(['dropdown_menu', 'openId']) !== null, firstLaunch: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION, username: state.getIn(['accounts', me, 'username']), diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index cf31b6ff62..71d66b3bd7 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -122,7 +122,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity visibility: @status_parser.visibility, thread: replied_to_status, conversation: conversation_from_uri(@object['conversation']), - media_attachment_ids: process_attachments.take(4).map(&:id), + media_attachment_ids: process_attachments.take(20).map(&:id), poll: process_poll, } end @@ -255,7 +255,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity as_array(@object['attachment']).each do |attachment| media_attachment_parser = ActivityPub::Parser::MediaAttachmentParser.new(attachment) - next if media_attachment_parser.remote_url.blank? || media_attachments.size >= 4 + next if media_attachment_parser.remote_url.blank? || media_attachments.size >= 20 begin media_attachment = MediaAttachment.create( diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index 7438a7c536..afa239efea 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -48,7 +48,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService as_array(@json['attachment']).each do |attachment| media_attachment_parser = ActivityPub::Parser::MediaAttachmentParser.new(attachment) - next if media_attachment_parser.remote_url.blank? || next_media_attachments.size > 4 + next if media_attachment_parser.remote_url.blank? || next_media_attachments.size > 20 begin media_attachment = previous_media_attachments.find { |previous_media_attachment| previous_media_attachment.remote_url == media_attachment_parser.remote_url } diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index c5061dd635..a289d43265 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -111,9 +111,9 @@ class PostStatusService < BaseService def validate_media! return if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable) - raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4 || @options[:poll].present? + raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 20 || @options[:poll].present? # Attachment limit patch - @media = @account.media_attachments.where(status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i)) + @media = @account.media_attachments.where(status_id: nil).where(id: @options[:media_ids].take(20).map(&:to_i)) # Attachment limit patch raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if @media.size > 1 && @media.find(&:audio_or_video?) raise Mastodon::ValidationError, I18n.t('media_attachments.validations.not_ready') if @media.any?(&:not_processed?) diff --git a/app/services/update_status_service.rb b/app/services/update_status_service.rb index 76530a54c7..dcfce8a562 100644 --- a/app/services/update_status_service.rb +++ b/app/services/update_status_service.rb @@ -55,9 +55,9 @@ class UpdateStatusService < BaseService def validate_media! return [] if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable) - raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4 || @options[:poll].present? + raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 20 || @options[:poll].present? # Attachment limit patch - media_attachments = @status.account.media_attachments.where(status_id: [nil, @status.id]).where(scheduled_status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i)).to_a + media_attachments = @status.account.media_attachments.where(status_id: [nil, @status.id]).where(scheduled_status_id: nil).where(id: @options[:media_ids].take(20).map(&:to_i)).to_a # Attachment limit patch raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if media_attachments.size > 1 && media_attachments.find(&:audio_or_video?) raise Mastodon::ValidationError, I18n.t('media_attachments.validations.not_ready') if media_attachments.any?(&:not_processed?)