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

Wyświetl plik

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

Wyświetl plik

@ -1,5 +1,6 @@
import xIcon from '@tabler/icons/outline/x.svg';
import clsx from 'clsx';
import { OrderedSet as ImmutableOrderedSet } from 'immutable';
import { useEffect, useRef } from 'react';
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 { useAppSelector } from 'soapbox/hooks/useAppSelector.ts';
import type { OrderedSet as ImmutableOrderedSet } from 'immutable';
import type { VirtuosoHandle } from 'react-virtuoso';
import type { SearchFilter } from 'soapbox/reducers/search.ts';
@ -198,7 +198,7 @@ const SearchResults = () => {
placeholderComponent = PlaceholderHashtag;
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()) {
searchResults = trends.map(hashtag => <Hashtag key={hashtag.name} hashtag={hashtag} />);
} else if (loaded) {
@ -236,7 +236,11 @@ const SearchResults = () => {
key={selectedFilter}
scrollKey={`${selectedFilter}:${value}`}
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}
onLoadMore={handleLoadMore}
placeholderComponent={placeholderComponent}

Wyświetl plik

@ -42,7 +42,7 @@ const UploadForm: React.FC<IUploadForm> = ({ composeId, onSubmit }) => {
<div className='overflow-hidden'>
<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) => (
<Upload
id={id}

Wyświetl plik

@ -15,7 +15,7 @@ const QuotedStatusContainer: React.FC<IQuotedStatusContainer> = ({ composeId })
const dispatch = useAppDispatch();
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 = () => {
dispatch(cancelQuoteCompose());

Wyświetl plik

@ -14,8 +14,8 @@ const makeMapStateToProps = () => {
const getStatus = makeGetStatus();
const mapStateToProps = (state: RootState, { composeId }: { composeId: string }) => {
const statusId = state.compose.get(composeId)?.in_reply_to!;
const editing = !!state.compose.get(composeId)?.id;
const statusId = state.compose[composeId]?.in_reply_to!;
const editing = !!state.compose[composeId]?.id;
return {
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';
const mapStateToProps = (state: RootState, { composeId }: { composeId: string }) => ({
disabled: state.compose.get(composeId)?.is_uploading,
resetFileKey: state.compose.get(composeId)?.resetFileKey!,
disabled: state.compose[composeId]?.is_uploading,
resetFileKey: state.compose[composeId]?.resetFileKey!,
});
const mapDispatchToProps = (dispatch: AppDispatch, { composeId }: { composeId: string }) => ({

Wyświetl plik

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

Wyświetl plik

@ -297,7 +297,7 @@ const AutosuggestPlugin = ({
};
const onSelectSuggestion = (index: number) => {
const suggestion = suggestions.get(index) as AutoSuggestion;
const suggestion = suggestions[index] as AutoSuggestion;
editor.update(() => {
dispatch((dispatch, getState) => {
@ -443,11 +443,11 @@ const AutosuggestPlugin = ({
]);
useEffect(() => {
if (suggestions && suggestions.size > 0) setSuggestionsHidden(false);
if (suggestions && suggestions.length > 0) setSuggestionsHidden(false);
}, [suggestions]);
useEffect(() => {
if (resolution !== null && !suggestionsHidden && !suggestions.isEmpty()) {
if (resolution !== null && !suggestionsHidden && suggestions.length > 0) {
const handleClick = (event: MouseEvent) => {
const target = event.target as HTMLElement;
@ -459,7 +459,7 @@ const AutosuggestPlugin = ({
return () => document.removeEventListener('click', handleClick);
}
}, [resolution, suggestionsHidden, suggestions.isEmpty()]);
}, [resolution, suggestionsHidden, suggestions.length === 0]);
useEffect(() => {
if (resolution === null) return;
@ -469,8 +469,8 @@ const AutosuggestPlugin = ({
KEY_ARROW_UP_COMMAND,
(payload) => {
const event = payload;
if (suggestions !== null && suggestions.size && selectedSuggestion !== null) {
const newSelectedSuggestion = selectedSuggestion !== 0 ? selectedSuggestion - 1 : suggestions.size - 1;
if (suggestions !== null && suggestions.length && selectedSuggestion !== null) {
const newSelectedSuggestion = selectedSuggestion !== 0 ? selectedSuggestion - 1 : suggestions.length - 1;
setSelectedSuggestion(newSelectedSuggestion);
event.preventDefault();
event.stopImmediatePropagation();
@ -483,8 +483,8 @@ const AutosuggestPlugin = ({
KEY_ARROW_DOWN_COMMAND,
(payload) => {
const event = payload;
if (suggestions !== null && suggestions.size && selectedSuggestion !== null) {
const newSelectedSuggestion = selectedSuggestion !== suggestions.size - 1 ? selectedSuggestion + 1 : 0;
if (suggestions !== null && suggestions.length && selectedSuggestion !== null) {
const newSelectedSuggestion = selectedSuggestion !== suggestions.length - 1 ? selectedSuggestion + 1 : 0;
setSelectedSuggestion(newSelectedSuggestion);
event.preventDefault();
event.stopImmediatePropagation();
@ -540,8 +540,8 @@ const AutosuggestPlugin = ({
<div
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,
hidden: suggestionsHidden || suggestions.isEmpty(),
block: !suggestionsHidden && !suggestions.isEmpty(),
hidden: suggestionsHidden || suggestions.length === 0,
block: !suggestionsHidden && suggestions.length > 0,
})}
>
{suggestions.map(renderSuggestion)}

Wyświetl plik

@ -42,7 +42,7 @@ const GroupTimeline: React.FC<IGroupTimeline> = (props) => {
const composeId = `group:${groupId}`;
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 { 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 { 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 onAdd = () => dispatch(addToMentions(composeId, accountId));