From eeb1e1370cd76167fb59f3edc5bef4cfbc76930f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sat, 5 Oct 2024 00:13:47 +0200 Subject: [PATCH] wip hooks migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-api/lib/entities/account.ts | 7 +++- packages/pl-fe/src/actions/accounts.ts | 2 +- .../src/features/notifications/index.tsx | 5 ++- packages/pl-fe/src/features/status/index.tsx | 2 +- packages/pl-fe/src/normalizers/account.ts | 1 - packages/pl-fe/src/pl-hooks | 1 - .../src/pl-hooks/hooks/accounts/useAccount.ts | 42 +++++++++++++++++++ .../src/pl-hooks/hooks/markers/useMarkers.ts | 24 +++++++++++ .../hooks/markers/useUpdateMarkerMutation.ts | 25 +++++++++++ .../hooks/notifications/useNotification.ts | 0 .../notifications/useNotificationList.ts | 0 .../src/pl-hooks}/hooks/statuses/useStatus.ts | 0 .../lib => pl-fe/src/pl-hooks}/importer.ts | 0 .../lib => pl-fe/src/pl-hooks}/main.ts | 0 .../pl-hooks}/minifiers/minifyNotification.ts | 0 .../src/pl-hooks}/minifiers/minifyStatus.ts | 0 .../normalizers/deduplicateNotifications.ts | 0 .../pl-hooks}/normalizers/normalizeStatus.ts | 0 .../pl-hooks/lib/hooks/markers/useMarkers.ts | 42 ------------------- 19 files changed, 101 insertions(+), 50 deletions(-) delete mode 120000 packages/pl-fe/src/pl-hooks create mode 100644 packages/pl-fe/src/pl-hooks/hooks/accounts/useAccount.ts create mode 100644 packages/pl-fe/src/pl-hooks/hooks/markers/useMarkers.ts create mode 100644 packages/pl-fe/src/pl-hooks/hooks/markers/useUpdateMarkerMutation.ts rename packages/{pl-hooks/lib => pl-fe/src/pl-hooks}/hooks/notifications/useNotification.ts (100%) rename packages/{pl-hooks/lib => pl-fe/src/pl-hooks}/hooks/notifications/useNotificationList.ts (100%) rename packages/{pl-hooks/lib => pl-fe/src/pl-hooks}/hooks/statuses/useStatus.ts (100%) rename packages/{pl-hooks/lib => pl-fe/src/pl-hooks}/importer.ts (100%) rename packages/{pl-hooks/lib => pl-fe/src/pl-hooks}/main.ts (100%) rename packages/{pl-hooks/lib => pl-fe/src/pl-hooks}/minifiers/minifyNotification.ts (100%) rename packages/{pl-hooks/lib => pl-fe/src/pl-hooks}/minifiers/minifyStatus.ts (100%) rename packages/{pl-hooks/lib => pl-fe/src/pl-hooks}/normalizers/deduplicateNotifications.ts (100%) rename packages/{pl-hooks/lib => pl-fe/src/pl-hooks}/normalizers/normalizeStatus.ts (100%) delete mode 100644 packages/pl-hooks/lib/hooks/markers/useMarkers.ts diff --git a/packages/pl-api/lib/entities/account.ts b/packages/pl-api/lib/entities/account.ts index 210b470c1..86a80c75c 100644 --- a/packages/pl-api/lib/entities/account.ts +++ b/packages/pl-api/lib/entities/account.ts @@ -85,6 +85,7 @@ const baseAccountSchema = z.object({ group: z.boolean().catch(false), discoverable: z.boolean().catch(false), noindex: z.boolean().nullable().catch(null), + moved: z.null().catch(null), suspended: z.boolean().optional().catch(undefined), limited: z.boolean().optional().catch(undefined), created_at: z.string().datetime().catch(new Date().toUTCString()), @@ -127,13 +128,15 @@ const baseAccountSchema = z.object({ }); const accountWithMovedAccountSchema = baseAccountSchema.extend({ - moved: baseAccountSchema.optional().catch(undefined), + moved: z.lazy((): typeof baseAccountSchema => accountWithMovedAccountSchema as any).nullable().catch(null), }); /** @see {@link https://docs.joinmastodon.org/entities/Account/} */ const accountSchema = z.preprocess(preprocessAccount, accountWithMovedAccountSchema); -type Account = z.infer; +type Account = z.infer & { + moved: Account | null; +}; const credentialAccountSchema = z.preprocess(preprocessAccount, accountWithMovedAccountSchema.extend({ source: z.object({ diff --git a/packages/pl-fe/src/actions/accounts.ts b/packages/pl-fe/src/actions/accounts.ts index 9b386f1bf..f52b6002e 100644 --- a/packages/pl-fe/src/actions/accounts.ts +++ b/packages/pl-fe/src/actions/accounts.ts @@ -1,8 +1,8 @@ import { PLEROMA, type UpdateNotificationSettingsParams, type Account, type CreateAccountParams, type PaginatedResponse, type Relationship } from 'pl-api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { getClient, type PlfeResponse } from 'pl-fe/api'; import { Entities } from 'pl-fe/entity-store/entities'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { selectAccount } from 'pl-fe/selectors'; import { isLoggedIn } from 'pl-fe/utils/auth'; diff --git a/packages/pl-fe/src/features/notifications/index.tsx b/packages/pl-fe/src/features/notifications/index.tsx index 9bc503207..0ce430dc4 100644 --- a/packages/pl-fe/src/features/notifications/index.tsx +++ b/packages/pl-fe/src/features/notifications/index.tsx @@ -1,6 +1,7 @@ import clsx from 'clsx'; import debounce from 'lodash/debounce'; -import { useMarker, useUpdateMarkerMutation } from 'pl-fe/pl-hooks/hooks/markers/useMarkers'; +import { useMarker } from 'pl-fe/pl-hooks/hooks/markers/useMarkers'; +import { useUpdateMarkerMutation } from 'pl-fe/pl-hooks/hooks/markers/useUpdateMarkerMutation'; import { useNotificationList } from 'pl-fe/pl-hooks/hooks/notifications/useNotificationList'; import React, { useCallback, useEffect, useRef } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; @@ -150,7 +151,7 @@ const Notifications = () => { placeholderCount={20} onLoadMore={handleLoadOlder} onScroll={handleScroll} - listClassName={clsx('black:divide-gray-800 dark:divide-primary-800 divide-y divide-solid divide-gray-200', { + listClassName={clsx('divide-y divide-solid divide-gray-200 black:divide-gray-800 dark:divide-primary-800', { 'animate-pulse': notifications.length === 0, })} > diff --git a/packages/pl-fe/src/features/status/index.tsx b/packages/pl-fe/src/features/status/index.tsx index 826c393e4..8119be363 100644 --- a/packages/pl-fe/src/features/status/index.tsx +++ b/packages/pl-fe/src/features/status/index.tsx @@ -1,5 +1,5 @@ import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect } from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { Redirect } from 'react-router-dom'; diff --git a/packages/pl-fe/src/normalizers/account.ts b/packages/pl-fe/src/normalizers/account.ts index 0a8d96353..fe76442a6 100644 --- a/packages/pl-fe/src/normalizers/account.ts +++ b/packages/pl-fe/src/normalizers/account.ts @@ -37,7 +37,6 @@ const normalizeAccount = (account: BaseAccount) => { const emojiMap = makeEmojiMap(account.emojis); return { - mute_expires_at: null, ...account, avatar: account.avatar || account.avatar_static || missingAvatar, avatar_static: account.avatar_static || account.avatar || missingAvatar, diff --git a/packages/pl-fe/src/pl-hooks b/packages/pl-fe/src/pl-hooks deleted file mode 120000 index 8a10dc6fb..000000000 --- a/packages/pl-fe/src/pl-hooks +++ /dev/null @@ -1 +0,0 @@ -../../pl-hooks/lib \ No newline at end of file diff --git a/packages/pl-fe/src/pl-hooks/hooks/accounts/useAccount.ts b/packages/pl-fe/src/pl-hooks/hooks/accounts/useAccount.ts new file mode 100644 index 000000000..d1510a465 --- /dev/null +++ b/packages/pl-fe/src/pl-hooks/hooks/accounts/useAccount.ts @@ -0,0 +1,42 @@ +import { useQuery } from '@tanstack/react-query'; +import { useRelationship } from 'pl-fe/api/hooks/accounts/useRelationship'; + +import { useAppSelector, useClient } from 'pl-fe/hooks'; + +interface UseAccountOpts { + withRelationship?: boolean; + withScrobble?: boolean; + withMoveTarget?: boolean; +} + +const useAccount = (accountId?: string, opts: UseAccountOpts = {}) => { + const client = useClient(); + + const accountQuery = useQuery({ + queryKey: ['accounts', 'entities', accountId], + queryFn: () => client.accounts.getAccount(accountId!) + .then(normalizeAccount) + .then(minifyAccount), + enabled: !!accountId, + }); + + const relationshipQuery = useRelationship(accountId, { + enabled: opts.withRelationship, + }); + + const movedQuery = useAccount(opts.withMoveTarget && accountQuery.data?.moved_id || undefined); + + const data: Account | null = useAppSelector((state) => { + const account = accountQuery.data; + if (!account) return null; + + return { + ...account, + account, + relationship: relationshipQuery.relationship, + moved: movedQuery.data || null, + }; + }); + + return { ...accountQuery, data }; +}; diff --git a/packages/pl-fe/src/pl-hooks/hooks/markers/useMarkers.ts b/packages/pl-fe/src/pl-hooks/hooks/markers/useMarkers.ts new file mode 100644 index 000000000..124c0448d --- /dev/null +++ b/packages/pl-fe/src/pl-hooks/hooks/markers/useMarkers.ts @@ -0,0 +1,24 @@ +import { useQuery } from '@tanstack/react-query'; +import { useClient } from 'pl-fe/hooks'; +import { queryClient } from 'pl-fe/queries/client'; + +import type { PlApiClient } from 'pl-api'; + +type Timeline = 'home' | 'notifications'; + +const useMarker = (timeline: Timeline) => { + const client = useClient(); + + return useQuery({ + queryKey: ['markers', timeline], + queryFn: () => client.timelines.getMarkers([timeline]).then(markers => markers[timeline]), + }); +}; + +const prefetchMarker = (client: PlApiClient, timeline: 'home' | 'notifications') => + queryClient.prefetchQuery({ + queryKey: ['markers', timeline], + queryFn: () => client.timelines.getMarkers([timeline]).then(markers => markers[timeline]), + }); + +export { useMarker, prefetchMarker, type Timeline }; diff --git a/packages/pl-fe/src/pl-hooks/hooks/markers/useUpdateMarkerMutation.ts b/packages/pl-fe/src/pl-hooks/hooks/markers/useUpdateMarkerMutation.ts new file mode 100644 index 000000000..9d158d22e --- /dev/null +++ b/packages/pl-fe/src/pl-hooks/hooks/markers/useUpdateMarkerMutation.ts @@ -0,0 +1,25 @@ +import { useMutation } from '@tanstack/react-query'; +import { useClient } from 'pl-fe/hooks'; +import { queryClient } from 'pl-fe/queries/client'; + +import type { Timeline } from './useMarkers'; +import type { Marker } from 'pl-api'; + +const useUpdateMarkerMutation = (timeline: Timeline) => { + const client = useClient(); + + return useMutation({ + mutationFn: (lastReadId: string) => client.timelines.saveMarkers({ + [timeline]: { + last_read_id: lastReadId, + }, + }), + retry: false, + onMutate: (lastReadId) => queryClient.setQueryData(['markers', timeline], (marker) => marker ? ({ + ...marker, + last_read_id: lastReadId, + }) : undefined), + }); +}; + +export { useUpdateMarkerMutation }; diff --git a/packages/pl-hooks/lib/hooks/notifications/useNotification.ts b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotification.ts similarity index 100% rename from packages/pl-hooks/lib/hooks/notifications/useNotification.ts rename to packages/pl-fe/src/pl-hooks/hooks/notifications/useNotification.ts diff --git a/packages/pl-hooks/lib/hooks/notifications/useNotificationList.ts b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotificationList.ts similarity index 100% rename from packages/pl-hooks/lib/hooks/notifications/useNotificationList.ts rename to packages/pl-fe/src/pl-hooks/hooks/notifications/useNotificationList.ts diff --git a/packages/pl-hooks/lib/hooks/statuses/useStatus.ts b/packages/pl-fe/src/pl-hooks/hooks/statuses/useStatus.ts similarity index 100% rename from packages/pl-hooks/lib/hooks/statuses/useStatus.ts rename to packages/pl-fe/src/pl-hooks/hooks/statuses/useStatus.ts diff --git a/packages/pl-hooks/lib/importer.ts b/packages/pl-fe/src/pl-hooks/importer.ts similarity index 100% rename from packages/pl-hooks/lib/importer.ts rename to packages/pl-fe/src/pl-hooks/importer.ts diff --git a/packages/pl-hooks/lib/main.ts b/packages/pl-fe/src/pl-hooks/main.ts similarity index 100% rename from packages/pl-hooks/lib/main.ts rename to packages/pl-fe/src/pl-hooks/main.ts diff --git a/packages/pl-hooks/lib/minifiers/minifyNotification.ts b/packages/pl-fe/src/pl-hooks/minifiers/minifyNotification.ts similarity index 100% rename from packages/pl-hooks/lib/minifiers/minifyNotification.ts rename to packages/pl-fe/src/pl-hooks/minifiers/minifyNotification.ts diff --git a/packages/pl-hooks/lib/minifiers/minifyStatus.ts b/packages/pl-fe/src/pl-hooks/minifiers/minifyStatus.ts similarity index 100% rename from packages/pl-hooks/lib/minifiers/minifyStatus.ts rename to packages/pl-fe/src/pl-hooks/minifiers/minifyStatus.ts diff --git a/packages/pl-hooks/lib/normalizers/deduplicateNotifications.ts b/packages/pl-fe/src/pl-hooks/normalizers/deduplicateNotifications.ts similarity index 100% rename from packages/pl-hooks/lib/normalizers/deduplicateNotifications.ts rename to packages/pl-fe/src/pl-hooks/normalizers/deduplicateNotifications.ts diff --git a/packages/pl-hooks/lib/normalizers/normalizeStatus.ts b/packages/pl-fe/src/pl-hooks/normalizers/normalizeStatus.ts similarity index 100% rename from packages/pl-hooks/lib/normalizers/normalizeStatus.ts rename to packages/pl-fe/src/pl-hooks/normalizers/normalizeStatus.ts diff --git a/packages/pl-hooks/lib/hooks/markers/useMarkers.ts b/packages/pl-hooks/lib/hooks/markers/useMarkers.ts deleted file mode 100644 index 7c4fda46d..000000000 --- a/packages/pl-hooks/lib/hooks/markers/useMarkers.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { useMutation, useQuery } from '@tanstack/react-query'; - -import { useClient } from 'pl-fe/hooks'; -import { queryClient } from 'pl-fe/queries/client'; - -import type { Marker, PlApiClient } from 'pl-api'; - -type Timeline = 'home' | 'notifications'; - -const useMarker = (timeline: Timeline) => { - const client = useClient(); - - return useQuery({ - queryKey: ['markers', timeline], - queryFn: () => client.timelines.getMarkers([timeline]).then(markers => markers[timeline]), - }); -}; - -const useUpdateMarkerMutation = (timeline: Timeline) => { - const client = useClient(); - - return useMutation({ - mutationFn: (lastReadId: string) => client.timelines.saveMarkers({ - [timeline]: { - last_read_id: lastReadId, - }, - }), - retry: false, - onMutate: (lastReadId) => queryClient.setQueryData(['markers', timeline], (marker) => marker ? ({ - ...marker, - last_read_id: lastReadId, - }) : undefined), - }); -}; - -const prefetchMarker = (client: PlApiClient, timeline: 'home' | 'notifications') => - queryClient.prefetchQuery({ - queryKey: ['markers', timeline], - queryFn: () => client.timelines.getMarkers([timeline]).then(markers => markers[timeline]), - }); - -export { useMarker, prefetchMarker, useUpdateMarkerMutation };