From 3fb923ed05e1a29d262e715c6d08c85bca547724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nicole=20miko=C5=82ajczyk?= Date: Sun, 15 Mar 2026 12:04:52 +0100 Subject: [PATCH] nicolium: some migrations to mutations, remove unused stuff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nicole mikołajczyk --- packages/nicolium/src/actions/auth.ts | 1 - packages/nicolium/src/actions/preload.ts | 2 +- packages/nicolium/src/actions/statuses.ts | 72 ++------------- packages/nicolium/src/columns/timeline.tsx | 4 +- .../components/statuses/status-action-bar.tsx | 24 ++--- .../src/components/statuses/status.tsx | 4 +- packages/nicolium/src/features/emoji/index.ts | 20 ----- .../event/components/event-header.tsx | 5 +- .../status/components/thread-status.tsx | 5 +- .../src/features/status/components/thread.tsx | 5 +- .../nicolium/src/layouts/landing-layout.tsx | 28 ------ packages/nicolium/src/normalizers/status.ts | 1 - .../src/queries/statuses/use-status.ts | 87 ++++++++++++++++++- .../src/queries/utils/mutation-options.ts | 13 --- packages/nicolium/src/stores/status-meta.ts | 9 ++ packages/nicolium/src/utils/badges.ts | 2 +- 16 files changed, 132 insertions(+), 150 deletions(-) delete mode 100644 packages/nicolium/src/layouts/landing-layout.tsx delete mode 100644 packages/nicolium/src/queries/utils/mutation-options.ts diff --git a/packages/nicolium/src/actions/auth.ts b/packages/nicolium/src/actions/auth.ts index b8db5b83b..103df0062 100644 --- a/packages/nicolium/src/actions/auth.ts +++ b/packages/nicolium/src/actions/auth.ts @@ -351,5 +351,4 @@ export { authLoggedIn, fetchMe, patchMe, - patchMeSuccess, }; diff --git a/packages/nicolium/src/actions/preload.ts b/packages/nicolium/src/actions/preload.ts index 503f8d9bd..2dfc61c5f 100644 --- a/packages/nicolium/src/actions/preload.ts +++ b/packages/nicolium/src/actions/preload.ts @@ -76,4 +76,4 @@ const preload = () => { } }; -export { pleromaDecoder, decodeFromMarkup, preload }; +export { preload }; diff --git a/packages/nicolium/src/actions/statuses.ts b/packages/nicolium/src/actions/statuses.ts index c019a8eee..43d64b687 100644 --- a/packages/nicolium/src/actions/statuses.ts +++ b/packages/nicolium/src/actions/statuses.ts @@ -15,11 +15,13 @@ import { shouldHaveCard } from '@/utils/status'; import { importEntities } from './importer'; import type { NormalizedStatus as Status } from '@/normalizers/status'; +import type { useQueryClient } from '@tanstack/react-query'; import type { CreateStatusParams, Status as BaseStatus } from 'pl-api'; import type { IntlShape } from 'react-intl'; const incrementReplyCount = ( params: Pick, + queryClient: ReturnType, ) => { if (params.in_reply_to_id) { updateStatus( @@ -45,6 +47,7 @@ const incrementReplyCount = ( const decrementReplyCount = ( params: Pick, + queryClient: ReturnType, ) => { if (params.in_reply_to_id) { updateStatus( @@ -77,7 +80,7 @@ const createStatus = ( useContextStore.getState().actions.importPendingStatus(params.in_reply_to_id, idempotencyKey); useTimelinesStore.getState().actions.importPendingStatus(params, idempotencyKey); if (!editedId) { - incrementReplyCount(params); + incrementReplyCount(params, queryClient); } } @@ -145,7 +148,7 @@ const createStatus = ( useTimelinesStore.getState().actions.deletePendingStatus(idempotencyKey); useContextStore.getState().actions.deletePendingStatus(params.in_reply_to_id, idempotencyKey); if (!editedId) { - decrementReplyCount(params); + decrementReplyCount(params, queryClient); } throw error; }); @@ -183,67 +186,6 @@ const fetchStatus = (statusId: string, intl?: IntlShape) => { }); }; -const deleteStatus = (statusId: string, withRedraft = false) => { - if (!isLoggedIn()) return null; - - const status = queryClient.getQueryData(queryKeys.statuses.show(statusId)); - if (!status) return null; - - const poll = status.poll_id - ? queryClient.getQueryData(queryKeys.statuses.polls.show(status.poll_id)) - : undefined; - - decrementReplyCount(status); - - return getClient() - .statuses.deleteStatus(statusId) - .then((source) => { - usePendingStatusesStore.getState().actions.deleteStatus(statusId); - useTimelinesStore.getState().actions.deleteStatus(statusId); - updateStatus( - statusId, - (s) => { - s.deleted = true; - }, - queryClient, - ); - - if (withRedraft) { - useComposeStore.getState().actions.setComposeToStatus(status, poll, source, withRedraft); - useModalsStore.getState().actions.openModal('COMPOSE'); - } - }) - .catch(() => { - incrementReplyCount(status); - }); -}; - -const deleteStatusFromGroup = (statusId: string, groupId: string) => { - if (!isLoggedIn()) return null; - - const status = queryClient.getQueryData(queryKeys.statuses.show(statusId)); - if (!status) return null; - - decrementReplyCount(status); - - return getClient() - .experimental.groups.deleteGroupStatus(statusId, groupId) - .then(() => { - usePendingStatusesStore.getState().actions.deleteStatus(statusId); - useTimelinesStore.getState().actions.deleteStatus(statusId); - updateStatus( - statusId, - (s) => { - s.deleted = true; - }, - queryClient, - ); - }) - .catch(() => { - incrementReplyCount(status); - }); -}; - const muteStatus = (statusId: string) => { if (!isLoggedIn()) return; @@ -283,7 +225,7 @@ export { createStatus, editStatus, fetchStatus, - deleteStatus, - deleteStatusFromGroup, toggleMuteStatus, + decrementReplyCount, + incrementReplyCount, }; diff --git a/packages/nicolium/src/columns/timeline.tsx b/packages/nicolium/src/columns/timeline.tsx index efd2688e6..292c13f84 100644 --- a/packages/nicolium/src/columns/timeline.tsx +++ b/packages/nicolium/src/columns/timeline.tsx @@ -32,6 +32,7 @@ import { useWrenchedTimeline, } from '@/queries/timelines/use-timelines'; import { useSettings } from '@/stores/settings'; +import { useStatusMeta } from '@/stores/status-meta'; import { selectChild } from '@/utils/scroll-utils'; import { hasActiveFilters, sortFilteredTimeline } from '@/utils/timeline-filter'; @@ -296,9 +297,10 @@ interface ITimelineStatus { const TimelineStatus: React.FC = (props): React.JSX.Element => { const { id, isConnectedTop, isConnectedBottom } = props; + const { deleted } = useStatusMeta(id); const statusQuery = useStatus(id, { withFilteredResults: true }); - if (statusQuery.data?.deleted) { + if (deleted) { return (
diff --git a/packages/nicolium/src/components/statuses/status-action-bar.tsx b/packages/nicolium/src/components/statuses/status-action-bar.tsx index ab44c7edb..1cc47f46c 100644 --- a/packages/nicolium/src/components/statuses/status-action-bar.tsx +++ b/packages/nicolium/src/components/statuses/status-action-bar.tsx @@ -6,12 +6,7 @@ import { defineMessages, useIntl } from 'react-intl'; import { redactStatus } from '@/actions/admin'; import { useDeleteStatusModal, useToggleStatusSensitivityModal } from '@/actions/moderation'; import { changeSetting } from '@/actions/settings'; -import { - deleteStatus, - deleteStatusFromGroup, - editStatus, - toggleMuteStatus, -} from '@/actions/statuses'; +import { editStatus, toggleMuteStatus } from '@/actions/statuses'; import DropdownMenu from '@/components/dropdown-menu'; import StatusActionButton from '@/components/statuses/status-action-button'; import { useCurrentAccount } from '@/contexts/current-account-context'; @@ -28,6 +23,11 @@ import { useGroupQuery } from '@/queries/groups/use-group'; import { useBlockGroupUserMutation } from '@/queries/groups/use-group-blocks'; import { useCustomEmojis } from '@/queries/instance/use-custom-emojis'; import { useTranslationLanguages } from '@/queries/instance/use-translation-languages'; +import { + useDeleteStatus, + useDeleteStatusFromGroup, + type SelectedStatus, +} from '@/queries/statuses/use-status'; import { useBookmarkStatus, useDislikeStatus, @@ -56,7 +56,6 @@ import Popover from '../ui/popover'; import type { Menu } from '@/components/dropdown-menu'; import type { Emoji as EmojiType } from '@/features/emoji'; import type { UnauthorizedModalAction } from '@/modals/unauthorized-modal'; -import type { SelectedStatus } from '@/queries/statuses/use-status'; import type { Me } from '@/stores/auth'; const messages = defineMessages({ @@ -739,6 +738,11 @@ const MenuButton: React.FC = ({ const { mutate: pinStatus } = usePinStatus(status.id); const { mutate: unpinStatus } = useUnpinStatus(status.id); const { mutate: unblockAccount } = useUnblockAccountMutation(status.account_id); + const { mutate: deleteStatus } = useDeleteStatus(status.id); + const { mutate: deleteStatusFromGroup } = useDeleteStatusFromGroup( + status.id, + status.group_id as string, + ); const deleteStatusModal = useDeleteStatusModal(status.id); const toggleStatusSensitivityModal = useToggleStatusSensitivityModal(status.id); @@ -788,7 +792,7 @@ const MenuButton: React.FC = ({ const doDeleteStatus = (withRedraft = false) => { if (!deleteModal) { - deleteStatus(status.id, withRedraft); + deleteStatus(withRedraft); } else { openModal('CONFIRM', { heading: intl.formatMessage( @@ -800,7 +804,7 @@ const MenuButton: React.FC = ({ confirm: intl.formatMessage( withRedraft ? messages.redraftConfirm : messages.deleteConfirm, ), - onConfirm: () => deleteStatus(status.id, withRedraft), + onConfirm: () => deleteStatus(withRedraft), }); } }; @@ -936,7 +940,7 @@ const MenuButton: React.FC = ({ }), confirm: intl.formatMessage(messages.deleteConfirm), onConfirm: () => { - deleteStatusFromGroup(status.id, group!.id); + deleteStatusFromGroup(); }, }); }; diff --git a/packages/nicolium/src/components/statuses/status.tsx b/packages/nicolium/src/components/statuses/status.tsx index 7c2c43542..252429112 100644 --- a/packages/nicolium/src/components/statuses/status.tsx +++ b/packages/nicolium/src/components/statuses/status.tsx @@ -206,7 +206,7 @@ const Status: React.FC = React.memo((props) => { const features = useFeatures(); const { toggleStatusesMediaHidden, unfilterStatus } = useStatusMetaActions(); - const { showFiltered } = useStatusMeta(status.id); + const { deleted, showFiltered } = useStatusMeta(status.id); const { openModal } = useModalsActions(); const { replyCompose, mentionCompose } = useComposeActions(); const { boostModal } = useSettings(); @@ -521,7 +521,7 @@ const Status: React.FC = React.memo((props) => { if (!status) return null; - if (status.deleted) + if (deleted) return ; if (filtered && showFiltered !== true) { diff --git a/packages/nicolium/src/features/emoji/index.ts b/packages/nicolium/src/features/emoji/index.ts index 956ce1ae9..5f9689766 100644 --- a/packages/nicolium/src/features/emoji/index.ts +++ b/packages/nicolium/src/features/emoji/index.ts @@ -56,25 +56,6 @@ const isAlphaNumeric = (c: string) => { const validEmojiChar = (c: string) => isAlphaNumeric(c) || ['_', '-', '.'].includes(c); -const buildCustomEmojis = (customEmojis: Array) => { - const emojis: EmojiMart[] = []; - - customEmojis.forEach((emoji) => { - const shortcode = emoji.shortcode; - const url = emoji.static_url; - const name = shortcode.replace(':', ''); - - emojis.push({ - id: name, - name, - keywords: [name], - skins: [{ src: url }], - }); - }); - - return emojis; -}; - const buildCustomEmojiCategories = (customEmojis: Array, intl?: IntlShape) => { const emojiCategories: Record[]> = {}; @@ -118,7 +99,6 @@ export { type Emoji, isCustomEmoji, isNativeEmoji, - buildCustomEmojis, buildCustomEmojiCategories, validEmojiChar, }; diff --git a/packages/nicolium/src/features/event/components/event-header.tsx b/packages/nicolium/src/features/event/components/event-header.tsx index 875f96be0..f59eb8e47 100644 --- a/packages/nicolium/src/features/event/components/event-header.tsx +++ b/packages/nicolium/src/features/event/components/event-header.tsx @@ -3,7 +3,6 @@ import React from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { useDeleteStatusModal, useToggleStatusSensitivityModal } from '@/actions/moderation'; -import { deleteStatus } from '@/actions/statuses'; import VerificationBadge from '@/components/accounts/verification-badge'; import DropdownMenu, { type Menu as MenuType } from '@/components/dropdown-menu'; import Icon from '@/components/icon'; @@ -17,6 +16,7 @@ import { useFeatures } from '@/hooks/use-features'; import { useOwnAccount } from '@/hooks/use-own-account'; import { useAccount } from '@/queries/accounts/use-account'; import { useChats } from '@/queries/chats'; +import { useDeleteStatus } from '@/queries/statuses/use-status'; import { useBookmarkStatus, usePinStatus, @@ -128,6 +128,7 @@ const EventHeader: React.FC = ({ status }) => { const { mutate: unbookmarkStatus } = useUnbookmarkStatus(status?.id!); const { mutate: pinStatus } = usePinStatus(status?.id!); const { mutate: unpinStatus } = useUnpinStatus(status?.id!); + const { mutate: deleteStatus } = useDeleteStatus(status?.id!); const deleteStatusModal = useDeleteStatusModal(status?.id!); const toggleStatusSensitivityModal = useToggleStatusSensitivityModal(status?.id!); @@ -209,7 +210,7 @@ const EventHeader: React.FC = ({ status }) => { /> ), confirm: , - onConfirm: () => deleteStatus(status.id), + onConfirm: () => deleteStatus(undefined), }); }; diff --git a/packages/nicolium/src/features/status/components/thread-status.tsx b/packages/nicolium/src/features/status/components/thread-status.tsx index e42e7834f..431121abf 100644 --- a/packages/nicolium/src/features/status/components/thread-status.tsx +++ b/packages/nicolium/src/features/status/components/thread-status.tsx @@ -6,6 +6,7 @@ import StatusContainer from '@/containers/status-container'; import PlaceholderStatus from '@/features/placeholder/components/placeholder-status'; import { useMinimalStatus } from '@/queries/statuses/use-status'; import { useReplyCount, useReplyToId } from '@/stores/contexts'; +import { useStatusMeta } from '@/stores/status-meta'; import type { FilterContextType } from '@/queries/settings/use-filters'; @@ -26,9 +27,9 @@ const ThreadStatus: React.FC = (props): React.JSX.Element => { const replyCount = useReplyCount(id); const { data: statusData } = useMinimalStatus(id); const isLoaded = Boolean(statusData); - const isDeleted = Boolean(statusData?.deleted); + const { deleted } = useStatusMeta(id); - if (isDeleted) { + if (deleted) { return (
diff --git a/packages/nicolium/src/features/status/components/thread.tsx b/packages/nicolium/src/features/status/components/thread.tsx index 861eb23e5..5895a9bb1 100644 --- a/packages/nicolium/src/features/status/components/thread.tsx +++ b/packages/nicolium/src/features/status/components/thread.tsx @@ -19,7 +19,7 @@ import { useComposeActions } from '@/stores/compose'; import { useThread } from '@/stores/contexts'; import { useModalsActions } from '@/stores/modals'; import { useSettings } from '@/stores/settings'; -import { useStatusMetaActions } from '@/stores/status-meta'; +import { useStatusMeta, useStatusMetaActions } from '@/stores/status-meta'; import { selectChild } from '@/utils/scroll-utils'; import { textForScreenReader } from '@/utils/status'; @@ -50,6 +50,7 @@ const Thread = ({ const intl = useIntl(); const { replyCompose, mentionCompose } = useComposeActions(); + const { deleted } = useStatusMeta(status.id); const { expandStatuses, revealStatusesMedia, toggleStatusesMediaHidden } = useStatusMetaActions(); const { openModal } = useModalsActions(); const { @@ -238,7 +239,7 @@ const Thread = ({ if (id === status.id) return (
- {status.deleted ? ( + {deleted ? ( { - const me = useCurrentAccount(); - const features = useFeatures(); - - return ( - <> - - - - - - {!me && } - {features.trends && } - - - - ); -}; - -export { LandingLayout as default }; diff --git a/packages/nicolium/src/normalizers/status.ts b/packages/nicolium/src/normalizers/status.ts index d4b73031e..889a38204 100644 --- a/packages/nicolium/src/normalizers/status.ts +++ b/packages/nicolium/src/normalizers/status.ts @@ -134,7 +134,6 @@ const normalizeStatus = ( poll_id: poll?.id ?? null, group_id: group?.id ?? null, expectsCard: false, - deleted: false, ...status, quote_id: status.quote_id ?? null, mentions, diff --git a/packages/nicolium/src/queries/statuses/use-status.ts b/packages/nicolium/src/queries/statuses/use-status.ts index d9042737b..2063d62ee 100644 --- a/packages/nicolium/src/queries/statuses/use-status.ts +++ b/packages/nicolium/src/queries/statuses/use-status.ts @@ -1,12 +1,24 @@ -import { useQueries, useQuery, type UseQueryResult } from '@tanstack/react-query'; +import { + useMutation, + useQueries, + useQuery, + useQueryClient, + type UseQueryResult, +} from '@tanstack/react-query'; import { useMemo } from 'react'; import { importEntities } from '@/actions/importer'; +import { decrementReplyCount, incrementReplyCount } from '@/actions/statuses'; import { useClient } from '@/hooks/use-client'; import { useFeatures } from '@/hooks/use-features'; import { normalizeStatus, type NormalizedStatus } from '@/normalizers/status'; import { useFilters } from '@/queries/settings/use-filters'; +import { useComposeActions } from '@/stores/compose'; import { useContextsActions } from '@/stores/contexts'; +import { useModalsActions } from '@/stores/modals'; +import { usePendingStatusesActions } from '@/stores/pending-statuses'; +import { useStatusMetaActions } from '@/stores/status-meta'; +import { useTimelinesActions } from '@/stores/timelines'; import { checkFiltered } from '@/utils/filters'; import { useAccount } from '../accounts/use-account'; @@ -170,11 +182,84 @@ const findStatuses = ( ) .map(([key, data]) => [key[1], data]); +const useDeleteStatus = (statusId: string) => { + const client = useClient(); + const queryClient = useQueryClient(); + const { markStatusDeleted } = useStatusMetaActions(); + const { deleteStatus: deletePendingStatus } = usePendingStatusesActions(); + const { deleteStatus: deleteStatusFromTimelines } = useTimelinesActions(); + const { setComposeToStatus } = useComposeActions(); + const { openModal } = useModalsActions(); + + return useMutation({ + mutationFn: (_withRedraft?: boolean) => client.statuses.deleteStatus(statusId), + onMutate: () => { + const status = queryClient.getQueryData(queryKeys.statuses.show(statusId)); + if (!status) return; + + decrementReplyCount(status, queryClient); + }, + onSuccess: (source, withRedraft) => { + const status = queryClient.getQueryData(queryKeys.statuses.show(statusId)); + + const poll = status?.poll_id + ? queryClient.getQueryData(queryKeys.statuses.polls.show(status.poll_id)) + : undefined; + + deletePendingStatus(statusId); + deleteStatusFromTimelines(statusId); + markStatusDeleted(statusId); + + if (withRedraft && status) { + setComposeToStatus(status, poll, source, withRedraft); + openModal('COMPOSE'); + } + }, + onError: () => { + const status = queryClient.getQueryData(queryKeys.statuses.show(statusId)); + if (!status) return; + + incrementReplyCount(status, queryClient); + }, + }); +}; + +const useDeleteStatusFromGroup = (statusId: string, groupId: string) => { + const client = useClient(); + const queryClient = useQueryClient(); + const { markStatusDeleted } = useStatusMetaActions(); + const { deleteStatus: deletePendingStatus } = usePendingStatusesActions(); + const { deleteStatus: deleteStatusFromTimelines } = useTimelinesActions(); + + return useMutation({ + mutationFn: () => client.experimental.groups.deleteGroupStatus(statusId, groupId), + onMutate: () => { + const status = queryClient.getQueryData(queryKeys.statuses.show(statusId)); + if (!status) return; + + decrementReplyCount(status, queryClient); + }, + onSuccess: () => { + deletePendingStatus(statusId); + deleteStatusFromTimelines(statusId); + markStatusDeleted(statusId); + }, + onError: () => { + const status = queryClient.getQueryData(queryKeys.statuses.show(statusId)); + if (!status) return; + + incrementReplyCount(status, queryClient); + }, + }); +}; + export { useMinimalStatus, useStatus, useStatusContext, useStatuses, + useDeleteStatus, + useDeleteStatusFromGroup, findStatuses, type MinifiedContext, type SelectedStatus, diff --git a/packages/nicolium/src/queries/utils/mutation-options.ts b/packages/nicolium/src/queries/utils/mutation-options.ts deleted file mode 100644 index ff7f9a591..000000000 --- a/packages/nicolium/src/queries/utils/mutation-options.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { DefaultError, UseMutationOptions } from '@tanstack/react-query'; - -// From https://github.com/TanStack/query/discussions/6096#discussioncomment-9685102 -const mutationOptions = < - TData = unknown, - TError = DefaultError, - TVariables = void, - TContext = unknown, ->( - options: UseMutationOptions, -): UseMutationOptions => options; - -export { mutationOptions }; diff --git a/packages/nicolium/src/stores/status-meta.ts b/packages/nicolium/src/stores/status-meta.ts index 8489dba44..4759117cf 100644 --- a/packages/nicolium/src/stores/status-meta.ts +++ b/packages/nicolium/src/stores/status-meta.ts @@ -12,6 +12,7 @@ type State = { localTargetLanguage?: string; showPollResults?: boolean; showFiltered?: boolean; + deleted?: boolean; } >; actions: { @@ -27,6 +28,7 @@ type State = { setStatusLanguage: (statusId: string, language: string) => void; toggleShowPollResults: (statusId: string) => void; unfilterStatus: (statusId: string) => void; + markStatusDeleted: (statusId: string) => void; }; }; @@ -126,6 +128,13 @@ const useStatusMetaStore = create()( state.statuses[statusId].showFiltered = true; }); }, + markStatusDeleted: (statusId) => { + set((state: State) => { + if (!state.statuses[statusId]) state.statuses[statusId] = {}; + + state.statuses[statusId].deleted = true; + }); + }, }, })), ); diff --git a/packages/nicolium/src/utils/badges.ts b/packages/nicolium/src/utils/badges.ts index 90c9fe306..d17dd9e79 100644 --- a/packages/nicolium/src/utils/badges.ts +++ b/packages/nicolium/src/utils/badges.ts @@ -29,4 +29,4 @@ const getBadges = (account: Pick) => { return filterBadges(tags); }; -export { tagToBadge, badgeToTag, filterBadges, getTagDiff, getBadges }; +export { tagToBadge, badgeToTag, getTagDiff, getBadges };