diff --git a/packages/pl-api/lib/entities/account.ts b/packages/pl-api/lib/entities/account.ts index 269d74d5f..e13843263 100644 --- a/packages/pl-api/lib/entities/account.ts +++ b/packages/pl-api/lib/entities/account.ts @@ -96,7 +96,7 @@ const baseAccountSchema = z.object({ acct: z.string().catch(''), url: z.string().url(), display_name: z.string().catch(''), - note: z.string().catch(''), + note: z.string().transform(note => note === '

' ? '' : note).catch(''), avatar: z.string().catch(''), avatar_static: z.string().url().catch(''), header: z.string().url().catch(''), diff --git a/packages/pl-api/lib/entities/status.ts b/packages/pl-api/lib/entities/status.ts index 69dc9e2b4..e6cd32770 100644 --- a/packages/pl-api/lib/entities/status.ts +++ b/packages/pl-api/lib/entities/status.ts @@ -41,7 +41,7 @@ const baseStatusSchema = z.object({ uri: z.string().url().catch(''), created_at: dateSchema, account: accountSchema, - content: z.string().catch(''), + content: z.string().transform(note => note === '

' ? '' : note).catch(''), visibility: z.string().catch('public'), sensitive: z.coerce.boolean(), spoiler_text: z.string().catch(''), diff --git a/packages/pl-fe/src/actions/accounts.ts b/packages/pl-fe/src/actions/accounts.ts index 7022cfff6..bea1397b1 100644 --- a/packages/pl-fe/src/actions/accounts.ts +++ b/packages/pl-fe/src/actions/accounts.ts @@ -1,10 +1,10 @@ import { PLEROMA, type UpdateNotificationSettingsParams, type Account, type CreateAccountParams, type PaginatedResponse, type Relationship } from 'pl-api'; +import { importEntities } from 'pl-hooks/importer'; import { getClient, type PlfeResponse } from 'pl-fe/api'; import { Entities } from 'pl-fe/entity-store/entities'; import { selectAccount } from 'pl-fe/selectors'; import { isLoggedIn } from 'pl-fe/utils/auth'; -import { importEntities } from 'pl-hooks/importer'; import type { Map as ImmutableMap } from 'immutable'; import type { MinifiedStatus } from 'pl-fe/reducers/statuses'; diff --git a/packages/pl-fe/src/actions/admin.ts b/packages/pl-fe/src/actions/admin.ts index 47795cea0..2ea917a98 100644 --- a/packages/pl-fe/src/actions/admin.ts +++ b/packages/pl-fe/src/actions/admin.ts @@ -1,7 +1,8 @@ +import { importEntities } from 'pl-hooks/importer'; + import { fetchRelationships } from 'pl-fe/actions/accounts'; import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { filterBadges, getTagDiff } from 'pl-fe/utils/badges'; import { deleteFromTimelines } from './timelines'; diff --git a/packages/pl-fe/src/actions/aliases.ts b/packages/pl-fe/src/actions/aliases.ts index aad1dc396..3b914eb01 100644 --- a/packages/pl-fe/src/actions/aliases.ts +++ b/packages/pl-fe/src/actions/aliases.ts @@ -1,7 +1,7 @@ +import { importEntities } from 'pl-hooks/importer'; import { defineMessages } from 'react-intl'; import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import toast from 'pl-fe/toast'; import { isLoggedIn } from 'pl-fe/utils/auth'; diff --git a/packages/pl-fe/src/actions/auth.ts b/packages/pl-fe/src/actions/auth.ts index efb65ec74..5584a754f 100644 --- a/packages/pl-fe/src/actions/auth.ts +++ b/packages/pl-fe/src/actions/auth.ts @@ -7,6 +7,7 @@ * @see module:pl-fe/actions/security */ import { credentialAccountSchema, PlApiClient, type CreateAccountParams, type Token } from 'pl-api'; +import { importEntities } from 'pl-hooks/importer'; import { defineMessages } from 'react-intl'; import { createAccount } from 'pl-fe/actions/accounts'; @@ -17,7 +18,6 @@ import { startOnboarding } from 'pl-fe/actions/onboarding'; import { type PlfeResponse, getClient } from 'pl-fe/api'; import * as BuildConfig from 'pl-fe/build-config'; import { custom } from 'pl-fe/custom'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { queryClient } from 'pl-fe/queries/client'; import { selectAccount } from 'pl-fe/selectors'; import { unsetSentryAccount } from 'pl-fe/sentry'; diff --git a/packages/pl-fe/src/actions/bookmarks.ts b/packages/pl-fe/src/actions/bookmarks.ts index 13cc43d06..87f371dd7 100644 --- a/packages/pl-fe/src/actions/bookmarks.ts +++ b/packages/pl-fe/src/actions/bookmarks.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import type { PaginatedResponse, Status } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/compose.ts b/packages/pl-fe/src/actions/compose.ts index 0089cc814..775f915b6 100644 --- a/packages/pl-fe/src/actions/compose.ts +++ b/packages/pl-fe/src/actions/compose.ts @@ -1,11 +1,11 @@ import throttle from 'lodash/throttle'; +import { importEntities } from 'pl-hooks/importer'; import { defineMessages, IntlShape } from 'react-intl'; import { getClient } from 'pl-fe/api'; import { isNativeEmoji } from 'pl-fe/features/emoji'; import emojiSearch from 'pl-fe/features/emoji/search'; import { Language } from 'pl-fe/features/preferences'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { selectAccount, selectOwnAccount, makeGetAccount } from 'pl-fe/selectors'; import { tagHistory } from 'pl-fe/settings'; import { useModalsStore, useSettingsStore } from 'pl-fe/stores'; diff --git a/packages/pl-fe/src/actions/conversations.ts b/packages/pl-fe/src/actions/conversations.ts index adac3b19f..c74bd11c0 100644 --- a/packages/pl-fe/src/actions/conversations.ts +++ b/packages/pl-fe/src/actions/conversations.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { isLoggedIn } from 'pl-fe/utils/auth'; import type { Account, Conversation, PaginatedResponse, Status } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/directory.ts b/packages/pl-fe/src/actions/directory.ts index 7e9fc983e..674c69063 100644 --- a/packages/pl-fe/src/actions/directory.ts +++ b/packages/pl-fe/src/actions/directory.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { fetchRelationships } from './accounts'; diff --git a/packages/pl-fe/src/actions/draft-statuses.ts b/packages/pl-fe/src/actions/draft-statuses.ts index d79d9fb45..7ed4ca2b2 100644 --- a/packages/pl-fe/src/actions/draft-statuses.ts +++ b/packages/pl-fe/src/actions/draft-statuses.ts @@ -1,8 +1,8 @@ import { queryClient } from 'pl-fe/queries/client'; import KVStore from 'pl-fe/storage/kv-store'; -import type { Account } from 'pl-fe/pl-hooks/normalizers/normalizeAccount'; import type { AppDispatch, RootState } from 'pl-fe/store'; +import type { Account } from 'pl-hooks/normalizers/normalizeAccount'; const DRAFT_STATUSES_FETCH_SUCCESS = 'DRAFT_STATUSES_FETCH_SUCCESS' as const; diff --git a/packages/pl-fe/src/actions/emoji-reacts.ts b/packages/pl-fe/src/actions/emoji-reacts.ts index 54bc4899d..01beefc25 100644 --- a/packages/pl-fe/src/actions/emoji-reacts.ts +++ b/packages/pl-fe/src/actions/emoji-reacts.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { isLoggedIn } from 'pl-fe/utils/auth'; import type { Status } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/events.ts b/packages/pl-fe/src/actions/events.ts index 515646a71..13f4a07ba 100644 --- a/packages/pl-fe/src/actions/events.ts +++ b/packages/pl-fe/src/actions/events.ts @@ -1,8 +1,8 @@ +import { importEntities } from 'pl-hooks/importer'; import { defineMessages } from 'react-intl'; import { STATUS_FETCH_SOURCE_FAIL, STATUS_FETCH_SOURCE_REQUEST, STATUS_FETCH_SOURCE_SUCCESS } from 'pl-fe/actions/statuses'; import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { useModalsStore } from 'pl-fe/stores'; import toast from 'pl-fe/toast'; diff --git a/packages/pl-fe/src/actions/familiar-followers.ts b/packages/pl-fe/src/actions/familiar-followers.ts index 404a99259..bf28b7a30 100644 --- a/packages/pl-fe/src/actions/familiar-followers.ts +++ b/packages/pl-fe/src/actions/familiar-followers.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { AppDispatch, RootState } from 'pl-fe/store'; import { fetchRelationships } from './accounts'; diff --git a/packages/pl-fe/src/actions/favourites.ts b/packages/pl-fe/src/actions/favourites.ts index 2ba10fcd5..0edef7438 100644 --- a/packages/pl-fe/src/actions/favourites.ts +++ b/packages/pl-fe/src/actions/favourites.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { isLoggedIn } from 'pl-fe/utils/auth'; import type { PaginatedResponse, Status } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/groups.ts b/packages/pl-fe/src/actions/groups.ts index e5aef02e7..116e98325 100644 --- a/packages/pl-fe/src/actions/groups.ts +++ b/packages/pl-fe/src/actions/groups.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import type { Account, PaginatedResponse } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/history.ts b/packages/pl-fe/src/actions/history.ts index ae46fa8bd..8a0eb0665 100644 --- a/packages/pl-fe/src/actions/history.ts +++ b/packages/pl-fe/src/actions/history.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import type { StatusEdit } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/interactions.ts b/packages/pl-fe/src/actions/interactions.ts index 81a36c9c8..c5010096b 100644 --- a/packages/pl-fe/src/actions/interactions.ts +++ b/packages/pl-fe/src/actions/interactions.ts @@ -1,7 +1,7 @@ +import { importEntities } from 'pl-hooks/importer'; import { defineMessages } from 'react-intl'; import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { useModalsStore } from 'pl-fe/stores'; import toast, { type IToastOptions } from 'pl-fe/toast'; import { isLoggedIn } from 'pl-fe/utils/auth'; diff --git a/packages/pl-fe/src/actions/lists.ts b/packages/pl-fe/src/actions/lists.ts index 502a363a9..2ec70deb3 100644 --- a/packages/pl-fe/src/actions/lists.ts +++ b/packages/pl-fe/src/actions/lists.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { selectAccount } from 'pl-fe/selectors'; import toast from 'pl-fe/toast'; import { isLoggedIn } from 'pl-fe/utils/auth'; diff --git a/packages/pl-fe/src/actions/me.ts b/packages/pl-fe/src/actions/me.ts index 27f7b10df..462004e8c 100644 --- a/packages/pl-fe/src/actions/me.ts +++ b/packages/pl-fe/src/actions/me.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { selectAccount } from 'pl-fe/selectors'; import { setSentryAccount } from 'pl-fe/sentry'; import KVStore from 'pl-fe/storage/kv-store'; diff --git a/packages/pl-fe/src/actions/notifications.ts b/packages/pl-fe/src/actions/notifications.ts index 3c7b2be1d..df82c8508 100644 --- a/packages/pl-fe/src/actions/notifications.ts +++ b/packages/pl-fe/src/actions/notifications.ts @@ -1,11 +1,11 @@ import IntlMessageFormat from 'intl-messageformat'; import 'intl-pluralrules'; +import { importEntities } from 'pl-hooks/importer'; import { defineMessages } from 'react-intl'; import { FILTER_TYPES, type FilterType } from 'pl-fe/features/notifications'; import { getNotificationStatus } from 'pl-fe/features/notifications/components/notification'; import { normalizeNotification } from 'pl-fe/normalizers'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { queryClient } from 'pl-fe/queries/client'; // import { getFilters, regexFromFilters } from 'pl-fe/selectors'; import { useSettingsStore } from 'pl-fe/stores'; diff --git a/packages/pl-fe/src/actions/pin-statuses.ts b/packages/pl-fe/src/actions/pin-statuses.ts index f4968f194..9ee169a10 100644 --- a/packages/pl-fe/src/actions/pin-statuses.ts +++ b/packages/pl-fe/src/actions/pin-statuses.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { isLoggedIn } from 'pl-fe/utils/auth'; import type { Status } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/polls.ts b/packages/pl-fe/src/actions/polls.ts index 132d5fcd9..601cc63c5 100644 --- a/packages/pl-fe/src/actions/polls.ts +++ b/packages/pl-fe/src/actions/polls.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import type { Poll } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/preload.ts b/packages/pl-fe/src/actions/preload.ts index 7925046ea..3fbab4a6e 100644 --- a/packages/pl-fe/src/actions/preload.ts +++ b/packages/pl-fe/src/actions/preload.ts @@ -1,6 +1,5 @@ import mapValues from 'lodash/mapValues'; - -import { importEntities } from 'pl-fe/pl-hooks/importer'; +import { importEntities } from 'pl-hooks/importer'; import { verifyCredentials } from './auth'; diff --git a/packages/pl-fe/src/actions/search.ts b/packages/pl-fe/src/actions/search.ts index ef7d8d12c..49d933c1b 100644 --- a/packages/pl-fe/src/actions/search.ts +++ b/packages/pl-fe/src/actions/search.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { useSettingsStore } from 'pl-fe/stores'; import { fetchRelationships } from './accounts'; diff --git a/packages/pl-fe/src/actions/settings.ts b/packages/pl-fe/src/actions/settings.ts index ddf9e8e3c..61003930c 100644 --- a/packages/pl-fe/src/actions/settings.ts +++ b/packages/pl-fe/src/actions/settings.ts @@ -1,9 +1,9 @@ +import { Account } from 'pl-hooks/normalizers/normalizeAccount'; import { defineMessage } from 'react-intl'; import { patchMe } from 'pl-fe/actions/me'; import { getClient } from 'pl-fe/api'; import messages from 'pl-fe/messages'; -import { Account } from 'pl-fe/pl-hooks/normalizers/normalizeAccount'; import { queryClient } from 'pl-fe/queries/client'; import KVStore from 'pl-fe/storage/kv-store'; import { useSettingsStore } from 'pl-fe/stores'; diff --git a/packages/pl-fe/src/actions/status-quotes.ts b/packages/pl-fe/src/actions/status-quotes.ts index 8aa0cad43..a40dbc437 100644 --- a/packages/pl-fe/src/actions/status-quotes.ts +++ b/packages/pl-fe/src/actions/status-quotes.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import type { Status as BaseStatus, PaginatedResponse } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/statuses.ts b/packages/pl-fe/src/actions/statuses.ts index bc9064538..cec4f6927 100644 --- a/packages/pl-fe/src/actions/statuses.ts +++ b/packages/pl-fe/src/actions/statuses.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { useModalsStore, useSettingsStore } from 'pl-fe/stores'; import { isLoggedIn } from 'pl-fe/utils/auth'; import { shouldHaveCard } from 'pl-fe/utils/status'; diff --git a/packages/pl-fe/src/actions/suggestions.ts b/packages/pl-fe/src/actions/suggestions.ts index 10d052e6f..109c5fcc9 100644 --- a/packages/pl-fe/src/actions/suggestions.ts +++ b/packages/pl-fe/src/actions/suggestions.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { fetchRelationships } from './accounts'; diff --git a/packages/pl-fe/src/actions/timelines.ts b/packages/pl-fe/src/actions/timelines.ts index 0dd14251c..8f0af94fc 100644 --- a/packages/pl-fe/src/actions/timelines.ts +++ b/packages/pl-fe/src/actions/timelines.ts @@ -1,9 +1,8 @@ import { Map as ImmutableMap } from 'immutable'; - +import { importEntities } from 'pl-hooks/importer'; import { getLocale } from 'pl-fe/actions/settings'; import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { useSettingsStore } from 'pl-fe/stores'; import { shouldFilter } from 'pl-fe/utils/timelines'; diff --git a/packages/pl-fe/src/actions/trending-statuses.ts b/packages/pl-fe/src/actions/trending-statuses.ts index 0cd76b090..5c41d8734 100644 --- a/packages/pl-fe/src/actions/trending-statuses.ts +++ b/packages/pl-fe/src/actions/trending-statuses.ts @@ -1,5 +1,6 @@ +import { importEntities } from 'pl-hooks/importer'; + import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/components/quoted-status-indicator.tsx b/packages/pl-fe/src/components/quoted-status-indicator.tsx index ee150fab4..34f3e7f7f 100644 --- a/packages/pl-fe/src/components/quoted-status-indicator.tsx +++ b/packages/pl-fe/src/components/quoted-status-indicator.tsx @@ -1,7 +1,7 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React from 'react'; import { HStack, Icon, Text } from 'pl-fe/components/ui'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; interface IQuotedStatusIndicator { /** The quoted status id. */ diff --git a/packages/pl-fe/src/components/status.tsx b/packages/pl-fe/src/components/status.tsx index 2a68df1a4..c3a1529be 100644 --- a/packages/pl-fe/src/components/status.tsx +++ b/packages/pl-fe/src/components/status.tsx @@ -1,4 +1,5 @@ import clsx from 'clsx'; +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React, { useEffect, useRef } from 'react'; import { defineMessages, useIntl, FormattedList, FormattedMessage } from 'react-intl'; import { Link, useHistory } from 'react-router-dom'; @@ -12,7 +13,6 @@ import StatusTypeIcon from 'pl-fe/features/status/components/status-type-icon'; import QuotedStatus from 'pl-fe/features/status/containers/quoted-status-container'; import { HotKeys } from 'pl-fe/features/ui/components/hotkeys'; import { useAppDispatch, useSettings } from 'pl-fe/hooks'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; import { useModalsStore } from 'pl-fe/stores'; import { textForScreenReader } from 'pl-fe/utils/status'; diff --git a/packages/pl-fe/src/containers/status-container.tsx b/packages/pl-fe/src/containers/status-container.tsx index 32ad7e395..cc1ae14df 100644 --- a/packages/pl-fe/src/containers/status-container.tsx +++ b/packages/pl-fe/src/containers/status-container.tsx @@ -1,7 +1,7 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React from 'react'; import Status, { IStatus } from 'pl-fe/components/status'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; interface IStatusContainer extends Omit { id: string; diff --git a/packages/pl-fe/src/features/compose/components/reply-group-indicator.tsx b/packages/pl-fe/src/features/compose/components/reply-group-indicator.tsx index 47ab97940..d3d900a80 100644 --- a/packages/pl-fe/src/features/compose/components/reply-group-indicator.tsx +++ b/packages/pl-fe/src/features/compose/components/reply-group-indicator.tsx @@ -1,10 +1,10 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React from 'react'; import { FormattedMessage } from 'react-intl'; import Link from 'pl-fe/components/link'; import { Text } from 'pl-fe/components/ui'; import { useCompose } from 'pl-fe/hooks'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; interface IReplyGroupIndicator { composeId: string; diff --git a/packages/pl-fe/src/features/compose/components/reply-mentions.tsx b/packages/pl-fe/src/features/compose/components/reply-mentions.tsx index 942fbe3ae..1d08a899b 100644 --- a/packages/pl-fe/src/features/compose/components/reply-mentions.tsx +++ b/packages/pl-fe/src/features/compose/components/reply-mentions.tsx @@ -1,8 +1,8 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React from 'react'; import { FormattedList, FormattedMessage } from 'react-intl'; import { useCompose, useFeatures } from 'pl-fe/hooks'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; import { useModalsStore } from 'pl-fe/stores'; interface IReplyMentions { diff --git a/packages/pl-fe/src/features/compose/containers/quoted-status-container.tsx b/packages/pl-fe/src/features/compose/containers/quoted-status-container.tsx index 3dbf2461c..bbcff3515 100644 --- a/packages/pl-fe/src/features/compose/containers/quoted-status-container.tsx +++ b/packages/pl-fe/src/features/compose/containers/quoted-status-container.tsx @@ -1,9 +1,9 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React from 'react'; import { cancelQuoteCompose } from 'pl-fe/actions/compose'; import QuotedStatus from 'pl-fe/components/quoted-status'; import { useAppDispatch, useCompose } from 'pl-fe/hooks'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; interface IQuotedStatusContainer { composeId: string; diff --git a/packages/pl-fe/src/features/compose/containers/reply-indicator-container.tsx b/packages/pl-fe/src/features/compose/containers/reply-indicator-container.tsx index 142667542..338ca170f 100644 --- a/packages/pl-fe/src/features/compose/containers/reply-indicator-container.tsx +++ b/packages/pl-fe/src/features/compose/containers/reply-indicator-container.tsx @@ -1,8 +1,8 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React from 'react'; import { cancelReplyCompose } from 'pl-fe/actions/compose'; import { useAppDispatch, useCompose } from 'pl-fe/hooks'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; import ReplyIndicator from '../components/reply-indicator'; diff --git a/packages/pl-fe/src/features/embedded-status/index.tsx b/packages/pl-fe/src/features/embedded-status/index.tsx index ba8f4479d..6d310fb78 100644 --- a/packages/pl-fe/src/features/embedded-status/index.tsx +++ b/packages/pl-fe/src/features/embedded-status/index.tsx @@ -1,3 +1,4 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React, { useEffect } from 'react'; import { useHistory } from 'react-router-dom'; @@ -7,7 +8,6 @@ import Status from 'pl-fe/components/status'; import { Spinner } from 'pl-fe/components/ui'; import { useLogo } from 'pl-fe/hooks'; import { iframeId } from 'pl-fe/iframe'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; interface IEmbeddedStatus { params: { diff --git a/packages/pl-fe/src/features/event/event-discussion.tsx b/packages/pl-fe/src/features/event/event-discussion.tsx index dffa4528f..fc1d243cd 100644 --- a/packages/pl-fe/src/features/event/event-discussion.tsx +++ b/packages/pl-fe/src/features/event/event-discussion.tsx @@ -1,4 +1,5 @@ import { List as ImmutableList, OrderedSet as ImmutableOrderedSet } from 'immutable'; +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React, { useEffect, useRef, useState } from 'react'; import { FormattedMessage, useIntl } from 'react-intl'; @@ -11,7 +12,6 @@ import { Stack } from 'pl-fe/components/ui'; import PlaceholderStatus from 'pl-fe/features/placeholder/components/placeholder-status'; import PendingStatus from 'pl-fe/features/ui/components/pending-status'; import { useAppDispatch, useAppSelector } from 'pl-fe/hooks'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; import ComposeForm from '../compose/components/compose-form'; import { getDescendantsIds } from '../status/components/thread'; diff --git a/packages/pl-fe/src/features/event/event-information.tsx b/packages/pl-fe/src/features/event/event-information.tsx index 44ed5c835..c90b1c48e 100644 --- a/packages/pl-fe/src/features/event/event-information.tsx +++ b/packages/pl-fe/src/features/event/event-information.tsx @@ -1,3 +1,4 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React, { useCallback } from 'react'; import { FormattedDate, FormattedMessage } from 'react-intl'; @@ -8,7 +9,6 @@ import TranslateButton from 'pl-fe/components/translate-button'; import { HStack, Icon, Stack, Text } from 'pl-fe/components/ui'; import QuotedStatus from 'pl-fe/features/status/containers/quoted-status-container'; import { usePlFeConfig } from 'pl-fe/hooks'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; import { useModalsStore } from 'pl-fe/stores'; type RouteParams = { statusId: string }; diff --git a/packages/pl-fe/src/features/events/components/event-carousel.tsx b/packages/pl-fe/src/features/events/components/event-carousel.tsx index d40479986..a8c9910e8 100644 --- a/packages/pl-fe/src/features/events/components/event-carousel.tsx +++ b/packages/pl-fe/src/features/events/components/event-carousel.tsx @@ -1,10 +1,10 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React, { useState } from 'react'; import { Link } from 'react-router-dom'; import ReactSwipeableViews from 'react-swipeable-views'; import EventPreview from 'pl-fe/components/event-preview'; import { Card, Icon } from 'pl-fe/components/ui'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; import PlaceholderEventPreview from '../../placeholder/components/placeholder-event-preview'; diff --git a/packages/pl-fe/src/features/notifications/components/notification.tsx b/packages/pl-fe/src/features/notifications/components/notification.tsx index 7b2e80200..47cdefd27 100644 --- a/packages/pl-fe/src/features/notifications/components/notification.tsx +++ b/packages/pl-fe/src/features/notifications/components/notification.tsx @@ -1,3 +1,4 @@ +import { useNotification } from 'pl-hooks/hooks/notifications/useNotification'; import React, { useCallback } from 'react'; import { defineMessages, useIntl, FormattedList, FormattedMessage, IntlShape, MessageDescriptor } from 'react-intl'; import { Link, useHistory } from 'react-router-dom'; @@ -13,7 +14,6 @@ import AccountContainer from 'pl-fe/containers/account-container'; import StatusContainer from 'pl-fe/containers/status-container'; import { HotKeys } from 'pl-fe/features/ui/components/hotkeys'; import { useAppDispatch, useInstance, useLoggedIn } from 'pl-fe/hooks'; -import { useNotification } from 'pl-fe/pl-hooks/hooks/notifications/useNotification'; import { useModalsStore, useSettingsStore } from 'pl-fe/stores'; import { NotificationType } from 'pl-fe/utils/notification'; diff --git a/packages/pl-fe/src/features/notifications/index.tsx b/packages/pl-fe/src/features/notifications/index.tsx index 2e1307b67..6526ea704 100644 --- a/packages/pl-fe/src/features/notifications/index.tsx +++ b/packages/pl-fe/src/features/notifications/index.tsx @@ -1,5 +1,8 @@ import clsx from 'clsx'; import debounce from 'lodash/debounce'; +import { useMarker } from 'pl-hooks/hooks/markers/useMarkers'; +import { useUpdateMarkerMutation } from 'pl-hooks/hooks/markers/useUpdateMarkerMutation'; +import { useNotificationList } from 'pl-hooks/hooks/notifications/useNotificationList'; import React, { useCallback, useEffect, useRef } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; @@ -10,9 +13,6 @@ import ScrollableList from 'pl-fe/components/scrollable-list'; import { Column, Portal } from 'pl-fe/components/ui'; import PlaceholderNotification from 'pl-fe/features/placeholder/components/placeholder-notification'; import { useAppDispatch, useAppSelector, useSettings } from 'pl-fe/hooks'; -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 { compareId } from 'pl-fe/utils/comparators'; import { NotificationType } from 'pl-fe/utils/notification'; diff --git a/packages/pl-fe/src/features/status/containers/quoted-status-container.tsx b/packages/pl-fe/src/features/status/containers/quoted-status-container.tsx index 9b3ac1ffa..6c28326a5 100644 --- a/packages/pl-fe/src/features/status/containers/quoted-status-container.tsx +++ b/packages/pl-fe/src/features/status/containers/quoted-status-container.tsx @@ -1,7 +1,7 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React from 'react'; import QuotedStatus from 'pl-fe/components/quoted-status'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; interface IQuotedStatusContainer { /** Status ID to the quoted status. */ diff --git a/packages/pl-fe/src/features/status/index.tsx b/packages/pl-fe/src/features/status/index.tsx index 7acb44d1f..00f0c0cb0 100644 --- a/packages/pl-fe/src/features/status/index.tsx +++ b/packages/pl-fe/src/features/status/index.tsx @@ -1,3 +1,4 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React, { useEffect } from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { Redirect } from 'react-router-dom'; @@ -8,7 +9,6 @@ import PullToRefresh from 'pl-fe/components/pull-to-refresh'; import { Column, Stack } from 'pl-fe/components/ui'; import PlaceholderStatus from 'pl-fe/features/placeholder/components/placeholder-status'; import { useAppDispatch, useLoggedIn } from 'pl-fe/hooks'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; import Thread from './components/thread'; import ThreadLoginCta from './components/thread-login-cta'; diff --git a/packages/pl-fe/src/features/test-timeline/index.tsx b/packages/pl-fe/src/features/test-timeline/index.tsx index ac7a8c8e2..c81c2c692 100644 --- a/packages/pl-fe/src/features/test-timeline/index.tsx +++ b/packages/pl-fe/src/features/test-timeline/index.tsx @@ -1,10 +1,10 @@ +import { importEntities } from 'pl-hooks/importer'; import React from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; import { expandTimelineSuccess } from 'pl-fe/actions/timelines'; import { useAppDispatch, useTheme } from 'pl-fe/hooks'; import { useIsMobile } from 'pl-fe/hooks/useIsMobile'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { Column } from '../../components/ui'; import Timeline from '../ui/components/timeline'; diff --git a/packages/pl-fe/src/features/ui/components/modals/boost-modal.tsx b/packages/pl-fe/src/features/ui/components/modals/boost-modal.tsx index 50a65e4ae..5f1a798b0 100644 --- a/packages/pl-fe/src/features/ui/components/modals/boost-modal.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/boost-modal.tsx @@ -1,10 +1,10 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import Icon from 'pl-fe/components/icon'; import { Modal, Stack, Text } from 'pl-fe/components/ui'; import ReplyIndicator from 'pl-fe/features/compose/components/reply-indicator'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; import type { BaseModalProps } from '../modal-root'; import type { Status as StatusEntity } from 'pl-fe/normalizers'; diff --git a/packages/pl-fe/src/features/ui/components/modals/event-map-modal.tsx b/packages/pl-fe/src/features/ui/components/modals/event-map-modal.tsx index 98608021d..8f651218e 100644 --- a/packages/pl-fe/src/features/ui/components/modals/event-map-modal.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/event-map-modal.tsx @@ -1,10 +1,10 @@ import L from 'leaflet'; +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React, { useEffect, useRef } from 'react'; import { FormattedMessage } from 'react-intl'; import { Button, Modal, Stack } from 'pl-fe/components/ui'; import { usePlFeConfig } from 'pl-fe/hooks'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; import type { BaseModalProps } from '../modal-root'; diff --git a/packages/pl-fe/src/features/ui/components/modals/media-modal.tsx b/packages/pl-fe/src/features/ui/components/modals/media-modal.tsx index c55943aad..a18d82454 100644 --- a/packages/pl-fe/src/features/ui/components/modals/media-modal.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/media-modal.tsx @@ -1,4 +1,5 @@ import clsx from 'clsx'; +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React, { useEffect, useState } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; import { Link } from 'react-router-dom'; @@ -15,7 +16,6 @@ import Thread from 'pl-fe/features/status/components/thread'; import Video from 'pl-fe/features/video'; import { useAppDispatch } from 'pl-fe/hooks'; import { userTouching } from 'pl-fe/is-mobile'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; import ImageLoader from '../image-loader'; diff --git a/packages/pl-fe/src/features/ui/components/modals/mentions-modal.tsx b/packages/pl-fe/src/features/ui/components/modals/mentions-modal.tsx index 76a2578c4..4d97e1c22 100644 --- a/packages/pl-fe/src/features/ui/components/modals/mentions-modal.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/mentions-modal.tsx @@ -1,3 +1,4 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React, { useEffect, useRef } from 'react'; import { FormattedMessage, useIntl } from 'react-intl'; @@ -6,7 +7,6 @@ import ScrollableList from 'pl-fe/components/scrollable-list'; import { Modal, Spinner } from 'pl-fe/components/ui'; import AccountContainer from 'pl-fe/containers/account-container'; import { useAppDispatch } from 'pl-fe/hooks'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; import type { BaseModalProps } from '../modal-root'; diff --git a/packages/pl-fe/src/features/ui/components/modals/reply-mentions-modal.tsx b/packages/pl-fe/src/features/ui/components/modals/reply-mentions-modal.tsx index 40838ae2d..0a8b78a0b 100644 --- a/packages/pl-fe/src/features/ui/components/modals/reply-mentions-modal.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/reply-mentions-modal.tsx @@ -1,10 +1,10 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React from 'react'; import { FormattedMessage } from 'react-intl'; import { Modal } from 'pl-fe/components/ui'; import Account from 'pl-fe/features/reply-mentions/account'; import { useCompose, useOwnAccount } from 'pl-fe/hooks'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; import { statusToMentionsAccountIdsArray } from 'pl-fe/reducers/compose'; import type { BaseModalProps } from '../modal-root'; diff --git a/packages/pl-fe/src/features/ui/components/modals/select-bookmark-folder-modal.tsx b/packages/pl-fe/src/features/ui/components/modals/select-bookmark-folder-modal.tsx index 91f1a27c7..76bd3b89e 100644 --- a/packages/pl-fe/src/features/ui/components/modals/select-bookmark-folder-modal.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/select-bookmark-folder-modal.tsx @@ -1,3 +1,4 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React, { useState } from 'react'; import { FormattedMessage } from 'react-intl'; @@ -7,7 +8,6 @@ import { RadioGroup, RadioItem } from 'pl-fe/components/radio'; import { Emoji, HStack, Icon, Modal, Spinner, Stack } from 'pl-fe/components/ui'; import NewFolderForm from 'pl-fe/features/bookmark-folders/components/new-folder-form'; import { useAppDispatch } from 'pl-fe/hooks'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; import type { BaseModalProps } from '../modal-root'; diff --git a/packages/pl-fe/src/features/ui/components/modals/video-modal.tsx b/packages/pl-fe/src/features/ui/components/modals/video-modal.tsx index a65e84569..b8f052aac 100644 --- a/packages/pl-fe/src/features/ui/components/modals/video-modal.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/video-modal.tsx @@ -1,9 +1,9 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React from 'react'; import { FormattedMessage } from 'react-intl'; import { Link } from 'react-router-dom'; import Video from 'pl-fe/features/video'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; import type { BaseModalProps } from '../modal-root'; import type { MediaAttachment } from 'pl-api'; diff --git a/packages/pl-fe/src/features/ui/index.tsx b/packages/pl-fe/src/features/ui/index.tsx index 914e9400e..12ea70c4c 100644 --- a/packages/pl-fe/src/features/ui/index.tsx +++ b/packages/pl-fe/src/features/ui/index.tsx @@ -1,4 +1,6 @@ import clsx from 'clsx'; +import { prefetchMarker } from 'pl-hooks/hooks/markers/useMarkers'; +import { prefetchNotifications } from 'pl-hooks/hooks/notifications/useNotificationList'; import React, { Suspense, lazy, useEffect, useRef } from 'react'; import { Switch, useHistory, useLocation, Redirect } from 'react-router-dom'; @@ -33,8 +35,6 @@ import ProfileLayout from 'pl-fe/layouts/profile-layout'; 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 { prefetchMarker } from 'pl-fe/pl-hooks/hooks/markers/useMarkers'; -import { prefetchNotifications } from 'pl-fe/pl-hooks/hooks/notifications/useNotificationList'; import { useUiStore } from 'pl-fe/stores'; import { getVapidKey } from 'pl-fe/utils/auth'; import { isStandalone } from 'pl-fe/utils/state'; diff --git a/packages/pl-fe/src/layouts/event-layout.tsx b/packages/pl-fe/src/layouts/event-layout.tsx index deafb6003..a7e3a9af6 100644 --- a/packages/pl-fe/src/layouts/event-layout.tsx +++ b/packages/pl-fe/src/layouts/event-layout.tsx @@ -1,3 +1,4 @@ +import { useStatus } from 'pl-hooks/hooks/statuses/useStatus'; import React from 'react'; import { Helmet } from 'react-helmet-async'; import { FormattedMessage } from 'react-intl'; @@ -13,7 +14,6 @@ import { WhoToFollowPanel, } from 'pl-fe/features/ui/util/async-components'; import { useAppSelector, useFeatures } from 'pl-fe/hooks'; -import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; interface IEventLayout { params?: { diff --git a/packages/pl-fe/src/queries/chats.ts b/packages/pl-fe/src/queries/chats.ts index 1c3125a98..a0dc540f8 100644 --- a/packages/pl-fe/src/queries/chats.ts +++ b/packages/pl-fe/src/queries/chats.ts @@ -1,14 +1,13 @@ import { InfiniteData, keepPreviousData, useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query'; import sumBy from 'lodash/sumBy'; import { type Chat, type ChatMessage as BaseChatMessage, type PaginatedResponse, chatMessageSchema, type Relationship } from 'pl-api'; - +import { importEntities } from 'pl-hooks/importer'; import { ChatWidgetScreens, useChatContext } from 'pl-fe/contexts/chat-context'; import { useStatContext } from 'pl-fe/contexts/stat-context'; import { Entities } from 'pl-fe/entity-store/entities'; import { useAppSelector, useClient, useFeatures, useLoggedIn, useOwnAccount } from 'pl-fe/hooks'; import { type ChatMessage, normalizeChatMessage } from 'pl-fe/normalizers'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { reOrderChatListItems } from 'pl-fe/utils/chats'; import { flattenPages, updatePageItem } from 'pl-fe/utils/queries'; diff --git a/packages/pl-fe/src/queries/suggestions.ts b/packages/pl-fe/src/queries/suggestions.ts index 267916557..096abcd98 100644 --- a/packages/pl-fe/src/queries/suggestions.ts +++ b/packages/pl-fe/src/queries/suggestions.ts @@ -1,9 +1,8 @@ import { useMutation, keepPreviousData, useQuery } from '@tanstack/react-query'; - +import { importEntities } from 'pl-hooks/importer'; import { fetchRelationships } from 'pl-fe/actions/accounts'; import { useAppDispatch, useClient } from 'pl-fe/hooks'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { removePageItem } from '../utils/queries'; diff --git a/packages/pl-fe/tsconfig.json b/packages/pl-fe/tsconfig.json index e34f118dc..6ecfb0520 100644 --- a/packages/pl-fe/tsconfig.json +++ b/packages/pl-fe/tsconfig.json @@ -15,7 +15,6 @@ "skipLibCheck": true, "paths": { "pl-fe/*": ["src/*"], - "pl-hooks/*": ["src/pl-hooks/*"], }, "typeRoots": [ "./src/types", diff --git a/packages/pl-fe/vite.config.ts b/packages/pl-fe/vite.config.ts index 3148f4143..26a59eedf 100644 --- a/packages/pl-fe/vite.config.ts +++ b/packages/pl-fe/vite.config.ts @@ -154,7 +154,6 @@ const config = defineConfig(({ command }) => ({ resolve: { alias: [ { find: 'pl-fe', replacement: fileURLToPath(new URL('./src', import.meta.url)) }, - { find: 'pl-hooks', replacement: fileURLToPath(new URL('./src/pl-hooks', import.meta.url)) }, ], }, test: { diff --git a/packages/pl-hooks/lib/client.ts b/packages/pl-hooks/lib/client.ts new file mode 100644 index 000000000..e11ce296c --- /dev/null +++ b/packages/pl-hooks/lib/client.ts @@ -0,0 +1,14 @@ +import { QueryClient } from '@tanstack/react-query'; + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + refetchOnWindowFocus: false, + staleTime: 60000, // 1 minute + gcTime: Infinity, + retry: false, + }, + }, +}); + +export { queryClient }; diff --git a/packages/pl-hooks/lib/hooks/accounts/useAccount.ts b/packages/pl-hooks/lib/hooks/accounts/useAccount.ts index 80f44e259..6ff3f807f 100644 --- a/packages/pl-hooks/lib/hooks/accounts/useAccount.ts +++ b/packages/pl-hooks/lib/hooks/accounts/useAccount.ts @@ -1,9 +1,9 @@ import { useQuery } from '@tanstack/react-query'; - import { useRelationship } from 'pl-fe/api/hooks/accounts/useRelationship'; import { useClient } from 'pl-fe/hooks'; -import { normalizeAccount } from 'pl-fe/pl-hooks/normalizers/normalizeAccount'; -import { queryClient } from 'pl-fe/queries/client'; + +import { queryClient } from 'pl-hooks/client'; +import { normalizeAccount } from 'pl-hooks/normalizers/normalizeAccount'; interface UseAccountOpts { withRelationship?: boolean; diff --git a/packages/pl-hooks/lib/hooks/markers/useMarkers.ts b/packages/pl-hooks/lib/hooks/markers/useMarkers.ts index 576e33d53..54c2e9a08 100644 --- a/packages/pl-hooks/lib/hooks/markers/useMarkers.ts +++ b/packages/pl-hooks/lib/hooks/markers/useMarkers.ts @@ -1,7 +1,7 @@ import { useQuery } from '@tanstack/react-query'; - import { useClient } from 'pl-fe/hooks'; -import { queryClient } from 'pl-fe/queries/client'; + +import { queryClient } from 'pl-hooks/client'; import type { PlApiClient } from 'pl-api'; diff --git a/packages/pl-hooks/lib/hooks/markers/useUpdateMarkerMutation.ts b/packages/pl-hooks/lib/hooks/markers/useUpdateMarkerMutation.ts index e2296c1b0..7fc27389f 100644 --- a/packages/pl-hooks/lib/hooks/markers/useUpdateMarkerMutation.ts +++ b/packages/pl-hooks/lib/hooks/markers/useUpdateMarkerMutation.ts @@ -1,7 +1,7 @@ import { useMutation } from '@tanstack/react-query'; - import { useClient } from 'pl-fe/hooks'; -import { queryClient } from 'pl-fe/queries/client'; + +import { queryClient } from 'pl-hooks/client'; import type { Timeline } from './useMarkers'; import type { Marker } from 'pl-api'; diff --git a/packages/pl-hooks/lib/hooks/notifications/useNotification.ts b/packages/pl-hooks/lib/hooks/notifications/useNotification.ts index 9571dae30..4b7224288 100644 --- a/packages/pl-hooks/lib/hooks/notifications/useNotification.ts +++ b/packages/pl-hooks/lib/hooks/notifications/useNotification.ts @@ -1,16 +1,16 @@ import { useQuery } from '@tanstack/react-query'; - - import { useAppSelector, useClient } from 'pl-fe/hooks'; -import { normalizeNotification, type Notification } from 'pl-fe/normalizers'; -import { type MinifiedNotification, minifyNotification } from 'pl-fe/pl-hooks/minifiers/minifyNotification'; -import { queryClient } from 'pl-fe/queries/client'; import { selectAccount, selectAccounts } from 'pl-fe/selectors'; +import { queryClient } from 'pl-hooks/client'; +import { type NormalizedNotification, normalizeNotification } from 'pl-hooks/normalizers/normalizeNotifications'; + +import { useAccount } from '../accounts/useAccount'; +import { useStatus } from '../statuses/useStatus'; type Account = ReturnType; -const importNotification = (notification: MinifiedNotification) => { - queryClient.setQueryData( +const importNotification = (notification: NormalizedNotification) => { + queryClient.setQueryData( ['notifications', 'entities', notification.id], existingNotification => existingNotification?.duplicate ? existingNotification : notification, ); @@ -22,25 +22,24 @@ const useNotification = (notificationId: string) => { const notificationQuery = useQuery({ queryKey: ['notifications', 'entities', notificationId], queryFn: () => client.notifications.getNotification(notificationId) - .then(normalizeNotification) - .then(minifyNotification), + .then(normalizeNotification), }); + const notification = notificationQuery.data; + + const accountQuery = useAccount(notification?.account_id); + const moveTargetAccountQuery = useAccount(notification?.target_id); + const statusQuery = useStatus(notification?.status_id); + const data: Notification | null = useAppSelector((state) => { - const notification = notificationQuery.data; if (!notification) return null; - const account = selectAccount(state, notification.account_id)!; - // @ts-ignore - const target = selectAccount(state, notification.target_id)!; - // @ts-ignore - const status = state.statuses.get(notification.status_id)!; const accounts = selectAccounts(state, notification.account_ids).filter((account): account is Account => account !== undefined); return { ...notification, - account, - target, - status, + account: accountQuery.data, + target: moveTargetAccountQuery.data, + status: statusQuery.data, accounts, }; }); diff --git a/packages/pl-hooks/lib/hooks/notifications/useNotificationList.ts b/packages/pl-hooks/lib/hooks/notifications/useNotificationList.ts index 9d1ac3c2f..44bfc4a4a 100644 --- a/packages/pl-hooks/lib/hooks/notifications/useNotificationList.ts +++ b/packages/pl-hooks/lib/hooks/notifications/useNotificationList.ts @@ -1,17 +1,16 @@ import { useInfiniteQuery } from '@tanstack/react-query'; - import { useClient } from 'pl-fe/hooks'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; -import { deduplicateNotifications } from 'pl-fe/pl-hooks/normalizers/deduplicateNotifications'; -import { queryClient } from 'pl-fe/queries/client'; -import { flattenPages } from 'pl-fe/utils/queries'; + +import { queryClient } from 'pl-hooks/client'; +import { importEntities } from 'pl-hooks/importer'; +import { deduplicateNotifications } from 'pl-hooks/normalizers/deduplicateNotifications'; +import { flattenPages } from 'pl-hooks/utils/queries'; import type { Notification as BaseNotification, PaginatedResponse, PlApiClient } from 'pl-api'; -import type { NotificationType } from 'pl-fe/utils/notification'; type UseNotificationParams = { - types?: Array; - excludeTypes?: Array; + types?: Array; + excludeTypes?: Array; } const getQueryKey = (params: UseNotificationParams) => [ diff --git a/packages/pl-hooks/lib/hooks/statuses/useStatus.ts b/packages/pl-hooks/lib/hooks/statuses/useStatus.ts index 64d5a0cdf..110268602 100644 --- a/packages/pl-hooks/lib/hooks/statuses/useStatus.ts +++ b/packages/pl-hooks/lib/hooks/statuses/useStatus.ts @@ -1,11 +1,11 @@ import { useQuery } from '@tanstack/react-query'; +import { useAppSelector, useClient } from 'pl-fe/hooks'; +import { selectAccount, selectAccounts } from 'pl-fe/selectors'; import { useIntl } from 'react-intl'; -import { useAccount } from 'pl-fe/api/hooks'; -import { useAppSelector, useClient } from 'pl-fe/hooks'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; -import { queryClient } from 'pl-fe/queries/client'; -import { selectAccount, selectAccounts } from 'pl-fe/selectors'; +import { queryClient } from 'pl-hooks/client'; +import { useAccount } from 'pl-hooks/hooks/accounts/useAccount'; +import { importEntities } from 'pl-hooks/importer'; import { normalizeStatus, type Status } from '../../normalizers/normalizeStatus'; @@ -106,7 +106,7 @@ const useStatus = (statusId?: string) => { const status = statusQuery.data; - const { account } = useAccount(status?.account_id || undefined); + const { data: account } = useAccount(status?.account_id || undefined); // : (Status & { // account: Account; diff --git a/packages/pl-hooks/lib/importer.ts b/packages/pl-hooks/lib/importer.ts index 17abfcfae..69d8d6797 100644 --- a/packages/pl-hooks/lib/importer.ts +++ b/packages/pl-hooks/lib/importer.ts @@ -1,10 +1,7 @@ -import { importAccounts, importGroups, importPolls, importStatuses } from 'pl-fe/actions/importer'; -import { importEntities as importEntityStoreEntities } from 'pl-fe/entity-store/actions'; -import { Entities } from 'pl-fe/entity-store/entities'; -import { queryClient } from 'pl-fe/queries/client'; +import { queryClient } from 'pl-hooks/client'; -import { minifyNotification, type MinifiedNotification } from './minifiers/minifyNotification'; -import { DeduplicatedNotification } from './normalizers/deduplicateNotifications'; +import { type MinifiedNotification, minifyNotification } from './minifiers/minifyNotification'; +import { DeduplicatedNotification } from './normalizers/normalizeNotifications'; import { normalizeStatus, type Status } from './normalizers/normalizeStatus'; import type { @@ -14,30 +11,34 @@ import type { Relationship as BaseRelationship, Status as BaseStatus, } from 'pl-api'; -import type { AppDispatch } from 'pl-fe/store'; -let dispatch: AppDispatch; +const importAccount = (account: BaseAccount) => queryClient.setQueryData( + ['accounts', 'entities', account.id], account, +); -import('pl-fe/store').then(value => dispatch = value.store.dispatch).catch(() => {}); +const importGroup = (group: BaseGroup) => queryClient.setQueryData( + ['groups', 'entities', group.id], group, +); -const importNotification = (notification: DeduplicatedNotification) => { - queryClient.setQueryData( - ['notifications', 'entities', notification.id], - existingNotification => existingNotification?.duplicate ? existingNotification : minifyNotification(notification), - ); -}; +const importNotification = (notification: DeduplicatedNotification) => queryClient.setQueryData( + ['notifications', 'entities', notification.id], + existingNotification => existingNotification?.duplicate ? existingNotification : minifyNotification(notification), +); -const importStatus = (status: BaseStatus) => { - queryClient.setQueryData( - ['statuses', 'entities', status.id], - _ => normalizeStatus(status), - ); -}; +const importPoll = (poll: BasePoll) => queryClient.setQueryData( + ['polls', 'entities', poll.id], poll, +); -const isEmpty = (object: Record) => { - for (const i in object) return false; - return true; -}; +const importRelationship = (relationship: BaseRelationship) => queryClient.setQueryData( + ['relationships', 'entities', relationship.id], relationship, +); + +const importStatus = (status: BaseStatus) => queryClient.setQueryData( + ['statuses', 'entities', status.id], + _ => normalizeStatus(status), +); + +const isEmpty = (object: Record) => !Object.values(object).some(value => value); const importEntities = (entities: { accounts?: Array; @@ -56,16 +57,12 @@ const importEntities = (entities: { const relationships: Record = {}; const statuses: Record = {}; - const processAccount = (account: BaseAccount, withParent = true) => { - if (withParent) accounts[account.id] = account; - + const processAccount = (account: BaseAccount) => { if (account.moved) processAccount(account.moved); if (account.relationship) relationships[account.relationship.id] = account.relationship; }; - const processNotification = (notification: DeduplicatedNotification, withParent = true) => { - if (withParent) notifications[notification.id] = notification; - + const processNotification = (notification: DeduplicatedNotification) => { processAccount(notification.account); if (notification.type === 'move') processAccount(notification.target); @@ -74,9 +71,8 @@ const importEntities = (entities: { processStatus(notification.status); }; - const processStatus = (status: BaseStatus, withParent = true) => { + const processStatus = (status: BaseStatus) => { if (status.account) { - if (withParent) statuses[status.id] = status; processAccount(status.account); } @@ -87,21 +83,23 @@ const importEntities = (entities: { }; if (options.withParents) { + entities.accounts?.forEach(account => accounts[account.id] = account); entities.groups?.forEach(group => groups[group.id] = group); + entities.notifications?.forEach(notification => notifications[notification.id] = notification); entities.polls?.forEach(poll => polls[poll.id] = poll); entities.relationships?.forEach(relationship => relationships[relationship.id] = relationship); + entities.statuses?.forEach(status => statuses[status.id] = status); } - entities.accounts?.forEach((account) => processAccount(account, options.withParents)); - entities.notifications?.forEach((notification) => processNotification(notification, options.withParents)); - entities.statuses?.forEach((status) => processStatus(status, options.withParents)); + entities.accounts?.forEach((account) => processAccount(account)); + entities.notifications?.forEach((notification) => processNotification(notification)); + entities.statuses?.forEach((status) => processStatus(status)); - if (!isEmpty(accounts)) dispatch(importAccounts(Object.values(accounts))); - if (!isEmpty(groups)) dispatch(importGroups(Object.values(groups))); + if (!isEmpty(accounts)) Object.values(accounts).forEach(importAccount); + if (!isEmpty(groups)) Object.values(groups).forEach(importGroup); if (!isEmpty(notifications)) Object.values(notifications).forEach(importNotification); - if (!isEmpty(polls)) dispatch(importPolls(Object.values(polls))); - if (!isEmpty(relationships)) dispatch(importEntityStoreEntities(Object.values(relationships), Entities.RELATIONSHIPS)); - if (!isEmpty(statuses)) dispatch(importStatuses(Object.values(statuses))); + if (!isEmpty(polls)) Object.values(polls).forEach(importPoll); + if (!isEmpty(relationships)) Object.values(relationships).forEach(importRelationship); if (!isEmpty(statuses)) Object.values(statuses).forEach(importStatus); }; diff --git a/packages/pl-hooks/lib/minifiers/minifyNotification.ts b/packages/pl-hooks/lib/minifiers/minifyNotification.ts index 3a972088c..ba0f01ae4 100644 --- a/packages/pl-hooks/lib/minifiers/minifyNotification.ts +++ b/packages/pl-hooks/lib/minifiers/minifyNotification.ts @@ -1,6 +1,6 @@ import omit from 'lodash/omit'; -import { DeduplicatedNotification } from '../normalizers/deduplicateNotifications'; +import { DeduplicatedNotification } from '../normalizers/normalizeNotifications'; import type { AccountWarning, RelationshipSeveranceEvent } from 'pl-api'; diff --git a/packages/pl-hooks/lib/normalizers/deduplicateNotifications.ts b/packages/pl-hooks/lib/normalizers/deduplicateNotifications.ts deleted file mode 100644 index 41e0d7cfd..000000000 --- a/packages/pl-hooks/lib/normalizers/deduplicateNotifications.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { getNotificationStatus } from 'pl-fe/features/notifications/components/notification'; - -import type { Account as BaseAccount, Notification as BaseNotification } from 'pl-api'; - -type DeduplicatedNotification = BaseNotification & { - accounts: Array; - duplicate?: boolean; -} - -const STATUS_NOTIFICATION_TYPES = [ - 'favourite', - 'reblog', - 'emoji_reaction', - 'event_reminder', - 'participation_accepted', - 'participation_request', -]; - -const deduplicateNotifications = (notifications: Array) => { - const deduplicatedNotifications: DeduplicatedNotification[] = []; - - for (const notification of notifications) { - if (STATUS_NOTIFICATION_TYPES.includes(notification.type)) { - const existingNotification = deduplicatedNotifications - .find(deduplicated => - deduplicated.type === notification.type - && ((notification.type === 'emoji_reaction' && deduplicated.type === 'emoji_reaction') ? notification.emoji === deduplicated.emoji : true) - && getNotificationStatus(deduplicated)?.id === getNotificationStatus(notification)?.id, - ); - - if (existingNotification) { - existingNotification.accounts.push(notification.account); - deduplicatedNotifications.push({ ...notification, accounts: [notification.account], duplicate: true }); - } else { - deduplicatedNotifications.push({ ...notification, accounts: [notification.account], duplicate: false }); - } - } else { - deduplicatedNotifications.push({ ...notification, accounts: [notification.account], duplicate: false }); - } - } - - return deduplicatedNotifications; -}; - -export { deduplicateNotifications, type DeduplicatedNotification }; diff --git a/packages/pl-hooks/lib/normalizers/normalizeAccount.ts b/packages/pl-hooks/lib/normalizers/normalizeAccount.ts index de583a430..2fca21d28 100644 --- a/packages/pl-hooks/lib/normalizers/normalizeAccount.ts +++ b/packages/pl-hooks/lib/normalizers/normalizeAccount.ts @@ -1,37 +1,9 @@ -import escapeTextContentForBrowser from 'escape-html'; - -import emojify from 'pl-fe/features/emoji'; -import { unescapeHTML } from 'pl-fe/utils/html'; -import { makeEmojiMap } from 'pl-fe/utils/normalizers'; - import type { Account as BaseAccount } from 'pl-api'; -const normalizeAccount = ({ moved, ...account }: BaseAccount) => { - const missingAvatar = require('pl-fe/assets/images/avatar-missing.png'); - const missingHeader = require('pl-fe/assets/images/header-missing.png'); - const note = account.note === '

' ? '' : account.note; - - const emojiMap = makeEmojiMap(account.emojis); - - return { - ...account, - moved_id: moved?.id || null, - avatar: account.avatar || account.avatar_static || missingAvatar, - avatar_static: account.avatar_static || account.avatar || missingAvatar, - header: account.header || account.header_static || missingHeader, - header_static: account.header_static || account.header || missingHeader, - note, - display_name_html: emojify(escapeTextContentForBrowser(account.display_name), emojiMap), - note_emojified: emojify(account.note, emojiMap), - note_plain: unescapeHTML(account.note), - fields: account.fields.map(field => ({ - ...field, - name_emojified: emojify(escapeTextContentForBrowser(field.name), emojiMap), - value_emojified: emojify(field.value, emojiMap), - value_plain: unescapeHTML(field.value), - })), - }; -}; +const normalizeAccount = ({ moved, ...account }: BaseAccount) => ({ + ...account, + moved_id: moved?.id || null, +}); type Account = ReturnType; diff --git a/packages/pl-hooks/lib/normalizers/normalizeNotifications.ts b/packages/pl-hooks/lib/normalizers/normalizeNotifications.ts new file mode 100644 index 000000000..0e7c5ba5c --- /dev/null +++ b/packages/pl-hooks/lib/normalizers/normalizeNotifications.ts @@ -0,0 +1,131 @@ +import omit from 'lodash/omit'; + +import type { AccountWarning, Account as BaseAccount, Notification as BaseNotification, RelationshipSeveranceEvent } from 'pl-api'; + +type DeduplicatedNotification = BaseNotification & { + accounts: Array; + duplicate?: boolean; +} + +const STATUS_NOTIFICATION_TYPES = [ + 'mention', + 'status', + 'reblog', + 'favourite', + 'poll', + 'update', + 'emoji_reaction', + 'event_reminder', + 'participation_accepted', + 'participation_request', +]; + +const getNotificationStatus = (n: Pick) => { + if (STATUS_NOTIFICATION_TYPES.includes(n.type)) + // @ts-ignore + return n.status; + return null; +}; + +const normalizeNotifications = (notifications: Array): Array => { + const deduplicatedNotifications: DeduplicatedNotification[] = []; + + for (const notification of notifications) { + if (STATUS_NOTIFICATION_TYPES.includes(notification.type)) { + const existingNotification = deduplicatedNotifications + .find(deduplicated => + deduplicated.type === notification.type + && ((notification.type === 'emoji_reaction' && deduplicated.type === 'emoji_reaction') ? notification.emoji === deduplicated.emoji : true) + && getNotificationStatus(deduplicated)?.id === getNotificationStatus(notification)?.id, + ); + + if (existingNotification) { + existingNotification.accounts.push(notification.account); + deduplicatedNotifications.push({ ...notification, accounts: [notification.account], duplicate: true }); + } else { + deduplicatedNotifications.push({ ...notification, accounts: [notification.account], duplicate: false }); + } + } else { + deduplicatedNotifications.push({ ...notification, accounts: [notification.account], duplicate: false }); + } + } + + return deduplicatedNotifications.map(normalizeNotification); +}; + + +const normalizeNotification = (notification: BaseNotification | DeduplicatedNotification) => { + // @ts-ignore + const minifiedNotification: { + duplicate: boolean; + account_id: string; + account_ids: string[]; + created_at: string; + id: string; + group_key: string; + } & ( + | { type: 'follow' | 'follow_request' | 'admin.sign_up' | 'bite' } + | { + type: 'mention'; + subtype?: 'reply'; + status_id: string; + } + | { + type: 'status' | 'reblog' | 'favourite' | 'poll' | 'update' | 'event_reminder'; + status_id: string; + } + | { + type: 'admin.report'; + report: Report; + } + | { + type: 'severed_relationships'; + relationship_severance_event: RelationshipSeveranceEvent; + } + | { + type: 'moderation_warning'; + moderation_warning: AccountWarning; + } + | { + type: 'move'; + target_id: string; + } + | { + type: 'emoji_reaction'; + emoji: string; + emoji_url: string | null; + status_id: string; + } + | { + type: 'chat_mention'; + chat_message_id: string; + } + | { + type: 'participation_accepted' | 'participation_request'; + status_id: string; + participation_message: string | null; + } + ) = { + duplicate: false, + ...omit(notification, ['account', 'accounts', 'status', 'target', 'chat_message']), + account_id: notification.account.id, + account_ids: ('accounts' in notification) ? notification.accounts.map(({ id }) => id) : [notification.account.id], + created_at: notification.created_at, + id: notification.id, + type: notification.type, + }; + + // @ts-ignore + if (notification.status) minifiedNotification.status_id = notification.status.id; + // @ts-ignore + if (notification.target) minifiedNotification.target_id = notification.target.id; + // @ts-ignore + if (notification.chat_message) minifiedNotification.chat_message_id = notification.chat_message.id; + + return minifiedNotification; +}; + +type NormalizedNotification = ReturnType; + + +export { normalizeNotifications, normalizeNotification, type NormalizedNotification }; diff --git a/packages/pl-hooks/lib/normalizers/normalizeStatus.ts b/packages/pl-hooks/lib/normalizers/normalizeStatus.ts index 4dbee8d69..aa5666483 100644 --- a/packages/pl-hooks/lib/normalizers/normalizeStatus.ts +++ b/packages/pl-hooks/lib/normalizers/normalizeStatus.ts @@ -3,96 +3,12 @@ * Converts API statuses into our internal format. * @see {@link https://docs.joinmastodon.org/entities/status/} */ -import escapeTextContentForBrowser from 'escape-html'; -import DOMPurify from 'isomorphic-dompurify'; -import { type Account as BaseAccount, type Status as BaseStatus, type MediaAttachment, mentionSchema, type Translation } from 'pl-api'; - -import emojify from 'pl-fe/features/emoji'; -import { queryClient } from 'pl-fe/queries/client'; -import { unescapeHTML } from 'pl-fe/utils/html'; -import { makeEmojiMap } from 'pl-fe/utils/normalizers'; - -const domParser = new DOMParser(); +import { type Account as BaseAccount, type Status as BaseStatus, type MediaAttachment, mentionSchema } from 'pl-api'; type StatusApprovalStatus = Exclude; type StatusVisibility = 'public' | 'unlisted' | 'private' | 'direct' | 'group' | 'mutuals_only' | 'local'; -type CalculatedValues = { - search_index: string; - contentHtml: string; - spoilerHtml: string; - contentMapHtml?: Record; - spoilerMapHtml?: Record; - expanded?: boolean | null; - hidden?: boolean | null; - translation?: Translation | null | false; - currentLanguage?: string; -}; - -type OldStatus = Pick & CalculatedValues; - -// Gets titles of poll options from status -const getPollOptionTitles = ({ poll }: Pick): readonly string[] => { - if (poll && typeof poll === 'object') { - return poll.options.map(({ title }) => title); - } else { - return []; - } -}; - -// Gets usernames of mentioned users from status -const getMentionedUsernames = (status: Pick): Array => - status.mentions.map(({ acct }) => `@${acct}`); - -// Creates search text from the status -const buildSearchContent = (status: Pick): string => { - const pollOptionTitles = getPollOptionTitles(status); - const mentionedUsernames = getMentionedUsernames(status); - - const fields = [ - status.spoiler_text, - status.content, - ...pollOptionTitles, - ...mentionedUsernames, - ]; - - return unescapeHTML(fields.join('\n\n')) || ''; -}; - -const calculateContent = (text: string, emojiMap: any, hasQuote?: boolean) => emojify(text, emojiMap); -const calculateSpoiler = (text: string, emojiMap: any) => DOMPurify.sanitize(emojify(escapeTextContentForBrowser(text), emojiMap), { USE_PROFILES: { html: true } }); - -const calculateStatus = (status: BaseStatus, oldStatus?: OldStatus): CalculatedValues => { - if (oldStatus && oldStatus.content === status.content && oldStatus.spoiler_text === status.spoiler_text) { - const { - search_index, contentHtml, spoilerHtml, contentMapHtml, spoilerMapHtml, hidden, expanded, translation, currentLanguage, - } = oldStatus; - - return { - search_index, contentHtml, spoilerHtml, contentMapHtml, spoilerMapHtml, hidden, expanded, translation, currentLanguage, - }; - } else { - const searchContent = buildSearchContent(status); - const emojiMap = makeEmojiMap(status.emojis); - - return { - search_index: domParser.parseFromString(searchContent, 'text/html').documentElement.textContent || '', - contentHtml: calculateContent(status.content, emojiMap, !!status.quote), - spoilerHtml: calculateSpoiler(status.spoiler_text, emojiMap), - contentMapHtml: status.content_map - ? Object.fromEntries(Object.entries(status.content_map)?.map(([key, value]) => [key, calculateContent(value, emojiMap, !!status.quote)])) - : undefined, - spoilerMapHtml: status.spoiler_text_map - ? Object.fromEntries(Object.entries(status.spoiler_text_map).map(([key, value]) => [key, calculateSpoiler(value, emojiMap)])) - : undefined, - }; - } -}; - const normalizeStatus = ({ account, accounts, reblog, poll, group, quote, ...status }: BaseStatus & { accounts?: Array }) => { - const oldStatus = queryClient.getQueryData(['statuses', 'entities', status.id]); - const calculated = calculateStatus(status, oldStatus); - // Sort the replied-to mention to the top let mentions = status.mentions.toSorted((a, _b) => { if (a.id === status.in_reply_to_account_id) { @@ -107,7 +23,7 @@ const normalizeStatus = ({ account, accounts, reblog, poll, group, quote, ...sta const hasSelfMention = status.mentions.some(mention => account.id === mention.id); if (isSelfReply && !hasSelfMention) { - const selfMention = mentionSchema.parse(status.account); + const selfMention = mentionSchema.parse(account); mentions = [selfMention, ...mentions]; } @@ -151,13 +67,9 @@ const normalizeStatus = ({ account, accounts, reblog, poll, group, quote, ...sta mentions, expanded: null, hidden: null, - /** Rewrite `

` to empty string. */ - content: status.content === '

' ? '' : status.content, filtered: status.filtered?.map(result => result.filter.title), event, media_attachments, - ...calculated, - translation: (status.translation || calculated.translation || null) as Translation | null | false, }; }; diff --git a/packages/pl-hooks/lib/utils/queries.ts b/packages/pl-hooks/lib/utils/queries.ts new file mode 100644 index 000000000..80b3e262b --- /dev/null +++ b/packages/pl-hooks/lib/utils/queries.ts @@ -0,0 +1,12 @@ +import type { InfiniteData } from '@tanstack/react-query'; +import type { PaginatedResponse } from 'pl-api'; + +/** Flatten paginated results into a single array. */ +const flattenPages = (queryData: InfiniteData, 'items'>> | undefined) => { + return queryData?.pages.reduce( + (prev: T[], curr) => [...prev, ...(curr.items)], + [], + ); +}; + +export { flattenPages }; diff --git a/packages/pl-hooks/package.json b/packages/pl-hooks/package.json index 86d8bb0d7..cc7cca04e 100644 --- a/packages/pl-hooks/package.json +++ b/packages/pl-hooks/package.json @@ -18,6 +18,7 @@ }, "license": "AGPL-3.0-or-later", "devDependencies": { + "@types/lodash": "^4.17.10", "@types/node": "^20.14.12", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.0.0", @@ -32,6 +33,7 @@ }, "dependencies": { "@tanstack/react-query": "^5.56.2", + "lodash": "^4.17.21", "pl-api": "^0.0.37" }, "module": "./dist/main.es.js", diff --git a/packages/pl-hooks/tsconfig.json b/packages/pl-hooks/tsconfig.json index eb60a062c..5ae37dd78 100644 --- a/packages/pl-hooks/tsconfig.json +++ b/packages/pl-hooks/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "baseUrl": "./", "target": "ESNext", "useDefineForClassFields": true, "module": "ESNext", @@ -18,7 +19,11 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true + "noFallthroughCasesInSwitch": true, + + "paths": { + "pl-hooks/*": ["lib/*"], + }, }, - "include": ["src", "lib"] + "include": ["lib"] } diff --git a/packages/pl-hooks/vite.config.ts b/packages/pl-hooks/vite.config.ts index 5b8156db5..2d3fb004e 100644 --- a/packages/pl-hooks/vite.config.ts +++ b/packages/pl-hooks/vite.config.ts @@ -1,3 +1,4 @@ +import { fileURLToPath, URL } from 'node:url'; import { resolve } from 'path'; import { defineConfig } from 'vite'; @@ -16,4 +17,9 @@ export default defineConfig({ target: 'esnext', sourcemap: true, }, + resolve: { + alias: [ + { find: 'pl-hooks', replacement: fileURLToPath(new URL('./lib', import.meta.url)) }, + ], + }, }); diff --git a/packages/pl-hooks/yarn.lock b/packages/pl-hooks/yarn.lock index 2571337ef..0d4981bb1 100644 --- a/packages/pl-hooks/yarn.lock +++ b/packages/pl-hooks/yarn.lock @@ -408,6 +408,11 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/lodash@^4.17.10": + version "4.17.10" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.10.tgz#64f3edf656af2fe59e7278b73d3e62404144a6e6" + integrity sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ== + "@types/node@^20.14.12": version "20.14.12" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.12.tgz#129d7c3a822cb49fc7ff661235f19cfefd422b49" @@ -1863,7 +1868,7 @@ lodash.pick@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q== -lodash@~4.17.15: +lodash@^4.17.21, lodash@~4.17.15: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==