EntityStore: let totalCount be undefined, don't try to set it from the local count
This commit is contained in:
parent
f016ac1e6d
commit
c4d0dd568e
|
@ -4,6 +4,7 @@ import z from 'zod';
|
||||||
import { getNextLink, getPrevLink } from 'soapbox/api';
|
import { getNextLink, getPrevLink } from 'soapbox/api';
|
||||||
import { useApi, useAppDispatch, useAppSelector, useGetState } from 'soapbox/hooks';
|
import { useApi, useAppDispatch, useAppSelector, useGetState } from 'soapbox/hooks';
|
||||||
import { filteredArray } from 'soapbox/schemas/utils';
|
import { filteredArray } from 'soapbox/schemas/utils';
|
||||||
|
import { realNumberSchema } from 'soapbox/utils/numbers';
|
||||||
|
|
||||||
import { entitiesFetchFail, entitiesFetchRequest, entitiesFetchSuccess, invalidateEntityList } from '../actions';
|
import { entitiesFetchFail, entitiesFetchRequest, entitiesFetchSuccess, invalidateEntityList } from '../actions';
|
||||||
|
|
||||||
|
@ -63,12 +64,12 @@ function useEntities<TEntity extends Entity>(
|
||||||
const response = await api.get(url);
|
const response = await api.get(url);
|
||||||
const schema = opts.schema || z.custom<TEntity>();
|
const schema = opts.schema || z.custom<TEntity>();
|
||||||
const entities = filteredArray(schema).parse(response.data);
|
const entities = filteredArray(schema).parse(response.data);
|
||||||
const numItems = (selectList(getState(), path)?.ids.size || 0) + entities.length;
|
const parsedCount = realNumberSchema.safeParse(response.headers['x-total-count']);
|
||||||
|
|
||||||
dispatch(entitiesFetchSuccess(entities, entityType, listKey, {
|
dispatch(entitiesFetchSuccess(entities, entityType, listKey, {
|
||||||
next: getNextLink(response),
|
next: getNextLink(response),
|
||||||
prev: getPrevLink(response),
|
prev: getPrevLink(response),
|
||||||
totalCount: Number(response.headers['x-total-count'] ?? numItems) || 0,
|
totalCount: parsedCount.success ? parsedCount.data : undefined,
|
||||||
fetching: false,
|
fetching: false,
|
||||||
fetched: true,
|
fetched: true,
|
||||||
error: null,
|
error: null,
|
||||||
|
|
|
@ -71,11 +71,14 @@ const deleteEntities = (
|
||||||
for (const list of Object.values(cache.lists)) {
|
for (const list of Object.values(cache.lists)) {
|
||||||
if (list) {
|
if (list) {
|
||||||
list.ids.delete(id);
|
list.ids.delete(id);
|
||||||
|
|
||||||
|
if (typeof list.state.totalCount === 'number') {
|
||||||
list.state.totalCount--;
|
list.state.totalCount--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
draft[entityType] = cache;
|
draft[entityType] = cache;
|
||||||
});
|
});
|
||||||
|
@ -94,8 +97,11 @@ const dismissEntities = (
|
||||||
if (list) {
|
if (list) {
|
||||||
for (const id of ids) {
|
for (const id of ids) {
|
||||||
list.ids.delete(id);
|
list.ids.delete(id);
|
||||||
|
|
||||||
|
if (typeof list.state.totalCount === 'number') {
|
||||||
list.state.totalCount--;
|
list.state.totalCount--;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
draft[entityType] = cache;
|
draft[entityType] = cache;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ interface EntityListState {
|
||||||
/** Previous URL for pagination, if any. */
|
/** Previous URL for pagination, if any. */
|
||||||
prev: string | undefined
|
prev: string | undefined
|
||||||
/** Total number of items according to the API. */
|
/** Total number of items according to the API. */
|
||||||
totalCount: number
|
totalCount: number | undefined
|
||||||
/** Error returned from the API, if any. */
|
/** Error returned from the API, if any. */
|
||||||
error: any
|
error: any
|
||||||
/** Whether data has already been fetched */
|
/** Whether data has already been fetched */
|
||||||
|
|
|
@ -13,8 +13,10 @@ const updateList = (list: EntityList, entities: Entity[]): EntityList => {
|
||||||
const newIds = entities.map(entity => entity.id);
|
const newIds = entities.map(entity => entity.id);
|
||||||
const ids = new Set([...Array.from(list.ids), ...newIds]);
|
const ids = new Set([...Array.from(list.ids), ...newIds]);
|
||||||
|
|
||||||
|
if (typeof list.state.totalCount === 'number') {
|
||||||
const sizeDiff = ids.size - list.ids.size;
|
const sizeDiff = ids.size - list.ids.size;
|
||||||
list.state.totalCount += sizeDiff;
|
list.state.totalCount += sizeDiff;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...list,
|
...list,
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedNumber } from 'react-intl';
|
import { FormattedNumber } from 'react-intl';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
/** Check if a value is REALLY a number. */
|
/** Check if a value is REALLY a number. */
|
||||||
export const isNumber = (value: unknown): value is number => typeof value === 'number' && !isNaN(value);
|
export const isNumber = (value: unknown): value is number => typeof value === 'number' && !isNaN(value);
|
||||||
|
|
||||||
|
/** The input is a number and is not NaN. */
|
||||||
|
export const realNumberSchema = z.coerce.number().refine(n => !isNaN(n));
|
||||||
|
|
||||||
export const secondsToDays = (seconds: number) => Math.floor(seconds / (3600 * 24));
|
export const secondsToDays = (seconds: number) => Math.floor(seconds / (3600 * 24));
|
||||||
|
|
||||||
const roundDown = (num: number) => {
|
const roundDown = (num: number) => {
|
||||||
|
|
Loading…
Reference in New Issue