Optimistically refresh categories on reordering

This commit is contained in:
schroda
2023-10-16 01:38:53 +02:00
parent b7e1afd4f4
commit e2fed69c90
2 changed files with 68 additions and 17 deletions

View File

@@ -61,8 +61,6 @@ import {
FilterChangeInput,
GetAboutQuery,
GetAboutQueryVariables,
GetExtensionsFetchMutation,
GetExtensionsFetchMutationVariables,
GetCategoriesQuery,
GetCategoriesQueryVariables,
GetCategoryMangasQuery,
@@ -71,6 +69,8 @@ import {
GetChapterPagesFetchMutationVariables,
GetChaptersQuery,
GetChaptersQueryVariables,
GetExtensionsFetchMutation,
GetExtensionsFetchMutationVariables,
GetExtensionsQuery,
GetExtensionsQueryVariables,
GetGlobalMetadatasQuery,
@@ -1407,17 +1407,70 @@ export class RequestManager {
);
}
public reorderCategory(
id: number,
position: number,
options?: MutationOptions<UpdateCategoryOrderMutation, UpdateCategoryOrderMutationVariables>,
): AbortableApolloMutationResponse<UpdateCategoryOrderMutation> {
return this.doRequest<UpdateCategoryOrderMutation, UpdateCategoryOrderMutationVariables>(
GQLMethod.MUTATION,
public useReorderCategory(
options?: MutationHookOptions<UpdateCategoryOrderMutation, UpdateCategoryOrderMutationVariables>,
): AbortableApolloUseMutationResponse<UpdateCategoryOrderMutation, UpdateCategoryOrderMutationVariables> {
const [mutate, result] = this.doRequest<UpdateCategoryOrderMutation, UpdateCategoryOrderMutationVariables>(
GQLMethod.USE_MUTATION,
UPDATE_CATEGORY_ORDER,
{ input: { id, position } },
{ refetchQueries: [GET_CATEGORIES], ...options },
undefined,
options,
);
const wrappedMutate = (mutateOptions: Parameters<typeof mutate>[0]) => {
const variables = mutateOptions?.variables?.input;
const cachedCategories = this.graphQLClient.client.readQuery<
GetCategoriesQuery,
GetCategoriesQueryVariables
>({
query: GET_CATEGORIES,
variables: { orderBy: CategoryOrderBy.Order },
})?.categories.nodes;
if (!variables) {
throw new Error('useReorderCategory: no variables passed');
}
if (!cachedCategories) {
throw new Error('useReorderCategory: there are no cached results');
}
const movedIndex = cachedCategories.findIndex((category) => category.id === variables.id);
const newData = [...cachedCategories.map((category) => ({ ...category }))];
const [removed] = newData.splice(movedIndex, 1);
newData.splice(variables.position, 0, removed);
removed.order = variables.position;
newData[movedIndex].order = movedIndex;
return mutate({
update: (cache) => {
cache.updateQuery<GetCategoriesQuery, GetCategoriesQueryVariables>(
{
id: cache.identify({ __typename: 'CategoryNodeList' }),
query: GET_CATEGORIES,
variables: { orderBy: CategoryOrderBy.Order },
},
(data) => ({
...data!,
categories: {
...data!.categories,
nodes: newData,
},
}),
);
},
optimisticResponse: {
__typename: 'Mutation',
updateCategoryOrder: {
__typename: 'UpdateCategoryOrderPayload',
categories: newData,
},
},
...mutateOptions,
});
};
return [wrappedMutate, result];
}
public useGetCategoryMangas(

View File

@@ -65,19 +65,17 @@ export default function Categories() {
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
const [dialogName, setDialogName] = useState<string>('');
const [dialogDefault, setDialogDefault] = useState<boolean>(false);
const [reorderCategory, { reset: revertReorder }] = requestManager.useReorderCategory();
const theme = useTheme();
useSetDefaultBackTo('settings');
const categoryReorder = (list: TCategory[], from: number, to: number) => {
const reorderedCategory = list[from];
const newData = [...list];
const [removed] = newData.splice(from, 1);
newData.splice(to, 0, removed);
// TODO - update cache immediately
// mutate(categoriesEndpoint, newData, { revalidate: false });
requestManager.reorderCategory(reorderedCategory.id, to + 1);
reorderCategory({ variables: { input: { id: reorderedCategory.id, position: to + 1 } } }).catch(() =>
revertReorder(),
);
};
const onDragEnd = (result: DropResult) => {