Merge branch 'develop' into hooks-migration
This commit is contained in:
commit
f6d124241b
10 changed files with 82 additions and 99 deletions
|
@ -316,7 +316,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"tailwindcss/migration-from-tailwind-2": "error",
|
"tailwindcss/migration-from-tailwind-2": "error",
|
||||||
|
"tailwindcss/no-custom-classname": "off",
|
||||||
|
|
||||||
"formatjs/enforce-default-message": "error",
|
"formatjs/enforce-default-message": "error",
|
||||||
"formatjs/enforce-id": "error",
|
"formatjs/enforce-id": "error",
|
||||||
|
|
|
@ -152,10 +152,7 @@ const Item: React.FC<IItem> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={clsx('media-gallery__item', {
|
className={clsx('media-gallery__item', standalone)}
|
||||||
standalone,
|
|
||||||
'rounded-md': total > 1,
|
|
||||||
})}
|
|
||||||
key={attachment.id}
|
key={attachment.id}
|
||||||
style={{ position, float, left, top, right, bottom, height, width: `${width}%` }}
|
style={{ position, float, left, top, right, bottom, height, width: `${width}%` }}
|
||||||
>
|
>
|
||||||
|
@ -250,10 +247,7 @@ const Item: React.FC<IItem> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={clsx('media-gallery__item', `media-gallery__item--${attachment.type}`, {
|
className={clsx('media-gallery__item', `media-gallery__item--${attachment.type}`, standalone)}
|
||||||
standalone,
|
|
||||||
'rounded-md': total > 1,
|
|
||||||
})}
|
|
||||||
key={attachment.id}
|
key={attachment.id}
|
||||||
style={{ position, float, left, top, right, bottom, height, width: `${width}%` }}
|
style={{ position, float, left, top, right, bottom, height, width: `${width}%` }}
|
||||||
>
|
>
|
||||||
|
@ -351,34 +345,34 @@ const MediaGallery: React.FC<IMediaGallery> = (props) => {
|
||||||
|
|
||||||
if (isPortrait(ar1) && isPortrait(ar2)) {
|
if (isPortrait(ar1) && isPortrait(ar2)) {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 50, h: '100%', r: '2px' },
|
{ w: 50, h: '100%', r: '1px' },
|
||||||
{ w: 50, h: '100%', l: '2px' },
|
{ w: 50, h: '100%', l: '1px' },
|
||||||
];
|
];
|
||||||
} else if (isPanoramic(ar1) && isPanoramic(ar2)) {
|
} else if (isPanoramic(ar1) && isPanoramic(ar2)) {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 100, h: panoSize_px, b: '2px' },
|
{ w: 100, h: panoSize_px, b: '1px' },
|
||||||
{ w: 100, h: panoSize_px, t: '2px' },
|
{ w: 100, h: panoSize_px, t: '1px' },
|
||||||
];
|
];
|
||||||
} else if (
|
} else if (
|
||||||
(isPanoramic(ar1) && isPortrait(ar2)) ||
|
(isPanoramic(ar1) && isPortrait(ar2)) ||
|
||||||
(isPanoramic(ar1) && isNonConformingRatio(ar2))
|
(isPanoramic(ar1) && isNonConformingRatio(ar2))
|
||||||
) {
|
) {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 100, h: `${(w / maximumAspectRatio)}px`, b: '2px' },
|
{ w: 100, h: `${(w / maximumAspectRatio)}px`, b: '1px' },
|
||||||
{ w: 100, h: `${(w * 0.6)}px`, t: '2px' },
|
{ w: 100, h: `${(w * 0.6)}px`, t: '1px' },
|
||||||
];
|
];
|
||||||
} else if (
|
} else if (
|
||||||
(isPortrait(ar1) && isPanoramic(ar2)) ||
|
(isPortrait(ar1) && isPanoramic(ar2)) ||
|
||||||
(isNonConformingRatio(ar1) && isPanoramic(ar2))
|
(isNonConformingRatio(ar1) && isPanoramic(ar2))
|
||||||
) {
|
) {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 100, h: `${(w * 0.6)}px`, b: '2px' },
|
{ w: 100, h: `${(w * 0.6)}px`, b: '1px' },
|
||||||
{ w: 100, h: `${(w / maximumAspectRatio)}px`, t: '2px' },
|
{ w: 100, h: `${(w / maximumAspectRatio)}px`, t: '1px' },
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 50, h: '100%', r: '2px' },
|
{ w: 50, h: '100%', r: '1px' },
|
||||||
{ w: 50, h: '100%', l: '2px' },
|
{ w: 50, h: '100%', l: '1px' },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
} else if (size === 3) {
|
} else if (size === 3) {
|
||||||
|
@ -392,9 +386,9 @@ const MediaGallery: React.FC<IMediaGallery> = (props) => {
|
||||||
|
|
||||||
if (isPanoramic(ar1) && isNonConformingRatio(ar2) && isNonConformingRatio(ar3)) {
|
if (isPanoramic(ar1) && isNonConformingRatio(ar2) && isNonConformingRatio(ar3)) {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 100, h: '50%', b: '2px' },
|
{ w: 100, h: '50%', b: '1px' },
|
||||||
{ w: 50, h: '50%', t: '2px', r: '2px' },
|
{ w: 50, h: '50%', t: '1px', r: '1px' },
|
||||||
{ w: 50, h: '50%', t: '2px', l: '2px' },
|
{ w: 50, h: '50%', t: '1px', l: '1px' },
|
||||||
];
|
];
|
||||||
} else if (isPanoramic(ar1) && isPanoramic(ar2) && isPanoramic(ar3)) {
|
} else if (isPanoramic(ar1) && isPanoramic(ar2) && isPanoramic(ar3)) {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
|
@ -404,13 +398,13 @@ const MediaGallery: React.FC<IMediaGallery> = (props) => {
|
||||||
];
|
];
|
||||||
} else if (isPortrait(ar1) && isNonConformingRatio(ar2) && isNonConformingRatio(ar3)) {
|
} else if (isPortrait(ar1) && isNonConformingRatio(ar2) && isNonConformingRatio(ar3)) {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 50, h: '100%', r: '2px' },
|
{ w: 50, h: '100%', r: '1px' },
|
||||||
{ w: 50, h: '50%', b: '2px', l: '2px' },
|
{ w: 50, h: '50%', b: '1px', l: '1px' },
|
||||||
{ w: 50, h: '50%', t: '2px', l: '2px' },
|
{ w: 50, h: '50%', t: '1px', l: '1px' },
|
||||||
];
|
];
|
||||||
} else if (isNonConformingRatio(ar1) && isNonConformingRatio(ar2) && isPortrait(ar3)) {
|
} else if (isNonConformingRatio(ar1) && isNonConformingRatio(ar2) && isPortrait(ar3)) {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 50, h: '50%', b: '2px', r: '2px' },
|
{ w: 50, h: '50%', b: '1px', r: '1px' },
|
||||||
{ w: 50, h: '50%', l: '-2px', b: '-2px', pos: 'absolute', float: 'none' },
|
{ w: 50, h: '50%', l: '-2px', b: '-2px', pos: 'absolute', float: 'none' },
|
||||||
{ w: 50, h: '100%', r: '-2px', t: '0px', b: '0px', pos: 'absolute', float: 'none' },
|
{ w: 50, h: '100%', r: '-2px', t: '0px', b: '0px', pos: 'absolute', float: 'none' },
|
||||||
];
|
];
|
||||||
|
@ -419,33 +413,33 @@ const MediaGallery: React.FC<IMediaGallery> = (props) => {
|
||||||
(isPortrait(ar1) && isPortrait(ar2) && isPortrait(ar3))
|
(isPortrait(ar1) && isPortrait(ar2) && isPortrait(ar3))
|
||||||
) {
|
) {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 50, h: '50%', b: '2px', r: '2px' },
|
{ w: 50, h: '50%', b: '1px', r: '1px' },
|
||||||
{ w: 50, h: '100%', l: '2px', float: 'right' },
|
{ w: 50, h: '100%', l: '1px', float: 'right' },
|
||||||
{ w: 50, h: '50%', t: '2px', r: '2px' },
|
{ w: 50, h: '50%', t: '1px', r: '1px' },
|
||||||
];
|
];
|
||||||
} else if (
|
} else if (
|
||||||
(isPanoramic(ar1) && isPanoramic(ar2) && isNonConformingRatio(ar3)) ||
|
(isPanoramic(ar1) && isPanoramic(ar2) && isNonConformingRatio(ar3)) ||
|
||||||
(isPanoramic(ar1) && isPanoramic(ar2) && isPortrait(ar3))
|
(isPanoramic(ar1) && isPanoramic(ar2) && isPortrait(ar3))
|
||||||
) {
|
) {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 50, h: panoSize_px, b: '2px', r: '2px' },
|
{ w: 50, h: panoSize_px, b: '1px', r: '1px' },
|
||||||
{ w: 50, h: panoSize_px, b: '2px', l: '2px' },
|
{ w: 50, h: panoSize_px, b: '1px', l: '1px' },
|
||||||
{ w: 100, h: `${w - panoSize}px`, t: '2px' },
|
{ w: 100, h: `${w - panoSize}px`, t: '1px' },
|
||||||
];
|
];
|
||||||
} else if (
|
} else if (
|
||||||
(isNonConformingRatio(ar1) && isPanoramic(ar2) && isPanoramic(ar3)) ||
|
(isNonConformingRatio(ar1) && isPanoramic(ar2) && isPanoramic(ar3)) ||
|
||||||
(isPortrait(ar1) && isPanoramic(ar2) && isPanoramic(ar3))
|
(isPortrait(ar1) && isPanoramic(ar2) && isPanoramic(ar3))
|
||||||
) {
|
) {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 100, h: `${w - panoSize}px`, b: '2px' },
|
{ w: 100, h: `${w - panoSize}px`, b: '1px' },
|
||||||
{ w: 50, h: panoSize_px, t: '2px', r: '2px' },
|
{ w: 50, h: panoSize_px, t: '1px', r: '1px' },
|
||||||
{ w: 50, h: panoSize_px, t: '2px', l: '2px' },
|
{ w: 50, h: panoSize_px, t: '1px', l: '1px' },
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 50, h: '50%', b: '2px', r: '2px' },
|
{ w: 50, h: '50%', b: '1px', r: '1px' },
|
||||||
{ w: 50, h: '50%', b: '2px', l: '2px' },
|
{ w: 50, h: '50%', b: '1px', l: '1px' },
|
||||||
{ w: 100, h: '50%', t: '2px' },
|
{ w: 100, h: '50%', t: '1px' },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
} else if (size >= 4) {
|
} else if (size >= 4) {
|
||||||
|
@ -470,34 +464,34 @@ const MediaGallery: React.FC<IMediaGallery> = (props) => {
|
||||||
|
|
||||||
if (isPanoramic(ar1) && isPanoramic(ar2) && isNonConformingRatio(ar3) && isNonConformingRatio(ar4)) {
|
if (isPanoramic(ar1) && isPanoramic(ar2) && isNonConformingRatio(ar3) && isNonConformingRatio(ar4)) {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 50, h: panoSize_px, b: '2px', r: '2px' },
|
{ w: 50, h: panoSize_px, b: '1px', r: '1px' },
|
||||||
{ w: 50, h: panoSize_px, b: '2px', l: '2px' },
|
{ w: 50, h: panoSize_px, b: '1px', l: '1px' },
|
||||||
{ w: 50, h: `${(w / 2)}px`, t: '2px', r: '2px' },
|
{ w: 50, h: `${(w / 2)}px`, t: '1px', r: '1px' },
|
||||||
{ w: 50, h: `${(w / 2)}px`, t: '2px', l: '2px' },
|
{ w: 50, h: `${(w / 2)}px`, t: '1px', l: '1px' },
|
||||||
];
|
];
|
||||||
} else if (isNonConformingRatio(ar1) && isNonConformingRatio(ar2) && isPanoramic(ar3) && isPanoramic(ar4)) {
|
} else if (isNonConformingRatio(ar1) && isNonConformingRatio(ar2) && isPanoramic(ar3) && isPanoramic(ar4)) {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 50, h: `${(w / 2)}px`, b: '2px', r: '2px' },
|
{ w: 50, h: `${(w / 2)}px`, b: '1px', r: '1px' },
|
||||||
{ w: 50, h: `${(w / 2)}px`, b: '2px', l: '2px' },
|
{ w: 50, h: `${(w / 2)}px`, b: '1px', l: '1px' },
|
||||||
{ w: 50, h: panoSize_px, t: '2px', r: '2px' },
|
{ w: 50, h: panoSize_px, t: '1px', r: '1px' },
|
||||||
{ w: 50, h: panoSize_px, t: '2px', l: '2px' },
|
{ w: 50, h: panoSize_px, t: '1px', l: '1px' },
|
||||||
];
|
];
|
||||||
} else if (
|
} else if (
|
||||||
(isPortrait(ar1) && isNonConformingRatio(ar2) && isNonConformingRatio(ar3) && isNonConformingRatio(ar4)) ||
|
(isPortrait(ar1) && isNonConformingRatio(ar2) && isNonConformingRatio(ar3) && isNonConformingRatio(ar4)) ||
|
||||||
(isPortrait(ar1) && isPanoramic(ar2) && isPanoramic(ar3) && isPanoramic(ar4))
|
(isPortrait(ar1) && isPanoramic(ar2) && isPanoramic(ar3) && isPanoramic(ar4))
|
||||||
) {
|
) {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 67, h: '100%', r: '2px' },
|
{ w: 67, h: '100%', r: '1px' },
|
||||||
{ w: 33, h: '33%', b: '4px', l: '2px' },
|
{ w: 33, h: '33%', b: '4px', l: '1px' },
|
||||||
{ w: 33, h: '33%', l: '2px' },
|
{ w: 33, h: '33%', l: '1px' },
|
||||||
{ w: 33, h: '33%', t: '4px', l: '2px' },
|
{ w: 33, h: '33%', t: '4px', l: '1px' },
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
itemsDimensions = [
|
itemsDimensions = [
|
||||||
{ w: 50, h: '50%', b: '2px', r: '2px' },
|
{ w: 50, h: '50%', b: '1px', r: '1px' },
|
||||||
{ w: 50, h: '50%', b: '2px', l: '2px' },
|
{ w: 50, h: '50%', b: '1px', l: '1px' },
|
||||||
{ w: 50, h: '50%', t: '2px', r: '2px' },
|
{ w: 50, h: '50%', t: '1px', r: '1px' },
|
||||||
{ w: 50, h: '50%', t: '2px', l: '2px' },
|
{ w: 50, h: '50%', t: '1px', l: '1px' },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -557,7 +551,9 @@ const MediaGallery: React.FC<IMediaGallery> = (props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={clsx(className, 'media-gallery', { 'media-gallery--compact !h-12 bg-transparent': compact })}
|
className={clsx(className, 'media-gallery overflow-hidden rounded-md', {
|
||||||
|
'media-gallery--compact !h-12 bg-transparent': compact,
|
||||||
|
})}
|
||||||
style={sizeData.style}
|
style={sizeData.style}
|
||||||
ref={node}
|
ref={node}
|
||||||
>
|
>
|
||||||
|
|
|
@ -47,7 +47,7 @@ const Widget: React.FC<IWidget> = ({
|
||||||
action,
|
action,
|
||||||
}): JSX.Element => (
|
}): JSX.Element => (
|
||||||
<Stack space={4}>
|
<Stack space={4}>
|
||||||
{title || action || onActionClick && (
|
{(title || action || onActionClick) && (
|
||||||
<HStack space={2} alignItems='center' justifyContent='between'>
|
<HStack space={2} alignItems='center' justifyContent='between'>
|
||||||
{title && <WidgetTitle title={title} />}
|
{title && <WidgetTitle title={title} />}
|
||||||
{action || (onActionClick && (
|
{action || (onActionClick && (
|
||||||
|
|
|
@ -12,9 +12,10 @@ import type { AccountGalleryAttachment } from 'pl-fe/selectors';
|
||||||
interface IMediaItem {
|
interface IMediaItem {
|
||||||
attachment: AccountGalleryAttachment;
|
attachment: AccountGalleryAttachment;
|
||||||
onOpenMedia: (attachment: AccountGalleryAttachment) => void;
|
onOpenMedia: (attachment: AccountGalleryAttachment) => void;
|
||||||
|
isLast?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MediaItem: React.FC<IMediaItem> = ({ attachment, onOpenMedia }) => {
|
const MediaItem: React.FC<IMediaItem> = ({ attachment, onOpenMedia, isLast }) => {
|
||||||
const { autoPlayGif, displayMedia } = useSettings();
|
const { autoPlayGif, displayMedia } = useSettings();
|
||||||
const [visible, setVisible] = useState<boolean>(displayMedia !== 'hide_all' && !attachment.status?.sensitive || displayMedia === 'show_all');
|
const [visible, setVisible] = useState<boolean>(displayMedia !== 'hide_all' && !attachment.status?.sensitive || displayMedia === 'show_all');
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ const MediaItem: React.FC<IMediaItem> = ({ attachment, onOpenMedia }) => {
|
||||||
src={attachment.preview_url}
|
src={attachment.preview_url}
|
||||||
alt={attachment.description}
|
alt={attachment.description}
|
||||||
style={{ objectPosition: `${x}% ${y}%` }}
|
style={{ objectPosition: `${x}% ${y}%` }}
|
||||||
className='size-full overflow-hidden rounded-lg'
|
className={clsx('size-full overflow-hidden', { 'rounded-br-md': isLast })}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else if (['gifv', 'video'].indexOf(attachment.type) !== -1) {
|
} else if (['gifv', 'video'].indexOf(attachment.type) !== -1) {
|
||||||
|
@ -80,7 +81,7 @@ const MediaItem: React.FC<IMediaItem> = ({ attachment, onOpenMedia }) => {
|
||||||
thumbnail = (
|
thumbnail = (
|
||||||
<div className={clsx('media-gallery__gifv', { autoplay: autoPlayGif })}>
|
<div className={clsx('media-gallery__gifv', { autoplay: autoPlayGif })}>
|
||||||
<video
|
<video
|
||||||
className='media-gallery__item-gifv-thumbnail'
|
className={clsx('media-gallery__item-gifv-thumbnail overflow-hidden', { 'rounded-br-md': isLast })}
|
||||||
aria-label={attachment.description}
|
aria-label={attachment.description}
|
||||||
title={attachment.description}
|
title={attachment.description}
|
||||||
role='application'
|
role='application'
|
||||||
|
@ -100,7 +101,7 @@ const MediaItem: React.FC<IMediaItem> = ({ attachment, onOpenMedia }) => {
|
||||||
const fileExtensionLastIndex = remoteURL.lastIndexOf('.');
|
const fileExtensionLastIndex = remoteURL.lastIndexOf('.');
|
||||||
const fileExtension = remoteURL.slice(fileExtensionLastIndex + 1).toUpperCase();
|
const fileExtension = remoteURL.slice(fileExtensionLastIndex + 1).toUpperCase();
|
||||||
thumbnail = (
|
thumbnail = (
|
||||||
<div className='media-gallery__item-thumbnail'>
|
<div className={clsx('media-gallery__item-thumbnail', { 'rounded-br-md': isLast })}>
|
||||||
<span className='media-gallery__item__icons'><Icon src={require('@tabler/icons/outline/volume.svg')} /></span>
|
<span className='media-gallery__item__icons'><Icon src={require('@tabler/icons/outline/volume.svg')} /></span>
|
||||||
<span className='media-gallery__file-extension__label'>{fileExtension}</span>
|
<span className='media-gallery__file-extension__label'>{fileExtension}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -122,6 +123,7 @@ const MediaItem: React.FC<IMediaItem> = ({ attachment, onOpenMedia }) => {
|
||||||
hash={attachment.blurhash}
|
hash={attachment.blurhash}
|
||||||
className={clsx('media-gallery__preview', {
|
className={clsx('media-gallery__preview', {
|
||||||
'hidden': visible,
|
'hidden': visible,
|
||||||
|
'rounded-br-md': isLast,
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
{visible && thumbnail}
|
{visible && thumbnail}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { List as ImmutableList } from 'immutable';
|
import { List as ImmutableList } from 'immutable';
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
|
|
||||||
|
@ -14,21 +14,6 @@ import { useModalsStore } from 'pl-fe/stores';
|
||||||
|
|
||||||
import MediaItem from './components/media-item';
|
import MediaItem from './components/media-item';
|
||||||
|
|
||||||
interface ILoadMoreMedia {
|
|
||||||
maxId: string | null;
|
|
||||||
onLoadMore: (value: string | null) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const LoadMoreMedia: React.FC<ILoadMoreMedia> = ({ maxId, onLoadMore }) => {
|
|
||||||
const handleLoadMore = () => {
|
|
||||||
onLoadMore(maxId);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<LoadMore onClick={handleLoadMore} />
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccountGallery = () => {
|
const AccountGallery = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { username } = useParams<{ username: string }>();
|
const { username } = useParams<{ username: string }>();
|
||||||
|
@ -44,8 +29,6 @@ const AccountGallery = () => {
|
||||||
const isLoading = useAppSelector((state) => state.timelines.get(`account:${account?.id}:with_replies:media`)?.isLoading);
|
const isLoading = useAppSelector((state) => state.timelines.get(`account:${account?.id}:with_replies:media`)?.isLoading);
|
||||||
const hasMore = useAppSelector((state) => state.timelines.get(`account:${account?.id}:with_replies:media`)?.hasMore);
|
const hasMore = useAppSelector((state) => state.timelines.get(`account:${account?.id}:with_replies:media`)?.hasMore);
|
||||||
|
|
||||||
const node = useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
const handleScrollToBottom = () => {
|
const handleScrollToBottom = () => {
|
||||||
if (hasMore) {
|
if (hasMore) {
|
||||||
handleLoadMore();
|
handleLoadMore();
|
||||||
|
@ -97,7 +80,7 @@ const AccountGallery = () => {
|
||||||
let loadOlder = null;
|
let loadOlder = null;
|
||||||
|
|
||||||
if (hasMore && !(isLoading && attachments.size === 0)) {
|
if (hasMore && !(isLoading && attachments.size === 0)) {
|
||||||
loadOlder = <LoadMore className='my-auto' visible={!isLoading} onClick={handleLoadOlder} />;
|
loadOlder = <LoadMore className='my-auto mt-4' visible={!isLoading} onClick={handleLoadOlder} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isUnavailable) {
|
if (isUnavailable) {
|
||||||
|
@ -112,14 +95,13 @@ const AccountGallery = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column label={`@${account.acct}`} transparent withHeader={false}>
|
<Column label={`@${account.acct}`} transparent withHeader={false}>
|
||||||
<div role='feed' className='grid grid-cols-2 gap-2 sm:grid-cols-3' ref={node}>
|
<div role='feed' className='grid grid-cols-2 gap-1 overflow-hidden rounded-md sm:grid-cols-3'>
|
||||||
{attachments.map((attachment, index) => attachment === null ? (
|
{attachments.map((attachment, index) => (
|
||||||
<LoadMoreMedia key={'more:' + attachments.get(index + 1)?.id} maxId={index > 0 ? (attachments.get(index - 1)?.id || null) : null} onLoadMore={handleLoadMore} />
|
|
||||||
) : (
|
|
||||||
<MediaItem
|
<MediaItem
|
||||||
key={`${attachment.status.id}+${attachment.id}`}
|
key={`${attachment.status.id}+${attachment.id}`}
|
||||||
attachment={attachment}
|
attachment={attachment}
|
||||||
onOpenMedia={handleOpenMedia}
|
onOpenMedia={handleOpenMedia}
|
||||||
|
isLast={index === attachments.size - 1}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
@ -128,10 +110,10 @@ const AccountGallery = () => {
|
||||||
<FormattedMessage id='account_gallery.none' defaultMessage='No media to show.' />
|
<FormattedMessage id='account_gallery.none' defaultMessage='No media to show.' />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{loadOlder}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{loadOlder}
|
||||||
|
|
||||||
{isLoading && attachments.size === 0 && (
|
{isLoading && attachments.size === 0 && (
|
||||||
<div className='relative flex-auto px-8 py-4'>
|
<div className='relative flex-auto px-8 py-4'>
|
||||||
<Spinner />
|
<Spinner />
|
||||||
|
|
|
@ -67,12 +67,13 @@ const GroupGallery: React.FC<IGroupGallery> = (props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column label={group.display_name} transparent withHeader={false}>
|
<Column label={group.display_name} transparent withHeader={false}>
|
||||||
<div role='feed' className='mt-4 grid grid-cols-2 gap-2 sm:grid-cols-3'>
|
<div role='feed' className='mt-4 grid grid-cols-2 gap-1 overflow-hidden rounded-md sm:grid-cols-3'>
|
||||||
{attachments.map((attachment) => (
|
{attachments.map((attachment, index) => (
|
||||||
<MediaItem
|
<MediaItem
|
||||||
key={`${attachment.status.id}+${attachment.id}`}
|
key={`${attachment.status.id}+${attachment.id}`}
|
||||||
attachment={attachment}
|
attachment={attachment}
|
||||||
onOpenMedia={handleOpenMedia}
|
onOpenMedia={handleOpenMedia}
|
||||||
|
isLast={index === attachments.length - 1}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
|
|
@ -341,7 +341,7 @@ const Thread: React.FC<IThread> = ({
|
||||||
|
|
||||||
<StatusActionBar
|
<StatusActionBar
|
||||||
status={status}
|
status={status}
|
||||||
expandable={false}
|
expandable={!useWindowScroll}
|
||||||
space='lg'
|
space='lg'
|
||||||
withLabels
|
withLabels
|
||||||
/>
|
/>
|
||||||
|
@ -391,7 +391,7 @@ const Thread: React.FC<IThread> = ({
|
||||||
ref={node}
|
ref={node}
|
||||||
className={
|
className={
|
||||||
clsx('bg-white black:bg-black dark:bg-primary-900', {
|
clsx('bg-white black:bg-black dark:bg-primary-900', {
|
||||||
'h-full': !useWindowScroll,
|
'h-full overflow-auto': !useWindowScroll,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
|
@ -54,12 +54,13 @@ const GroupMediaPanel: React.FC<IGroupMediaPanel> = ({ group }) => {
|
||||||
|
|
||||||
if (!nineAttachments.isEmpty()) {
|
if (!nineAttachments.isEmpty()) {
|
||||||
return (
|
return (
|
||||||
<div className='grid grid-cols-3 gap-1'>
|
<div className='grid grid-cols-3 gap-0.5 overflow-hidden rounded-md'>
|
||||||
{nineAttachments.map((attachment, _index) => (
|
{nineAttachments.map((attachment, index) => (
|
||||||
<MediaItem
|
<MediaItem
|
||||||
key={`${attachment.status.id}+${attachment.id}`}
|
key={`${attachment.status.id}+${attachment.id}`}
|
||||||
attachment={attachment}
|
attachment={attachment}
|
||||||
onOpenMedia={handleOpenMedia}
|
onOpenMedia={handleOpenMedia}
|
||||||
|
isLast={index === nineAttachments.size - 1}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -52,12 +52,13 @@ const ProfileMediaPanel: React.FC<IProfileMediaPanel> = ({ account }) => {
|
||||||
|
|
||||||
if (!nineAttachments.isEmpty()) {
|
if (!nineAttachments.isEmpty()) {
|
||||||
return (
|
return (
|
||||||
<div className='grid grid-cols-3 gap-1'>
|
<div className='grid grid-cols-3 gap-0.5 overflow-hidden rounded-md'>
|
||||||
{nineAttachments.map((attachment, _index) => (
|
{nineAttachments.map((attachment, index) => (
|
||||||
<MediaItem
|
<MediaItem
|
||||||
key={`${attachment.status.id}+${attachment.id}`}
|
key={`${attachment.status.id}+${attachment.id}`}
|
||||||
attachment={attachment}
|
attachment={attachment}
|
||||||
onOpenMedia={handleOpenMedia}
|
onOpenMedia={handleOpenMedia}
|
||||||
|
isLast={index === nineAttachments.size - 1}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
@apply rounded-lg box-border overflow-hidden isolate relative w-full h-auto;
|
@apply rounded-lg box-border overflow-hidden isolate relative w-full h-auto;
|
||||||
|
|
||||||
&__item {
|
&__item {
|
||||||
@apply rounded-sm border-0 box-border block float-left relative overflow-hidden;
|
@apply border-0 box-border block float-left relative overflow-hidden;
|
||||||
|
|
||||||
&__icons {
|
&__icons {
|
||||||
@apply absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2;
|
@apply absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2;
|
||||||
|
@ -21,13 +21,13 @@
|
||||||
@apply text-gray-400 cursor-zoom-in block no-underline leading-[0] relative z-[1] h-full w-full;
|
@apply text-gray-400 cursor-zoom-in block no-underline leading-[0] relative z-[1] h-full w-full;
|
||||||
|
|
||||||
video {
|
video {
|
||||||
@apply w-full h-full object-cover
|
@apply w-full h-full object-cover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__preview {
|
&__preview {
|
||||||
@apply bg-gray-200 dark:bg-gray-900 rounded-lg w-full h-full object-cover absolute top-0 left-0 z-0;
|
@apply bg-gray-200 dark:bg-gray-900 w-full h-full object-cover absolute top-0 left-0 z-0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__gifv {
|
&__gifv {
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&__item-gifv-thumbnail {
|
&__item-gifv-thumbnail {
|
||||||
@apply rounded-md cursor-zoom-in h-full object-cover relative w-full z-[1] transform-none top-0;
|
@apply cursor-zoom-in h-full object-cover relative w-full z-[1] transform-none top-0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__gifv__label,
|
&__gifv__label,
|
||||||
|
@ -60,10 +60,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&--compact {
|
&--compact {
|
||||||
@apply rounded-sm;
|
@apply flex rounded-sm w-fit gap-0.5;
|
||||||
|
|
||||||
.media-gallery__item {
|
.media-gallery__item {
|
||||||
@apply h-12 w-12 inset-auto float-left mr-[5px] #{!important};
|
@apply h-12 w-12 inset-auto float-left #{!important};
|
||||||
|
|
||||||
&-overflow {
|
&-overflow {
|
||||||
@apply text-xl;
|
@apply text-xl;
|
||||||
|
|
Loading…
Reference in a new issue