diff --git a/packages/pl-fe/src/actions/scheduled-statuses.ts b/packages/pl-fe/src/actions/scheduled-statuses.ts deleted file mode 100644 index e2473419c..000000000 --- a/packages/pl-fe/src/actions/scheduled-statuses.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { getClient } from '../api'; - -import type { PaginatedResponse, ScheduledStatus } from 'pl-api'; -import type { AppDispatch, RootState } from 'pl-fe/store'; - -const SCHEDULED_STATUSES_FETCH_REQUEST = 'SCHEDULED_STATUSES_FETCH_REQUEST' as const; -const SCHEDULED_STATUSES_FETCH_SUCCESS = 'SCHEDULED_STATUSES_FETCH_SUCCESS' as const; -const SCHEDULED_STATUSES_FETCH_FAIL = 'SCHEDULED_STATUSES_FETCH_FAIL' as const; - -const SCHEDULED_STATUSES_EXPAND_REQUEST = 'SCHEDULED_STATUSES_EXPAND_REQUEST' as const; -const SCHEDULED_STATUSES_EXPAND_SUCCESS = 'SCHEDULED_STATUSES_EXPAND_SUCCESS' as const; -const SCHEDULED_STATUSES_EXPAND_FAIL = 'SCHEDULED_STATUSES_EXPAND_FAIL' as const; - -const SCHEDULED_STATUS_CANCEL_REQUEST = 'SCHEDULED_STATUS_CANCEL_REQUEST' as const; -const SCHEDULED_STATUS_CANCEL_SUCCESS = 'SCHEDULED_STATUS_CANCEL_SUCCESS' as const; - -const fetchScheduledStatuses = () => - (dispatch: AppDispatch, getState: () => RootState) => { - const state = getState(); - - if (state.status_lists.scheduled_statuses?.isLoading) { - return; - } - - const features = state.auth.client.features; - - if (!features.scheduledStatuses) return; - - dispatch(fetchScheduledStatusesRequest()); - - return getClient(getState()).scheduledStatuses.getScheduledStatuses().then(({ next, items }) => { - dispatch(fetchScheduledStatusesSuccess(items, next)); - }).catch(error => { - dispatch(fetchScheduledStatusesFail(error)); - }); - }; - -interface ScheduledStatusCancelRequestAction { - type: typeof SCHEDULED_STATUS_CANCEL_REQUEST; - statusId: string; -} - -interface ScheduledStatusCancelSuccessAction { - type: typeof SCHEDULED_STATUS_CANCEL_SUCCESS; - statusId: string; -} - -const cancelScheduledStatus = (statusId: string) => - (dispatch: AppDispatch, getState: () => RootState) => { - dispatch({ type: SCHEDULED_STATUS_CANCEL_REQUEST, statusId }); - return getClient(getState()).scheduledStatuses.cancelScheduledStatus(statusId).then(() => { - dispatch({ type: SCHEDULED_STATUS_CANCEL_SUCCESS, statusId }); - }); - }; - -const fetchScheduledStatusesRequest = () => ({ - type: SCHEDULED_STATUSES_FETCH_REQUEST, -}); - -const fetchScheduledStatusesSuccess = (statuses: Array, next: (() => Promise>) | null) => ({ - type: SCHEDULED_STATUSES_FETCH_SUCCESS, - statuses, - next, -}); - -const fetchScheduledStatusesFail = (error: unknown) => ({ - type: SCHEDULED_STATUSES_FETCH_FAIL, - error, -}); - -const expandScheduledStatuses = () => - (dispatch: AppDispatch, getState: () => RootState) => { - const next = getState().status_lists.scheduled_statuses?.next as any as () => Promise> || null; - - if (next === null || getState().status_lists.scheduled_statuses?.isLoading) { - return; - } - - dispatch(expandScheduledStatusesRequest()); - - next().then(response => { - dispatch(expandScheduledStatusesSuccess(response.items, response.next)); - }).catch(error => { - dispatch(expandScheduledStatusesFail(error)); - }); - }; - -const expandScheduledStatusesRequest = () => ({ - type: SCHEDULED_STATUSES_EXPAND_REQUEST, -}); - -const expandScheduledStatusesSuccess = (statuses: Array, next: (() => Promise>) | null) => ({ - type: SCHEDULED_STATUSES_EXPAND_SUCCESS, - statuses, - next, -}); - -const expandScheduledStatusesFail = (error: unknown) => ({ - type: SCHEDULED_STATUSES_EXPAND_FAIL, - error, -}); - -type ScheduledStatusesAction = - | ScheduledStatusCancelRequestAction - | ScheduledStatusCancelSuccessAction - | ReturnType - | ReturnType - | ReturnType - | ReturnType - | ReturnType - | ReturnType - -export { - SCHEDULED_STATUSES_FETCH_REQUEST, - SCHEDULED_STATUSES_FETCH_SUCCESS, - SCHEDULED_STATUSES_FETCH_FAIL, - SCHEDULED_STATUSES_EXPAND_REQUEST, - SCHEDULED_STATUSES_EXPAND_SUCCESS, - SCHEDULED_STATUSES_EXPAND_FAIL, - SCHEDULED_STATUS_CANCEL_REQUEST, - SCHEDULED_STATUS_CANCEL_SUCCESS, - fetchScheduledStatuses, - cancelScheduledStatus, - expandScheduledStatuses, - type ScheduledStatusesAction, -}; diff --git a/packages/pl-fe/src/actions/statuses.ts b/packages/pl-fe/src/actions/statuses.ts index 882df2302..494a40398 100644 --- a/packages/pl-fe/src/actions/statuses.ts +++ b/packages/pl-fe/src/actions/statuses.ts @@ -1,3 +1,5 @@ +import { queryClient } from 'pl-fe/queries/client'; +import { scheduledStatusesQueryOptions } from 'pl-fe/queries/statuses/scheduled-statuses'; import { useModalsStore } from 'pl-fe/stores/modals'; import { useSettingsStore } from 'pl-fe/stores/settings'; import { isLoggedIn } from 'pl-fe/utils/auth'; @@ -43,7 +45,12 @@ const createStatus = (params: CreateStatusParams, idempotencyKey: string, status // The backend might still be processing the rich media attachment const expectsCard = status.scheduled_at === null && !status.card && shouldHaveCard(status); - if (status.scheduled_at === null) dispatch(importEntities({ statuses: [{ ...status, expectsCard }] }, { idempotencyKey, withParents: true })); + if (status.scheduled_at === null) { + dispatch(importEntities({ statuses: [{ ...status, expectsCard }] }, { idempotencyKey, withParents: true })); + } else { + queryClient.invalidateQueries(scheduledStatusesQueryOptions); + } + dispatch({ type: STATUS_CREATE_SUCCESS, status, params, idempotencyKey, editing: !!statusId }); // Poll the backend for the updated card diff --git a/packages/pl-fe/src/api/index.ts b/packages/pl-fe/src/api/index.ts index 9de440028..b8fde7455 100644 --- a/packages/pl-fe/src/api/index.ts +++ b/packages/pl-fe/src/api/index.ts @@ -3,9 +3,13 @@ * @module pl-fe/api */ import * as BuildConfig from 'pl-fe/build-config'; -import { RootState } from 'pl-fe/store'; import { buildFullPath } from 'pl-fe/utils/url'; +import type { RootState, Store } from 'pl-fe/store'; + +let store: Store; +import('pl-fe/store').then((value) => store = value.store).catch(() => {}); + type PlfeResponse = Response & { data: string; json: T }; /** @@ -33,7 +37,7 @@ const staticFetch = async (input: URL | RequestInfo, init?: RequestInit | undefi return { headers, ok, redirected, status, statusText, type, url, data, json } as any as PlfeResponse; }; -const getClient = (state: RootState | (() => RootState)) => { +const getClient = (state: RootState | (() => RootState) = store?.getState()) => { if (typeof state === 'function') state = state(); return state.auth.client; diff --git a/packages/pl-fe/src/components/sidebar-menu.tsx b/packages/pl-fe/src/components/sidebar-menu.tsx index 86734f31e..7ae1f5a23 100644 --- a/packages/pl-fe/src/components/sidebar-menu.tsx +++ b/packages/pl-fe/src/components/sidebar-menu.tsx @@ -1,4 +1,5 @@ /* eslint-disable jsx-a11y/interactive-supports-focus */ +import { useInfiniteQuery } from '@tanstack/react-query'; import clsx from 'clsx'; import React, { useCallback, useEffect, useRef, useState } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; @@ -19,6 +20,7 @@ import { useFeatures } from 'pl-fe/hooks/use-features'; import { useInstance } from 'pl-fe/hooks/use-instance'; import { useRegistrationStatus } from 'pl-fe/hooks/use-registration-status'; import { useFollowRequestsCount } from 'pl-fe/queries/accounts/use-follow-requests'; +import { scheduledStatusesCountQueryOptions } from 'pl-fe/queries/statuses/scheduled-statuses'; import { useInteractionRequestsCount } from 'pl-fe/queries/statuses/use-interaction-requests'; import { makeGetOtherAccounts } from 'pl-fe/selectors'; import { useSettingsStore } from 'pl-fe/stores/settings'; @@ -98,7 +100,7 @@ const SidebarMenu: React.FC = React.memo((): JSX.Element | null => { const { settings } = useSettingsStore(); const followRequestsCount = useFollowRequestsCount().data || 0; const interactionRequestsCount = useInteractionRequestsCount().data || 0; - const scheduledStatusCount = useAppSelector((state) => Object.keys(state.scheduled_statuses).length); + const scheduledStatusCount = useInfiniteQuery(scheduledStatusesCountQueryOptions).data || 0; const draftCount = useAppSelector((state) => Object.keys(state.draft_statuses).length); // const dashboardCount = useAppSelector((state) => state.admin.openReports.count() + state.admin.awaitingApproval.count()); const [sidebarVisible, setSidebarVisible] = useState(isSidebarOpen); diff --git a/packages/pl-fe/src/components/sidebar-navigation.tsx b/packages/pl-fe/src/components/sidebar-navigation.tsx index 25ee3ca54..d41b32502 100644 --- a/packages/pl-fe/src/components/sidebar-navigation.tsx +++ b/packages/pl-fe/src/components/sidebar-navigation.tsx @@ -1,3 +1,4 @@ +import { useInfiniteQuery } from '@tanstack/react-query'; import React, { useMemo } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; @@ -12,6 +13,7 @@ import { useInstance } from 'pl-fe/hooks/use-instance'; import { useOwnAccount } from 'pl-fe/hooks/use-own-account'; import { useRegistrationStatus } from 'pl-fe/hooks/use-registration-status'; import { useFollowRequestsCount } from 'pl-fe/queries/accounts/use-follow-requests'; +import { scheduledStatusesCountQueryOptions } from 'pl-fe/queries/statuses/scheduled-statuses'; import { useInteractionRequestsCount } from 'pl-fe/queries/statuses/use-interaction-requests'; import Account from './account'; @@ -47,7 +49,7 @@ const SidebarNavigation = React.memo(() => { const followRequestsCount = useFollowRequestsCount().data || 0; const interactionRequestsCount = useInteractionRequestsCount().data || 0; const dashboardCount = useAppSelector((state) => state.admin.openReports.length + state.admin.awaitingApproval.length); - const scheduledStatusCount = useAppSelector((state) => Object.keys(state.scheduled_statuses).length); + const scheduledStatusCount = useInfiniteQuery(scheduledStatusesCountQueryOptions).data || 0; const draftCount = useAppSelector((state) => Object.keys(state.draft_statuses).length); const restrictUnauth = instance.pleroma.metadata.restrict_unauthenticated; diff --git a/packages/pl-fe/src/features/scheduled-statuses/components/scheduled-status-action-bar.tsx b/packages/pl-fe/src/features/scheduled-statuses/components/scheduled-status-action-bar.tsx index e656a95b1..c43317682 100644 --- a/packages/pl-fe/src/features/scheduled-statuses/components/scheduled-status-action-bar.tsx +++ b/packages/pl-fe/src/features/scheduled-statuses/components/scheduled-status-action-bar.tsx @@ -1,10 +1,10 @@ +import { useMutation } from '@tanstack/react-query'; import React from 'react'; import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; -import { cancelScheduledStatus } from 'pl-fe/actions/scheduled-statuses'; import Button from 'pl-fe/components/ui/button'; import HStack from 'pl-fe/components/ui/hstack'; -import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch'; +import { cancelScheduledStatusMutationOptions } from 'pl-fe/queries/statuses/scheduled-statuses'; import { useModalsStore } from 'pl-fe/stores/modals'; import { useSettingsStore } from 'pl-fe/stores/settings'; @@ -24,20 +24,20 @@ interface IScheduledStatusActionBar { const ScheduledStatusActionBar: React.FC = ({ status }) => { const intl = useIntl(); - const dispatch = useAppDispatch(); + const { mutate: cancelScheduledStatus } = useMutation(cancelScheduledStatusMutationOptions(status.id)); const { openModal } = useModalsStore(); const { settings } = useSettingsStore(); const handleCancelClick = () => { const deleteModal = settings.deleteModal; if (!deleteModal) { - dispatch(cancelScheduledStatus(status.id)); + cancelScheduledStatus(); } else { openModal('CONFIRM', { heading: intl.formatMessage(messages.deleteHeading), message: intl.formatMessage(messages.deleteMessage), confirm: intl.formatMessage(messages.deleteConfirm), - onConfirm: () => dispatch(cancelScheduledStatus(status.id)), + onConfirm: () => cancelScheduledStatus(), }); } }; diff --git a/packages/pl-fe/src/features/scheduled-statuses/components/scheduled-status.tsx b/packages/pl-fe/src/features/scheduled-statuses/components/scheduled-status.tsx index e0451620a..a1c778286 100644 --- a/packages/pl-fe/src/features/scheduled-statuses/components/scheduled-status.tsx +++ b/packages/pl-fe/src/features/scheduled-statuses/components/scheduled-status.tsx @@ -14,14 +14,14 @@ import { buildStatus } from '../builder'; import ScheduledStatusActionBar from './scheduled-status-action-bar'; +import type { ScheduledStatus as ScheduledStatusEntity } from 'pl-api'; + interface IScheduledStatus { - statusId: string; + scheduledStatus: ScheduledStatusEntity; } -const ScheduledStatus: React.FC = ({ statusId, ...other }) => { +const ScheduledStatus: React.FC = ({ scheduledStatus, ...other }) => { const status = useAppSelector((state) => { - const scheduledStatus = state.scheduled_statuses[statusId]; - if (!scheduledStatus) return null; return buildStatus(state, scheduledStatus); }); diff --git a/packages/pl-fe/src/features/scheduled-statuses/index.tsx b/packages/pl-fe/src/features/scheduled-statuses/index.tsx index 5cb4eaa1f..bdfa01076 100644 --- a/packages/pl-fe/src/features/scheduled-statuses/index.tsx +++ b/packages/pl-fe/src/features/scheduled-statuses/index.tsx @@ -1,12 +1,10 @@ -import debounce from 'lodash/debounce'; -import React, { useEffect } from 'react'; -import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; +import { useInfiniteQuery } from '@tanstack/react-query'; +import React from 'react'; +import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; -import { fetchScheduledStatuses, expandScheduledStatuses } from 'pl-fe/actions/scheduled-statuses'; import ScrollableList from 'pl-fe/components/scrollable-list'; import Column from 'pl-fe/components/ui/column'; -import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch'; -import { useAppSelector } from 'pl-fe/hooks/use-app-selector'; +import { scheduledStatusesQueryOptions } from 'pl-fe/queries/statuses/scheduled-statuses'; import ScheduledStatus from './components/scheduled-status'; @@ -14,35 +12,23 @@ const messages = defineMessages({ heading: { id: 'column.scheduled_statuses', defaultMessage: 'Scheduled posts' }, }); -const handleLoadMore = debounce((dispatch) => { - dispatch(expandScheduledStatuses()); -}, 300, { leading: true }); - const ScheduledStatuses = () => { const intl = useIntl(); - const dispatch = useAppDispatch(); - const statusIds = useAppSelector((state) => state.status_lists.scheduled_statuses!.items); - const isLoading = useAppSelector((state) => state.status_lists.scheduled_statuses!.isLoading); - const hasMore = useAppSelector((state) => !!state.status_lists.scheduled_statuses!.next); - - useEffect(() => { - dispatch(fetchScheduledStatuses()); - }, []); + const { data: scheduledStatuses = [], isLoading, hasNextPage, fetchNextPage } = useInfiniteQuery(scheduledStatusesQueryOptions); const emptyMessage = ; return ( handleLoadMore(dispatch)} + onLoadMore={() => fetchNextPage({ cancelRefetch: false })} emptyMessage={emptyMessage} listClassName='divide-y divide-solid divide-gray-200 dark:divide-gray-800' > - {statusIds.map((id: string) => )} + {scheduledStatuses.map((status) => )} ); diff --git a/packages/pl-fe/src/features/ui/index.tsx b/packages/pl-fe/src/features/ui/index.tsx index 5a63f30e1..6774c19cc 100644 --- a/packages/pl-fe/src/features/ui/index.tsx +++ b/packages/pl-fe/src/features/ui/index.tsx @@ -8,7 +8,6 @@ import { fetchFilters } from 'pl-fe/actions/filters'; import { fetchMarker } from 'pl-fe/actions/markers'; import { expandNotifications } from 'pl-fe/actions/notifications'; import { register as registerPushNotifications } from 'pl-fe/actions/push-notifications/registerer'; -import { fetchScheduledStatuses } from 'pl-fe/actions/scheduled-statuses'; import { fetchHomeTimeline } from 'pl-fe/actions/timelines'; import { useUserStream } from 'pl-fe/api/hooks/streaming/use-user-stream'; import SidebarNavigation from 'pl-fe/components/sidebar-navigation'; @@ -40,7 +39,9 @@ import RemoteInstanceLayout from 'pl-fe/layouts/remote-instance-layout'; import SearchLayout from 'pl-fe/layouts/search-layout'; import StatusLayout from 'pl-fe/layouts/status-layout'; import { prefetchFollowRequests } from 'pl-fe/queries/accounts/use-follow-requests'; +import { queryClient } from 'pl-fe/queries/client'; import { prefetchCustomEmojis } from 'pl-fe/queries/instance/use-custom-emojis'; +import { scheduledStatusesQueryOptions } from 'pl-fe/queries/statuses/scheduled-statuses'; import { useUiStore } from 'pl-fe/stores/ui'; import { getVapidKey } from 'pl-fe/utils/auth'; import { isStandalone } from 'pl-fe/utils/state'; @@ -420,7 +421,9 @@ const UI: React.FC = React.memo(({ children }) => { setTimeout(() => prefetchFollowRequests(client), 700); } - setTimeout(() => dispatch(fetchScheduledStatuses()), 900); + setTimeout(() => { + queryClient.prefetchInfiniteQuery(scheduledStatusesQueryOptions); + }, 900); }; useEffect(() => { diff --git a/packages/pl-fe/src/queries/statuses/scheduled-statuses.ts b/packages/pl-fe/src/queries/statuses/scheduled-statuses.ts new file mode 100644 index 000000000..55ee1ff61 --- /dev/null +++ b/packages/pl-fe/src/queries/statuses/scheduled-statuses.ts @@ -0,0 +1,30 @@ +import { infiniteQueryOptions } from '@tanstack/react-query'; +import { create } from 'mutative'; + +import { getClient } from 'pl-fe/api'; + +import { queryClient } from '../client'; +import { makePaginatedResponseQueryOptions } from '../utils/make-paginated-response-query-options'; +import { mutationOptions } from '../utils/mutation-options'; + +const scheduledStatusesQueryOptions = makePaginatedResponseQueryOptions( + ['scheduledStatuses'], + (client) => client.scheduledStatuses.getScheduledStatuses(), +)(); + +const scheduledStatusesCountQueryOptions = infiniteQueryOptions({ + ...scheduledStatusesQueryOptions, + select: (data) => data.pages.map(page => page.items).flat().length, +}); + +const cancelScheduledStatusMutationOptions = (scheduledStatusId: string) => mutationOptions({ + mutationKey: ['scheduledStatuses', scheduledStatusId], + mutationFn: () => getClient().scheduledStatuses.cancelScheduledStatus(scheduledStatusId), + onSettled: () => { + queryClient.setQueryData(scheduledStatusesQueryOptions.queryKey, (data) => create(data, (draft) => { + draft?.pages.forEach(page => page.items = page.items.filter(({ id }) => id !== scheduledStatusId)); + })); + }, +}); + +export { scheduledStatusesQueryOptions, scheduledStatusesCountQueryOptions, cancelScheduledStatusMutationOptions }; diff --git a/packages/pl-fe/src/queries/utils/make-paginated-response-query-options.ts b/packages/pl-fe/src/queries/utils/make-paginated-response-query-options.ts new file mode 100644 index 000000000..146c97370 --- /dev/null +++ b/packages/pl-fe/src/queries/utils/make-paginated-response-query-options.ts @@ -0,0 +1,19 @@ +import { type InfiniteData, infiniteQueryOptions } from '@tanstack/react-query'; + +import { store } from 'pl-fe/store'; + +import type { PaginatedResponse, PlApiClient } from 'pl-api'; + +const makePaginatedResponseQueryOptions = , T2, T3 = Array>( + queryKey: Array | ((...params: T1) => Array), + queryFn: (client: PlApiClient, params: T1) => Promise>, + select?: (data: InfiniteData>) => T3, +) => (...params: T1) => infiniteQueryOptions({ + queryKey: typeof queryKey === 'object' ? queryKey : queryKey(...params), + queryFn: ({ pageParam }) => pageParam.next?.() || queryFn(store.getState().auth.client, params), + initialPageParam: { previous: null, next: null, items: [], partial: false } as Awaited>, + getNextPageParam: (page) => page.next ? page : undefined, + select: select ?? ((data) => data.pages.map(page => page.items).flat() as T3), + }); + +export { makePaginatedResponseQueryOptions }; diff --git a/packages/pl-fe/src/queries/utils/mutation-options.ts b/packages/pl-fe/src/queries/utils/mutation-options.ts new file mode 100644 index 000000000..3515e486f --- /dev/null +++ b/packages/pl-fe/src/queries/utils/mutation-options.ts @@ -0,0 +1,12 @@ +import type { DefaultError } from '@tanstack/query-core'; +import type { 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/pl-fe/src/reducers/index.ts b/packages/pl-fe/src/reducers/index.ts index c477d3fac..da86c668b 100644 --- a/packages/pl-fe/src/reducers/index.ts +++ b/packages/pl-fe/src/reducers/index.ts @@ -27,7 +27,6 @@ import pending_statuses from './pending-statuses'; import plfe from './pl-fe'; import polls from './polls'; import push_notifications from './push-notifications'; -import scheduled_statuses from './scheduled-statuses'; import security from './security'; import status_lists from './status-lists'; import statuses from './statuses'; @@ -58,7 +57,6 @@ const reducers = { plfe, polls, push_notifications, - scheduled_statuses, security, status_lists, statuses, diff --git a/packages/pl-fe/src/reducers/scheduled-statuses.ts b/packages/pl-fe/src/reducers/scheduled-statuses.ts deleted file mode 100644 index 705d2eb60..000000000 --- a/packages/pl-fe/src/reducers/scheduled-statuses.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { create } from 'mutative'; - -import { STATUS_IMPORT, STATUSES_IMPORT, type ImporterAction } from 'pl-fe/actions/importer'; -import { - SCHEDULED_STATUSES_FETCH_SUCCESS, - SCHEDULED_STATUS_CANCEL_REQUEST, - SCHEDULED_STATUS_CANCEL_SUCCESS, - type ScheduledStatusesAction, -} from 'pl-fe/actions/scheduled-statuses'; -import { STATUS_CREATE_SUCCESS, type StatusesAction } from 'pl-fe/actions/statuses'; - -import type { Status, ScheduledStatus } from 'pl-api'; - -type State = Record; - -const initialState: State = {}; - -const importStatus = (state: State, status: Status | ScheduledStatus) => { - if (!status.scheduled_at) return state; - state[status.id] = status; -}; - -const importStatuses = (state: State, statuses: Array) => { - statuses.forEach(status => importStatus(state, status)); -}; - -const deleteStatus = (state: State, statusId: string) => { - delete state[statusId]; -}; - -const scheduled_statuses = (state: State = initialState, action: ImporterAction | ScheduledStatusesAction | StatusesAction) => { - switch (action.type) { - case STATUS_IMPORT: - case STATUS_CREATE_SUCCESS: - return create(state, (draft) => importStatus(draft, action.status)); - case STATUSES_IMPORT: - case SCHEDULED_STATUSES_FETCH_SUCCESS: - return create(state, (draft) => importStatuses(draft, action.statuses)); - case SCHEDULED_STATUS_CANCEL_REQUEST: - case SCHEDULED_STATUS_CANCEL_SUCCESS: - return create(state, (draft) => deleteStatus(draft, action.statusId)); - default: - return state; - } -}; - -export { scheduled_statuses as default }; diff --git a/packages/pl-fe/src/reducers/status-lists.ts b/packages/pl-fe/src/reducers/status-lists.ts index bdf663edc..ad12a6465 100644 --- a/packages/pl-fe/src/reducers/status-lists.ts +++ b/packages/pl-fe/src/reducers/status-lists.ts @@ -43,20 +43,9 @@ import { type InteractionsAction, } from 'pl-fe/actions/interactions'; import { PINNED_STATUSES_FETCH_SUCCESS, type PinStatusesAction } from 'pl-fe/actions/pin-statuses'; -import { - SCHEDULED_STATUSES_FETCH_REQUEST, - SCHEDULED_STATUSES_FETCH_SUCCESS, - SCHEDULED_STATUSES_FETCH_FAIL, - SCHEDULED_STATUSES_EXPAND_REQUEST, - SCHEDULED_STATUSES_EXPAND_SUCCESS, - SCHEDULED_STATUSES_EXPAND_FAIL, - SCHEDULED_STATUS_CANCEL_REQUEST, - SCHEDULED_STATUS_CANCEL_SUCCESS, - type ScheduledStatusesAction, -} from 'pl-fe/actions/scheduled-statuses'; -import { STATUS_CREATE_SUCCESS, type StatusesAction } from 'pl-fe/actions/statuses'; -import type { PaginatedResponse, ScheduledStatus, Status } from 'pl-api'; +import type { PaginatedResponse, Status } from 'pl-api'; +import type { StatusesAction } from 'pl-fe/actions/statuses'; interface StatusList { next: (() => Promise>) | null; @@ -78,7 +67,6 @@ const initialState: State = { favourites: newStatusList(), bookmarks: newStatusList(), pins: newStatusList(), - scheduled_statuses: newStatusList(), recent_events: newStatusList(), joined_events: newStatusList(), }; @@ -125,11 +113,6 @@ const removeOneFromList = (state: State, listType: string, status: string | Pick list.items = list.items.filter(id => id !== statusId); }; -const maybeAppendScheduledStatus = (state: State, status: Pick) => { - if (!status.scheduled_at) return state; - return prependOneToList(state, 'scheduled_statuses', getStatusId(status)); -}; - const addBookmarkToLists = (state: State, status: Pick) => { prependOneToList(state, 'bookmarks', status); const folderId = status.bookmark_folder; @@ -146,7 +129,7 @@ const removeBookmarkFromLists = (state: State, status: Pick { +const statusLists = (state = initialState, action: BookmarksAction | EventsAction | FavouritesAction | InteractionsAction | PinStatusesAction | StatusesAction): State => { switch (action.type) { case FAVOURITED_STATUSES_FETCH_REQUEST: case FAVOURITED_STATUSES_EXPAND_REQUEST: @@ -192,19 +175,6 @@ const statusLists = (state = initialState, action: BookmarksAction | EventsActio return create(state, draft => prependOneToList(draft, 'pins', action.status)); case UNPIN_SUCCESS: return create(state, draft => removeOneFromList(draft, 'pins', action.status)); - case SCHEDULED_STATUSES_FETCH_REQUEST: - case SCHEDULED_STATUSES_EXPAND_REQUEST: - return create(state, draft => setLoading(draft, 'scheduled_statuses', true)); - case SCHEDULED_STATUSES_FETCH_FAIL: - case SCHEDULED_STATUSES_EXPAND_FAIL: - return create(state, draft => setLoading(draft, 'scheduled_statuses', false)); - case SCHEDULED_STATUSES_FETCH_SUCCESS: - return create(state, draft => normalizeList(draft, 'scheduled_statuses', action.statuses, action.next as any)); - case SCHEDULED_STATUSES_EXPAND_SUCCESS: - return create(state, draft => appendToList(draft, 'scheduled_statuses', action.statuses, action.next as any)); - case SCHEDULED_STATUS_CANCEL_REQUEST: - case SCHEDULED_STATUS_CANCEL_SUCCESS: - return create(state, draft => removeOneFromList(draft, 'scheduled_statuses', action.statusId)); case RECENT_EVENTS_FETCH_REQUEST: return create(state, draft => setLoading(draft, 'recent_events', true)); case RECENT_EVENTS_FETCH_FAIL: @@ -217,8 +187,6 @@ const statusLists = (state = initialState, action: BookmarksAction | EventsActio return create(state, draft => setLoading(draft, 'joined_events', false)); case JOINED_EVENTS_FETCH_SUCCESS: return create(state, draft => normalizeList(draft, 'joined_events', action.statuses, action.next)); - case STATUS_CREATE_SUCCESS: - return create(state, draft => maybeAppendScheduledStatus(draft, action.status)); default: return state; }