1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
@@ -16,6 +16,14 @@ import { formatTime } from 'mastodon/features/video';
import { autoPlayGif, displayMedia, useBlurhash } from '../initial_state';
+const colCount = function(size) { + return Math.max(Math.ceil(Math.sqrt(size)), 2); +}; + +const rowCount = function(size) { + return Math.ceil(size / colCount(size)); +}; + class Item extends PureComponent {
static propTypes = { @@ -87,14 +95,18 @@ class Item extends PureComponent { let badges = [], thumbnail;
let width = 50; - let height = 100; + let height = 50;
- if (size === 1) { - width = 100; - } + const cols = colCount(size); + const remaining = (-size % cols + cols) % cols; + const largeCount = Math.floor(remaining / 3); // width=2, height=2 + const mediumCount = remaining % 3; // height=2
- if (size === 4 || (size === 3 && index > 0)) { - height = 50; + if (size === 1 || index < largeCount) { + width = 100; + height = 100; + } else if (size === 2 || index < largeCount + mediumCount) { + height = 100; }
const description = attachment.getIn(['translation', 'description']) || attachment.get('description'); @@ -302,7 +314,12 @@ class MediaGallery extends PureComponent { if (this.isFullSizeEligible()) { style.aspectRatio = `${this.props.media.getIn([0, 'meta', 'small', 'aspect'])}`; } else { - style.aspectRatio = '3 / 2'; + const cols = colCount(media.size); + const rows = rowCount(media.size); + style.gridTemplateColumns = `repeat(${cols}, 1fr)`; + style.gridTemplateRows = `repeat(${rows}, 1fr)`; + + style.aspectRatio = '1 / 1'; }
const size = media.size;
@@ -33,6 +33,9 @@ import { useAppSelector, useAppDispatch } from 'mastodon/store'; import { Upload } from './upload'; import { UploadProgress } from './upload_progress';
+const colCount = (size: number) => Math.max(Math.ceil(Math.sqrt(size)), 2); +const rowCount = (size: number) => Math.ceil(size / colCount(size)); + const messages = defineMessages({ screenReaderInstructions: { id: 'upload_form.drag_and_drop.instructions', @@ -140,6 +143,15 @@ export const UploadForm: React.FC = () => { [intl], );
+ const style = { + gridTemplateColumns: '1fr', + gridTemplateRows: '1fr', + }; + const cols = colCount(mediaIds.size); + const rows = rowCount(mediaIds.size); + style.gridTemplateColumns = `repeat(${cols}, 1fr)`; + style.gridTemplateRows = `repeat(${rows}, 1fr)`; + return ( <> <UploadProgress @@ -151,6 +163,7 @@ export const UploadForm: React.FC = () => { {mediaIds.size > 0 && ( <div className={`compose-form__uploads media-gallery media-gallery--layout-${mediaIds.size}`} + style={style} > <DndContext sensors={sensors}
|