kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
Refactor: replace Immutable.js methods with plain JavaScript equivalents
rodzic
aac4798034
commit
f892cec183
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 }) => ({
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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));
|
||||
|
|
Ładowanie…
Reference in New Issue