Refactor: replace Immutable.js methods with plain JavaScript equivalents

remove-immutable-compose
danidfra 2024-12-18 17:29:21 -03:00
rodzic aac4798034
commit f892cec183
11 zmienionych plików z 32 dodań i 29 usunięć

Wyświetl plik

@ -2,7 +2,6 @@ import backspaceIcon from '@tabler/icons/outline/backspace.svg';
import searchIcon from '@tabler/icons/outline/search.svg'; import searchIcon from '@tabler/icons/outline/search.svg';
import clsx from 'clsx'; import clsx from 'clsx';
import { throttle } from 'es-toolkit'; import { throttle } from 'es-toolkit';
import { OrderedSet as ImmutableOrderedSet } from 'immutable';
import { useCallback, useEffect, useRef, useState } from 'react'; import { useCallback, useEffect, useRef, useState } from 'react';
import { defineMessages, useIntl } from 'react-intl'; import { defineMessages, useIntl } from 'react-intl';
@ -26,7 +25,7 @@ interface ILocationSearch {
const LocationSearch: React.FC<ILocationSearch> = ({ onSelected }) => { const LocationSearch: React.FC<ILocationSearch> = ({ onSelected }) => {
const intl = useIntl(); const intl = useIntl();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const [locationIds, setLocationIds] = useState(ImmutableOrderedSet<string>()); const [locationIds, setLocationIds] = useState(new Set<string>());
const controller = useRef(new AbortController()); const controller = useRef(new AbortController());
const [value, setValue] = useState(''); const [value, setValue] = useState('');
@ -67,14 +66,14 @@ const LocationSearch: React.FC<ILocationSearch> = ({ onSelected }) => {
}; };
const clearResults = () => { const clearResults = () => {
setLocationIds(ImmutableOrderedSet()); setLocationIds(new Set<string>());
}; };
const handleLocationSearch = useCallback(throttle(q => { const handleLocationSearch = useCallback(throttle(q => {
dispatch(locationSearch(q, controller.current.signal)) dispatch(locationSearch(q, controller.current.signal))
.then((locations: { origin_id: string }[]) => { .then((locations: { origin_id: string }[]) => {
const locationIds = locations.map(location => location.origin_id); const locationIds = locations.map(location => location.origin_id);
setLocationIds(ImmutableOrderedSet(locationIds)); setLocationIds(new Set<string>(locationIds));
}) })
.catch(noOp); .catch(noOp);
@ -93,7 +92,7 @@ const LocationSearch: React.FC<ILocationSearch> = ({ onSelected }) => {
placeholder={intl.formatMessage(messages.placeholder)} placeholder={intl.formatMessage(messages.placeholder)}
value={value} value={value}
onChange={handleChange} onChange={handleChange}
suggestions={locationIds.toList()} suggestions={Array.from(locationIds)}
onSuggestionsFetchRequested={noOp} onSuggestionsFetchRequested={noOp}
onSuggestionsClearRequested={noOp} onSuggestionsClearRequested={noOp}
onSuggestionSelected={handleSelected} onSuggestionSelected={handleSelected}

Wyświetl plik

@ -156,7 +156,7 @@ const PollForm: React.FC<IPollForm> = ({ composeId }) => {
onChange={onChangeOption} onChange={onChangeOption}
onRemove={onRemoveOption} onRemove={onRemoveOption}
maxChars={maxOptionChars} maxChars={maxOptionChars}
numOptions={options.size} numOptions={options.length}
onRemovePoll={onRemovePoll} onRemovePoll={onRemovePoll}
/> />
))} ))}
@ -164,7 +164,7 @@ const PollForm: React.FC<IPollForm> = ({ composeId }) => {
<HStack space={2}> <HStack space={2}>
<div className='w-6' /> <div className='w-6' />
{options.size < maxOptions && ( {options.length < maxOptions && (
<Button <Button
theme='secondary' theme='secondary'
onClick={handleAddOption} onClick={handleAddOption}

Wyświetl plik

@ -1,5 +1,6 @@
import xIcon from '@tabler/icons/outline/x.svg'; import xIcon from '@tabler/icons/outline/x.svg';
import clsx from 'clsx'; import clsx from 'clsx';
import { OrderedSet as ImmutableOrderedSet } from 'immutable';
import { useEffect, useRef } from 'react'; import { useEffect, useRef } from 'react';
import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
@ -21,7 +22,6 @@ import PlaceholderStatus from 'soapbox/features/placeholder/components/placehold
import { useAppDispatch } from 'soapbox/hooks/useAppDispatch.ts'; import { useAppDispatch } from 'soapbox/hooks/useAppDispatch.ts';
import { useAppSelector } from 'soapbox/hooks/useAppSelector.ts'; import { useAppSelector } from 'soapbox/hooks/useAppSelector.ts';
import type { OrderedSet as ImmutableOrderedSet } from 'immutable';
import type { VirtuosoHandle } from 'react-virtuoso'; import type { VirtuosoHandle } from 'react-virtuoso';
import type { SearchFilter } from 'soapbox/reducers/search.ts'; import type { SearchFilter } from 'soapbox/reducers/search.ts';
@ -198,7 +198,7 @@ const SearchResults = () => {
placeholderComponent = PlaceholderHashtag; placeholderComponent = PlaceholderHashtag;
if (results.hashtags && results.hashtags.size > 0) { if (results.hashtags && results.hashtags.size > 0) {
searchResults = results.hashtags.map(hashtag => <Hashtag key={hashtag.name} hashtag={hashtag} />); searchResults = [...results.hashtags].map(hashtag => <Hashtag key={hashtag.name} hashtag={hashtag} />);
} else if (!submitted && suggestions && !suggestions.isEmpty()) { } else if (!submitted && suggestions && !suggestions.isEmpty()) {
searchResults = trends.map(hashtag => <Hashtag key={hashtag.name} hashtag={hashtag} />); searchResults = trends.map(hashtag => <Hashtag key={hashtag.name} hashtag={hashtag} />);
} else if (loaded) { } else if (loaded) {
@ -236,7 +236,11 @@ const SearchResults = () => {
key={selectedFilter} key={selectedFilter}
scrollKey={`${selectedFilter}:${value}`} scrollKey={`${selectedFilter}:${value}`}
isLoading={submitted && !loaded} isLoading={submitted && !loaded}
showLoading={submitted && !loaded && searchResults?.isEmpty()} showLoading={submitted && !loaded && (
!searchResults ||
(Array.isArray(searchResults) && searchResults.length === 0) ||
(ImmutableOrderedSet.isOrderedSet(searchResults) && searchResults.size === 0)
)}
hasMore={hasMore} hasMore={hasMore}
onLoadMore={handleLoadMore} onLoadMore={handleLoadMore}
placeholderComponent={placeholderComponent} placeholderComponent={placeholderComponent}

Wyświetl plik

@ -42,7 +42,7 @@ const UploadForm: React.FC<IUploadForm> = ({ composeId, onSubmit }) => {
<div className='overflow-hidden'> <div className='overflow-hidden'>
<UploadProgress composeId={composeId} /> <UploadProgress composeId={composeId} />
<HStack wrap className={clsx('overflow-hidden', mediaIds.size !== 0 && 'p-1')}> <HStack wrap className={clsx('overflow-hidden', mediaIds.length !== 0 && 'p-1')}>
{mediaIds.map((id: string) => ( {mediaIds.map((id: string) => (
<Upload <Upload
id={id} id={id}

Wyświetl plik

@ -15,7 +15,7 @@ const QuotedStatusContainer: React.FC<IQuotedStatusContainer> = ({ composeId })
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const getStatus = useCallback(makeGetStatus(), []); const getStatus = useCallback(makeGetStatus(), []);
const status = useAppSelector(state => getStatus(state, { id: state.compose.get(composeId)?.quote! })); const status = useAppSelector(state => getStatus(state, { id: state.compose[composeId]?.quote! }));
const onCancel = () => { const onCancel = () => {
dispatch(cancelQuoteCompose()); dispatch(cancelQuoteCompose());

Wyświetl plik

@ -14,8 +14,8 @@ const makeMapStateToProps = () => {
const getStatus = makeGetStatus(); const getStatus = makeGetStatus();
const mapStateToProps = (state: RootState, { composeId }: { composeId: string }) => { const mapStateToProps = (state: RootState, { composeId }: { composeId: string }) => {
const statusId = state.compose.get(composeId)?.in_reply_to!; const statusId = state.compose[composeId]?.in_reply_to!;
const editing = !!state.compose.get(composeId)?.id; const editing = !!state.compose[composeId]?.id;
return { return {
status: (getStatus(state, { id: statusId }) as LegacyStatus)?.toJS() as StatusEntity, status: (getStatus(state, { id: statusId }) as LegacyStatus)?.toJS() as StatusEntity,

Wyświetl plik

@ -8,8 +8,8 @@ import type { IntlShape } from 'react-intl';
import type { AppDispatch, RootState } from 'soapbox/store.ts'; import type { AppDispatch, RootState } from 'soapbox/store.ts';
const mapStateToProps = (state: RootState, { composeId }: { composeId: string }) => ({ const mapStateToProps = (state: RootState, { composeId }: { composeId: string }) => ({
disabled: state.compose.get(composeId)?.is_uploading, disabled: state.compose[composeId]?.is_uploading,
resetFileKey: state.compose.get(composeId)?.resetFileKey!, resetFileKey: state.compose[composeId]?.resetFileKey!,
}); });
const mapDispatchToProps = (dispatch: AppDispatch, { composeId }: { composeId: string }) => ({ const mapDispatchToProps = (dispatch: AppDispatch, { composeId }: { composeId: string }) => ({

Wyświetl plik

@ -94,7 +94,7 @@ const ComposeEditor = forwardRef<LexicalEditor, IComposeEditor>(({
theme, theme,
editorState: dispatch((_, getState) => { editorState: dispatch((_, getState) => {
const state = getState(); const state = getState();
const compose = state.compose.get(composeId); const compose = state.compose[composeId];
if (!compose) return; if (!compose) return;

Wyświetl plik

@ -297,7 +297,7 @@ const AutosuggestPlugin = ({
}; };
const onSelectSuggestion = (index: number) => { const onSelectSuggestion = (index: number) => {
const suggestion = suggestions.get(index) as AutoSuggestion; const suggestion = suggestions[index] as AutoSuggestion;
editor.update(() => { editor.update(() => {
dispatch((dispatch, getState) => { dispatch((dispatch, getState) => {
@ -443,11 +443,11 @@ const AutosuggestPlugin = ({
]); ]);
useEffect(() => { useEffect(() => {
if (suggestions && suggestions.size > 0) setSuggestionsHidden(false); if (suggestions && suggestions.length > 0) setSuggestionsHidden(false);
}, [suggestions]); }, [suggestions]);
useEffect(() => { useEffect(() => {
if (resolution !== null && !suggestionsHidden && !suggestions.isEmpty()) { if (resolution !== null && !suggestionsHidden && suggestions.length > 0) {
const handleClick = (event: MouseEvent) => { const handleClick = (event: MouseEvent) => {
const target = event.target as HTMLElement; const target = event.target as HTMLElement;
@ -459,7 +459,7 @@ const AutosuggestPlugin = ({
return () => document.removeEventListener('click', handleClick); return () => document.removeEventListener('click', handleClick);
} }
}, [resolution, suggestionsHidden, suggestions.isEmpty()]); }, [resolution, suggestionsHidden, suggestions.length === 0]);
useEffect(() => { useEffect(() => {
if (resolution === null) return; if (resolution === null) return;
@ -469,8 +469,8 @@ const AutosuggestPlugin = ({
KEY_ARROW_UP_COMMAND, KEY_ARROW_UP_COMMAND,
(payload) => { (payload) => {
const event = payload; const event = payload;
if (suggestions !== null && suggestions.size && selectedSuggestion !== null) { if (suggestions !== null && suggestions.length && selectedSuggestion !== null) {
const newSelectedSuggestion = selectedSuggestion !== 0 ? selectedSuggestion - 1 : suggestions.size - 1; const newSelectedSuggestion = selectedSuggestion !== 0 ? selectedSuggestion - 1 : suggestions.length - 1;
setSelectedSuggestion(newSelectedSuggestion); setSelectedSuggestion(newSelectedSuggestion);
event.preventDefault(); event.preventDefault();
event.stopImmediatePropagation(); event.stopImmediatePropagation();
@ -483,8 +483,8 @@ const AutosuggestPlugin = ({
KEY_ARROW_DOWN_COMMAND, KEY_ARROW_DOWN_COMMAND,
(payload) => { (payload) => {
const event = payload; const event = payload;
if (suggestions !== null && suggestions.size && selectedSuggestion !== null) { if (suggestions !== null && suggestions.length && selectedSuggestion !== null) {
const newSelectedSuggestion = selectedSuggestion !== suggestions.size - 1 ? selectedSuggestion + 1 : 0; const newSelectedSuggestion = selectedSuggestion !== suggestions.length - 1 ? selectedSuggestion + 1 : 0;
setSelectedSuggestion(newSelectedSuggestion); setSelectedSuggestion(newSelectedSuggestion);
event.preventDefault(); event.preventDefault();
event.stopImmediatePropagation(); event.stopImmediatePropagation();
@ -540,8 +540,8 @@ const AutosuggestPlugin = ({
<div <div
className={clsx({ className={clsx({
'scroll-smooth snap-y snap-always will-change-scroll mt-6 overflow-y-auto max-h-56 relative w-max z-[1000] shadow bg-white dark:bg-gray-900 rounded-lg py-1 space-y-0 dark:ring-2 dark:ring-primary-700 focus:outline-none': true, 'scroll-smooth snap-y snap-always will-change-scroll mt-6 overflow-y-auto max-h-56 relative w-max z-[1000] shadow bg-white dark:bg-gray-900 rounded-lg py-1 space-y-0 dark:ring-2 dark:ring-primary-700 focus:outline-none': true,
hidden: suggestionsHidden || suggestions.isEmpty(), hidden: suggestionsHidden || suggestions.length === 0,
block: !suggestionsHidden && !suggestions.isEmpty(), block: !suggestionsHidden && suggestions.length > 0,
})} })}
> >
{suggestions.map(renderSuggestion)} {suggestions.map(renderSuggestion)}

Wyświetl plik

@ -42,7 +42,7 @@ const GroupTimeline: React.FC<IGroupTimeline> = (props) => {
const composeId = `group:${groupId}`; const composeId = `group:${groupId}`;
const canComposeGroupStatus = !!account && group?.relationship?.member; const canComposeGroupStatus = !!account && group?.relationship?.member;
const groupTimelineVisible = useAppSelector((state) => !!state.compose.get(composeId)?.group_timeline_visible); const groupTimelineVisible = useAppSelector((state) => !!state.compose[composeId]?.group_timeline_visible);
const featuredStatusIds = useAppSelector((state) => getStatusIds(state, { type: `group:${group?.id}:pinned` })); const featuredStatusIds = useAppSelector((state) => getStatusIds(state, { type: `group:${group?.id}:pinned` }));
const { isDragging, isDraggedOver } = useDraggedFiles(composer, (files) => { const { isDragging, isDraggedOver } = useDraggedFiles(composer, (files) => {

Wyświetl plik

@ -29,7 +29,7 @@ const Account: React.FC<IAccount> = ({ composeId, accountId, author }) => {
const compose = useCompose(composeId); const compose = useCompose(composeId);
const { account } = useAccount(accountId); const { account } = useAccount(accountId);
const added = !!account && compose.to?.includes(account.acct); const added = !!account && Array.from(compose.to)?.includes(account.acct);
const onRemove = () => dispatch(removeFromMentions(composeId, accountId)); const onRemove = () => dispatch(removeFromMentions(composeId, accountId));
const onAdd = () => dispatch(addToMentions(composeId, accountId)); const onAdd = () => dispatch(addToMentions(composeId, accountId));