From 4df50b9c7e547ce1d99a43eeccdd92d88406eca2 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 22 Aug 2025 14:34:37 +0200 Subject: [PATCH] Visibility Modal fixes (#35865) --- .../mastodon/components/dropdown_selector.tsx | 8 ++-- .../ui/components/visibility_modal.tsx | 43 ++++++++++--------- app/javascript/mastodon/locales/en.json | 3 +- .../styles/mastodon-light/diff.scss | 14 +++--- .../styles/mastodon/components.scss | 31 +++++++++++-- 5 files changed, 64 insertions(+), 35 deletions(-) diff --git a/app/javascript/mastodon/components/dropdown_selector.tsx b/app/javascript/mastodon/components/dropdown_selector.tsx index 9299e7d6bd7..672665c80e5 100644 --- a/app/javascript/mastodon/components/dropdown_selector.tsx +++ b/app/javascript/mastodon/components/dropdown_selector.tsx @@ -98,13 +98,13 @@ export const DropdownSelector: React.FC = ({ break; case 'Tab': if (e.shiftKey) { - element = - nodeRef.current?.children[index + 1] ?? - nodeRef.current?.firstElementChild; - } else { element = nodeRef.current?.children[index - 1] ?? nodeRef.current?.lastElementChild; + } else { + element = + nodeRef.current?.children[index + 1] ?? + nodeRef.current?.firstElementChild; } break; case 'Home': diff --git a/app/javascript/mastodon/features/ui/components/visibility_modal.tsx b/app/javascript/mastodon/features/ui/components/visibility_modal.tsx index 8e681ea5c52..4200cc4d41b 100644 --- a/app/javascript/mastodon/features/ui/components/visibility_modal.tsx +++ b/app/javascript/mastodon/features/ui/components/visibility_modal.tsx @@ -1,11 +1,4 @@ -import { - forwardRef, - useCallback, - useId, - useImperativeHandle, - useMemo, - useState, -} from 'react'; +import { forwardRef, useCallback, useId, useMemo, useState } from 'react'; import type { FC } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; @@ -16,6 +9,7 @@ import type { ApiQuotePolicy } from '@/mastodon/api_types/quotes'; import { isQuotePolicy } from '@/mastodon/api_types/quotes'; import { isStatusVisibility } from '@/mastodon/api_types/statuses'; import type { StatusVisibility } from '@/mastodon/api_types/statuses'; +import { Button } from '@/mastodon/components/button'; import { Dropdown } from '@/mastodon/components/dropdown'; import type { SelectItem } from '@/mastodon/components/dropdown_selector'; import { IconButton } from '@/mastodon/components/icon_button'; @@ -96,7 +90,8 @@ const selectStatusPolicy = createAppSelector( ); export const VisibilityModal: FC = forwardRef( - ({ onClose, onChange, statusId }, ref) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + ({ onClose, onChange, statusId }, _ref) => { const intl = useIntl(); const currentVisibility = useAppSelector((state) => statusId @@ -172,18 +167,10 @@ export const VisibilityModal: FC = forwardRef( setQuotePolicy(value); } }, []); - - // Save on close - useImperativeHandle( - ref, - () => ({ - getCloseConfirmationMessage() { - onChange(visibility, quotePolicy); - return null; - }, - }), - [onChange, quotePolicy, visibility], - ); + const handleSave = useCallback(() => { + onChange(visibility, quotePolicy); + onClose(); + }, [onChange, onClose, visibility, quotePolicy]); const privacyDropdownId = useId(); const quoteDropdownId = useId(); @@ -274,6 +261,20 @@ export const VisibilityModal: FC = forwardRef( +
+ + +
); diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index c025d8b69b6..63c96173cd7 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -987,5 +987,6 @@ "visibility_modal.quote_followers": "Followers only", "visibility_modal.quote_label": "Change who can quote", "visibility_modal.quote_nobody": "No one", - "visibility_modal.quote_public": "Anyone" + "visibility_modal.quote_public": "Anyone", + "visibility_modal.save": "Save" } diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss index 96d6f81bcfc..fe3265f357f 100644 --- a/app/javascript/styles/mastodon-light/diff.scss +++ b/app/javascript/styles/mastodon-light/diff.scss @@ -384,14 +384,8 @@ .compose-form__actions .icon-button.active, .dropdown-button.active, -.privacy-dropdown__option.active, -.privacy-dropdown__option:focus, .language-dropdown__dropdown__results__item:focus, .language-dropdown__dropdown__results__item.active, -.privacy-dropdown__option:focus .privacy-dropdown__option__content, -.privacy-dropdown__option:focus .privacy-dropdown__option__content strong, -.privacy-dropdown__option.active .privacy-dropdown__option__content, -.privacy-dropdown__option.active .privacy-dropdown__option__content strong, .language-dropdown__dropdown__results__item:focus .language-dropdown__dropdown__results__item__common-name, .language-dropdown__dropdown__results__item.active @@ -399,6 +393,14 @@ color: $white; } +.privacy-dropdown__option, +.visibility-dropdown__option { + &:focus, + &.active { + --dropdown-text-color: #{$white}; + } +} + .compose-form .spoiler-input__input { color: lighten($ui-highlight-color, 8%); } diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 9a153d4cbef..4e60cb8a649 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -5496,6 +5496,8 @@ a.status-card { .privacy-dropdown__option, .visibility-dropdown__option { + --dropdown-text-color: $primary-text-color; + font-size: 14px; line-height: 20px; letter-spacing: 0.25px; @@ -5505,7 +5507,22 @@ a.status-card { align-items: center; gap: 12px; border-radius: 4px; - color: $primary-text-color; + color: var(--dropdown-text-color); + + // Make sure adjacent hover/active states don't have a meeting radius. + &:hover + &:is(:focus, .active), + &:is(:focus, .active) + &:hover, + &:is(:focus, .active) + &:is(:focus, .active) { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + + &:hover:has(+ :focus, .active), + &:is(:focus, .active):has(+ :hover), + &:is(:focus, .active):has(+ :is(:focus, .active)) { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } &:hover, &:active { @@ -5515,7 +5532,7 @@ a.status-card { &:focus, &.active { background: $ui-highlight-color; - color: $primary-text-color; + color: var(--dropdown-text-color); outline: 0; .privacy-dropdown__option__content, @@ -5524,7 +5541,7 @@ a.status-card { .visibility-dropdown__option__content, .visibility-dropdown__option__content strong, .visibility-dropdown__option__additional { - color: $primary-text-color; + color: var(--dropdown-text-color); } } @@ -6532,6 +6549,14 @@ a.status-card { max-height: 45vh; } } + + &__actions { + display: flex; + align-items: center; + gap: 8px; + justify-content: flex-end; + padding: 0 24px 24px; + } } &__popout {