More improvments to optimistic caching

This commit is contained in:
Jackson Harper 2024-07-30 16:48:24 +08:00
parent 6c6cc8d4c4
commit 6356a8a3c7
3 changed files with 77 additions and 61 deletions

View file

@ -19,6 +19,7 @@ import {
ArticleAttributes,
Recommendation,
TextDirection,
useUpdateItemReadStatus,
} from '../../../lib/networking/library_items/useLibraryItems'
import { Avatar } from '../../elements/Avatar'
import { UserBasicData } from '../../../lib/networking/queries/useGetViewerQuery'
@ -115,7 +116,7 @@ const RecommendationComments = (
export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
const [labels, setLabels] = useState(props.labels)
const [title, setTitle] = useState(props.article.title)
const [title, setTitle] = useState<string | undefined>(undefined)
const [showReportIssuesModal, setShowReportIssuesModal] = useState(false)
const [fontSize, setFontSize] = useState(props.fontSize ?? 20)
const [highlightOnRelease, setHighlightOnRelease] = useState(
@ -447,9 +448,9 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element {
'-webkit-line-clamp': '6',
},
}}
title={title}
title={title ?? props.article.title}
>
{title}
{title ?? props.article.title}
</StyledText>
<ArticleSubtitle
author={props.article.author}

View file

