diff --git a/app/javascript/mastodon/components/media_gallery.jsx b/app/javascript/mastodon/components/media_gallery.jsx
index ba54b7f90..35924008b 100644
--- a/app/javascript/mastodon/components/media_gallery.jsx
+++ b/app/javascript/mastodon/components/media_gallery.jsx
@@ -11,6 +11,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import { debounce } from 'lodash';
import { Blurhash } from 'mastodon/components/blurhash';
+import { formatTime } from 'mastodon/features/video';
import { autoPlayGif, displayMedia, useBlurhash } from '../initial_state';
@@ -57,7 +58,7 @@ class Item extends PureComponent {
hoverToPlay () {
const { attachment } = this.props;
- return !this.getAutoPlay() && attachment.get('type') === 'gifv';
+ return !this.getAutoPlay() && ['gifv', 'video'].includes(attachment.get('type'));
}
handleClick = (e) => {
@@ -150,10 +151,15 @@ class Item extends PureComponent {
/>
);
- } else if (attachment.get('type') === 'gifv') {
+ } else if (['gifv', 'video'].includes(attachment.get('type'))) {
const autoPlay = this.getAutoPlay();
+ const duration = attachment.getIn(['meta', 'original', 'duration']);
- badges.push(GIF);
+ if (attachment.get('type') === 'gifv') {
+ badges.push(GIF);
+ } else {
+ badges.push({formatTime(Math.floor(duration))});
+ }
thumbnail = (
@@ -167,6 +173,7 @@ class Item extends PureComponent {
onClick={this.handleClick}
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
+ onLoadedData={this.handleImageLoad}
autoPlay={autoPlay}
playsInline
loop
diff --git a/app/javascript/mastodon/components/status.jsx b/app/javascript/mastodon/components/status.jsx
index 6c32fd245..46926b4aa 100644
--- a/app/javascript/mastodon/components/status.jsx
+++ b/app/javascript/mastodon/components/status.jsx
@@ -449,7 +449,25 @@ class Status extends ImmutablePureComponent {
} else if (status.get('media_attachments').size > 0) {
const language = status.getIn(['translation', 'language']) || status.get('language');
- if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
+ if (['image', 'gifv'].includes(status.getIn(['media_attachments', 0, 'type'])) || status.get('media_attachments').size > 1) {
+ media = (
+
+ {Component => (
+
+ )}
+
+ );
+ } else if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
const attachment = status.getIn(['media_attachments', 0]);
const description = attachment.getIn(['translation', 'description']) || attachment.get('description');
@@ -501,24 +519,6 @@ class Status extends ImmutablePureComponent {
)}
);
- } else {
- media = (
-
- {Component => (
-
- )}
-
- );
}
} else if (status.get('spoiler_text').length === 0 && status.get('card')) {
media = (
diff --git a/app/javascript/mastodon/features/account_gallery/components/media_item.jsx b/app/javascript/mastodon/features/account_gallery/components/media_item.jsx
deleted file mode 100644
index 087e77575..000000000
--- a/app/javascript/mastodon/features/account_gallery/components/media_item.jsx
+++ /dev/null
@@ -1,158 +0,0 @@
-import PropTypes from 'prop-types';
-
-import classNames from 'classnames';
-
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import ImmutablePureComponent from 'react-immutable-pure-component';
-
-import AudiotrackIcon from '@/material-icons/400-24px/music_note.svg?react';
-import PlayArrowIcon from '@/material-icons/400-24px/play_arrow.svg?react';
-import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?react';
-import { Blurhash } from 'mastodon/components/blurhash';
-import { Icon } from 'mastodon/components/icon';
-import { autoPlayGif, displayMedia, useBlurhash } from 'mastodon/initial_state';
-
-export default class MediaItem extends ImmutablePureComponent {
-
- static propTypes = {
- attachment: ImmutablePropTypes.map.isRequired,
- displayWidth: PropTypes.number.isRequired,
- onOpenMedia: PropTypes.func.isRequired,
- };
-
- state = {
- visible: displayMedia !== 'hide_all' && !this.props.attachment.getIn(['status', 'sensitive']) || displayMedia === 'show_all',
- loaded: false,
- };
-
- handleImageLoad = () => {
- this.setState({ loaded: true });
- };
-
- handleMouseEnter = e => {
- if (this.hoverToPlay()) {
- e.target.play();
- }
- };
-
- handleMouseLeave = e => {
- if (this.hoverToPlay()) {
- e.target.pause();
- e.target.currentTime = 0;
- }
- };
-
- hoverToPlay () {
- return !autoPlayGif && ['gifv', 'video'].indexOf(this.props.attachment.get('type')) !== -1;
- }
-
- handleClick = e => {
- if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
- e.preventDefault();
-
- if (this.state.visible) {
- this.props.onOpenMedia(this.props.attachment);
- } else {
- this.setState({ visible: true });
- }
- }
- };
-
- render () {
- const { attachment, displayWidth } = this.props;
- const { visible, loaded } = this.state;
-
- const width = `${Math.floor((displayWidth - 4) / 3) - 4}px`;
- const height = width;
- const status = attachment.get('status');
- const title = status.get('spoiler_text') || attachment.get('description');
-
- let thumbnail, label, icon, content;
-
- if (!visible) {
- icon = (
-
-
-
- );
- } else {
- if (['audio', 'video'].includes(attachment.get('type'))) {
- content = (
-
- );
-
- if (attachment.get('type') === 'audio') {
- label =
;
- } else {
- label =
;
- }
- } else if (attachment.get('type') === 'image') {
- const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0;
- const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0;
- const x = ((focusX / 2) + .5) * 100;
- const y = ((focusY / -2) + .5) * 100;
-
- content = (
-
- );
- } else if (attachment.get('type') === 'gifv') {
- content = (
-
- );
-
- label = 'GIF';
- }
-
- thumbnail = (
-
- {content}
-
- {label && (
-
- {label}
-
- )}
-
- );
- }
-
- return (
-
- );
- }
-
-}
diff --git a/app/javascript/mastodon/features/account_gallery/components/media_item.tsx b/app/javascript/mastodon/features/account_gallery/components/media_item.tsx
new file mode 100644
index 000000000..1a294a74a
--- /dev/null
+++ b/app/javascript/mastodon/features/account_gallery/components/media_item.tsx
@@ -0,0 +1,197 @@
+import { useState, useCallback } from 'react';
+
+import classNames from 'classnames';
+
+import HeadphonesIcon from '@/material-icons/400-24px/headphones-fill.svg?react';
+import MovieIcon from '@/material-icons/400-24px/movie-fill.svg?react';
+import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?react';
+import { Blurhash } from 'mastodon/components/blurhash';
+import { Icon } from 'mastodon/components/icon';
+import { formatTime } from 'mastodon/features/video';
+import { autoPlayGif, displayMedia, useBlurhash } from 'mastodon/initial_state';
+import type { Status, MediaAttachment } from 'mastodon/models/status';
+
+export const MediaItem: React.FC<{
+ attachment: MediaAttachment;
+ onOpenMedia: (arg0: MediaAttachment) => void;
+}> = ({ attachment, onOpenMedia }) => {
+ const [visible, setVisible] = useState(
+ (displayMedia !== 'hide_all' &&
+ !attachment.getIn(['status', 'sensitive'])) ||
+ displayMedia === 'show_all',
+ );
+ const [loaded, setLoaded] = useState(false);
+
+ const handleImageLoad = useCallback(() => {
+ setLoaded(true);
+ }, [setLoaded]);
+
+ const handleMouseEnter = useCallback(
+ (e: React.MouseEvent
) => {
+ if (e.target instanceof HTMLVideoElement) {
+ void e.target.play();
+ }
+ },
+ [],
+ );
+
+ const handleMouseLeave = useCallback(
+ (e: React.MouseEvent) => {
+ if (e.target instanceof HTMLVideoElement) {
+ e.target.pause();
+ e.target.currentTime = 0;
+ }
+ },
+ [],
+ );
+
+ const handleClick = useCallback(
+ (e: React.MouseEvent) => {
+ if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
+ e.preventDefault();
+
+ if (visible) {
+ onOpenMedia(attachment);
+ } else {
+ setVisible(true);
+ }
+ }
+ },
+ [attachment, visible, onOpenMedia, setVisible],
+ );
+
+ const status = attachment.get('status') as Status;
+ const description = (attachment.getIn(['translation', 'description']) ||
+ attachment.get('description')) as string | undefined;
+ const previewUrl = attachment.get('preview_url') as string;
+ const fullUrl = attachment.get('url') as string;
+ const avatarUrl = status.getIn(['account', 'avatar_static']) as string;
+ const lang = status.get('language') as string;
+ const blurhash = attachment.get('blurhash') as string;
+ const statusId = status.get('id') as string;
+ const acct = status.getIn(['account', 'acct']) as string;
+ const type = attachment.get('type') as string;
+
+ let thumbnail;
+
+ const badges = [];
+
+ if (description && description.length > 0) {
+ badges.push(
+
+ ALT
+ ,
+ );
+ }
+
+ if (!visible) {
+ thumbnail = (
+
+
+
+ );
+ } else if (type === 'audio') {
+ thumbnail = (
+ <>
+
+
+
+
+
+ >
+ );
+ } else if (type === 'image') {
+ const focusX = (attachment.getIn(['meta', 'focus', 'x']) || 0) as number;
+ const focusY = (attachment.getIn(['meta', 'focus', 'y']) || 0) as number;
+ const x = (focusX / 2 + 0.5) * 100;
+ const y = (focusY / -2 + 0.5) * 100;
+
+ thumbnail = (
+
+ );
+ } else if (['video', 'gifv'].includes(type)) {
+ const duration = attachment.getIn([
+ 'meta',
+ 'original',
+ 'duration',
+ ]) as number;
+
+ thumbnail = (
+
+
+
+ {type === 'video' && (
+
+
+
+ )}
+
+ );
+
+ if (type === 'gifv') {
+ badges.push(
+
+ GIF
+ ,
+ );
+ } else {
+ badges.push(
+
+ {formatTime(Math.floor(duration))}
+ ,
+ );
+ }
+ }
+
+ return (
+
+ );
+};
diff --git a/app/javascript/mastodon/features/account_gallery/index.jsx b/app/javascript/mastodon/features/account_gallery/index.jsx
index 6a1d0b322..35a0fbd2c 100644
--- a/app/javascript/mastodon/features/account_gallery/index.jsx
+++ b/app/javascript/mastodon/features/account_gallery/index.jsx
@@ -20,7 +20,7 @@ import { expandAccountMediaTimeline } from '../../actions/timelines';
import HeaderContainer from '../account_timeline/containers/header_container';
import Column from '../ui/components/column';
-import MediaItem from './components/media_item';
+import { MediaItem } from './components/media_item';
const mapStateToProps = (state, { params: { acct, id } }) => {
const accountId = id || state.getIn(['accounts_map', normalizeForLookup(acct)]);
diff --git a/app/javascript/mastodon/features/status/components/detailed_status.tsx b/app/javascript/mastodon/features/status/components/detailed_status.tsx
index fa843122f..0bf1bfda8 100644
--- a/app/javascript/mastodon/features/status/components/detailed_status.tsx
+++ b/app/javascript/mastodon/features/status/components/detailed_status.tsx
@@ -151,7 +151,25 @@ export const DetailedStatus: React.FC<{
if (pictureInPicture.get('inUse')) {
media = ;
} else if (status.get('media_attachments').size > 0) {
- if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
+ if (
+ ['image', 'gifv'].includes(
+ status.getIn(['media_attachments', 0, 'type']) as string,
+ ) ||
+ status.get('media_attachments').size > 1
+ ) {
+ media = (
+
+ );
+ } else if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
const attachment = status.getIn(['media_attachments', 0]);
const description =
attachment.getIn(['translation', 'description']) ||
@@ -200,19 +218,6 @@ export const DetailedStatus: React.FC<{
onToggleVisibility={onToggleMediaVisibility}
/>
);
- } else {
- media = (
-
- );
}
} else if (status.get('spoiler_text').length === 0) {
media = (
diff --git a/app/javascript/mastodon/models/status.ts b/app/javascript/mastodon/models/status.ts
index 3900df4e3..7f9144280 100644
--- a/app/javascript/mastodon/models/status.ts
+++ b/app/javascript/mastodon/models/status.ts
@@ -10,3 +10,5 @@ export type Status = Immutable.Map;
type CardShape = Required;
export type Card = RecordOf;
+
+export type MediaAttachment = Immutable.Map;
diff --git a/app/javascript/material-icons/400-20px/mood-fill.svg b/app/javascript/material-icons/400-20px/mood-fill.svg
index ef72aeef6..febf01290 100644
--- a/app/javascript/material-icons/400-20px/mood-fill.svg
+++ b/app/javascript/material-icons/400-20px/mood-fill.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-20px/mood.svg b/app/javascript/material-icons/400-20px/mood.svg
index abb44c466..898697c4c 100644
--- a/app/javascript/material-icons/400-20px/mood.svg
+++ b/app/javascript/material-icons/400-20px/mood.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-20px/warning-fill.svg b/app/javascript/material-icons/400-20px/warning-fill.svg
index 85dd926d3..a4fc7efc5 100644
--- a/app/javascript/material-icons/400-20px/warning-fill.svg
+++ b/app/javascript/material-icons/400-20px/warning-fill.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-20px/warning.svg b/app/javascript/material-icons/400-20px/warning.svg
index d7d45a321..d67ad689a 100644
--- a/app/javascript/material-icons/400-20px/warning.svg
+++ b/app/javascript/material-icons/400-20px/warning.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-24px/add_photo_alternate-fill.svg b/app/javascript/material-icons/400-24px/add_photo_alternate-fill.svg
index deb3f8e0d..932454ac6 100644
--- a/app/javascript/material-icons/400-24px/add_photo_alternate-fill.svg
+++ b/app/javascript/material-icons/400-24px/add_photo_alternate-fill.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-24px/add_photo_alternate.svg b/app/javascript/material-icons/400-24px/add_photo_alternate.svg
index 0ae8ad841..80cd74f85 100644
--- a/app/javascript/material-icons/400-24px/add_photo_alternate.svg
+++ b/app/javascript/material-icons/400-24px/add_photo_alternate.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-24px/bookmarks-fill.svg b/app/javascript/material-icons/400-24px/bookmarks-fill.svg
index f5231f925..62e78c6b5 100644
--- a/app/javascript/material-icons/400-24px/bookmarks-fill.svg
+++ b/app/javascript/material-icons/400-24px/bookmarks-fill.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-24px/bookmarks.svg b/app/javascript/material-icons/400-24px/bookmarks.svg
index 67dffd685..6a1ea474c 100644
--- a/app/javascript/material-icons/400-24px/bookmarks.svg
+++ b/app/javascript/material-icons/400-24px/bookmarks.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-24px/headphones-fill.svg b/app/javascript/material-icons/400-24px/headphones-fill.svg
new file mode 100644
index 000000000..acc5e9236
--- /dev/null
+++ b/app/javascript/material-icons/400-24px/headphones-fill.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-24px/headphones.svg b/app/javascript/material-icons/400-24px/headphones.svg
new file mode 100644
index 000000000..788b32354
--- /dev/null
+++ b/app/javascript/material-icons/400-24px/headphones.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-24px/manufacturing-fill.svg b/app/javascript/material-icons/400-24px/manufacturing-fill.svg
new file mode 100644
index 000000000..f19180759
--- /dev/null
+++ b/app/javascript/material-icons/400-24px/manufacturing-fill.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-24px/manufacturing.svg b/app/javascript/material-icons/400-24px/manufacturing.svg
index e0946f5ba..f19180759 100644
--- a/app/javascript/material-icons/400-24px/manufacturing.svg
+++ b/app/javascript/material-icons/400-24px/manufacturing.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-24px/movie-fill.svg b/app/javascript/material-icons/400-24px/movie-fill.svg
new file mode 100644
index 000000000..d29540895
--- /dev/null
+++ b/app/javascript/material-icons/400-24px/movie-fill.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-24px/movie.svg b/app/javascript/material-icons/400-24px/movie.svg
new file mode 100644
index 000000000..e98fa4847
--- /dev/null
+++ b/app/javascript/material-icons/400-24px/movie.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-24px/quiet_time-fill.svg b/app/javascript/material-icons/400-24px/quiet_time-fill.svg
index aed5740db..b4595fa04 100644
--- a/app/javascript/material-icons/400-24px/quiet_time-fill.svg
+++ b/app/javascript/material-icons/400-24px/quiet_time-fill.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-24px/quiet_time.svg b/app/javascript/material-icons/400-24px/quiet_time.svg
index 552da6658..9295548f4 100644
--- a/app/javascript/material-icons/400-24px/quiet_time.svg
+++ b/app/javascript/material-icons/400-24px/quiet_time.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-24px/share-fill.svg b/app/javascript/material-icons/400-24px/share-fill.svg
index 5a6b0d0a8..dd9fa89c6 100644
--- a/app/javascript/material-icons/400-24px/share-fill.svg
+++ b/app/javascript/material-icons/400-24px/share-fill.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/javascript/material-icons/400-24px/share.svg b/app/javascript/material-icons/400-24px/share.svg
index 6876cd42d..23e617121 100644
--- a/app/javascript/material-icons/400-24px/share.svg
+++ b/app/javascript/material-icons/400-24px/share.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 1d710546c..f3464c83b 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -242,6 +242,7 @@
flex: 0 0 auto;
a {
+ display: flex;
color: inherit;
text-decoration: none;
}
@@ -5821,6 +5822,7 @@ a.status-card {
.icon {
width: 24px;
height: 24px;
+ filter: var(--overlay-icon-shadow);
}
&:hover,
@@ -5915,6 +5917,10 @@ a.status-card {
.icon-button {
color: $white;
+ .icon {
+ filter: var(--overlay-icon-shadow);
+ }
+
&:hover,
&:focus,
&:active {
@@ -5973,6 +5979,7 @@ a.status-card {
.media-modal__page-dot {
flex: 0 0 auto;
background-color: $white;
+ filter: var(--overlay-icon-shadow);
opacity: 0.4;
height: 6px;
width: 6px;
@@ -7053,8 +7060,8 @@ a.status-card {
width: 100%;
min-height: 64px;
display: grid;
- grid-template-columns: 50% 50%;
- grid-template-rows: 50% 50%;
+ grid-template-columns: 1fr 1fr;
+ grid-template-rows: 1fr 1fr;
gap: 2px;
&--layout-2 {
@@ -7123,6 +7130,9 @@ a.status-card {
position: relative;
border-radius: 8px;
overflow: hidden;
+ outline: 1px solid var(--media-outline-color);
+ outline-offset: -1px;
+ z-index: 1;
&--tall {
grid-row: span 2;
@@ -7131,15 +7141,44 @@ a.status-card {
&--wide {
grid-column: span 2;
}
+
+ &--square {
+ aspect-ratio: 1;
+ }
+
+ &__overlay {
+ position: absolute;
+ top: 0;
+ inset-inline-start: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-sizing: border-box;
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+ padding: 8px;
+ z-index: 1;
+
+ &--corner {
+ align-items: flex-start;
+ justify-content: flex-end;
+ }
+
+ .icon {
+ color: $white;
+ filter: var(--overlay-icon-shadow);
+ }
+ }
}
.media-gallery__item-thumbnail {
- cursor: zoom-in;
+ cursor: pointer;
display: block;
text-decoration: none;
color: $secondary-text-color;
position: relative;
- z-index: 1;
+ z-index: -1;
&,
img {
@@ -7159,7 +7198,7 @@ a.status-card {
position: absolute;
top: 0;
inset-inline-start: 0;
- z-index: 0;
+ z-index: -2;
background: $base-overlay-background;
&--hidden {
@@ -7172,22 +7211,16 @@ a.status-card {
overflow: hidden;
position: relative;
width: 100%;
+ z-index: -1;
}
.media-gallery__item-gifv-thumbnail {
- cursor: zoom-in;
+ cursor: pointer;
height: 100%;
object-fit: cover;
width: 100%;
}
-.media-gallery__item-thumbnail-label {
- clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
- clip: rect(1px, 1px, 1px, 1px);
- overflow: hidden;
- position: absolute;
-}
-
/* End Media Gallery */
.detailed,
@@ -7210,6 +7243,8 @@ a.status-card {
border-radius: 8px;
padding-bottom: 44px;
width: 100%;
+ outline: 1px solid var(--media-outline-color);
+ outline-offset: -1px;
&.editable {
border-radius: 0;
@@ -7266,6 +7301,7 @@ a.status-card {
.video-player__controls {
padding-top: 10px;
background: transparent;
+ z-index: 1;
}
}
@@ -7279,19 +7315,18 @@ a.status-card {
color: $white;
display: flex;
align-items: center;
+ outline: 1px solid var(--media-outline-color);
+ outline-offset: -1px;
+ z-index: 2;
&.editable {
border-radius: 0;
height: 100% !important;
}
- &:focus {
- outline: 0;
- }
-
video {
display: block;
- z-index: 1;
+ z-index: -2;
}
&.fullscreen {
@@ -7310,7 +7345,7 @@ a.status-card {
&__controls {
position: absolute;
direction: ltr;
- z-index: 2;
+ z-index: -1;
bottom: 0;
inset-inline-start: 0;
inset-inline-end: 0;
@@ -7625,26 +7660,16 @@ a.status-card {
}
.account-gallery__container {
- display: flex;
- flex-wrap: wrap;
- padding: 4px 2px;
-}
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr;
+ gap: 2px;
-.account-gallery__item {
- border: 0;
- box-sizing: border-box;
- display: block;
- position: relative;
- border-radius: 4px;
- overflow: hidden;
- margin: 2px;
+ .media-gallery__item {
+ border-radius: 0;
+ }
- &__icons {
- position: absolute;
- top: 50%;
- inset-inline-start: 50%;
- transform: translate(-50%, -50%);
- font-size: 24px;
+ .load-more {
+ grid-column: span 3;
}
}
diff --git a/app/javascript/styles/mastodon/variables.scss b/app/javascript/styles/mastodon/variables.scss
index 2601113d3..baaec5f58 100644
--- a/app/javascript/styles/mastodon/variables.scss
+++ b/app/javascript/styles/mastodon/variables.scss
@@ -111,6 +111,8 @@ $font-monospace: 'mastodon-font-monospace' !default;
--surface-variant-active-background-color: #{lighten($ui-base-color, 4%)};
--on-surface-color: #{transparentize($ui-base-color, 0.5)};
--avatar-border-radius: 8px;
+ --media-outline-color: #{rgba(#fcf8ff, 0.15)};
+ --overlay-icon-shadow: drop-shadow(0 0 8px #{rgba($base-shadow-color, 0.25)});
--error-background-color: #{darken($error-red, 16%)};
--error-active-background-color: #{darken($error-red, 12%)};
--on-error-color: #fff;