diff --git a/packages/pl-fe/src/actions/accounts.ts b/packages/pl-fe/src/actions/accounts.ts index 902e56995..7f78a4dd9 100644 --- a/packages/pl-fe/src/actions/accounts.ts +++ b/packages/pl-fe/src/actions/accounts.ts @@ -22,7 +22,6 @@ import type { MinifiedSuggestion } from 'pl-fe/api/hooks/trends/use-suggested-ac import type { MinifiedStatus } from 'pl-fe/reducers/statuses'; import type { AppDispatch, RootState } from 'pl-fe/store'; import type { History } from 'pl-fe/types/history'; -import type { Me } from 'pl-fe/types/pl-fe'; const ACCOUNT_CREATE_REQUEST = 'ACCOUNT_CREATE_REQUEST' as const; const ACCOUNT_CREATE_SUCCESS = 'ACCOUNT_CREATE_SUCCESS' as const; @@ -72,10 +71,6 @@ const NOTIFICATION_SETTINGS_REQUEST = 'NOTIFICATION_SETTINGS_REQUEST' as const; const NOTIFICATION_SETTINGS_SUCCESS = 'NOTIFICATION_SETTINGS_SUCCESS' as const; const NOTIFICATION_SETTINGS_FAIL = 'NOTIFICATION_SETTINGS_FAIL' as const; -const BIRTHDAY_REMINDERS_FETCH_REQUEST = 'BIRTHDAY_REMINDERS_FETCH_REQUEST' as const; -const BIRTHDAY_REMINDERS_FETCH_SUCCESS = 'BIRTHDAY_REMINDERS_FETCH_SUCCESS' as const; -const BIRTHDAY_REMINDERS_FETCH_FAIL = 'BIRTHDAY_REMINDERS_FETCH_FAIL' as const; - const maybeRedirectLogin = (error: { response: PlfeResponse }, history?: History) => { // The client is unauthorized - redirect to login. if (history && error?.response?.status === 401) { @@ -565,50 +560,6 @@ const accountLookup = (acct: string, signal?: AbortSignal) => }); }; -interface BirthdayRemindersFetchRequestAction { - type: typeof BIRTHDAY_REMINDERS_FETCH_REQUEST; - day: number; - month: number; - accountId: Me; -} - -interface BirthdayRemindersFetchSuccessAction { - type: typeof BIRTHDAY_REMINDERS_FETCH_SUCCESS; - day: number; - month: number; - accountId: string; - accounts: Array; -} - -interface BirthdayRemindersFetchFailAction { - type: typeof BIRTHDAY_REMINDERS_FETCH_FAIL; - day: number; - month: number; - accountId: Me; -} - -const fetchBirthdayReminders = (month: number, day: number) => - (dispatch: AppDispatch, getState: () => RootState) => { - if (!isLoggedIn(getState)) return; - - const me = getState().me as string; - - dispatch({ type: BIRTHDAY_REMINDERS_FETCH_REQUEST, day, month, accountId: me }); - - return getClient(getState).accounts.getBirthdays(day, month).then(response => { - dispatch(importEntities({ accounts: response })); - dispatch({ - type: BIRTHDAY_REMINDERS_FETCH_SUCCESS, - accounts: response, - day, - month, - accountId: me, - }); - }).catch(() => { - dispatch({ type: BIRTHDAY_REMINDERS_FETCH_FAIL, day, month, accountId: me }); - }); - }; - const biteAccount = (accountId: string) => (dispatch: AppDispatch, getState: () => RootState) => { const client = getClient(getState); @@ -652,10 +603,7 @@ type AccountsAction = | AccountSearchFailAction | AccountLookupRequestAction | AccountLookupSuccessAction - | AccountLookupFailAction - | BirthdayRemindersFetchSuccessAction - | BirthdayRemindersFetchRequestAction - | BirthdayRemindersFetchFailAction + | AccountLookupFailAction; export { ACCOUNT_CREATE_REQUEST, @@ -694,9 +642,6 @@ export { NOTIFICATION_SETTINGS_REQUEST, NOTIFICATION_SETTINGS_SUCCESS, NOTIFICATION_SETTINGS_FAIL, - BIRTHDAY_REMINDERS_FETCH_REQUEST, - BIRTHDAY_REMINDERS_FETCH_SUCCESS, - BIRTHDAY_REMINDERS_FETCH_FAIL, createAccount, fetchAccount, fetchAccountByUsername, @@ -716,7 +661,6 @@ export { fetchPinnedAccounts, accountSearch, accountLookup, - fetchBirthdayReminders, biteAccount, type AccountsAction, }; diff --git a/packages/pl-fe/src/api/hooks/account-lists/use-birthday-reminders.ts b/packages/pl-fe/src/api/hooks/account-lists/use-birthday-reminders.ts new file mode 100644 index 000000000..e80405779 --- /dev/null +++ b/packages/pl-fe/src/api/hooks/account-lists/use-birthday-reminders.ts @@ -0,0 +1,22 @@ + +import { useQuery } from '@tanstack/react-query'; + +import { importEntities } from 'pl-fe/actions/importer'; +import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch'; +import { useClient } from 'pl-fe/hooks/use-client'; + +const useBirthdayReminders = (month: number, day: number) => { + const client = useClient(); + const dispatch = useAppDispatch(); + + return useQuery({ + queryKey: ['accountsLists', 'birthdayReminders', month, day], + queryFn: () => client.accounts.getBirthdays(day, month).then((accounts) => { + dispatch(importEntities({ accounts })); + + return accounts.map(({ id }) => id); + }), + }); +}; + +export { useBirthdayReminders }; diff --git a/packages/pl-fe/src/components/birthday-panel.tsx b/packages/pl-fe/src/components/birthday-panel.tsx index 68115e5db..b7b9f06a6 100644 --- a/packages/pl-fe/src/components/birthday-panel.tsx +++ b/packages/pl-fe/src/components/birthday-panel.tsx @@ -1,11 +1,9 @@ -import React, { useRef } from 'react'; +import React, { useRef, useState } from 'react'; import { FormattedMessage } from 'react-intl'; -import { fetchBirthdayReminders } from 'pl-fe/actions/accounts'; +import { useBirthdayReminders } from 'pl-fe/api/hooks/account-lists/use-birthday-reminders'; import Widget from 'pl-fe/components/ui/widget'; import AccountContainer from 'pl-fe/containers/account-container'; -import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch'; -import { useAppSelector } from 'pl-fe/hooks/use-app-selector'; const timeToMidnight = () => { const now = new Date(); @@ -14,31 +12,36 @@ const timeToMidnight = () => { return midnight.getTime() - now.getTime(); }; +const getCurrentDate = () => { + const date = new Date(); + + const day = date.getDate(); + const month = date.getMonth() + 1; + + return [day, month]; +}; + interface IBirthdayPanel { limit: number; } const BirthdayPanel = ({ limit }: IBirthdayPanel) => { - const dispatch = useAppDispatch(); + const [[day, month], setDate] = useState(getCurrentDate); - const birthdays = useAppSelector(state => state.user_lists.birthday_reminders[state.me as string]?.items || []); + const { data: birthdays = [] } = useBirthdayReminders(month, day); const birthdaysToRender = birthdays.slice(0, limit); const timeout = useRef(); - const handleFetchBirthdayReminders = () => { - const date = new Date(); - - const day = date.getDate(); - const month = date.getMonth() + 1; - - dispatch(fetchBirthdayReminders(month, day))?.then(() => { - timeout.current = setTimeout(() => handleFetchBirthdayReminders(), timeToMidnight()); - }); - }; - React.useEffect(() => { - handleFetchBirthdayReminders(); + const updateTimeout = () => { + timeout.current = setTimeout(() => { + setDate(getCurrentDate); + updateTimeout(); + }, timeToMidnight()); + }; + + updateTimeout(); return () => { if (timeout.current) { @@ -65,4 +68,4 @@ const BirthdayPanel = ({ limit }: IBirthdayPanel) => { ); }; -export { BirthdayPanel as default }; +export { BirthdayPanel as default, getCurrentDate }; diff --git a/packages/pl-fe/src/features/ui/components/modals/birthdays-modal.tsx b/packages/pl-fe/src/features/ui/components/modals/birthdays-modal.tsx index 654042c22..10726bed5 100644 --- a/packages/pl-fe/src/features/ui/components/modals/birthdays-modal.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/birthdays-modal.tsx @@ -1,16 +1,18 @@ -import React from 'react'; +import React, { useState } from 'react'; import { FormattedMessage } from 'react-intl'; +import { useBirthdayReminders } from 'pl-fe/api/hooks/account-lists/use-birthday-reminders'; +import { getCurrentDate } from 'pl-fe/components/birthday-panel'; import ScrollableList from 'pl-fe/components/scrollable-list'; import Modal from 'pl-fe/components/ui/modal'; import Spinner from 'pl-fe/components/ui/spinner'; import Account from 'pl-fe/features/birthdays/account'; -import { useAppSelector } from 'pl-fe/hooks/use-app-selector'; import type { BaseModalProps } from '../modal-root'; const BirthdaysModal = ({ onClose }: BaseModalProps) => { - const accountIds = useAppSelector(state => state.user_lists.birthday_reminders[state.me as string]?.items); + const [[day, month]] = useState(getCurrentDate); + const { data: accountIds } = useBirthdayReminders(month, day); const onClickClose = () => { onClose('BIRTHDAYS'); diff --git a/packages/pl-fe/src/reducers/user-lists.ts b/packages/pl-fe/src/reducers/user-lists.ts index 6f31a6095..0c37787b5 100644 --- a/packages/pl-fe/src/reducers/user-lists.ts +++ b/packages/pl-fe/src/reducers/user-lists.ts @@ -6,7 +6,6 @@ import { FOLLOW_REQUEST_AUTHORIZE_SUCCESS, FOLLOW_REQUEST_REJECT_SUCCESS, PINNED_ACCOUNTS_FETCH_SUCCESS, - BIRTHDAY_REMINDERS_FETCH_SUCCESS, type AccountsAction, } from 'pl-fe/actions/accounts'; import { FAMILIAR_FOLLOWERS_FETCH_SUCCESS, type FamiliarFollowersAction } from 'pl-fe/actions/familiar-followers'; @@ -50,7 +49,7 @@ interface ReactionList { } type ListKey = 'follow_requests'; -type NestedListKey = 'reblogged_by' | 'favourited_by' | 'disliked_by' | 'pinned' | 'birthday_reminders' | 'familiar_followers' | 'membership_requests' | 'group_blocks'; +type NestedListKey = 'reblogged_by' | 'favourited_by' | 'disliked_by' | 'pinned' | 'familiar_followers' | 'membership_requests' | 'group_blocks'; type State = Record & Record> & { reactions: Record; @@ -63,7 +62,6 @@ const initialState: State = { reactions: {}, follow_requests: { next: null, items: [], isLoading: false }, pinned: {}, - birthday_reminders: {}, familiar_followers: {}, membership_requests: {}, group_blocks: {}, @@ -155,8 +153,6 @@ const userLists = (state = initialState, action: AccountsAction | FamiliarFollow return removeFromList(state, ['follow_requests'], action.accountId); case PINNED_ACCOUNTS_FETCH_SUCCESS: return normalizeList(state, ['pinned', action.accountId], action.accounts, action.next); - case BIRTHDAY_REMINDERS_FETCH_SUCCESS: - return normalizeList(state, ['birthday_reminders', action.accountId], action.accounts); case FAMILIAR_FOLLOWERS_FETCH_SUCCESS: return normalizeList(state, ['familiar_followers', action.accountId], action.accounts); case GROUP_BLOCKS_FETCH_SUCCESS: