Skip to content

Commit

Permalink
[Glitch] Change media reordering design in the compose form in web UI
Browse files Browse the repository at this point in the history
Port 11a12e5 to glitch-soc

Signed-off-by: Claire <[email protected]>
  • Loading branch information
Gargron authored and ClearlyClaire committed Sep 29, 2024
1 parent 9e10fd5 commit e80971e
Show file tree
Hide file tree
Showing 7 changed files with 364 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ const messages = defineMessages({
export const SensitiveButton = () => {
const intl = useIntl();

const spoilersAlwaysOn = useAppSelector((state) => state.getIn(['local_settings', 'always_show_spoilers_field']));
const spoilerText = useAppSelector((state) => state.getIn(['compose', 'spoiler_text']));
const sensitive = useAppSelector((state) => state.getIn(['compose', 'sensitive']));
const spoiler = useAppSelector((state) => state.getIn(['compose', 'spoiler']));
const mediaCount = useAppSelector((state) => state.getIn(['compose', 'media_attachments']).size);
const spoilersAlwaysOn = useAppSelector((state) => state.local_settings.getIn(['always_show_spoilers_field']));
const spoilerText = useAppSelector((state) => state.compose.get('spoiler_text'));
const sensitive = useAppSelector((state) => state.compose.get('sensitive'));
const spoiler = useAppSelector((state) => state.compose.get('spoiler'));
const mediaCount = useAppSelector((state) => state.compose.get('media_attachments').size);
const disabled = spoilersAlwaysOn ? (spoilerText && spoilerText.length > 0) : spoiler;

const active = sensitive || (spoilersAlwaysOn && spoilerText && spoilerText.length > 0);
Expand Down

This file was deleted.

130 changes: 130 additions & 0 deletions app/javascript/flavours/glitch/features/compose/components/upload.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { useCallback } from 'react';

import { FormattedMessage } from 'react-intl';

import classNames from 'classnames';

import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';

import CloseIcon from '@/material-icons/400-20px/close.svg?react';
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
import WarningIcon from '@/material-icons/400-24px/warning.svg?react';
import {
undoUploadCompose,
initMediaEditModal,
} from 'flavours/glitch/actions/compose';
import { Blurhash } from 'flavours/glitch/components/blurhash';
import { Icon } from 'flavours/glitch/components/icon';
import type { MediaAttachment } from 'flavours/glitch/models/media_attachment';
import { useAppDispatch, useAppSelector } from 'flavours/glitch/store';

export const Upload: React.FC<{
id: string;
dragging?: boolean;
overlay?: boolean;
tall?: boolean;
wide?: boolean;
}> = ({ id, dragging, overlay, tall, wide }) => {
const dispatch = useAppDispatch();
const media = useAppSelector(
(state) =>
state.compose // eslint-disable-line @typescript-eslint/no-unsafe-call
.get('media_attachments') // eslint-disable-line @typescript-eslint/no-unsafe-member-access
.find((item: MediaAttachment) => item.get('id') === id) as // eslint-disable-line @typescript-eslint/no-unsafe-member-access
| MediaAttachment
| undefined,
);
const sensitive = useAppSelector(
(state) => state.compose.get('sensitive') as boolean, // eslint-disable-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
);

const handleUndoClick = useCallback(() => {
dispatch(undoUploadCompose(id));
}, [dispatch, id]);

const handleFocalPointClick = useCallback(() => {
dispatch(initMediaEditModal(id));
}, [dispatch, id]);

const { attributes, listeners, setNodeRef, transform, transition } =
useSortable({ id });

if (!media) {
return null;
}

const focusX = media.getIn(['meta', 'focus', 'x']) as number;
const focusY = media.getIn(['meta', 'focus', 'y']) as number;
const x = (focusX / 2 + 0.5) * 100;
const y = (focusY / -2 + 0.5) * 100;
const missingDescription =
((media.get('description') as string | undefined) ?? '').length === 0;

const style = {
transform: CSS.Transform.toString(transform),
transition,
};

return (
<div
className={classNames('compose-form__upload media-gallery__item', {
dragging,
overlay,
'media-gallery__item--tall': tall,
'media-gallery__item--wide': wide,
})}
ref={setNodeRef}
style={style}
{...attributes}
{...listeners}
>
<div
className='compose-form__upload__thumbnail'
style={{
backgroundImage: !sensitive
? `url(${media.get('preview_url') as string})`
: undefined,
backgroundPosition: `${x}% ${y}%`,
}}
>
{sensitive && (
<Blurhash
hash={media.get('blurhash') as string}
className='compose-form__upload__preview'
/>
)}

<div className='compose-form__upload__actions'>
<button
type='button'
className='icon-button compose-form__upload__delete'
onClick={handleUndoClick}
>
<Icon id='close' icon={CloseIcon} />
</button>
<button
type='button'
className='icon-button'
onClick={handleFocalPointClick}
>
<Icon id='edit' icon={EditIcon} />{' '}
<FormattedMessage id='upload_form.edit' defaultMessage='Edit' />
</button>
</div>

<div className='compose-form__upload__warning'>
<button
type='button'
className={classNames('icon-button', {
active: missingDescription,
})}
onClick={handleFocalPointClick}
>
{missingDescription && <Icon id='warning' icon={WarningIcon} />} ALT
</button>
</div>
</div>
</div>
);
};

This file was deleted.

Loading

0 comments on commit e80971e

Please sign in to comment.