sforkowany z mirror/soapbox
Reducers: TypeScript, fixes
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>dnd
rodzic
5bb26c9b47
commit
41a2b1f08f
|
@ -249,7 +249,7 @@ export interface IDropdown extends RouteComponentProps {
|
|||
) => void,
|
||||
onClose?: (id: number) => void,
|
||||
dropdownPlacement?: string,
|
||||
openDropdownId?: number,
|
||||
openDropdownId?: number | null,
|
||||
openedViaKeyboard?: boolean,
|
||||
text?: string,
|
||||
onShiftClick?: React.EventHandler<React.MouseEvent | React.KeyboardEvent>,
|
||||
|
|
|
@ -7,8 +7,6 @@ import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
|||
|
||||
import Column from '../ui/components/column';
|
||||
|
||||
import type { Map as ImmutableMap } from 'immutable';
|
||||
|
||||
const messages = defineMessages({
|
||||
heading: { id: 'column.admin.moderation_log', defaultMessage: 'Moderation Log' },
|
||||
emptyMessage: { id: 'admin.moderation_log.empty_message', defaultMessage: 'You have not performed any moderation actions yet. When you do, a history will be shown here.' },
|
||||
|
@ -18,8 +16,10 @@ const ModerationLog = () => {
|
|||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const items = useAppSelector((state) => state.admin_log.get('index').map((i: number) => state.admin_log.getIn(['items', String(i)]))) as ImmutableMap<string, any>;
|
||||
const hasMore = useAppSelector((state) => state.admin_log.get('total', 0) - state.admin_log.get('index').count() > 0);
|
||||
const items = useAppSelector((state) => {
|
||||
return state.admin_log.index.map((i) => state.admin_log.items.get(String(i)));
|
||||
});
|
||||
const hasMore = useAppSelector((state) => state.admin_log.total - state.admin_log.index.count() > 0);
|
||||
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [lastPage, setLastPage] = useState(0);
|
||||
|
@ -56,12 +56,12 @@ const ModerationLog = () => {
|
|||
hasMore={hasMore}
|
||||
onLoadMore={handleLoadMore}
|
||||
>
|
||||
{items.map((item, i) => (
|
||||
<div className='logentry' key={i}>
|
||||
<div className='logentry__message'>{item.get('message')}</div>
|
||||
{items.map((item) => item && (
|
||||
<div className='logentry' key={item.id}>
|
||||
<div className='logentry__message'>{item.message}</div>
|
||||
<div className='logentry__timestamp'>
|
||||
<FormattedDate
|
||||
value={new Date(item.get('time') * 1000)}
|
||||
value={new Date(item.time * 1000)}
|
||||
hour12={false}
|
||||
year='numeric'
|
||||
month='short'
|
||||
|
|
|
@ -20,9 +20,9 @@ const Bookmarks: React.FC = () => {
|
|||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const statusIds = useAppSelector((state) => state.status_lists.getIn(['bookmarks', 'items']));
|
||||
const isLoading = useAppSelector((state) => state.status_lists.getIn(['bookmarks', 'isLoading'], true));
|
||||
const hasMore = useAppSelector((state) => !!state.status_lists.getIn(['bookmarks', 'next']));
|
||||
const statusIds = useAppSelector((state) => state.status_lists.get('bookmarks')!.items);
|
||||
const isLoading = useAppSelector((state) => state.status_lists.get('bookmarks')!.isLoading);
|
||||
const hasMore = useAppSelector((state) => !!state.status_lists.get('bookmarks')!.next);
|
||||
|
||||
React.useEffect(() => {
|
||||
dispatch(fetchBookmarkedStatuses());
|
||||
|
@ -43,7 +43,7 @@ const Bookmarks: React.FC = () => {
|
|||
statusIds={statusIds}
|
||||
scrollKey='bookmarked_statuses'
|
||||
hasMore={hasMore}
|
||||
isLoading={isLoading}
|
||||
isLoading={typeof isLoading === 'boolean' ? isLoading : true}
|
||||
onLoadMore={() => handleLoadMore(dispatch)}
|
||||
onRefresh={handleRefresh}
|
||||
emptyMessage={emptyMessage}
|
||||
|
|
|
@ -32,9 +32,9 @@ const mapStateToProps = (state, { params }) => {
|
|||
if (isMyAccount) {
|
||||
return {
|
||||
isMyAccount,
|
||||
statusIds: state.getIn(['status_lists', 'favourites', 'items']),
|
||||
isLoading: state.getIn(['status_lists', 'favourites', 'isLoading'], true),
|
||||
hasMore: !!state.getIn(['status_lists', 'favourites', 'next']),
|
||||
statusIds: state.status_lists.get('favourites').items,
|
||||
isLoading: state.status_lists.get('favourites').isLoading,
|
||||
hasMore: !!state.status_lists.get('favourites').next,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -57,9 +57,9 @@ const mapStateToProps = (state, { params }) => {
|
|||
unavailable,
|
||||
username,
|
||||
isAccount: !!state.getIn(['accounts', accountId]),
|
||||
statusIds: state.getIn(['status_lists', `favourites:${accountId}`, 'items'], []),
|
||||
isLoading: state.getIn(['status_lists', `favourites:${accountId}`, 'isLoading'], true),
|
||||
hasMore: !!state.getIn(['status_lists', `favourites:${accountId}`, 'next']),
|
||||
statusIds: state.status_lists.get(`favourites:${accountId}`)?.items || [],
|
||||
isLoading: state.status_lists.get(`favourites:${accountId}`)?.isLoading,
|
||||
hasMore: !!state.status_lists.get(`favourites:${accountId}`)?.next,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -147,7 +147,7 @@ class Favourites extends ImmutablePureComponent {
|
|||
statusIds={statusIds}
|
||||
scrollKey='favourited_statuses'
|
||||
hasMore={hasMore}
|
||||
isLoading={isLoading}
|
||||
isLoading={typeof isLoading === 'boolean' ? isLoading : true}
|
||||
onLoadMore={this.handleLoadMore}
|
||||
emptyMessage={emptyMessage}
|
||||
/>
|
||||
|
|
|
@ -11,8 +11,8 @@ import Account from './account';
|
|||
const FollowRecommendationsList: React.FC = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const suggestions = useAppSelector((state) => state.suggestions.get('items'));
|
||||
const isLoading = useAppSelector((state) => state.suggestions.get('isLoading'));
|
||||
const suggestions = useAppSelector((state) => state.suggestions.items);
|
||||
const isLoading = useAppSelector((state) => state.suggestions.isLoading);
|
||||
|
||||
useEffect(() => {
|
||||
if (suggestions.size === 0) {
|
||||
|
@ -30,8 +30,8 @@ const FollowRecommendationsList: React.FC = () => {
|
|||
|
||||
return (
|
||||
<div className='column-list'>
|
||||
{suggestions.size > 0 ? suggestions.map((suggestion: { account: string }, idx: number) => (
|
||||
<Account key={idx} id={suggestion.account} />
|
||||
{suggestions.size > 0 ? suggestions.map((suggestion) => (
|
||||
<Account key={suggestion.account} id={suggestion.account} />
|
||||
)) : (
|
||||
<div className='column-list__empty-message'>
|
||||
<FormattedMessage id='empty_column.follow_recommendations' defaultMessage='Looks like no suggestions could be generated for you. You can try using search to look for people you might know or explore trending hashtags.' />
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { Map as ImmutableMap } from 'immutable';
|
||||
import debounce from 'lodash/debounce';
|
||||
import * as React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
@ -13,9 +12,9 @@ import { useAppSelector } from 'soapbox/hooks';
|
|||
const SuggestedAccountsStep = ({ onNext }: { onNext: () => void }) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const suggestions = useAppSelector((state) => state.suggestions.get('items'));
|
||||
const hasMore = useAppSelector((state) => !!state.suggestions.get('next'));
|
||||
const isLoading = useAppSelector((state) => state.suggestions.get('isLoading'));
|
||||
const suggestions = useAppSelector((state) => state.suggestions.items);
|
||||
const hasMore = useAppSelector((state) => !!state.suggestions.next);
|
||||
const isLoading = useAppSelector((state) => state.suggestions.isLoading);
|
||||
|
||||
const handleLoadMore = debounce(() => {
|
||||
if (isLoading) {
|
||||
|
@ -40,11 +39,11 @@ const SuggestedAccountsStep = ({ onNext }: { onNext: () => void }) => {
|
|||
useWindowScroll={false}
|
||||
style={{ height: 320 }}
|
||||
>
|
||||
{suggestions.map((suggestion: ImmutableMap<string, any>) => (
|
||||
<div key={suggestion.get('account')} className='py-2'>
|
||||
{suggestions.map((suggestion) => (
|
||||
<div key={suggestion.account} className='py-2'>
|
||||
<AccountContainer
|
||||
// @ts-ignore: TS thinks `id` is passed to <Account>, but it isn't
|
||||
id={suggestion.get('account')}
|
||||
id={suggestion.account}
|
||||
showProfileHoverCard={false}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -21,8 +21,8 @@ const mapStateToProps = (state, { params }) => {
|
|||
const meUsername = state.getIn(['accounts', me, 'username'], '');
|
||||
return {
|
||||
isMyAccount: (username.toLowerCase() === meUsername.toLowerCase()),
|
||||
statusIds: state.getIn(['status_lists', 'pins', 'items']),
|
||||
hasMore: !!state.getIn(['status_lists', 'pins', 'next']),
|
||||
statusIds: state.status_lists.get('pins').items,
|
||||
hasMore: !!state.status_lists.get('pins').next,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ const ScheduledStatuses = () => {
|
|||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const statusIds = useAppSelector((state) => state.status_lists.getIn(['scheduled_statuses', 'items']));
|
||||
const isLoading = useAppSelector((state) => state.status_lists.getIn(['scheduled_statuses', 'isLoading']));
|
||||
const hasMore = useAppSelector((state) => !!state.status_lists.getIn(['scheduled_statuses', 'next']));
|
||||
const statusIds = useAppSelector((state) => state.status_lists.get('scheduled_statuses')!.items);
|
||||
const isLoading = useAppSelector((state) => state.status_lists.get('scheduled_statuses')!.isLoading);
|
||||
const hasMore = useAppSelector((state) => !!state.status_lists.get('scheduled_statuses')!.next);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchScheduledStatuses());
|
||||
|
@ -37,7 +37,7 @@ const ScheduledStatuses = () => {
|
|||
<ScrollableList
|
||||
scrollKey='scheduled_statuses'
|
||||
hasMore={hasMore}
|
||||
isLoading={isLoading}
|
||||
isLoading={typeof isLoading === 'boolean' ? isLoading : true}
|
||||
onLoadMore={() => handleLoadMore(dispatch)}
|
||||
emptyMessage={emptyMessage}
|
||||
>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Map as ImmutableMap, fromJS } from 'immutable';
|
||||
import { Map as ImmutableMap, OrderedSet as ImmutableOrderedSet } from 'immutable';
|
||||
import React from 'react';
|
||||
|
||||
import { render, screen } from '../../../../jest/test-helpers';
|
||||
|
@ -16,12 +16,12 @@ describe('<WhoToFollow />', () => {
|
|||
avatar: 'test.jpg',
|
||||
}),
|
||||
}),
|
||||
suggestions: ImmutableMap({
|
||||
items: fromJS([{
|
||||
suggestions: {
|
||||
items: ImmutableOrderedSet([{
|
||||
source: 'staff',
|
||||
account: '1',
|
||||
}]),
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
render(<WhoToFollowPanel limit={1} />, null, store);
|
||||
|
@ -44,8 +44,8 @@ describe('<WhoToFollow />', () => {
|
|||
avatar: 'test.jpg',
|
||||
}),
|
||||
}),
|
||||
suggestions: ImmutableMap({
|
||||
items: fromJS([
|
||||
suggestions: {
|
||||
items: ImmutableOrderedSet([
|
||||
{
|
||||
source: 'staff',
|
||||
account: '1',
|
||||
|
@ -55,7 +55,7 @@ describe('<WhoToFollow />', () => {
|
|||
account: '2',
|
||||
},
|
||||
]),
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
render(<WhoToFollowPanel limit={3} />, null, store);
|
||||
|
@ -78,8 +78,8 @@ describe('<WhoToFollow />', () => {
|
|||
avatar: 'test.jpg',
|
||||
}),
|
||||
}),
|
||||
suggestions: ImmutableMap({
|
||||
items: fromJS([
|
||||
suggestions: {
|
||||
items: ImmutableOrderedSet([
|
||||
{
|
||||
source: 'staff',
|
||||
account: '1',
|
||||
|
@ -89,7 +89,7 @@ describe('<WhoToFollow />', () => {
|
|||
account: '2',
|
||||
},
|
||||
]),
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
render(<WhoToFollowPanel limit={1} />, null, store);
|
||||
|
@ -112,9 +112,9 @@ describe('<WhoToFollow />', () => {
|
|||
avatar: 'test.jpg',
|
||||
}),
|
||||
}),
|
||||
suggestions: ImmutableMap({
|
||||
items: fromJS([]),
|
||||
}),
|
||||
suggestions: {
|
||||
items: ImmutableOrderedSet([]),
|
||||
},
|
||||
};
|
||||
|
||||
render(<WhoToFollowPanel limit={1} />, null, store);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { Map as ImmutableMap } from 'immutable';
|
||||
import * as React from 'react';
|
||||
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { fetchSuggestions, dismissSuggestion } from 'soapbox/actions/suggestions';
|
||||
|
@ -8,6 +7,8 @@ import { Widget } from 'soapbox/components/ui';
|
|||
import AccountContainer from 'soapbox/containers/account_container';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
|
||||
import type { Account as AccountEntity } from 'soapbox/types/entities';
|
||||
|
||||
const messages = defineMessages({
|
||||
dismissSuggestion: { id: 'suggestions.dismiss', defaultMessage: 'Dismiss suggestion' },
|
||||
});
|
||||
|
@ -20,11 +21,11 @@ const WhoToFollowPanel = ({ limit }: IWhoToFollowPanel) => {
|
|||
const dispatch = useDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const suggestions = useAppSelector((state) => state.suggestions.get('items'));
|
||||
const suggestions = useAppSelector((state) => state.suggestions.items);
|
||||
const suggestionsToRender = suggestions.slice(0, limit);
|
||||
|
||||
const handleDismiss = (account: ImmutableMap<string, any>) => {
|
||||
dispatch(dismissSuggestion(account.get('id')));
|
||||
const handleDismiss = (account: AccountEntity) => {
|
||||
dispatch(dismissSuggestion(account.id));
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
|
@ -45,11 +46,11 @@ const WhoToFollowPanel = ({ limit }: IWhoToFollowPanel) => {
|
|||
title={<FormattedMessage id='who_to_follow.title' defaultMessage='People To Follow' />}
|
||||
// onAction={handleAction}
|
||||
>
|
||||
{suggestionsToRender.map((suggestion: ImmutableMap<string, any>) => (
|
||||
{suggestionsToRender.map((suggestion) => (
|
||||
<AccountContainer
|
||||
key={suggestion.get('account')}
|
||||
key={suggestion.account}
|
||||
// @ts-ignore: TS thinks `id` is passed to <Account>, but it isn't
|
||||
id={suggestion.get('account')}
|
||||
id={suggestion.account}
|
||||
actionIcon={require('@tabler/icons/icons/x.svg')}
|
||||
actionTitle={intl.formatMessage(messages.dismissSuggestion)}
|
||||
onActionClick={handleDismiss}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
import { Map as ImmutableMap, OrderedSet as ImmutableOrderedSet } from 'immutable';
|
||||
|
||||
import reducer from '../status_lists';
|
||||
|
||||
describe('status_lists reducer', () => {
|
||||
it('should return the initial state', () => {
|
||||
expect(reducer(undefined, {})).toEqual(ImmutableMap({
|
||||
favourites: ImmutableMap({
|
||||
next: null,
|
||||
loaded: false,
|
||||
items: ImmutableOrderedSet(),
|
||||
}),
|
||||
bookmarks: ImmutableMap({
|
||||
next: null,
|
||||
loaded: false,
|
||||
items: ImmutableOrderedSet(),
|
||||
}),
|
||||
pins: ImmutableMap({
|
||||
next: null,
|
||||
loaded: false,
|
||||
items: ImmutableOrderedSet(),
|
||||
}),
|
||||
scheduled_statuses: ImmutableMap({
|
||||
next: null,
|
||||
loaded: false,
|
||||
items: ImmutableOrderedSet(),
|
||||
}),
|
||||
}));
|
||||
});
|
||||
});
|
|
@ -0,0 +1,32 @@
|
|||
import reducer from '../status_lists';
|
||||
|
||||
describe('status_lists reducer', () => {
|
||||
it('should return the initial state', () => {
|
||||
expect(reducer(undefined, {} as any).toJS()).toEqual({
|
||||
favourites: {
|
||||
next: null,
|
||||
loaded: false,
|
||||
isLoading: null,
|
||||
items: [],
|
||||
},
|
||||
bookmarks: {
|
||||
next: null,
|
||||
loaded: false,
|
||||
isLoading: null,
|
||||
items: [],
|
||||
},
|
||||
pins: {
|
||||
next: null,
|
||||
loaded: false,
|
||||
isLoading: null,
|
||||
items: [],
|
||||
},
|
||||
scheduled_statuses: {
|
||||
next: null,
|
||||
loaded: false,
|
||||
isLoading: null,
|
||||
items: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
|
@ -2,30 +2,37 @@ import {
|
|||
Map as ImmutableMap,
|
||||
Record as ImmutableRecord,
|
||||
OrderedSet as ImmutableOrderedSet,
|
||||
fromJS,
|
||||
} from 'immutable';
|
||||
|
||||
import { ADMIN_LOG_FETCH_SUCCESS } from 'soapbox/actions/admin';
|
||||
|
||||
import type { AnyAction } from 'redux';
|
||||
|
||||
const LogEntryRecord = ImmutableRecord({
|
||||
data: ImmutableMap<string, any>(),
|
||||
id: 0,
|
||||
message: '',
|
||||
time: 0,
|
||||
});
|
||||
|
||||
const ReducerRecord = ImmutableRecord({
|
||||
items: ImmutableMap(),
|
||||
index: ImmutableOrderedSet(),
|
||||
items: ImmutableMap<string, LogEntry>(),
|
||||
index: ImmutableOrderedSet<number>(),
|
||||
total: 0,
|
||||
});
|
||||
|
||||
type LogEntry = ReturnType<typeof LogEntryRecord>;
|
||||
type State = ReturnType<typeof ReducerRecord>;
|
||||
type APIEntity = Record<string, any>;
|
||||
type APIEntities = Array<APIEntity>;
|
||||
|
||||
const parseItems = (items: APIEntities) => {
|
||||
const ids: Array<number> = [];
|
||||
const map: Record<number, any> = {};
|
||||
const map: Record<string, LogEntry> = {};
|
||||
|
||||
items.forEach(item => {
|
||||
ids.push(item.id);
|
||||
map[item.id] = item;
|
||||
map[item.id] = LogEntryRecord(item);
|
||||
});
|
||||
|
||||
return { ids: ids, map: map };
|
||||
|
@ -36,7 +43,7 @@ const importItems = (state: State, items: APIEntities, total: number) => {
|
|||
|
||||
return state.withMutations(state => {
|
||||
state.update('index', v => v.union(ids));
|
||||
state.update('items', v => v.merge(fromJS(map)));
|
||||
state.update('items', v => v.merge(map));
|
||||
state.set('total', total);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -6,10 +6,11 @@ import {
|
|||
} from '../actions/dropdown_menu';
|
||||
|
||||
import type { AnyAction } from 'redux';
|
||||
import type { DropdownPlacement } from 'soapbox/components/dropdown_menu';
|
||||
|
||||
const ReducerRecord = ImmutableRecord({
|
||||
openId: null as number | null,
|
||||
placement: null as 'top' | 'bottom' | null,
|
||||
placement: null as any as DropdownPlacement,
|
||||
keyboard: false,
|
||||
});
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import { Map as ImmutableMap, OrderedSet as ImmutableOrderedSet } from 'immutable';
|
||||
import {
|
||||
Map as ImmutableMap,
|
||||
OrderedSet as ImmutableOrderedSet,
|
||||
Record as ImmutableRecord,
|
||||
} from 'immutable';
|
||||
|
||||
import {
|
||||
BOOKMARKED_STATUSES_FETCH_REQUEST,
|
||||
|
@ -44,29 +48,38 @@ import {
|
|||
SCHEDULED_STATUS_CANCEL_SUCCESS,
|
||||
} from '../actions/scheduled_statuses';
|
||||
|
||||
const initialMap = ImmutableMap({
|
||||
next: null,
|
||||
import type { AnyAction } from 'redux';
|
||||
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||
|
||||
const StatusListRecord = ImmutableRecord({
|
||||
next: null as string | null,
|
||||
loaded: false,
|
||||
items: ImmutableOrderedSet(),
|
||||
isLoading: null as boolean | null,
|
||||
items: ImmutableOrderedSet<string>(),
|
||||
});
|
||||
|
||||
const initialState = ImmutableMap({
|
||||
favourites: initialMap,
|
||||
bookmarks: initialMap,
|
||||
pins: initialMap,
|
||||
scheduled_statuses: initialMap,
|
||||
type State = ImmutableMap<string, StatusList>;
|
||||
type StatusList = ReturnType<typeof StatusListRecord>;
|
||||
type Status = string | StatusEntity;
|
||||
type Statuses = Array<string | StatusEntity>;
|
||||
|
||||
const initialState: State = ImmutableMap({
|
||||
favourites: StatusListRecord(),
|
||||
bookmarks: StatusListRecord(),
|
||||
pins: StatusListRecord(),
|
||||
scheduled_statuses: StatusListRecord(),
|
||||
});
|
||||
|
||||
const getStatusId = status => typeof status === 'string' ? status : status.get('id');
|
||||
const getStatusId = (status: string | StatusEntity) => typeof status === 'string' ? status : status.id;
|
||||
|
||||
const getStatusIds = (statuses = []) => (
|
||||
ImmutableOrderedSet(statuses.map(status => status.id))
|
||||
const getStatusIds = (statuses: Statuses = []) => (
|
||||
ImmutableOrderedSet(statuses.map(getStatusId))
|
||||
);
|
||||
|
||||
const setLoading = (state, listType, loading) => state.setIn([listType, 'isLoading'], loading);
|
||||
const setLoading = (state: State, listType: string, loading: boolean) => state.setIn([listType, 'isLoading'], loading);
|
||||
|
||||
const normalizeList = (state, listType, statuses, next) => {
|
||||
return state.update(listType, initialMap, listMap => listMap.withMutations(map => {
|
||||
const normalizeList = (state: State, listType: string, statuses: Statuses, next: string | null) => {
|
||||
return state.update(listType, StatusListRecord(), listMap => listMap.withMutations(map => {
|
||||
map.set('next', next);
|
||||
map.set('loaded', true);
|
||||
map.set('isLoading', false);
|
||||
|
@ -74,29 +87,29 @@ const normalizeList = (state, listType, statuses, next) => {
|
|||
}));
|
||||
};
|
||||
|
||||
const appendToList = (state, listType, statuses, next) => {
|
||||
const appendToList = (state: State, listType: string, statuses: Statuses, next: string | null) => {
|
||||
const newIds = getStatusIds(statuses);
|
||||
|
||||
return state.update(listType, initialMap, listMap => listMap.withMutations(map => {
|
||||
return state.update(listType, StatusListRecord(), listMap => listMap.withMutations(map => {
|
||||
map.set('next', next);
|
||||
map.set('isLoading', false);
|
||||
map.update('items', ImmutableOrderedSet(), items => items.union(newIds));
|
||||
map.update('items', items => items.union(newIds));
|
||||
}));
|
||||
};
|
||||
|
||||
const prependOneToList = (state, listType, status) => {
|
||||
const prependOneToList = (state: State, listType: string, status: Status) => {
|
||||
const statusId = getStatusId(status);
|
||||
return state.updateIn([listType, 'items'], ImmutableOrderedSet(), items => {
|
||||
return ImmutableOrderedSet([statusId]).union(items);
|
||||
return ImmutableOrderedSet([statusId]).union(items as ImmutableOrderedSet<string>);
|
||||
});
|
||||
};
|
||||
|
||||
const removeOneFromList = (state, listType, status) => {
|
||||
const removeOneFromList = (state: State, listType: string, status: Status) => {
|
||||
const statusId = getStatusId(status);
|
||||
return state.updateIn([listType, 'items'], ImmutableOrderedSet(), items => items.delete(statusId));
|
||||
return state.updateIn([listType, 'items'], ImmutableOrderedSet(), items => (items as ImmutableOrderedSet<string>).delete(statusId));
|
||||
};
|
||||
|
||||
export default function statusLists(state = initialState, action) {
|
||||
export default function statusLists(state = initialState, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case FAVOURITED_STATUSES_FETCH_REQUEST:
|
||||
case FAVOURITED_STATUSES_EXPAND_REQUEST:
|
||||
|
@ -154,7 +167,7 @@ export default function statusLists(state = initialState, action) {
|
|||
return appendToList(state, 'scheduled_statuses', action.statuses, action.next);
|
||||
case SCHEDULED_STATUS_CANCEL_REQUEST:
|
||||
case SCHEDULED_STATUS_CANCEL_SUCCESS:
|
||||
return removeOneFromList(state, 'scheduled_statuses', action.id || action.status.get('id'));
|
||||
return removeOneFromList(state, 'scheduled_statuses', action.id || action.status.id);
|
||||
default:
|
||||
return state;
|
||||
}
|
Ładowanie…
Reference in New Issue