pl-fe: migrate bookmarks to react query

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
nicole mikołajczyk
2025-06-26 11:13:23 +02:00
parent 16e2b5c3fc
commit 6faf7f48a3
10 changed files with 138 additions and 169 deletions

View File

@@ -3986,7 +3986,6 @@ class PlApiClient {
response = await this.request(`/api/v1/admin/accounts/${accountId}/enable`, { method: 'POST' });
} else {
const account = await this.admin.accounts.getAccount(accountId)!;
console.log(account);
response = await this.request('/api/v1/pleroma/admin/users/activate', { method: 'PATCH', body: { nicknames: [account.username] } });
response.json = response.json?.users?.[0];
}

View File

@@ -1,7 +1,3 @@
import { defineMessages } from 'react-intl';
import { useModalsStore } from 'pl-fe/stores/modals';
import toast, { type IToastOptions } from 'pl-fe/toast';
import { isLoggedIn } from 'pl-fe/utils/auth';
import { getClient } from '../api';
@@ -31,18 +27,6 @@ const PIN_SUCCESS = 'PIN_SUCCESS' as const;
const UNPIN_SUCCESS = 'UNPIN_SUCCESS' as const;
const BOOKMARK_SUCCESS = 'BOOKMARKED_SUCCESS' as const;
const UNBOOKMARK_SUCCESS = 'UNBOOKMARKED_SUCCESS' as const;
const messages = defineMessages({
bookmarkAdded: { id: 'status.bookmarked', defaultMessage: 'Bookmark added.' },
bookmarkRemoved: { id: 'status.unbookmarked', defaultMessage: 'Bookmark removed.' },
folderChanged: { id: 'status.bookmark_folder_changed', defaultMessage: 'Changed folder' },
view: { id: 'toast.view', defaultMessage: 'View' },
selectFolder: { id: 'status.bookmark.select_folder', defaultMessage: 'Select folder' },
});
interface ReblogRequest {
type: typeof REBLOG_REQUEST;
statusId: string;
@@ -97,63 +81,6 @@ interface UndislikeRequest {
statusId: string;
}
const bookmark = (status: Pick<Status, 'id'>, folderId?: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const features = state.auth.client.features;
return getClient(getState()).statuses.bookmarkStatus(status.id, folderId).then((response) => {
dispatch(importEntities({ statuses: [response] }));
dispatch(bookmarkSuccess(response));
let opts: IToastOptions = {
actionLabel: messages.view,
actionLink: folderId ? `/bookmarks/${folderId}` : '/bookmarks/all',
};
if (features.bookmarkFolders && typeof folderId !== 'string') {
opts = {
actionLabel: messages.selectFolder,
action: () => useModalsStore.getState().openModal('SELECT_BOOKMARK_FOLDER', {
statusId: status.id,
}),
};
}
toast.success(typeof folderId === 'string' ? messages.folderChanged : messages.bookmarkAdded, opts);
});
};
const unbookmark = (status: Pick<Status, 'id'>) =>
(dispatch: AppDispatch, getState: () => RootState) =>
getClient(getState).statuses.unbookmarkStatus(status.id).then(response => {
dispatch(importEntities({ statuses: [response] }));
dispatch(unbookmarkSuccess(response));
toast.success(messages.bookmarkRemoved);
});
const toggleBookmark = (status: Pick<Status, 'id' | 'bookmarked'>) =>
(dispatch: AppDispatch) => {
if (status.bookmarked) {
dispatch(unbookmark(status));
} else {
dispatch(bookmark(status));
}
};
const bookmarkSuccess = (status: Status) => ({
type: BOOKMARK_SUCCESS,
status,
statusId: status.id,
});
const unbookmarkSuccess = (status: Status) => ({
type: UNBOOKMARK_SUCCESS,
status,
statusId: status.id,
});
const pin = (status: Pick<Status, 'id'>, accountId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return;
@@ -202,10 +129,6 @@ const unpinSuccess = (status: Status, accountId: string) => ({
accountId,
});
const remoteInteraction = (ap_id: string, profile: string) =>
(dispatch: AppDispatch, getState: () => RootState) =>
getClient(getState).accounts.remoteInteraction(ap_id, profile).then((data) => data.url);
type InteractionsAction =
| ReblogRequest
| ReblogFail
@@ -217,8 +140,6 @@ type InteractionsAction =
| DislikeRequest
| DislikeFail
| UndislikeRequest
| ReturnType<typeof bookmarkSuccess>
| ReturnType<typeof unbookmarkSuccess>
| ReturnType<typeof pinSuccess>
| ReturnType<typeof unpinSuccess>
@@ -235,11 +156,6 @@ export {
UNDISLIKE_REQUEST,
PIN_SUCCESS,
UNPIN_SUCCESS,
BOOKMARK_SUCCESS,
UNBOOKMARK_SUCCESS,
bookmark,
toggleBookmark,
togglePin,
remoteInteraction,
type InteractionsAction,
};

View File

@@ -6,7 +6,7 @@ import { useHistory, useRouteMatch } from 'react-router-dom';
import { blockAccount } from 'pl-fe/actions/accounts';
import { directCompose, mentionCompose, quoteCompose, replyCompose } from 'pl-fe/actions/compose';
import { emojiReact, unEmojiReact } from 'pl-fe/actions/emoji-reacts';
import { toggleBookmark, togglePin } from 'pl-fe/actions/interactions';
import { togglePin } from 'pl-fe/actions/interactions';
import { deleteStatusModal, toggleStatusSensitivityModal } from 'pl-fe/actions/moderation';
import { initReport, ReportableEntities } from 'pl-fe/actions/reports';
import { changeSetting } from 'pl-fe/actions/settings';
@@ -30,7 +30,7 @@ import { useChats } from 'pl-fe/queries/chats';
import { useBlockGroupUserMutation } from 'pl-fe/queries/groups/use-group-blocks';
import { useCustomEmojis } from 'pl-fe/queries/instance/use-custom-emojis';
import { useTranslationLanguages } from 'pl-fe/queries/instance/use-translation-languages';
import { useDislikeStatus, useFavouriteStatus, useReblogStatus, useUndislikeStatus, useUnfavouriteStatus, useUnreblogStatus } from 'pl-fe/queries/statuses/use-status-interactions';
import { useBookmarkStatus, useDislikeStatus, useFavouriteStatus, useReblogStatus, useUnbookmarkStatus, useUndislikeStatus, useUnfavouriteStatus, useUnreblogStatus } from 'pl-fe/queries/statuses/use-status-interactions';
import { useModalsStore } from 'pl-fe/stores/modals';
import { useStatusMetaStore } from 'pl-fe/stores/status-meta';
import toast from 'pl-fe/toast';
@@ -622,6 +622,8 @@ const MenuButton: React.FC<IMenuButton> = ({
const { group } = useGroup((status.group as Group)?.id as string);
const { mutate: blockGroupMember } = useBlockGroupUserMutation(status.group?.id as string, status.account.id);
const { getOrCreateChatByAccountId } = useChats();
const { mutate: bookmarkStatus } = useBookmarkStatus(status.id);
const { mutate: unbookmarkStatus } = useUnbookmarkStatus(status.id);
const { groupRelationship } = useGroupRelationship(status.group_id || undefined);
const features = useFeatures();
@@ -654,7 +656,8 @@ const MenuButton: React.FC<IMenuButton> = ({
const { username, local: localAccount } = status.account;
const handleBookmarkClick: React.EventHandler<React.MouseEvent> = (e) => {
dispatch(toggleBookmark(status));
if (status.bookmarked) unbookmarkStatus();
else bookmarkStatus(undefined);
};
const handleBookmarkFolderClick = () => {
@@ -1099,7 +1102,7 @@ const MenuButton: React.FC<IMenuButton> = ({
}
return menu;
}, [me, targetLanguage, status.muted, status.emoji_reactions.length > 0, status.pinned, status.reblogged]);
}, [me, targetLanguage, status.bookmarked, status.muted, status.emoji_reactions.length > 0, status.pinned, status.reblogged]);
return useMemo(() => (
<DropdownMenu items={menu}>

View File

@@ -5,7 +5,7 @@ import { Link, useHistory } from 'react-router-dom';
import { blockAccount } from 'pl-fe/actions/accounts';
import { directCompose, mentionCompose, quoteCompose } from 'pl-fe/actions/compose';
import { fetchEventIcs } from 'pl-fe/actions/events';
import { toggleBookmark, togglePin } from 'pl-fe/actions/interactions';
import { togglePin } from 'pl-fe/actions/interactions';
import { deleteStatusModal, toggleStatusSensitivityModal } from 'pl-fe/actions/moderation';
import { initReport, ReportableEntities } from 'pl-fe/actions/reports';
import { deleteStatus } from 'pl-fe/actions/statuses';
@@ -24,7 +24,7 @@ import { useFeatures } from 'pl-fe/hooks/use-features';
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
import { useSettings } from 'pl-fe/hooks/use-settings';
import { useChats } from 'pl-fe/queries/chats';
import { useReblogStatus, useUnreblogStatus } from 'pl-fe/queries/statuses/use-status-interactions';
import { useBookmarkStatus, useReblogStatus, useUnbookmarkStatus, useUnreblogStatus } from 'pl-fe/queries/statuses/use-status-interactions';
import { useModalsStore } from 'pl-fe/stores/modals';
import copy from 'pl-fe/utils/copy';
import { download } from 'pl-fe/utils/download';
@@ -92,6 +92,8 @@ const EventHeader: React.FC<IEventHeader> = ({ status }) => {
const { mutate: reblogStatus } = useReblogStatus(status?.id!);
const { mutate: unreblogStatus } = useUnreblogStatus(status?.id!);
const { mutate: bookmarkStatus } = useBookmarkStatus(status?.id!);
const { mutate: unbookmarkStatus } = useUnbookmarkStatus(status?.id!);
if (!status || !status.event) {
return (
@@ -131,7 +133,8 @@ const EventHeader: React.FC<IEventHeader> = ({ status }) => {
};
const handleBookmarkClick = () => {
dispatch(toggleBookmark(status));
if (status.bookmarked) unbookmarkStatus();
else bookmarkStatus(undefined);
};
const handleReblogClick = (visibility?: string) => {

View File

@@ -1,7 +1,6 @@
import React, { useCallback, useState } from 'react';
import { FormattedMessage } from 'react-intl';
import { bookmark } from 'pl-fe/actions/interactions';
import { ListItem } from 'pl-fe/components/list';
import { RadioGroup, RadioItem } from 'pl-fe/components/radio';
import Emoji from 'pl-fe/components/ui/emoji';
@@ -11,11 +10,11 @@ import Modal from 'pl-fe/components/ui/modal';
import Spinner from 'pl-fe/components/ui/spinner';
import Stack from 'pl-fe/components/ui/stack';
import Toggle from 'pl-fe/components/ui/toggle';
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
import { useFeatures } from 'pl-fe/hooks/use-features';
import { NewFolderForm } from 'pl-fe/pages/status-lists/bookmark-folders';
import { useAddBookmarkToFolder, useBookmarkFolders, useRemoveBookmarkFromFolder, useStatusBookmarkFolders } from 'pl-fe/queries/statuses/use-bookmark-folders';
import { useBookmarkStatus } from 'pl-fe/queries/statuses/use-status-interactions';
import { makeGetStatus } from 'pl-fe/selectors';
import type { BaseModalProps } from 'pl-fe/features/ui/components/modal-root';
@@ -27,7 +26,6 @@ interface SelectBookmarkFolderModalProps {
const SelectBookmarkFolderModal: React.FC<SelectBookmarkFolderModalProps & BaseModalProps> = ({ statusId, onClose }) => {
const getStatus = useCallback(makeGetStatus(), []);
const status = useAppSelector(state => getStatus(state, { id: statusId }))!;
const dispatch = useAppDispatch();
const features = useFeatures();
const [selectedFolder, setSelectedFolder] = useState(status.bookmark_folder);
@@ -36,14 +34,15 @@ const SelectBookmarkFolderModal: React.FC<SelectBookmarkFolderModalProps & BaseM
const { data: selectedBookmarkFolders, isPending: fetchingSelectedBookmarkFolders } = useStatusBookmarkFolders(statusId);
const { mutate: addBookmarkToFolder, isPending: addingBookmarkToFolder } = useAddBookmarkToFolder(statusId);
const { mutate: removeBookmarkFromFolder, isPending: removingBookmarkFromFolder } = useRemoveBookmarkFromFolder(statusId);
const { mutate: bookmarkStatus } = useBookmarkStatus(status.id);
const onChange: React.ChangeEventHandler<HTMLInputElement> = e => {
const folderId = e.target.value;
setSelectedFolder(folderId);
dispatch(bookmark(status, folderId)).then(() => {
onClose('SELECT_BOOKMARK_FOLDER');
}).catch(() => {});
bookmarkStatus(folderId, {
onSuccess: () => onClose('SELECT_BOOKMARK_FOLDER'),
});
};
const onClickClose = () => {

View File

@@ -2,15 +2,14 @@ import React, { useState } from 'react';
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
import { useHistory } from 'react-router-dom';
import { remoteInteraction } from 'pl-fe/actions/interactions';
import Button from 'pl-fe/components/ui/button';
import Form from 'pl-fe/components/ui/form';
import Input from 'pl-fe/components/ui/input';
import Modal from 'pl-fe/components/ui/modal';
import Stack from 'pl-fe/components/ui/stack';
import Text from 'pl-fe/components/ui/text';
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
import { useClient } from 'pl-fe/hooks/use-client';
import { useFeatures } from 'pl-fe/hooks/use-features';
import { useInstance } from 'pl-fe/hooks/use-instance';
import { useRegistrationStatus } from 'pl-fe/hooks/use-registration-status';
@@ -39,9 +38,9 @@ interface UnauthorizedModalProps {
const UnauthorizedModal: React.FC<UnauthorizedModalProps & BaseModalProps> = ({ action, onClose, account: accountId, ap_id: apId }) => {
const intl = useIntl();
const history = useHistory();
const dispatch = useAppDispatch();
const instance = useInstance();
const { isOpen } = useRegistrationStatus();
const client = useClient();
const username = useAppSelector(state => selectAccount(state, accountId!)?.display_name);
const features = useFeatures();
@@ -59,8 +58,8 @@ const UnauthorizedModal: React.FC<UnauthorizedModalProps & BaseModalProps> = ({
const onSubmit: React.FormEventHandler = e => {
e.preventDefault();
dispatch(remoteInteraction(apId!, account))
.then(url => {
client.accounts.remoteInteraction(apId!, account)
.then(({ url }) => {
window.open(url, '_new', 'noopener,noreferrer');
onClose('UNAUTHORIZED');
})

View File

@@ -1,17 +1,14 @@
import debounce from 'lodash/debounce';
import React from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { useHistory } from 'react-router-dom';
import { fetchBookmarkedStatuses, expandBookmarkedStatuses } from 'pl-fe/actions/bookmarks';
import DropdownMenu from 'pl-fe/components/dropdown-menu';
import PullToRefresh from 'pl-fe/components/pull-to-refresh';
import StatusList from 'pl-fe/components/status-list';
import Column from 'pl-fe/components/ui/column';
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
import { useIsMobile } from 'pl-fe/hooks/use-is-mobile';
import { useTheme } from 'pl-fe/hooks/use-theme';
import { useBookmarks } from 'pl-fe/queries/status-lists/use-bookmarks';
import { useBookmarkFolder, useDeleteBookmarkFolder } from 'pl-fe/queries/statuses/use-bookmark-folders';
import { useModalsStore } from 'pl-fe/stores/modals';
import toast from 'pl-fe/toast';
@@ -27,10 +24,6 @@ const messages = defineMessages({
deleteFolderFail: { id: 'bookmarks.delete_folder.fail', defaultMessage: 'Failed to delete folder' },
});
const handleLoadMore = debounce((dispatch, folderId) => {
dispatch(expandBookmarkedStatuses(folderId));
}, 300, { leading: true });
interface IBookmarks {
params?: {
id?: string;
@@ -38,7 +31,6 @@ interface IBookmarks {
}
const BookmarksPage: React.FC<IBookmarks> = ({ params }) => {
const dispatch = useAppDispatch();
const intl = useIntl();
const history = useHistory();
const theme = useTheme();
@@ -50,17 +42,9 @@ const BookmarksPage: React.FC<IBookmarks> = ({ params }) => {
const { data: folder } = useBookmarkFolder(folderId);
const { mutate: deleteBookmarkFolder } = useDeleteBookmarkFolder();
const bookmarksKey = folderId ? `bookmarks:${folderId}` : 'bookmarks';
const { data: statusIds = [], isFetching, hasNextPage, fetchNextPage, refetch } = useBookmarks(folderId);
const statusIds = useAppSelector((state) => state.status_lists[bookmarksKey]?.items || []);
const isLoading = useAppSelector((state) => state.status_lists[bookmarksKey]?.isLoading === true);
const hasMore = useAppSelector((state) => !!state.status_lists[bookmarksKey]?.next);
React.useEffect(() => {
dispatch(fetchBookmarkedStatuses(folderId));
}, [folderId]);
const handleRefresh = () => dispatch(fetchBookmarkedStatuses(folderId));
const handleRefresh = () => refetch();
const handleEditFolder = () => {
if (!folderId) return;
@@ -115,9 +99,9 @@ const BookmarksPage: React.FC<IBookmarks> = ({ params }) => {
loadMoreClassName='black:sm:mx-4'
statusIds={statusIds}
scrollKey='bookmarked_statuses'
hasMore={hasMore}
isLoading={typeof isLoading === 'boolean' ? isLoading : true}
onLoadMore={() => handleLoadMore(dispatch, folderId)}
hasMore={hasNextPage}
isLoading={isFetching}
onLoadMore={() => fetchNextPage({ cancelRefetch: false })}
emptyMessage={emptyMessage}
divideType={(theme === 'black' || isMobile) ? 'border' : 'space'}
/>

View File

@@ -0,0 +1,9 @@
import { makePaginatedResponseQuery } from 'pl-fe/queries/utils/make-paginated-response-query';
import { minifyStatusList } from 'pl-fe/queries/utils/minify-list';
const useBookmarks = makePaginatedResponseQuery(
(folderId?: string) => ['statusLists', 'bookmarks', folderId],
(client, [folder_id]) => client.myAccount.getBookmarks({ folder_id }).then(minifyStatusList),
);
export { useBookmarks };

View File

@@ -1,13 +1,26 @@
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { InfiniteData, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { defineMessages } from 'react-intl';
import { importEntities } from 'pl-fe/actions/importer';
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
import { useClient } from 'pl-fe/hooks/use-client';
import { useFeatures } from 'pl-fe/hooks/use-features';
import { makePaginatedResponseQuery } from 'pl-fe/queries/utils/make-paginated-response-query';
import { minifyAccountList } from 'pl-fe/queries/utils/minify-list';
import { useModalsStore } from 'pl-fe/stores/modals';
import toast, { IToastOptions } from 'pl-fe/toast';
import type { PaginatedResponse } from 'pl-api';
import type { InteractionsAction } from 'pl-fe/actions/interactions';
const messages = defineMessages({
bookmarkAdded: { id: 'status.bookmarked', defaultMessage: 'Bookmark added.' },
bookmarkRemoved: { id: 'status.unbookmarked', defaultMessage: 'Bookmark removed.' },
folderChanged: { id: 'status.bookmark_folder_changed', defaultMessage: 'Changed folder' },
view: { id: 'toast.view', defaultMessage: 'View' },
selectFolder: { id: 'status.bookmark.select_folder', defaultMessage: 'Select folder' },
});
const queryKey = {
getDislikedBy: 'statusDislikes',
getFavouritedBy: 'statusFavourites',
@@ -140,6 +153,90 @@ const useUnreblogStatus = (statusId: string) => {
});
};
const useBookmarkStatus = (statusId: string) => {
const client = useClient();
const dispatch = useAppDispatch();
const queryClient = useQueryClient();
const features = useFeatures();
const { openModal } = useModalsStore();
let previouslyBookmarked = false;
let previousFolder: string | null;
return useMutation({
mutationKey: ['statuses', 'bookmark', statusId],
mutationFn: (folderId?: string) => {
dispatch((_, getState) => {
const status = getState().statuses[statusId];
previouslyBookmarked = status?.bookmarked;
previousFolder = status?.bookmark_folder;
});
return client.statuses.bookmarkStatus(statusId, folderId);
},
onSettled: (status, _, folderId) => {
dispatch(importEntities({ statuses: [status] }));
queryClient.invalidateQueries({ queryKey: ['accountsLists', 'statusReblogs', statusId] });
if (previousFolder) {
queryClient.setQueryData<InfiniteData<PaginatedResponse<string>>>(
['statusLists', 'bookmarks', previousFolder],
(data) => data ? {
...data,
pages: data.pages.map(({ items, ...page }) => ({ ...page, items: items.filter((id) => id !== statusId) })),
} : undefined);
}
if (!previouslyBookmarked) {
queryClient.invalidateQueries({ queryKey: ['statusLists', 'bookmarks', undefined] });
}
if (folderId) {
queryClient.invalidateQueries({ queryKey: ['statusLists', 'bookmarks', folderId] });
}
let opts: IToastOptions = {
actionLabel: messages.view,
actionLink: folderId ? `/bookmarks/${folderId}` : '/bookmarks/all',
};
if (features.bookmarkFolders && typeof folderId !== 'string') {
opts = {
actionLabel: messages.selectFolder,
action: () => openModal('SELECT_BOOKMARK_FOLDER', {
statusId,
}),
};
}
toast.success(typeof folderId === 'string' ? messages.folderChanged : messages.bookmarkAdded, opts);
},
});
};
const useUnbookmarkStatus = (statusId: string) => {
const client = useClient();
const dispatch = useAppDispatch();
const queryClient = useQueryClient();
return useMutation({
mutationKey: ['statuses', 'bookmark', statusId],
mutationFn: () => client.statuses.unbookmarkStatus(statusId),
onSettled: (status) => {
dispatch(importEntities({ statuses: [status] }));
queryClient.setQueriesData<InfiniteData<PaginatedResponse<string>>>({
queryKey: ['statusLists', 'bookmarks'],
exact: false,
}, (data) => data ? {
...data,
pages: data.pages.map(({ items, ...page }) => ({ ...page, items: items.filter((id) => id !== statusId) })),
} : undefined);
toast.success(messages.bookmarkRemoved);
},
});
};
export {
useStatusDislikes,
useStatusFavourites,
@@ -151,4 +248,6 @@ export {
useUndislikeStatus,
useReblogStatus,
useUnreblogStatus,
useBookmarkStatus,
useUnbookmarkStatus,
};

View File

@@ -1,14 +1,5 @@
import { create } from 'mutative';
import {
BOOKMARKED_STATUSES_FETCH_REQUEST,
BOOKMARKED_STATUSES_FETCH_SUCCESS,
BOOKMARKED_STATUSES_FETCH_FAIL,
BOOKMARKED_STATUSES_EXPAND_REQUEST,
BOOKMARKED_STATUSES_EXPAND_SUCCESS,
BOOKMARKED_STATUSES_EXPAND_FAIL,
type BookmarksAction,
} from 'pl-fe/actions/bookmarks';
import {
FAVOURITED_STATUSES_FETCH_REQUEST,
FAVOURITED_STATUSES_FETCH_SUCCESS,
@@ -25,8 +16,6 @@ import {
type FavouritesAction,
} from 'pl-fe/actions/favourites';
import {
BOOKMARK_SUCCESS,
UNBOOKMARK_SUCCESS,
PIN_SUCCESS,
UNPIN_SUCCESS,
type InteractionsAction,
@@ -54,7 +43,6 @@ type State = Record<string, StatusList>;
const initialState: State = {
favourites: newStatusList(),
bookmarks: newStatusList(),
pins: newStatusList(),
};
@@ -100,23 +88,7 @@ const removeOneFromList = (state: State, listType: string, status: string | Pick
list.items = list.items.filter(id => id !== statusId);
};
const addBookmarkToLists = (state: State, status: Pick<Status, 'id' | 'bookmark_folder'>) => {
prependOneToList(state, 'bookmarks', status);
const folderId = status.bookmark_folder;
if (folderId) {
prependOneToList(state, `bookmarks:${folderId}`, status);
}
};
const removeBookmarkFromLists = (state: State, status: Pick<Status, 'id' | 'bookmark_folder'>) => {
removeOneFromList(state, 'bookmarks', status);
const folderId = status.bookmark_folder;
if (folderId) {
removeOneFromList(state, `bookmarks:${folderId}`, status);
}
};
const statusLists = (state = initialState, action: BookmarksAction | FavouritesAction | InteractionsAction | PinStatusesAction | StatusesAction): State => {
const statusLists = (state = initialState, action: FavouritesAction | InteractionsAction | PinStatusesAction | StatusesAction): State => {
switch (action.type) {
case FAVOURITED_STATUSES_FETCH_REQUEST:
case FAVOURITED_STATUSES_EXPAND_REQUEST:
@@ -138,20 +110,6 @@ const statusLists = (state = initialState, action: BookmarksAction | FavouritesA
return create(state, draft => normalizeList(draft, `favourites:${action.accountId}`, action.statuses, action.next));
case ACCOUNT_FAVOURITED_STATUSES_EXPAND_SUCCESS:
return create(state, draft => appendToList(draft, `favourites:${action.accountId}`, action.statuses, action.next));
case BOOKMARKED_STATUSES_FETCH_REQUEST:
case BOOKMARKED_STATUSES_EXPAND_REQUEST:
return create(state, draft => setLoading(draft, action.folderId ? `bookmarks:${action.folderId}` : 'bookmarks', true));
case BOOKMARKED_STATUSES_FETCH_FAIL:
case BOOKMARKED_STATUSES_EXPAND_FAIL:
return create(state, draft => setLoading(draft, action.folderId ? `bookmarks:${action.folderId}` : 'bookmarks', false));
case BOOKMARKED_STATUSES_FETCH_SUCCESS:
return create(state, draft => normalizeList(draft, action.folderId ? `bookmarks:${action.folderId}` : 'bookmarks', action.statuses, action.next));
case BOOKMARKED_STATUSES_EXPAND_SUCCESS:
return create(state, draft => appendToList(draft, action.folderId ? `bookmarks:${action.folderId}` : 'bookmarks', action.statuses, action.next));
case BOOKMARK_SUCCESS:
return create(state, draft => addBookmarkToLists(draft, action.status));
case UNBOOKMARK_SUCCESS:
return create(state, draft => removeBookmarkFromLists(draft, action.status));
case PINNED_STATUSES_FETCH_SUCCESS:
return create(state, draft => normalizeList(draft, 'pins', action.statuses, action.next));
case PIN_SUCCESS: