diff --git a/packages/pl-fe/src/actions/notifications.ts b/packages/pl-fe/src/actions/notifications.ts index b02dfcf1b..7d4c8d7fa 100644 --- a/packages/pl-fe/src/actions/notifications.ts +++ b/packages/pl-fe/src/actions/notifications.ts @@ -71,7 +71,7 @@ const updateNotifications = (notification: BaseNotification) => dispatch(importEntities({ accounts: [notification.account, notification.type === 'move' ? notification.target : undefined], - statuses: [getNotificationStatus(notification)], + statuses: [getNotificationStatus(notification) as any], })); if (showInColumn) { diff --git a/packages/pl-fe/src/actions/statuses.ts b/packages/pl-fe/src/actions/statuses.ts index 348daa636..3df9c6c90 100644 --- a/packages/pl-fe/src/actions/statuses.ts +++ b/packages/pl-fe/src/actions/statuses.ts @@ -42,12 +42,6 @@ const STATUS_UNMUTE_REQUEST = 'STATUS_UNMUTE_REQUEST' as const; const STATUS_UNMUTE_SUCCESS = 'STATUS_UNMUTE_SUCCESS' as const; const STATUS_UNMUTE_FAIL = 'STATUS_UNMUTE_FAIL' as const; -const STATUS_REVEAL_MEDIA = 'STATUS_REVEAL_MEDIA' as const; -const STATUS_HIDE_MEDIA = 'STATUS_HIDE_MEDIA' as const; - -const STATUS_EXPAND_SPOILER = 'STATUS_EXPAND_SPOILER' as const; -const STATUS_COLLAPSE_SPOILER = 'STATUS_COLLAPSE_SPOILER' as const; - const STATUS_UNFILTER = 'STATUS_UNFILTER' as const; const STATUS_LANGUAGE_CHANGE = 'STATUS_LANGUAGE_CHANGE' as const; @@ -212,58 +206,6 @@ const toggleMuteStatus = (status: Pick) => } }; -const hideStatusMedia = (statusIds: string[] | string) => { - if (!Array.isArray(statusIds)) { - statusIds = [statusIds]; - } - - return { - type: STATUS_HIDE_MEDIA, - statusIds, - }; -}; - -const revealStatusMedia = (statusIds: string[] | string) => { - if (!Array.isArray(statusIds)) { - statusIds = [statusIds]; - } - - return { - type: STATUS_REVEAL_MEDIA, - statusIds, - }; -}; - -const toggleStatusMediaHidden = (status: Pick) => { - if (status.hidden) { - return revealStatusMedia(status.id); - } else { - return hideStatusMedia(status.id); - } -}; - -const collapseStatusSpoiler = (statusIds: string[] | string) => { - if (!Array.isArray(statusIds)) { - statusIds = [statusIds]; - } - - return { - type: STATUS_COLLAPSE_SPOILER, - statusIds, - }; -}; - -const expandStatusSpoiler = (statusIds: string[] | string) => { - if (!Array.isArray(statusIds)) { - statusIds = [statusIds]; - } - - return { - type: STATUS_EXPAND_SPOILER, - statusIds, - }; -}; - // let TRANSLATIONS_QUEUE: Set = new Set(); // let TRANSLATIONS_TIMEOUT: NodeJS.Timeout | null = null; @@ -346,10 +288,6 @@ type StatusesAction = | { type: typeof STATUS_UNMUTE_REQUEST; statusId: string } | { type: typeof STATUS_UNMUTE_SUCCESS; statusId: string } | { type: typeof STATUS_UNMUTE_FAIL; statusId: string; error: unknown } - | ReturnType - | ReturnType - | ReturnType - | ReturnType | ReturnType | ReturnType; @@ -375,10 +313,6 @@ export { STATUS_UNMUTE_REQUEST, STATUS_UNMUTE_SUCCESS, STATUS_UNMUTE_FAIL, - STATUS_REVEAL_MEDIA, - STATUS_HIDE_MEDIA, - STATUS_EXPAND_SPOILER, - STATUS_COLLAPSE_SPOILER, STATUS_UNFILTER, STATUS_LANGUAGE_CHANGE, createStatus, @@ -391,11 +325,6 @@ export { muteStatus, unmuteStatus, toggleMuteStatus, - hideStatusMedia, - revealStatusMedia, - toggleStatusMediaHidden, - expandStatusSpoiler, - collapseStatusSpoiler, unfilterStatus, changeStatusLanguage, type StatusesAction, diff --git a/packages/pl-fe/src/components/attachment-thumbs.tsx b/packages/pl-fe/src/components/attachment-thumbs.tsx index 1129afd21..04423bedd 100644 --- a/packages/pl-fe/src/components/attachment-thumbs.tsx +++ b/packages/pl-fe/src/components/attachment-thumbs.tsx @@ -4,7 +4,7 @@ import { MediaGallery } from 'pl-fe/features/ui/util/async-components'; import { useSettings } from 'pl-fe/hooks/use-settings'; import { useModalsStore } from 'pl-fe/stores/modals'; -import { isMediaVisible } from './statuses/sensitive-content-overlay'; +import { useMediaVisible } from './statuses/sensitive-content-overlay'; import type { MediaAttachment } from 'pl-api'; import type { Status } from 'pl-fe/normalizers/status'; @@ -21,7 +21,7 @@ const AttachmentThumbs = ({ status, onClick }: IAttachmentThumbs) => { const fallback =
; const onOpenMedia = (media: Array, index: number) => openModal('MEDIA', { media, index }); - const visible = isMediaVisible(status, displayMedia); + const visible = useMediaVisible(status, displayMedia); return (
diff --git a/packages/pl-fe/src/components/status-action-bar.tsx b/packages/pl-fe/src/components/status-action-bar.tsx index dbeb44665..413173f89 100644 --- a/packages/pl-fe/src/components/status-action-bar.tsx +++ b/packages/pl-fe/src/components/status-action-bar.tsx @@ -708,7 +708,7 @@ const MenuButton: React.FC = ({ }); }; - const handleOpenReactionsModal = (): void => { + const handleOpenReactionsModal = () => { openModal('REACTIONS', { statusId: status.id }); }; diff --git a/packages/pl-fe/src/components/status-content.tsx b/packages/pl-fe/src/components/status-content.tsx index b2288966d..0bdf368d7 100644 --- a/packages/pl-fe/src/components/status-content.tsx +++ b/packages/pl-fe/src/components/status-content.tsx @@ -2,7 +2,6 @@ import clsx from 'clsx'; import React, { useState, useRef, useLayoutEffect, useMemo, useEffect } from 'react'; import { FormattedMessage } from 'react-intl'; -import { collapseStatusSpoiler, expandStatusSpoiler } from 'pl-fe/actions/statuses'; import { useStatusTranslation } from 'pl-fe/api/hooks/statuses/use-status-translation'; import Icon from 'pl-fe/components/icon'; import Button from 'pl-fe/components/ui/button'; @@ -10,7 +9,6 @@ import Stack from 'pl-fe/components/ui/stack'; import Text from 'pl-fe/components/ui/text'; import Emojify from 'pl-fe/features/emoji/emojify'; import QuotedStatus from 'pl-fe/features/status/containers/quoted-status-container'; -import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch'; import { useSettings } from 'pl-fe/hooks/use-settings'; import { useStatusMetaStore } from 'pl-fe/stores/status-meta'; import { onlyEmoji as isOnlyEmoji } from 'pl-fe/utils/rich-content'; @@ -83,7 +81,6 @@ const StatusContent: React.FC = React.memo(({ preview, withMedia, }) => { - const dispatch = useAppDispatch(); const { displaySpoilers } = useSettings(); const [collapsed, setCollapsed] = useState(false); @@ -93,8 +90,9 @@ const StatusContent: React.FC = React.memo(({ const node = useRef(null); const spoilerNode = useRef(null); - const { statuses: statusesMeta } = useStatusMetaStore(); - const { data: translation } = useStatusTranslation(status.id, statusesMeta[status.id]?.targetLanguage); + const { statuses: statusesMeta, collapseStatus, expandStatus } = useStatusMetaStore(); + const statusMeta = statusesMeta[status.id] || {}; + const { data: translation } = useStatusTranslation(status.id, statusMeta.targetLanguage); const maybeSetCollapsed = (): void => { if (!node.current) return; @@ -120,8 +118,8 @@ const StatusContent: React.FC = React.memo(({ e.preventDefault(); e.stopPropagation(); - if (expanded) dispatch(collapseStatusSpoiler(status.id)); - else dispatch(expandStatusSpoiler(status.id)); + if (expanded) collapseStatus(status.id); + else expandStatus(status.id); }; useLayoutEffect(() => { @@ -166,7 +164,7 @@ const StatusContent: React.FC = React.memo(({ }); const expandable = !displaySpoilers; - const expanded = !withSpoiler || status.expanded || false; + const expanded = !withSpoiler || statusMeta.expanded || false; const output = []; diff --git a/packages/pl-fe/src/components/status-media.tsx b/packages/pl-fe/src/components/status-media.tsx index 63c241fc2..d0df2eea4 100644 --- a/packages/pl-fe/src/components/status-media.tsx +++ b/packages/pl-fe/src/components/status-media.tsx @@ -7,14 +7,14 @@ import { MediaGallery, Video, Audio } from 'pl-fe/features/ui/util/async-compone import { useSettings } from 'pl-fe/hooks/use-settings'; import { useModalsStore } from 'pl-fe/stores/modals'; -import { isMediaVisible } from './statuses/sensitive-content-overlay'; +import { useMediaVisible } from './statuses/sensitive-content-overlay'; import type { MediaAttachment } from 'pl-api'; import type { Status } from 'pl-fe/normalizers/status'; interface IStatusMedia { /** Status entity to render media for. */ - status: Pick; + status: Pick; /** Whether to display compact media. */ muted?: boolean; /** Callback when compact media is clicked. */ @@ -30,7 +30,7 @@ const StatusMedia: React.FC = ({ const { openModal } = useModalsStore(); const { displayMedia } = useSettings(); - const visible = isMediaVisible(status, displayMedia); + const visible = useMediaVisible(status, displayMedia); const size = status.media_attachments.length; const firstAttachment = status.media_attachments[0]; diff --git a/packages/pl-fe/src/components/status.tsx b/packages/pl-fe/src/components/status.tsx index d5fccae75..2a0296326 100644 --- a/packages/pl-fe/src/components/status.tsx +++ b/packages/pl-fe/src/components/status.tsx @@ -5,7 +5,7 @@ import { Link, useHistory } from 'react-router-dom'; import { mentionCompose, replyCompose } from 'pl-fe/actions/compose'; import { toggleFavourite, toggleReblog } from 'pl-fe/actions/interactions'; -import { toggleStatusMediaHidden, unfilterStatus } from 'pl-fe/actions/statuses'; +import { unfilterStatus } from 'pl-fe/actions/statuses'; import Card from 'pl-fe/components/ui/card'; import Icon from 'pl-fe/components/ui/icon'; import Stack from 'pl-fe/components/ui/stack'; @@ -19,6 +19,7 @@ import { useAppSelector } from 'pl-fe/hooks/use-app-selector'; import { useSettings } from 'pl-fe/hooks/use-settings'; import { makeGetStatus, type SelectedStatus } from 'pl-fe/selectors'; import { useModalsStore } from 'pl-fe/stores/modals'; +import { useStatusMetaStore } from 'pl-fe/stores/status-meta'; import { textForScreenReader } from 'pl-fe/utils/status'; import EventPreview from './event-preview'; @@ -77,6 +78,7 @@ const Status: React.FC = (props) => { const history = useHistory(); const dispatch = useAppDispatch(); + const { toggleStatusMediaHidden } = useStatusMetaStore(); const { openModal } = useModalsStore(); const { boostModal } = useSettings(); const didShowCard = useRef(false); @@ -96,7 +98,7 @@ const Status: React.FC = (props) => { didShowCard.current = Boolean(!muted && !hidden && status?.card); }, []); - const handleClick = (e?: React.MouseEvent): void => { + const handleClick = (e?: React.MouseEvent) => { e?.stopPropagation(); // If the user is selecting text, don't focus the status. @@ -115,7 +117,7 @@ const Status: React.FC = (props) => { } }; - const handleHotkeyOpenMedia = (e?: KeyboardEvent): void => { + const handleHotkeyOpenMedia = (e?: KeyboardEvent) => { const status = actualStatus; const firstAttachment = status.media_attachments[0]; @@ -130,17 +132,17 @@ const Status: React.FC = (props) => { } }; - const handleHotkeyReply = (e?: KeyboardEvent): void => { + const handleHotkeyReply = (e?: KeyboardEvent) => { e?.preventDefault(); dispatch(replyCompose(actualStatus, status.reblog_id ? status.account : undefined)); }; - const handleHotkeyFavourite = (e?: KeyboardEvent): void => { + const handleHotkeyFavourite = (e?: KeyboardEvent) => { e?.preventDefault(); dispatch(toggleFavourite(actualStatus)); }; - const handleHotkeyBoost = (e?: KeyboardEvent): void => { + const handleHotkeyBoost = (e?: KeyboardEvent) => { const modalReblog = () => dispatch(toggleReblog(actualStatus)); if ((e && e.shiftKey) || !boostModal) { modalReblog(); @@ -149,36 +151,36 @@ const Status: React.FC = (props) => { } }; - const handleHotkeyMention = (e?: KeyboardEvent): void => { + const handleHotkeyMention = (e?: KeyboardEvent) => { e?.preventDefault(); dispatch(mentionCompose(actualStatus.account)); }; - const handleHotkeyOpen = (): void => { + const handleHotkeyOpen = () => { history.push(statusUrl); }; - const handleHotkeyOpenProfile = (): void => { + const handleHotkeyOpenProfile = () => { history.push(`/@${actualStatus.account.acct}`); }; - const handleHotkeyMoveUp = (e?: KeyboardEvent): void => { + const handleHotkeyMoveUp = (e?: KeyboardEvent) => { if (onMoveUp) { onMoveUp(status.id, featured); } }; - const handleHotkeyMoveDown = (e?: KeyboardEvent): void => { + const handleHotkeyMoveDown = (e?: KeyboardEvent) => { if (onMoveDown) { onMoveDown(status.id, featured); } }; - const handleHotkeyToggleSensitive = (): void => { - dispatch(toggleStatusMediaHidden(actualStatus)); + const handleHotkeyToggleSensitive = () => { + toggleStatusMediaHidden(actualStatus.id); }; - const handleHotkeyReact = (): void => { + const handleHotkeyReact = () => { (node.current?.querySelector('.emoji-picker-dropdown') as HTMLButtonElement)?.click(); }; diff --git a/packages/pl-fe/src/components/statuses/sensitive-content-overlay.tsx b/packages/pl-fe/src/components/statuses/sensitive-content-overlay.tsx index c12247809..341e751a3 100644 --- a/packages/pl-fe/src/components/statuses/sensitive-content-overlay.tsx +++ b/packages/pl-fe/src/components/statuses/sensitive-content-overlay.tsx @@ -2,27 +2,29 @@ import clsx from 'clsx'; import React from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import { hideStatusMedia, revealStatusMedia } from 'pl-fe/actions/statuses'; import Button from 'pl-fe/components/ui/button'; import HStack from 'pl-fe/components/ui/hstack'; import Text from 'pl-fe/components/ui/text'; -import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch'; import { useSettings } from 'pl-fe/hooks/use-settings'; +import { useStatusMetaStore } from 'pl-fe/stores/status-meta'; import type { Status } from 'pl-fe/normalizers/status'; -const isMediaVisible = (status: Pick & { hidden?: boolean | null }, displayMedia: 'default' | 'show_all' | 'hide_all') => { +const useMediaVisible = (status: Pick & { id?: string }, displayMedia: 'default' | 'show_all' | 'hide_all') => { let visible = !(status.sensitive || status.spoiler_text); - if (status.hidden !== null) visible = !status.hidden; + const statusesMeta = useStatusMetaStore().statuses; + const mediaVisible = status.id ? statusesMeta[status.id]?.mediaVisible : undefined; + + if (mediaVisible !== undefined) visible = mediaVisible; else if (displayMedia === 'show_all') visible = true; else if (displayMedia === 'hide_all' && status.media_attachments.length) visible = false; return visible; }; -const showOverlay = (status: Pick, displayMedia: 'default' | 'show_all' | 'hide_all') => { - const visible = isMediaVisible(status, displayMedia); +const useShowOverlay = (status: Pick, displayMedia: 'default' | 'show_all' | 'hide_all') => { + const visible = useMediaVisible(status, displayMedia); const showHideButton = status.sensitive || (status.media_attachments.length && displayMedia === 'hide_all'); @@ -41,26 +43,27 @@ const messages = defineMessages({ }); interface ISensitiveContentOverlay { - status: Pick; + status: Pick; } const SensitiveContentOverlay = React.forwardRef((props, ref) => { const { status } = props; - const dispatch = useAppDispatch(); const intl = useIntl(); const { displayMedia } = useSettings(); - const visible = isMediaVisible(status, displayMedia); + const visible = useMediaVisible(status, displayMedia); + + const { hideStatusMedia, revealStatusMedia } = useStatusMetaStore(); const toggleVisibility = (event: React.MouseEvent) => { event.stopPropagation(); - if (visible) dispatch(hideStatusMedia(status.id)); - else dispatch(revealStatusMedia(status.id)); + if (visible) hideStatusMedia(status.id); + else revealStatusMedia(status.id); }; - if (!showOverlay(status, displayMedia)) return null; + if (!useShowOverlay(status, displayMedia)) return null; return (
; + status?: Pick; onCancel?: () => void; hideActions: boolean; } diff --git a/packages/pl-fe/src/features/notifications/components/notification.tsx b/packages/pl-fe/src/features/notifications/components/notification.tsx index 359457574..eeea9071c 100644 --- a/packages/pl-fe/src/features/notifications/components/notification.tsx +++ b/packages/pl-fe/src/features/notifications/components/notification.tsx @@ -4,7 +4,6 @@ import { Link, useHistory } from 'react-router-dom'; import { mentionCompose } from 'pl-fe/actions/compose'; import { reblog, favourite, unreblog, unfavourite } from 'pl-fe/actions/interactions'; -import { toggleStatusMediaHidden } from 'pl-fe/actions/statuses'; import HoverAccountWrapper from 'pl-fe/components/hover-account-wrapper'; import Icon from 'pl-fe/components/icon'; import RelativeTimestamp from 'pl-fe/components/relative-timestamp'; @@ -22,6 +21,7 @@ import { useLoggedIn } from 'pl-fe/hooks/use-logged-in'; import { makeGetNotification } from 'pl-fe/selectors'; import { useModalsStore } from 'pl-fe/stores/modals'; import { useSettingsStore } from 'pl-fe/stores/settings'; +import { useStatusMetaStore } from 'pl-fe/stores/status-meta'; import { NotificationType } from 'pl-fe/utils/notification'; import type { NotificationGroup } from 'pl-api'; @@ -188,7 +188,7 @@ interface INotification { onReblog?: (status: StatusEntity, e?: KeyboardEvent) => void; } -const getNotificationStatus = (n: Pick & ({ status: StatusEntity } | { })) => { +const getNotificationStatus = (n: Pick & ({ status: StatusEntity } | { })): StatusEntity | null => { if (['mention', 'status', 'reblog', 'favourite', 'poll', 'update', 'emoji_reaction', 'event_reminder', 'participation_accepted', 'participation_request'].includes(n.type)) // @ts-ignore return n.status; @@ -203,6 +203,7 @@ const Notification: React.FC = (props) => { const getNotification = useCallback(makeGetNotification(), []); const { me } = useLoggedIn(); + const { toggleStatusMediaHidden } = useStatusMetaStore(); const { openModal } = useModalsStore(); const { settings } = useSettingsStore(); @@ -281,9 +282,9 @@ const Notification: React.FC = (props) => { } }, [status]); - const handleHotkeyToggleSensitive = useCallback((e?: KeyboardEvent) => { + const handleHotkeyToggleSensitive = useCallback(() => { if (status && typeof status === 'object') { - dispatch(toggleStatusMediaHidden(status)); + toggleStatusMediaHidden(status.id); } }, [status]); @@ -299,7 +300,7 @@ const Notification: React.FC = (props) => { } }; - const displayedType = notification.type === 'mention' && (notification.subtype === 'reply' || status.in_reply_to_account_id === me) ? 'reply' : notification.type; + const displayedType = notification.type === 'mention' && (notification.subtype === 'reply' || status?.in_reply_to_account_id === me) ? 'reply' : notification.type; const renderIcon = (): React.ReactNode => { if (type === 'emoji_reaction' && notification.emoji) { diff --git a/packages/pl-fe/src/features/status/components/thread.tsx b/packages/pl-fe/src/features/status/components/thread.tsx index d45f733d7..8272561c6 100644 --- a/packages/pl-fe/src/features/status/components/thread.tsx +++ b/packages/pl-fe/src/features/status/components/thread.tsx @@ -7,7 +7,6 @@ import { useHistory } from 'react-router-dom'; import { type ComposeReplyAction, mentionCompose, replyCompose } from 'pl-fe/actions/compose'; import { reblog, toggleFavourite, unreblog } from 'pl-fe/actions/interactions'; -import { toggleStatusMediaHidden } from 'pl-fe/actions/statuses'; import ScrollableList from 'pl-fe/components/scrollable-list'; import StatusActionBar from 'pl-fe/components/status-action-bar'; import Tombstone from 'pl-fe/components/tombstone'; @@ -20,6 +19,7 @@ import { useAppSelector } from 'pl-fe/hooks/use-app-selector'; import { RootState } from 'pl-fe/store'; import { useModalsStore } from 'pl-fe/stores/modals'; import { useSettingsStore } from 'pl-fe/stores/settings'; +import { useStatusMetaStore } from 'pl-fe/stores/status-meta'; import { textForScreenReader } from 'pl-fe/utils/status'; import DetailedStatus from './detailed-status'; @@ -113,6 +113,7 @@ const Thread: React.FC = ({ const history = useHistory(); const intl = useIntl(); + const { toggleStatusMediaHidden } = useStatusMetaStore(); const { openModal } = useModalsStore(); const { settings } = useSettingsStore(); @@ -159,7 +160,7 @@ const Thread: React.FC = ({ const handleMentionClick = (account: Pick) => dispatch(mentionCompose(account)); const handleHotkeyOpenMedia = (e?: KeyboardEvent) => { - const media = status?.media_attachments; + const media = status.media_attachments; e?.preventDefault(); @@ -175,43 +176,43 @@ const Thread: React.FC = ({ }; const handleHotkeyMoveUp = () => { - handleMoveUp(status!.id); + handleMoveUp(status.id); }; const handleHotkeyMoveDown = () => { - handleMoveDown(status!.id); + handleMoveDown(status.id); }; const handleHotkeyReply = (e?: KeyboardEvent) => { e?.preventDefault(); - handleReplyClick(status!); + handleReplyClick(status); }; const handleHotkeyFavourite = () => { - handleFavouriteClick(status!); + handleFavouriteClick(status); }; const handleHotkeyBoost = () => { - handleReblogClick(status!); + handleReblogClick(status); }; const handleHotkeyMention = (e?: KeyboardEvent) => { e?.preventDefault(); - const { account } = status!; + const { account } = status; if (!account || typeof account !== 'object') return; handleMentionClick(account); }; const handleHotkeyOpenProfile = () => { - history.push(`/@${status!.account.acct}`); + history.push(`/@${status.account.acct}`); }; const handleHotkeyToggleSensitive = () => { - dispatch(toggleStatusMediaHidden(status)); + toggleStatusMediaHidden(status.id); }; const handleMoveUp = (id: string) => { - if (id === status?.id) { + if (id === status.id) { _selectChild(ancestorsIds.length - 1); } else { let index = ancestorsIds.indexOf(id); @@ -226,7 +227,7 @@ const Thread: React.FC = ({ }; const handleMoveDown = (id: string) => { - if (id === status?.id) { + if (id === status.id) { _selectChild(ancestorsIds.length + 1); } else { let index = ancestorsIds.indexOf(id); @@ -269,7 +270,7 @@ const Thread: React.FC = ({ { if (oldStatus && oldStatus.content === status.content && oldStatus.spoiler_text === status.spoiler_text) { const { - search_index, hidden, expanded, currentLanguage, + search_index, currentLanguage, } = oldStatus; return { - search_index, hidden, expanded, currentLanguage, + search_index, currentLanguage, }; } else { const searchContent = buildSearchContent(status); @@ -135,8 +133,6 @@ const normalizeStatus = (status: BaseStatus & { account: normalizeAccount(status.account), accounts: status.accounts?.map(normalizeAccount), mentions, - expanded: null, - hidden: null, filtered: status.filtered?.map(result => result.filter.title), event, group, diff --git a/packages/pl-fe/src/reducers/statuses.ts b/packages/pl-fe/src/reducers/statuses.ts index bc5e5f49c..82cdbdf40 100644 --- a/packages/pl-fe/src/reducers/statuses.ts +++ b/packages/pl-fe/src/reducers/statuses.ts @@ -36,14 +36,10 @@ import { STATUS_CREATE_FAIL, STATUS_DELETE_REQUEST, STATUS_DELETE_FAIL, - STATUS_HIDE_MEDIA, STATUS_MUTE_SUCCESS, - STATUS_REVEAL_MEDIA, STATUS_UNFILTER, STATUS_UNMUTE_SUCCESS, STATUS_LANGUAGE_CHANGE, - STATUS_COLLAPSE_SPOILER, - STATUS_EXPAND_SPOILER, type StatusesAction, } from '../actions/statuses'; import { TIMELINE_DELETE, type TimelineAction } from '../actions/timelines'; @@ -251,42 +247,6 @@ const statuses = (state = initialState, action: EmojiReactsAction | EventsAction status.muted = false; } }); - case STATUS_REVEAL_MEDIA: - return create(state, (draft) => { - action.statusIds.forEach((id: string) => { - const status = draft[id]; - if (status) { - status.hidden = false; - } - }); - }); - case STATUS_HIDE_MEDIA: - return create(state, (draft) => { - action.statusIds.forEach((id: string) => { - const status = draft[id]; - if (status) { - status.hidden = true; - } - }); - }); - case STATUS_EXPAND_SPOILER: - return create(state, (draft) => { - action.statusIds.forEach((id: string) => { - const status = draft[id]; - if (status) { - status.expanded = true; - } - }); - }); - case STATUS_COLLAPSE_SPOILER: - return create(state, (draft) => { - action.statusIds.forEach((id: string) => { - const status = draft[id]; - if (status) { - status.expanded = false; - } - }); - }); case STATUS_DELETE_REQUEST: return create(state, (draft) => decrementReplyCount(draft, action.params)); case STATUS_DELETE_FAIL: diff --git a/packages/pl-fe/src/stores/status-meta.ts b/packages/pl-fe/src/stores/status-meta.ts index 8625842c4..3af0ddbd4 100644 --- a/packages/pl-fe/src/stores/status-meta.ts +++ b/packages/pl-fe/src/stores/status-meta.ts @@ -2,25 +2,39 @@ import { create } from 'zustand'; import { mutative } from 'zustand-mutative'; type State = { - statuses: Record; - revealStatus: (statusId: string) => void; - hideStatus: (statusId: string) => void; + statuses: Record; + expandStatus: (statusId: string) => void; + collapseStatus: (statusId: string) => void; + revealStatusMedia: (statusId: string) => void; + hideStatusMedia: (statusId: string) => void; + toggleStatusMediaHidden: (statusId: string) => void; fetchTranslation: (statusId: string, targetLanguage: string) => void; hideTranslation: (statusId: string) => void; }; const useStatusMetaStore = create()(mutative((set) => ({ statuses: {}, - revealStatus: (statusId) => set((state: State) => { + expandStatus: (statusId) => set((state: State) => { if (!state.statuses[statusId]) state.statuses[statusId] = {}; - state.statuses[statusId].visible = true; + state.statuses[statusId].expanded = true; }), - hideStatus: (statusId) => set((state: State) => { + collapseStatus: (statusId) => set((state: State) => { if (!state.statuses[statusId]) state.statuses[statusId] = {}; - state.statuses[statusId].visible = false; + state.statuses[statusId].expanded = false; }), + revealStatusMedia: (statusId) => set((state: State) => { + if (!state.statuses[statusId]) state.statuses[statusId] = {}; + + state.statuses[statusId].mediaVisible = true; + }), + hideStatusMedia: (statusId) => set((state: State) => { + if (!state.statuses[statusId]) state.statuses[statusId] = {}; + + state.statuses[statusId].mediaVisible = false; + }), + toggleStatusMediaHidden: (statusId) => (state: State) => state[state.statuses[statusId].mediaVisible ? 'hideStatusMedia' : 'revealStatusMedia'](statusId), fetchTranslation: (statusId, targetLanguage) => set((state: State) => { if (!state.statuses[statusId]) state.statuses[statusId] = {}; diff --git a/packages/pl-fe/src/utils/status.ts b/packages/pl-fe/src/utils/status.ts index 6b9b42169..b7e149149 100644 --- a/packages/pl-fe/src/utils/status.ts +++ b/packages/pl-fe/src/utils/status.ts @@ -34,7 +34,7 @@ const hasIntegerMediaIds = (status: Pick): boolean /** Sanitize status text for use with screen readers. */ const textForScreenReader = ( intl: IntlShape, - status: Pick, + status: Pick, rebloggedByText?: string, ): string => { const { account } = status; @@ -44,7 +44,7 @@ const textForScreenReader = ( const values = [ displayName.length === 0 ? account.acct.split('@')[0] : displayName, - status.spoiler_text && status.hidden ? status.spoiler_text : status.search_index?.slice(status.spoiler_text.length) || '', + status.spoiler_text ? status.spoiler_text : status.search_index?.slice(status.spoiler_text.length) || '', intl.formatDate(status.created_at, { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' }), account.acct, ];