pl-fe: Migrate thread context selectors to createSelector

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2024-10-25 23:47:31 +02:00
parent 0a253894a6
commit d4f930132e
3 changed files with 37 additions and 31 deletions

View file

@ -15,7 +15,7 @@ import { useAppSelector } from 'pl-fe/hooks/useAppSelector';
import { makeGetStatus } from 'pl-fe/selectors';
import ComposeForm from '../compose/components/compose-form';
import { getDescendantsIds } from '../status/components/thread';
import { makeGetDescendantsIds } from '../status/components/thread';
import ThreadStatus from '../status/components/thread-status';
import type { MediaAttachment } from 'pl-api';
@ -33,6 +33,7 @@ const EventDiscussion: React.FC<IEventDiscussion> = ({ params: { statusId: statu
const dispatch = useAppDispatch();
const getStatus = useCallback(makeGetStatus(), []);
const getDescendantsIds = useCallback(makeGetDescendantsIds(), []);
const status = useAppSelector(state => getStatus(state, { id: statusId }));
const me = useAppSelector((state) => state.me);

View file

@ -1,7 +1,7 @@
import { createSelector } from '@reduxjs/toolkit';
import clsx from 'clsx';
import { List as ImmutableList, OrderedSet as ImmutableOrderedSet } from 'immutable';
import React, { useEffect, useRef } from 'react';
import React, { useCallback, useEffect, useRef } from 'react';
import { Helmet } from 'react-helmet-async';
import { useIntl } from 'react-intl';
import { useHistory } from 'react-router-dom';
@ -31,7 +31,7 @@ import type { Account } from 'pl-fe/normalizers/account';
import type { Status } from 'pl-fe/normalizers/status';
import type { SelectedStatus } from 'pl-fe/selectors';
const getAncestorsIds = createSelector([
const makeGetAncestorsIds = () => createSelector([
(_: RootState, statusId: string | undefined) => statusId,
(state: RootState) => state.contexts.inReplyTos,
], (statusId, inReplyTos) => {
@ -46,7 +46,7 @@ const getAncestorsIds = createSelector([
return ancestorsIds;
});
const getDescendantsIds = createSelector([
const makeGetDescendantsIds = () => createSelector([
(_: RootState, statusId: string) => statusId,
(state: RootState) => state.contexts.replies,
], (statusId, contextReplies) => {
@ -77,6 +77,26 @@ const getDescendantsIds = createSelector([
return descendantsIds;
});
const makeGetThread = () => {
const getAncestorsIds = makeGetAncestorsIds();
const getDescendantsIds = makeGetDescendantsIds();
return createSelector([
(state: RootState, statusId: string) => getAncestorsIds(state, state.contexts.inReplyTos.get(statusId)),
(state: RootState, statusId: string) => getDescendantsIds(state, statusId),
(_, statusId: string) => statusId,
],
(ancestorsIds, descendantsIds, statusId) => {
ancestorsIds = ancestorsIds.delete(statusId).subtract(descendantsIds);
descendantsIds = descendantsIds.delete(statusId).subtract(ancestorsIds);
return {
ancestorsIds,
descendantsIds,
};
});
};
interface IThread {
status: SelectedStatus;
withMedia?: boolean;
@ -97,24 +117,9 @@ const Thread: React.FC<IThread> = ({
const { openModal } = useModalsStore();
const { settings } = useSettingsStore();
const { ancestorsIds, descendantsIds } = useAppSelector((state) => {
let ancestorsIds = ImmutableOrderedSet<string>();
let descendantsIds = ImmutableOrderedSet<string>();
const getThread = useCallback(makeGetThread(), []);
if (status) {
const statusId = status.id;
ancestorsIds = getAncestorsIds(state, state.contexts.inReplyTos.get(statusId));
descendantsIds = getDescendantsIds(state, statusId);
ancestorsIds = ancestorsIds.delete(statusId).subtract(descendantsIds);
descendantsIds = descendantsIds.delete(statusId).subtract(ancestorsIds);
}
return {
status,
ancestorsIds,
descendantsIds,
};
});
const { ancestorsIds, descendantsIds } = useAppSelector((state) => getThread(state, status.id));
let initialIndex = ancestorsIds.size;
if (isModal && initialIndex !== 0) initialIndex = ancestorsIds.size + 1;
@ -418,4 +423,4 @@ const Thread: React.FC<IThread> = ({
);
};
export { getDescendantsIds, Thread as default };
export { makeGetDescendantsIds, Thread as default };

View file

@ -235,11 +235,11 @@ const makeGetReport = () => {
return createSelector(
[
(state: RootState, id: string) => state.admin.reports.get(id),
(state: RootState, id: string) => selectAccount(state, state.admin.reports.get(id)?.account_id || ''),
(state: RootState, id: string) => selectAccount(state, state.admin.reports.get(id)?.target_account_id || ''),
(state: RootState, id: string) => state.admin.reports.get(id)!.status_ids
.map((id) => getStatus(state, { id }))
(state: RootState, reportId: string) => state.admin.reports.get(reportId),
(state: RootState, reportId: string) => selectAccount(state, state.admin.reports.get(reportId)?.account_id || ''),
(state: RootState, reportId: string) => selectAccount(state, state.admin.reports.get(reportId)?.target_account_id || ''),
(state: RootState, reportId: string) => state.admin.reports.get(reportId)!.status_ids
.map((statusId) => getStatus(state, { id: statusId }))
.filter((status): status is SelectedStatus => status !== null),
],
(report, account, target_account, statuses) => {
@ -256,12 +256,12 @@ const makeGetReport = () => {
const getAuthUserIds = createSelector(
[(state: RootState) => state.auth.users],
authUsers => authUsers.reduce((ids: ImmutableOrderedSet<string>, authUser) => {
authUsers => authUsers.reduce((userIds: ImmutableOrderedSet<string>, authUser) => {
try {
const id = authUser.id;
return validId(id) ? ids.add(id) : ids;
const userId = authUser.id;
return validId(userId) ? userIds.add(userId) : userIds;
} catch {
return ids;
return userIds;
}
}, ImmutableOrderedSet<string>()));