From ceb9be7dc5b3757182acbbf68a2bd4501cf2cfd0 Mon Sep 17 00:00:00 2001 From: Echo Date: Thu, 20 Aug 2026 12:04:30 +0000 Subject: [PATCH] Redesign: Menu and modal fixes (#40220) --- .../components/modal_shell/redesign.tsx | 6 +- .../features/compose/redesign/hints.tsx | 11 +- .../compose/redesign/modal_cancel.tsx | 19 ++- .../compose/redesign/modal_rearrange.tsx | 30 ++-- .../compose/redesign/modals.module.scss | 24 --- .../features/compose/redesign/upload.tsx | 159 +++++++++--------- app/javascript/mastodon/locales/en.json | 10 +- 7 files changed, 127 insertions(+), 132 deletions(-) diff --git a/app/javascript/mastodon/components/modal_shell/redesign.tsx b/app/javascript/mastodon/components/modal_shell/redesign.tsx index e224cae091b..4702269346e 100644 --- a/app/javascript/mastodon/components/modal_shell/redesign.tsx +++ b/app/javascript/mastodon/components/modal_shell/redesign.tsx @@ -57,7 +57,11 @@ export const ModalTitle: React.FC< const Header = `h${level}` as const; if (!noFocus) { return ( - + {children} ); diff --git a/app/javascript/mastodon/features/compose/redesign/hints.tsx b/app/javascript/mastodon/features/compose/redesign/hints.tsx index 60ae65b6f7a..1384e2a40fe 100644 --- a/app/javascript/mastodon/features/compose/redesign/hints.tsx +++ b/app/javascript/mastodon/features/compose/redesign/hints.tsx @@ -59,12 +59,13 @@ export const ComposeHints = () => { defaultMessage="You're replying to a followers-only post. People not following {user} might see your reply without the context of what you’re replying to." values={{ user: `@${replyFollowersHandle}` }} />, + 'followers-reply', ), ); } if (isDifferentLanguage) { - messages.push(); + messages.push(); } if (missingAlt && count === 1) { @@ -74,6 +75,7 @@ export const ComposeHints = () => { id='compose.hints.missing-alt' defaultMessage='Your attachment is missing alt text.' />, + 'missing-alt', ), ); } else if (missingAlt) { @@ -83,6 +85,7 @@ export const ComposeHints = () => { id='compose.hints.missing-alt-many' defaultMessage='One or more of your attachments are missing alt text.' />, + 'missing-alts', ), ); } @@ -94,8 +97,10 @@ export const ComposeHints = () => { return
{messages}
; }; -const defaultWrapper = (children: React.ReactNode) => ( - {children} +const defaultWrapper = (children: React.ReactNode, key: string) => ( + + {children} + ); const LanguageHint: React.FC<{ guess: string }> = ({ guess }) => { diff --git a/app/javascript/mastodon/features/compose/redesign/modal_cancel.tsx b/app/javascript/mastodon/features/compose/redesign/modal_cancel.tsx index 1e595160bb2..68be6e08535 100644 --- a/app/javascript/mastodon/features/compose/redesign/modal_cancel.tsx +++ b/app/javascript/mastodon/features/compose/redesign/modal_cancel.tsx @@ -4,6 +4,11 @@ import { FormattedMessage } from 'react-intl'; import { closeModal } from '@/mastodon/actions/modal'; import { Button } from '@/mastodon/components/button/redesign'; +import { + ModalActions, + ModalShell, + ModalTitle, +} from '@/mastodon/components/modal_shell/redesign'; import { focusComposerTextarea, openNewComposer, @@ -11,8 +16,6 @@ import { } from '@/mastodon/reducers/slices/composer'; import { useAppDispatch } from '@/mastodon/store'; -import classes from './modals.module.scss'; - const ComposerModalCancelConfirm: React.FC<{ openNew?: boolean }> = ({ openNew, }) => { @@ -37,20 +40,20 @@ const ComposerModalCancelConfirm: React.FC<{ openNew?: boolean }> = ({ }, [dispatch]); return ( -
-

+ + -

+ -
+ -
-
+ + ); }; diff --git a/app/javascript/mastodon/features/compose/redesign/modal_rearrange.tsx b/app/javascript/mastodon/features/compose/redesign/modal_rearrange.tsx index 79da37d2c17..4a3e88a915b 100644 --- a/app/javascript/mastodon/features/compose/redesign/modal_rearrange.tsx +++ b/app/javascript/mastodon/features/compose/redesign/modal_rearrange.tsx @@ -10,6 +10,11 @@ import { DotsSixVerticalIcon } from '@phosphor-icons/react'; import { rearrangeComposeAttachments } from '@/mastodon/actions/compose_typed'; import { Button, IconButton } from '@/mastodon/components/button/redesign'; +import { + ModalActions, + ModalShell, + ModalTitle, +} from '@/mastodon/components/modal_shell/redesign'; import { SortableList, SortableListItem, @@ -28,26 +33,26 @@ const messages = defineMessages({ }, onDragStart: { id: 'compose.rearrange_modal.drag_start', - defaultMessage: 'Picked up attachment at index {index, number}.', + defaultMessage: 'Picked up attachment at index {item, number}.', }, onDragMove: { id: 'compose.rearrange_modal.drag_move', - defaultMessage: 'Attachment index {index, number} was moved.', + defaultMessage: 'Attachment index {item, number} was moved.', }, onDragMoveOver: { id: 'compose.rearrange_modal.drag_over', defaultMessage: - 'Attachment index {index, number} was moved over index {over, number}.', + 'Attachment index {item, number} was moved over index {over, number}.', }, onDragEnd: { id: 'compose.rearrange_modal.drag_end', defaultMessage: - 'Attachment index {index, number} was moved to index {newIndex, number}.', + 'Attachment index {item, number} was moved to index {over, number}.', }, onDragCancel: { id: 'compose.rearrange_modal.drag_cancel', defaultMessage: - 'Dragging was cancelled. Attachment index {index, number} was dropped.', + 'Dragging was cancelled. Attachment index {item, number} was dropped.', }, }); @@ -80,16 +85,13 @@ const ComposerModalRearrange: React.FC<{ onClose: () => void }> = ({ ); return ( -
-

+ + -

+ void }> = ({ ))} -
+ -
-
+ + ); }; diff --git a/app/javascript/mastodon/features/compose/redesign/modals.module.scss b/app/javascript/mastodon/features/compose/redesign/modals.module.scss index 9f209142bab..d2c6b0d91e2 100644 --- a/app/javascript/mastodon/features/compose/redesign/modals.module.scss +++ b/app/javascript/mastodon/features/compose/redesign/modals.module.scss @@ -1,29 +1,5 @@ @use '@/styles/mastodon/mixins'; -.root { - @include mixins.elevation-2; - - border-radius: var(--radius-xl); - background: var(--color-bg-primary); - display: flex; - flex-direction: column; - gap: var(--space-md); - padding: var(--space-md); - pointer-events: auto; - user-select: text; - max-width: 100vw; -} - -.title { - @include mixins.type-heading-sm; -} - -.footer { - display: flex; - align-items: center; - justify-content: space-between; -} - // Attachment rearrange modal .attachmentRoot { diff --git a/app/javascript/mastodon/features/compose/redesign/upload.tsx b/app/javascript/mastodon/features/compose/redesign/upload.tsx index 01d8d82848c..309700134aa 100644 --- a/app/javascript/mastodon/features/compose/redesign/upload.tsx +++ b/app/javascript/mastodon/features/compose/redesign/upload.tsx @@ -1,5 +1,5 @@ import type React from 'react'; -import { useCallback, useState } from 'react'; +import { useCallback } from 'react'; import { FormattedMessage } from 'react-intl'; @@ -13,11 +13,13 @@ import type { ApiAudioAttachmentJSON } from '@/mastodon/api_types/media_attachme import { Blurhash } from '@/mastodon/components/blurhash'; import { IconButton } from '@/mastodon/components/button/redesign'; import { + Menu, + MenuButton, MenuItem, MenuItemDivider, MenuList, + useMenuContext, } from '@/mastodon/components/menu'; -import { useToggle } from '@/mastodon/hooks/useToggle'; import { useAppDispatch, useAppSelector } from '@/mastodon/store'; import classes from './attachments.module.scss'; @@ -33,26 +35,6 @@ export const ComposeUpload: React.FC<{ selectComposeAttachment(state, id), ); const sensitive = useAppSelector((state) => !!state.compose.get('spoiler')); - const [open, { onToggle, onFalse }] = useToggle(); - const [target, setTarget] = useState(null); - - const dispatch = useAppDispatch(); - const handleEdit = useCallback(() => { - if (id) { - dispatch( - openModal({ modalType: 'FOCAL_POINT', modalProps: { mediaId: id } }), - ); - } - }, [dispatch, id]); - const handleRearrange = useCallback(() => { - onFalse(); - dispatch(openModal({ modalType: 'COMPOSER_REARRANGE', modalProps: {} })); - }, [dispatch, onFalse]); - const handleDelete = useCallback(() => { - if (id) { - dispatch(undoUploadCompose(id)); - } - }, [dispatch, id]); if (!attachment || attachment.type === 'unknown') { return
; @@ -90,64 +72,22 @@ export const ComposeUpload: React.FC<{ )} - - - - - - - {attachment.description ? ( - - ) : ( - - )} - - - {!single && ( - - - - )} - - - - + - - + + + + {attachment.description && ( @@ -158,6 +98,71 @@ export const ComposeUpload: React.FC<{ ); }; +const ComposeUploadMenu: React.FC<{ + attachment: ComposeAttachment; + single?: boolean; +}> = ({ attachment, single }) => { + const dispatch = useAppDispatch(); + const id = attachment.id; + + const { popover } = useMenuContext(); + + const handleEdit = useCallback(() => { + popover.closeMenu(); + dispatch( + openModal({ modalType: 'FOCAL_POINT', modalProps: { mediaId: id } }), + ); + }, [dispatch, id, popover]); + const handleRearrange = useCallback(() => { + popover.closeMenu(); + dispatch(openModal({ modalType: 'COMPOSER_REARRANGE', modalProps: {} })); + }, [dispatch, popover]); + const handleDelete = useCallback(() => { + popover.closeMenu(); + dispatch(undoUploadCompose(id)); + }, [dispatch, id, popover]); + + return ( + + + {attachment.description ? ( + + ) : ( + + )} + + + {!single && ( + + + + )} + + + + + + + + ); +}; + const ComposeAudioUpload: React.FC<{ attachment: ComposeAttachment; }> = ({ attachment }) => { diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 544c131701e..a02f47b2888 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -524,12 +524,12 @@ "compose.published.open": "Open", "compose.quotable": "Allow others to quote", "compose.rearrange_modal.cancel": "Cancel", - "compose.rearrange_modal.drag_cancel": "Dragging was cancelled. Attachment index {index, number} was dropped.", - "compose.rearrange_modal.drag_end": "Attachment index {index, number} was moved to index {newIndex, number}.", + "compose.rearrange_modal.drag_cancel": "Dragging was cancelled. Attachment index {item, number} was dropped.", + "compose.rearrange_modal.drag_end": "Attachment index {item, number} was moved to index {over, number}.", "compose.rearrange_modal.drag_instructions": "To rearrange attachments, press space or enter. While dragging, use the arrow keys to move the attachment up or down. Press space or enter again to drop the attachment in its new position, or press escape to cancel.", - "compose.rearrange_modal.drag_move": "Attachment index {index, number} was moved.", - "compose.rearrange_modal.drag_over": "Attachment index {index, number} was moved over index {over, number}.", - "compose.rearrange_modal.drag_start": "Picked up attachment at index {index, number}.", + "compose.rearrange_modal.drag_move": "Attachment index {item, number} was moved.", + "compose.rearrange_modal.drag_over": "Attachment index {item, number} was moved over index {over, number}.", + "compose.rearrange_modal.drag_start": "Picked up attachment at index {item, number}.", "compose.rearrange_modal.handle": "Drag attachment at position {index, number}", "compose.rearrange_modal.save": "Save", "compose.rearrange_modal.title": "Rearrange media",