Changeset View
Changeset View
Standalone View
Standalone View
web/selectors/thread-selectors.js
// @flow | // @flow | ||||
import invariant from 'invariant'; | import invariant from 'invariant'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { useDispatch } from 'react-redux'; | import { useDispatch } from 'react-redux'; | ||||
import { createSelector } from 'reselect'; | |||||
import { ENSCacheContext } from 'lib/components/ens-cache-provider.react'; | import { ENSCacheContext } from 'lib/components/ens-cache-provider.react'; | ||||
import { threadInfoSelector } from 'lib/selectors/thread-selectors'; | |||||
import { createPendingSidebar } from 'lib/shared/thread-utils'; | import { createPendingSidebar } from 'lib/shared/thread-utils'; | ||||
import type { | import type { | ||||
ComposableMessageInfo, | ComposableMessageInfo, | ||||
RobotextMessageInfo, | RobotextMessageInfo, | ||||
} from 'lib/types/message-types'; | } from 'lib/types/message-types'; | ||||
import type { ThreadInfo } from 'lib/types/thread-types'; | import type { ThreadInfo, RawThreadInfo } from 'lib/types/thread-types'; | ||||
import { values } from 'lib/utils/objects'; | |||||
import { getDefaultTextMessageRules } from '../markdown/rules.react'; | import { getDefaultTextMessageRules } from '../markdown/rules.react'; | ||||
import { updateNavInfoActionType } from '../redux/action-types'; | import { updateNavInfoActionType } from '../redux/action-types'; | ||||
import type { AppState } from '../redux/redux-setup'; | |||||
import { useSelector } from '../redux/redux-utils'; | import { useSelector } from '../redux/redux-utils'; | ||||
function useOnClickThread( | function useOnClickThread( | ||||
thread: ?ThreadInfo, | thread: ?ThreadInfo, | ||||
): (event: SyntheticEvent<HTMLElement>) => void { | ): (event: SyntheticEvent<HTMLElement>) => void { | ||||
const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
return React.useCallback( | return React.useCallback( | ||||
(event: SyntheticEvent<HTMLElement>) => { | (event: SyntheticEvent<HTMLElement>) => { | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | (event: SyntheticEvent<HTMLElement>) => { | ||||
selectedUserList: [], | selectedUserList: [], | ||||
}, | }, | ||||
}); | }); | ||||
}, | }, | ||||
[dispatch], | [dispatch], | ||||
); | ); | ||||
} | } | ||||
function filteredCommunityThreadIDs( | |||||
communityID: string, | |||||
threadInfosObj: { +[id: string]: ThreadInfo | RawThreadInfo }, | |||||
): $ReadOnlySet<string> { | |||||
const threadInfos = values(threadInfosObj); | |||||
const threadIDs = threadInfos | |||||
.filter( | |||||
thread => thread.community === communityID || thread.id === communityID, | |||||
) | |||||
.map(item => item.id); | |||||
return new Set(threadIDs); | |||||
} | |||||
const filteredCommunityThreadIDsSelector: ( | |||||
state: AppState, | |||||
) => ?$ReadOnlySet<string> = createSelector( | |||||
(state: AppState) => state.communityIDFilter, | |||||
threadInfoSelector, | |||||
( | |||||
communityIDFilter: ?string, | |||||
threadInfos: { +[id: string]: ThreadInfo }, | |||||
): ?$ReadOnlySet<string> => { | |||||
kamil: This type could be skipped since it's obvious this will be the same as the return type of the… | |||||
if (!communityIDFilter) { | |||||
return null; | |||||
} | |||||
return filteredCommunityThreadIDs(communityIDFilter, threadInfos); | |||||
}, | |||||
); | |||||
export { | export { | ||||
useOnClickThread, | useOnClickThread, | ||||
useThreadIsActive, | useThreadIsActive, | ||||
useOnClickPendingSidebar, | useOnClickPendingSidebar, | ||||
useOnClickNewThread, | useOnClickNewThread, | ||||
filteredCommunityThreadIDsSelector, | |||||
filteredCommunityThreadIDs, | |||||
}; | }; |
This type could be skipped since it's obvious this will be the same as the return type of the entire selector but I saw in codebase versions with/without type in last callback so deffering to you