@ -15,11 +15,15 @@ export const useSetPageLabels = (
libraryItemSlug?: string
): [{ labels: Label[] }, LabelsDispatcher] => {
const setItemLabels = useSetItemLabels()
const saveLabels = (labels: Label[], articleId: string) => {
const saveLabels = (
labels: Label[],
libraryItemId: string,
libraryItemSlug: string
) => {
;(async () => {
if (articleId) {
if (libraryItemId) {
const result = await setItemLabels.mutateAsync({
itemId: articleId,
itemId: libraryItemId,
slug: libraryItemSlug,
labels,
})
@ -36,12 +40,14 @@ export const useSetPageLabels = (
state: {
labels: Label[]
articleId: string | undefined
throttledSave: (labels: Label[], articleId: string) => void
slug: string | undefined
throttledSave: (labels: Label[], articleId: string, slug: string) => void
},
action: {
type: string
labels: Label[]
articleId?: string
slug?: string
}
) => {
switch (action.type) {
@ -58,8 +64,8 @@ export const useSetPageLabels = (
}
}
case 'SAVE': {
if (state.articleId) {
state.throttledSave(action.labels, state.articleId)
if (state.articleId && state.slug) {
state.throttledSave(action.labels, state.articleId, state.slug)
} else {
showErrorToast('Unable to update labels', {
position: 'bottom-right',
@ -73,6 +79,7 @@ export const useSetPageLabels = (
case 'UPDATE_ARTICLE_ID': {
return {
...state,
slug: action.slug,
articleId: action.articleId,
}
}
@ -83,7 +90,8 @@ export const useSetPageLabels = (
const debouncedSave = useCallback(
throttle(
(labels: Label[], articleId: string) => saveLabels(labels, articleId),
(labels: Label[], articleId: string, slug: string) =>
saveLabels(labels, articleId, slug),
2000
),
[]
@ -93,6 +101,7 @@ export const useSetPageLabels = (
dispatchLabels({
type: 'UPDATE_ARTICLE_ID',
labels: [],
slug: libraryItemSlug,
articleId: libraryItemId,
})
}, [libraryItemId])
@ -100,6 +109,7 @@ export const useSetPageLabels = (
const [labels, dispatchLabels] = useReducer(labelsReducer, {
labels: [],
articleId: libraryItemId,
slug: libraryItemSlug,
throttledSave: debouncedSave,
})

View file

@ -106,17 +106,18 @@ export const updateItemProperty = (
}
return updatedData
})
if (foundItemSlug || slug)
queryClient.setQueryData(
['libraryItem', foundItemSlug ?? slug],
(oldData: ArticleAttributes) => {
return {
...oldData,
...updateFunc(oldData),
}
}
)
})
if (foundItemSlug || slug) {
queryClient.setQueryData(
['libraryItem', foundItemSlug ?? slug],
(oldData: ArticleAttributes) => {
return {
...oldData,
...updateFunc(oldData),
}
}
)
}
}
const overwriteItemPropertiesInCache = (
@ -129,26 +130,8 @@ const overwriteItemPropertiesInCache = (
const keys = queryClient
.getQueryCache()
.findAll({ queryKey: ['libraryItems'] })
console.log('overwriteItemPropertiesInCache::KEYS: ', keys)
// keys.forEach((query) => {
// queryClient.setQueryData(query.queryKey, (data: any) => {
// if (!data) return data
// return {
// ...data,
// pages: data.pages.map((page: any) => ({
// ...page,
// edges: page.edges.map((edge: any) =>
// edge.node.id === itemId
// ? { ...edge, node: { ...edge.node, ...item } }
// : edge
// ),
// })),
// }
// })
// })
keys.forEach((query) => {
queryClient.setQueryData(query.queryKey, (data: any) => {
console.log('query.queryKey', query.queryKey, data)
if (!data) return data
const updatedData = {
...data,
@ -168,18 +151,18 @@ const overwriteItemPropertiesInCache = (
}
return updatedData
})
console.log('updating foundItem slug: ', foundItemSlug)
if (foundItemSlug || slug)
queryClient.setQueryData(
['libraryItem', foundItemSlug ?? slug],
(oldData: ArticleAttributes) => {
return {
...oldData,
...item,
}
}
)
})
if (foundItemSlug || slug) {
queryClient.setQueryData(
['libraryItem', foundItemSlug ?? slug],
(oldData: ArticleAttributes) => {
return {
...oldData,
...item,
}
}
)
}
}
export function useGetLibraryItems(
@ -355,7 +338,6 @@ export const useUpdateItem = () => {
input: UpdateLibraryItemInput
}) => {
await queryClient.cancelQueries({ queryKey: ['libraryItems'] })
console.log('will update item')
overwriteItemPropertiesInCache(
queryClient,
variables.itemId,
@ -369,10 +351,13 @@ export const useUpdateItem = () => {
queryClient.setQueryData(['libraryItems'], context.previousItems)
}
},
onSettled: async () => {
onSuccess: async (data, variables) => {
await queryClient.invalidateQueries({
queryKey: ['libraryItems'],
})
await queryClient.invalidateQueries({
queryKey: ['libraryItem', variables.slug],
})
},
})
}
@ -486,12 +471,24 @@ export const useMoveItemToFolder = () => {
'folder',
variables.folder
)
return { previousItems: queryClient.getQueryData(['libraryItems']) }
return {
previousDetail: queryClient.getQueryData([
'libraryItem',
variables.slug,
]),
previousItems: queryClient.getQueryData(['libraryItems']),
}
},
onError: (error, itemId, context) => {
onError: (error, variables, context) => {
if (context?.previousItems) {
queryClient.setQueryData(['libraryItems'], context.previousItems)
}
if (context?.previousDetail) {
queryClient.setQueryData(
['libraryItem', variables.slug],
context.previousDetail
)
}
},
onSettled: async () => {
await queryClient.invalidateQueries({
@ -525,6 +522,7 @@ export const useSetItemLabels = () => {
labels: Label[]
}) => {
await queryClient.cancelQueries({ queryKey: ['libraryItems'] })
console
updateItemPropertyInCache(
queryClient,
variables.itemId,
@ -532,14 +530,26 @@ export const useSetItemLabels = () => {
'labels',
variables.labels
)
return { previousItems: queryClient.getQueryData(['libraryItems']) }
return {
previousItems: queryClient.getQueryData(['libraryItems']),
previousDetail: queryClient.getQueryData([
'libraryItem',
variables.slug,
]),
}
},
onError: (error, itemId, context) => {
onError: (error, variables, context) => {
if (context?.previousItems) {
queryClient.setQueryData(['libraryItems'], context.previousItems)
}
if (context?.previousDetail) {
queryClient.setQueryData(
['libraryItem', variables.slug],
context.previousDetail
)
}
},
onSuccess: (newLabels, variables) => {
onSuccess: async (newLabels, variables) => {
updateItemPropertyInCache(
queryClient,
variables.itemId,
@ -548,11 +558,6 @@ export const useSetItemLabels = () => {
newLabels
)
},
onSettled: async () => {
await queryClient.invalidateQueries({
queryKey: ['libraryItems'],
})
},
})
}