From 348a66890b75401cfc5fd5a42cd1af74f2d0546c Mon Sep 17 00:00:00 2001 From: Echo Date: Thu, 13 Aug 2026 12:22:05 +0000 Subject: [PATCH] Composer redesign: Poll duration (#40148) --- .../mastodon/components/button/redesign.tsx | 2 + .../form_fields/redesign.module.scss | 2 +- .../features/compose/redesign/poll.tsx | 106 +++++++++++++----- .../compose/redesign/styles.module.scss | 11 +- 4 files changed, 87 insertions(+), 34 deletions(-) diff --git a/app/javascript/mastodon/components/button/redesign.tsx b/app/javascript/mastodon/components/button/redesign.tsx index 0362e95b3c0..887fb24f2f8 100644 --- a/app/javascript/mastodon/components/button/redesign.tsx +++ b/app/javascript/mastodon/components/button/redesign.tsx @@ -12,6 +12,8 @@ import { Icon } from '../icon'; import classes from './redesign.module.scss'; +export const buttonClasses = classes; + interface ButtonPropsBase { size?: 'lg' | 'md' | 'sm' | 'xs'; variant?: 'solid' | 'ghost'; diff --git a/app/javascript/mastodon/components/form_fields/redesign.module.scss b/app/javascript/mastodon/components/form_fields/redesign.module.scss index d6bea5dd41c..0e603436970 100644 --- a/app/javascript/mastodon/components/form_fields/redesign.module.scss +++ b/app/javascript/mastodon/components/form_fields/redesign.module.scss @@ -64,7 +64,7 @@ input.input { } &:focus { - outline: 2px solid var(--color-border-strong); + outline: 2px solid var(--color-border-brand); } &:disabled { diff --git a/app/javascript/mastodon/features/compose/redesign/poll.tsx b/app/javascript/mastodon/features/compose/redesign/poll.tsx index e7fc8be36da..dc763fe18d1 100644 --- a/app/javascript/mastodon/features/compose/redesign/poll.tsx +++ b/app/javascript/mastodon/features/compose/redesign/poll.tsx @@ -3,6 +3,8 @@ import { useCallback, useId } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; +import classNames from 'classnames'; + import { PlusIcon } from '@phosphor-icons/react'; import { changePollSettings, removePoll } from '@/mastodon/actions/compose'; @@ -11,12 +13,13 @@ import { deletePollOption, updatePollOption, } from '@/mastodon/actions/compose_typed'; -import { Button } from '@/mastodon/components/button/redesign'; +import { Button, buttonClasses } from '@/mastodon/components/button/redesign'; import { ToggleField, TextInput, } from '@/mastodon/components/form_fields/redesign'; import { useAppSelector, useAppDispatch } from '@/mastodon/store'; +import { DAY, HOUR, MINUTE } from '@/mastodon/utils/time'; import { selectComposePoll } from './selectors'; import classes from './styles.module.scss'; @@ -40,26 +43,31 @@ const messages = defineMessages({ }, }); +const pollDurationOptions = [ + 5 * MINUTE, + 30 * MINUTE, + HOUR, + 12 * HOUR, + DAY, + 3 * DAY, + 7 * DAY, +]; +function durationToMessage(durationMs: number) { + if (durationMs < HOUR) { + return { message: messages.minutes, multiplier: MINUTE }; + } else if (durationMs < DAY) { + return { message: messages.hours, multiplier: HOUR }; + } + return { message: messages.days, multiplier: DAY }; +} + export const ComposePoll: React.FC = () => { const { options, maxOptions, expiresIn, multiple } = useAppSelector(selectComposePoll); const listId = useId(); + const intl = useIntl(); const dispatch = useAppDispatch(); - const handleAdd = useCallback(() => { - dispatch(addPollOption()); - }, [dispatch]); - const handlePollChangeMultiple: React.ChangeEventHandler = - useCallback( - (event) => { - dispatch(changePollSettings(expiresIn, event.target.checked)); - }, - [dispatch, expiresIn], - ); - const handleDelete = useCallback(() => { - dispatch(removePoll()); - }, [dispatch]); - const handleKeyDown = useCallback( (index: number, event: React.KeyboardEvent) => { const value = event.currentTarget.value; @@ -91,6 +99,28 @@ export const ComposePoll: React.FC = () => { }, [dispatch, listId, maxOptions], ); + const handleAdd = useCallback(() => { + dispatch(addPollOption()); + }, [dispatch]); + const handlePollChangeMultiple: React.ChangeEventHandler = + useCallback( + (event) => { + dispatch(changePollSettings(expiresIn, event.target.checked)); + }, + [dispatch, expiresIn], + ); + const handleDurationChange: React.ChangeEventHandler = + useCallback( + (event) => { + dispatch( + changePollSettings(Number.parseInt(event.target.value), multiple), + ); + }, + [dispatch, multiple], + ); + const handleDelete = useCallback(() => { + dispatch(removePoll()); + }, [dispatch]); const firstItemEmpty = !options.at(0); @@ -138,22 +168,36 @@ export const ComposePoll: React.FC = () => { />
- - - - ), - }} - tagName='span' - /> + + +   + +