diff --git a/packages/pl-api/lib/entities/account.ts b/packages/pl-api/lib/entities/account.ts index 86a80c75c..7505f193f 100644 --- a/packages/pl-api/lib/entities/account.ts +++ b/packages/pl-api/lib/entities/account.ts @@ -6,6 +6,26 @@ import { relationshipSchema } from './relationship'; import { roleSchema } from './role'; import { coerceObject, dateSchema, filteredArray } from './utils'; +const getDomainFromURL = (account: Pick): string => { + try { + const url = account.url; + return new URL(url).host; + } catch { + return ''; + } +}; + +const guessFqn = (account: Pick): string => { + const acct = account.acct; + const [user, domain] = acct.split('@'); + + if (domain) { + return acct; + } else { + return [user, getDomainFromURL(account)].join('@'); + } +}; + const filterBadges = (tags?: string[]) => tags?.filter(tag => tag.startsWith('badge:')).map(tag => roleSchema.parse({ id: tag, name: tag.replace(/^badge:/, '') })); @@ -13,9 +33,12 @@ const preprocessAccount = (account: any) => { if (!account?.acct) return null; const username = account.username || account.acct.split('@')[0]; + const fqn = guessFqn(account); return { username, + fqn, + domain: fqn.split('@')[1] || '', avatar_static: account.avatar_static || account.avatar, header_static: account.header_static || account.header, local: typeof account.pleroma?.is_local === 'boolean' ? account.pleroma.is_local : account.acct.split('@')[1] === undefined, @@ -120,6 +143,7 @@ const baseAccountSchema = z.object({ header_description: z.string().catch(''), verified: z.boolean().optional().catch(undefined), + domain: z.string().catch(''), __meta: coerceObject({ pleroma: z.any().optional().catch(undefined), diff --git a/packages/pl-fe/src/actions/draft-statuses.ts b/packages/pl-fe/src/actions/draft-statuses.ts index d83bdf6cd..3036a2af2 100644 --- a/packages/pl-fe/src/actions/draft-statuses.ts +++ b/packages/pl-fe/src/actions/draft-statuses.ts @@ -1,7 +1,8 @@ -import { makeGetAccount } from 'pl-fe/selectors'; +import { queryClient } from 'pl-fe/queries/client'; import KVStore from 'pl-fe/storage/kv-store'; +import type { MinifiedAccount } from 'pl-fe/pl-hooks/minifiers/minifyAccount'; import type { AppDispatch, RootState } from 'pl-fe/store'; const DRAFT_STATUSES_FETCH_SUCCESS = 'DRAFT_STATUSES_FETCH_SUCCESS' as const; @@ -9,12 +10,10 @@ const DRAFT_STATUSES_FETCH_SUCCESS = 'DRAFT_STATUSES_FETCH_SUCCESS' as const; const PERSIST_DRAFT_STATUS = 'PERSIST_DRAFT_STATUS' as const; const CANCEL_DRAFT_STATUS = 'DELETE_DRAFT_STATUS' as const; -const getAccount = makeGetAccount(); - const fetchDraftStatuses = () => (dispatch: AppDispatch, getState: () => RootState) => { const state = getState(); - const accountUrl = getAccount(state, state.me as string)!.url; + const accountUrl = queryClient.getQueryData(['accounts', 'entities', state.me])!.url; return KVStore.getItem(`drafts:${accountUrl}`).then((statuses) => { dispatch({ @@ -27,7 +26,7 @@ const fetchDraftStatuses = () => const saveDraftStatus = (composeId: string) => (dispatch: AppDispatch, getState: () => RootState) => { const state = getState(); - const accountUrl = getAccount(state, state.me as string)!.url; + const accountUrl = queryClient.getQueryData(['accounts', 'entities', state.me])!.url; const compose = state.compose.get(composeId)!; @@ -46,7 +45,7 @@ const saveDraftStatus = (composeId: string) => const cancelDraftStatus = (statusId: string) => (dispatch: AppDispatch, getState: () => RootState) => { const state = getState(); - const accountUrl = getAccount(state, state.me as string)!.url; + const accountUrl = queryClient.getQueryData(['accounts', 'entities', state.me])!.url; dispatch({ type: CANCEL_DRAFT_STATUS, diff --git a/packages/pl-fe/src/actions/notifications.ts b/packages/pl-fe/src/actions/notifications.ts index fe755cdc2..edab29e00 100644 --- a/packages/pl-fe/src/actions/notifications.ts +++ b/packages/pl-fe/src/actions/notifications.ts @@ -7,7 +7,7 @@ import { getNotificationStatus } from 'pl-fe/features/notifications/components/n 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 { getFilters, regexFromFilters } from 'pl-fe/selectors'; import { useSettingsStore } from 'pl-fe/stores/settings'; import { unescapeHTML } from 'pl-fe/utils/html'; import { joinPublicPath } from 'pl-fe/utils/static'; @@ -60,26 +60,27 @@ const updateNotificationsQueue = (notification: Notification, intlMessages: Reco if (!notification.type) return; // drop invalid notifications if (notification.type === 'chat_mention') return; // Drop chat notifications, handle them per-chat - const filters = getFilters(getState(), { contextType: 'notifications' }); + // TODO: Restore filtering + // const filters = getFilters(getState(), { contextType: 'notifications' }); const status = getNotificationStatus(notification); - let filtered: boolean | null = false; + // let filtered: boolean | null = false; const isOnNotificationsPage = curPath === '/notifications'; - if (notification.type === 'mention' || notification.type === 'status') { - const regex = regexFromFilters(filters); - const searchIndex = notification.status.spoiler_text + '\n' + unescapeHTML(notification.status.content); - filtered = regex && regex.test(searchIndex); - } + // if (notification.type === 'mention' || notification.type === 'status') { + // const regex = regexFromFilters(filters); + // const searchIndex = notification.status.spoiler_text + '\n' + unescapeHTML(notification.status.content); + // filtered = regex && regex.test(searchIndex); + // } // Desktop notifications try { // eslint-disable-next-line compat/compat const isNotificationsEnabled = window.Notification?.permission === 'granted'; - if (!filtered && isNotificationsEnabled) { + if (/* !filtered && */ isNotificationsEnabled) { const title = new IntlMessageFormat(intlMessages[`notification.${notification.type}`], intlLocale).format({ name: notification.account.display_name.length > 0 ? notification.account.display_name : notification.account.username }) as string; const body = (status && status.spoiler_text.length > 0) ? status.spoiler_text : unescapeHTML(status ? status.content : ''); diff --git a/packages/pl-fe/src/actions/settings.ts b/packages/pl-fe/src/actions/settings.ts index 9d2fbf957..aa2beebc8 100644 --- a/packages/pl-fe/src/actions/settings.ts +++ b/packages/pl-fe/src/actions/settings.ts @@ -3,7 +3,8 @@ 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 { makeGetAccount } from 'pl-fe/selectors'; +import { MinifiedAccount } from 'pl-fe/pl-hooks/minifiers/minifyAccount'; +import { queryClient } from 'pl-fe/queries/client'; import KVStore from 'pl-fe/storage/kv-store'; import { useSettingsStore } from 'pl-fe/stores/settings'; import toast from 'pl-fe/toast'; @@ -13,8 +14,6 @@ import type { AppDispatch, RootState } from 'pl-fe/store'; const FE_NAME = 'pl_fe'; -const getAccount = makeGetAccount(); - /** Options when changing/saving settings. */ type SettingOpts = { /** Whether to display an alert when settings are saved. */ @@ -71,7 +70,7 @@ const updateSettingsStore = (settings: any) => }, })); } else { - const accountUrl = getAccount(state, state.me as string)!.url; + const accountUrl = queryClient.getQueryData(['accounts', 'entities', state.me])!.url; return updateAuthAccount(accountUrl, settings); } diff --git a/packages/pl-fe/src/components/status-hover-card.tsx b/packages/pl-fe/src/components/status-hover-card.tsx index 261e49bbc..df5578abf 100644 --- a/packages/pl-fe/src/components/status-hover-card.tsx +++ b/packages/pl-fe/src/components/status-hover-card.tsx @@ -80,7 +80,6 @@ const StatusHoverCard: React.FC = ({ visible = true }) => { if (!statusId) return null; const renderStatus = (statusId: string) => ( - // @ts-ignore = (props) => { const didShowCard = useRef(false); const node = useRef(null); - const getStatus = useCallback(makeGetStatus(), []); - const actualStatus = useAppSelector(state => status.reblog_id && getStatus(state, { id: status.reblog_id }) || status)!; + const actualStatus = useStatus(status.reblog_id || undefined).data || status; const isReblog = status.reblog_id; const statusUrl = `/@${actualStatus.account.acct}/posts/${actualStatus.id}`; diff --git a/packages/pl-fe/src/containers/status-container.tsx b/packages/pl-fe/src/containers/status-container.tsx index 96fd73897..32ad7e395 100644 --- a/packages/pl-fe/src/containers/status-container.tsx +++ b/packages/pl-fe/src/containers/status-container.tsx @@ -1,8 +1,7 @@ -import React, { useCallback } from 'react'; +import React from 'react'; import Status, { IStatus } from 'pl-fe/components/status'; -import { useAppSelector } from 'pl-fe/hooks'; -import { makeGetStatus } from 'pl-fe/selectors'; +import { useStatus } from 'pl-fe/pl-hooks/hooks/statuses/useStatus'; interface IStatusContainer extends Omit { id: string; @@ -12,14 +11,12 @@ interface IStatusContainer extends Omit { } /** - * Legacy Status wrapper accepting a status ID instead of the full entity. - * @deprecated Use the Status component directly. + * Status wrapper accepting a status ID instead of the full entity. */ const StatusContainer: React.FC = (props) => { const { id, contextType, ...rest } = props; - const getStatus = useCallback(makeGetStatus(), []); - const status = useAppSelector(state => getStatus(state, { id, contextType })); + const { data: status } = useStatus(id); if (status) { return ; diff --git a/packages/pl-fe/src/features/conversations/components/conversation.tsx b/packages/pl-fe/src/features/conversations/components/conversation.tsx index 93d530f92..e24575235 100644 --- a/packages/pl-fe/src/features/conversations/components/conversation.tsx +++ b/packages/pl-fe/src/features/conversations/components/conversation.tsx @@ -47,7 +47,6 @@ const Conversation: React.FC = ({ conversationId, onMoveUp, onMov } return ( - // @ts-ignore { if (results.statuses && results.statuses.length > 0) { searchResults = results.statuses.map((statusId: string) => ( - // @ts-ignore { resultsIds = results.statuses; } else if (!submitted && !filterByAccount && trendingStatuses && trendingStatuses.length !== 0) { searchResults = trendingStatuses.map((statusId: string) => ( - // @ts-ignore = (props): JSX.Element => {
{renderConnector()} {isLoaded ? ( - // @ts-ignore FIXME ) : ( diff --git a/packages/pl-fe/src/pl-hooks/hooks/accounts/useAccount.ts b/packages/pl-fe/src/pl-hooks/hooks/accounts/useAccount.ts index 2f0b27e09..9d6e9cc16 100644 --- a/packages/pl-fe/src/pl-hooks/hooks/accounts/useAccount.ts +++ b/packages/pl-fe/src/pl-hooks/hooks/accounts/useAccount.ts @@ -1,7 +1,10 @@ import { useQuery } from '@tanstack/react-query'; import { useRelationship } from 'pl-fe/api/hooks/accounts/useRelationship'; -import { useAppSelector, useClient } from 'pl-fe/hooks'; +import { useClient } from 'pl-fe/hooks'; +import { type MinifiedAccount, minifyAccount } from 'pl-fe/pl-hooks/minifiers/minifyAccount'; +import { normalizeAccount } from 'pl-fe/pl-hooks/normalizers/normalizeAccount'; +import { queryClient } from 'pl-fe/queries/client'; interface UseAccountOpts { withRelationship?: boolean; @@ -24,19 +27,14 @@ const useAccount = (accountId?: string, opts: UseAccountOpts = {}) => { 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, + let data; + if (accountQuery.data) { + data = { + ...accountQuery.data, relationship: relationshipQuery.relationship, - moved: movedQuery.data || null, + moved: opts.withMoveTarget && queryClient.getQueryData(['accounts', 'entities', accountQuery.data?.moved_id]) as MinifiedAccount || null, }; - }); + } else data = null; return { ...accountQuery, data }; }; diff --git a/packages/pl-fe/src/pl-hooks/hooks/statuses/useStatus.ts b/packages/pl-fe/src/pl-hooks/hooks/statuses/useStatus.ts index c6db19082..9b3bcfe25 100644 --- a/packages/pl-fe/src/pl-hooks/hooks/statuses/useStatus.ts +++ b/packages/pl-fe/src/pl-hooks/hooks/statuses/useStatus.ts @@ -3,6 +3,7 @@ import { useIntl } from 'react-intl'; import { useAccount, useGroup } 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'; @@ -13,6 +14,76 @@ import { normalizeStatus } from '../../normalizers/normalizeStatus'; type Account = ReturnType; +// const toServerSideType = (columnType: string): Filter['context'][0] => { +// switch (columnType) { +// case 'home': +// case 'notifications': +// case 'public': +// case 'thread': +// return columnType; +// default: +// if (columnType.includes('list:')) { +// return 'home'; +// } else { +// return 'public'; // community, account, hashtag +// } +// } +// }; + +// type FilterContext = { contextType?: string }; + +// const getFilters = (state: RootState, query: FilterContext) => +// state.filters.filter((filter) => +// (!query?.contextType || filter.context.includes(toServerSideType(query.contextType))) +// && (filter.expires_at === null || Date.parse(filter.expires_at) > new Date().getTime()), +// ); + +// const escapeRegExp = (string: string) => +// string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string + +// const regexFromFilters = (filters: ImmutableList) => { +// if (filters.size === 0) return null; + +// return new RegExp(filters.map(filter => +// filter.keywords.map(keyword => { +// let expr = escapeRegExp(keyword.keyword); + +// if (keyword.whole_word) { +// if (/^[\w]/.test(expr)) { +// expr = `\\b${expr}`; +// } + +// if (/[\w]$/.test(expr)) { +// expr = `${expr}\\b`; +// } +// } + +// return expr; +// }).join('|'), +// ).join('|'), 'i'); +// }; + +// const checkFiltered = (index: string, filters: ImmutableList) => +// filters.reduce((result: Array, filter) => +// result.concat(filter.keywords.reduce((result: Array, keyword) => { +// let expr = escapeRegExp(keyword.keyword); + +// if (keyword.whole_word) { +// if (/^[\w]/.test(expr)) { +// expr = `\\b${expr}`; +// } + +// if (/[\w]$/.test(expr)) { +// expr = `${expr}\\b`; +// } +// } + +// const regex = new RegExp(expr); + +// if (regex.test(index)) return result.concat(filter.title); +// return result; +// }, [])), []); + const importStatus = (status: MinifiedStatus) => { queryClient.setQueryData( ['statuses', 'entities', status.id], @@ -29,6 +100,7 @@ const useStatus = (statusId?: string) => { queryFn: () => client.statuses.getStatus(statusId!, { language: intl.locale, }) + .then(status => (importEntities({ statuses: [status] }, { withParents: false }), status)) .then(normalizeStatus) .then(minifyStatus), enabled: !!statusId, @@ -51,9 +123,13 @@ const useStatus = (statusId?: string) => { return { ...status, - account, + account: account!, accounts, group, + // quote, + // reblog, + // poll + }; }); diff --git a/packages/pl-fe/src/pl-hooks/importer.ts b/packages/pl-fe/src/pl-hooks/importer.ts index e4b950462..a75031794 100644 --- a/packages/pl-fe/src/pl-hooks/importer.ts +++ b/packages/pl-fe/src/pl-hooks/importer.ts @@ -47,6 +47,8 @@ const importEntities = (entities: { polls?: Array; statuses?: Array; relationships?: Array; +}, options = { + withParents: true, }) => { const accounts: Record = {}; const groups: Record = {}; @@ -55,14 +57,15 @@ const importEntities = (entities: { const relationships: Record = {}; const statuses: Record = {}; - const processAccount = (account: BaseAccount) => { - accounts[account.id] = account; + const processAccount = (account: BaseAccount, withParent = true) => { + if (withParent) accounts[account.id] = account; + if (account.moved) processAccount(account.moved); if (account.relationship) relationships[account.relationship.id] = account.relationship; }; - const processNotification = (notification: DeduplicatedNotification) => { - notifications[notification.id] = notification; + const processNotification = (notification: DeduplicatedNotification, withParent = true) => { + if (withParent) notifications[notification.id] = notification; processAccount(notification.account); if (notification.type === 'move') processAccount(notification.target); @@ -72,9 +75,9 @@ const importEntities = (entities: { processStatus(notification.status); }; - const processStatus = (status: BaseStatus) => { + const processStatus = (status: BaseStatus, withParent = true) => { if (status.account) { - statuses[status.id] = status; + if (withParent) statuses[status.id] = status; processAccount(status.account); } @@ -84,12 +87,15 @@ const importEntities = (entities: { if (status.group) groups[status.group.id] = status.group; }; - entities.accounts?.forEach(processAccount); - entities.groups?.forEach(group => groups[group.id] = group); - entities.notifications?.forEach(processNotification); - entities.polls?.forEach(poll => polls[poll.id] = poll); - entities.relationships?.forEach(relationship => relationships[relationship.id] = relationship); - entities.statuses?.forEach(processStatus); + if (options.withParents) { + entities.groups?.forEach(group => groups[group.id] = group); + entities.polls?.forEach(poll => polls[poll.id] = poll); + entities.relationships?.forEach(relationship => relationships[relationship.id] = relationship); + } + + entities.accounts?.forEach((account) => processAccount(account, options.withParents)); + entities.notifications?.forEach((notification) => processNotification(notification, options.withParents)); + entities.statuses?.forEach((status) => processStatus(status, options.withParents)); if (!isEmpty(accounts)) dispatch(importAccounts(Object.values(accounts))); if (!isEmpty(groups)) dispatch(importGroups(Object.values(groups))); diff --git a/packages/pl-fe/src/pl-hooks/minifiers/minifyAccount.ts b/packages/pl-fe/src/pl-hooks/minifiers/minifyAccount.ts new file mode 100644 index 000000000..abf5de8a1 --- /dev/null +++ b/packages/pl-fe/src/pl-hooks/minifiers/minifyAccount.ts @@ -0,0 +1,10 @@ +import type { Account } from '../normalizers/normalizeAccount'; + +const minifyAccount = ({ moved, ...account }: Account) => ({ + ...account, + moved_id: moved?.id || null, +}); + +type MinifiedAccount = ReturnType; + +export { minifyAccount, type MinifiedAccount }; diff --git a/packages/pl-fe/src/pl-hooks/normalizers/normalizeAccount.ts b/packages/pl-fe/src/pl-hooks/normalizers/normalizeAccount.ts new file mode 100644 index 000000000..0aa5b4e23 --- /dev/null +++ b/packages/pl-fe/src/pl-hooks/normalizers/normalizeAccount.ts @@ -0,0 +1,37 @@ +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 = (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, + 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), + })), + }; +}; + +type Account = ReturnType; + +export { normalizeAccount, type Account }; diff --git a/packages/pl-fe/src/pl-hooks/normalizers/normalizeStatus.ts b/packages/pl-fe/src/pl-hooks/normalizers/normalizeStatus.ts index a34a53227..632d82d7b 100644 --- a/packages/pl-fe/src/pl-hooks/normalizers/normalizeStatus.ts +++ b/packages/pl-fe/src/pl-hooks/normalizers/normalizeStatus.ts @@ -8,7 +8,7 @@ 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 { stripCompatibilityFeatures, unescapeHTML } from 'pl-fe/utils/html'; +import { unescapeHTML } from 'pl-fe/utils/html'; import { makeEmojiMap } from 'pl-fe/utils/normalizers'; const domParser = new DOMParser(); @@ -58,7 +58,7 @@ const buildSearchContent = (status: Pick DOMPurify.sanitize(stripCompatibilityFeatures(emojify(text, emojiMap), hasQuote), { USE_PROFILES: { html: true } }); +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 => { diff --git a/packages/pl-fe/src/selectors/index.ts b/packages/pl-fe/src/selectors/index.ts index 445898db9..81eb32bfa 100644 --- a/packages/pl-fe/src/selectors/index.ts +++ b/packages/pl-fe/src/selectors/index.ts @@ -13,7 +13,7 @@ import { validId } from 'pl-fe/utils/auth'; import ConfigDB from 'pl-fe/utils/config-db'; import { shouldFilter } from 'pl-fe/utils/timelines'; -import type { Account as BaseAccount, Filter, MediaAttachment, Relationship } from 'pl-api'; +import type { Account as BaseAccount, MediaAttachment, Relationship } from 'pl-api'; import type { EntityStore } from 'pl-fe/entity-store/types'; import type { Account, Group } from 'pl-fe/normalizers'; import type { MinifiedStatus } from 'pl-fe/reducers/statuses'; @@ -49,76 +49,6 @@ const makeGetAccount = () => createSelector([ }; }); -const toServerSideType = (columnType: string): Filter['context'][0] => { - switch (columnType) { - case 'home': - case 'notifications': - case 'public': - case 'thread': - return columnType; - default: - if (columnType.includes('list:')) { - return 'home'; - } else { - return 'public'; // community, account, hashtag - } - } -}; - -type FilterContext = { contextType?: string }; - -const getFilters = (state: RootState, query: FilterContext) => - state.filters.filter((filter) => - (!query?.contextType || filter.context.includes(toServerSideType(query.contextType))) - && (filter.expires_at === null || Date.parse(filter.expires_at) > new Date().getTime()), - ); - -const escapeRegExp = (string: string) => - string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string - -const regexFromFilters = (filters: ImmutableList) => { - if (filters.size === 0) return null; - - return new RegExp(filters.map(filter => - filter.keywords.map(keyword => { - let expr = escapeRegExp(keyword.keyword); - - if (keyword.whole_word) { - if (/^[\w]/.test(expr)) { - expr = `\\b${expr}`; - } - - if (/[\w]$/.test(expr)) { - expr = `${expr}\\b`; - } - } - - return expr; - }).join('|'), - ).join('|'), 'i'); -}; - -const checkFiltered = (index: string, filters: ImmutableList) => - filters.reduce((result: Array, filter) => - result.concat(filter.keywords.reduce((result: Array, keyword) => { - let expr = escapeRegExp(keyword.keyword); - - if (keyword.whole_word) { - if (/^[\w]/.test(expr)) { - expr = `\\b${expr}`; - } - - if (/[\w]$/.test(expr)) { - expr = `${expr}\\b`; - } - } - - const regex = new RegExp(expr); - - if (regex.test(index)) return result.concat(filter.title); - return result; - }, [])), []); - type APIStatus = { id: string; username?: string }; const makeGetStatus = () => createSelector( @@ -133,13 +63,12 @@ const makeGetStatus = () => createSelector( }, (state: RootState, { id }: APIStatus) => state.polls.get(id) || null, (_state: RootState, { username }: APIStatus) => username, - getFilters, (state: RootState) => state.me, (state: RootState) => state.auth.client.features, (state: RootState) => getLocale('en'), ], - (statusBase, statusReblog, statusQuote, statusGroup, poll, username, filters, me, features, locale) => { + (statusBase, statusReblog, statusQuote, statusGroup, poll, username, me, features, locale) => { if (!statusBase) return null; const { account } = statusBase; const accountUsername = account.acct; @@ -149,17 +78,12 @@ const makeGetStatus = () => createSelector( return null; } - const filtered = features.filtersV2 - ? statusBase.filtered - : features.filters && account.id !== me && checkFiltered(statusReblog?.search_index || statusBase.search_index || '', filters) || []; - return { ...statusBase, reblog: statusReblog || null, quote: statusQuote || null, group: statusGroup || null, poll, - filtered, }; // if (map.currentLanguage === null && map.content_map?.size) { // let currentLanguage: string | null = null; @@ -329,9 +253,6 @@ export { selectAccounts, selectOwnAccount, makeGetAccount, - getFilters, - regexFromFilters, - makeGetStatus, type SelectedStatus, type AccountGalleryAttachment, getAccountGallery,