From aa01d6712b4ac4a66b3a134d77f0c1252a50dd16 Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Fri, 24 Nov 2023 03:20:16 +0100 Subject: [PATCH] Update extensions list after extension update (#471) --- src/components/ExtensionCard.tsx | 4 ++++ src/lib/requests/RequestManager.ts | 35 +++++++++++++++++++++++++++++- src/screens/Extensions.tsx | 9 +++++--- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/components/ExtensionCard.tsx b/src/components/ExtensionCard.tsx index 732703a7..20bae09f 100644 --- a/src/components/ExtensionCard.tsx +++ b/src/components/ExtensionCard.tsx @@ -19,6 +19,7 @@ import { requestManager } from '@/lib/requests/RequestManager.ts'; interface IProps { extension: PartialExtension; + handleUpdate: () => void; } enum ExtensionAction { @@ -65,6 +66,7 @@ export function ExtensionCard(props: IProps) { const { extension: { name, lang, versionName, isInstalled, hasUpdate, isObsolete, pkgName, iconUrl, isNsfw }, + handleUpdate, } = props; const [installedState, setInstalledState] = useState(() => { if (isObsolete) { @@ -97,6 +99,8 @@ export function ExtensionCard(props: IProps) { throw new Error(`Unexpected ExtensionAction "${action}"`); } setInstalledState(nextAction); + + handleUpdate(); }; function handleButtonClick() { diff --git a/src/lib/requests/RequestManager.ts b/src/lib/requests/RequestManager.ts index 38285494..70c2937e 100644 --- a/src/lib/requests/RequestManager.ts +++ b/src/lib/requests/RequestManager.ts @@ -14,6 +14,7 @@ import { FetchResult, MutationHookOptions as ApolloMutationHookOptions, MutationOptions as ApolloMutationOptions, + MutationResult, MutationTuple, QueryHookOptions as ApolloQueryHookOptions, QueryOptions as ApolloQueryOptions, @@ -956,8 +957,40 @@ export class RequestManager { options, ); - result.response.then(() => { + result.response.then((response) => { this.graphQLClient.client.cache.evict({ fieldName: 'sources' }); + const cachedExtensions = this.cache.getResponseFor>( + EXTENSION_LIST_CACHE_KEY, + undefined, + ); + + if (!cachedExtensions || !cachedExtensions.data) { + return; + } + + const updatedCachedExtensions: MutationResult = { + ...cachedExtensions, + data: { + ...cachedExtensions.data, + fetchExtensions: { + ...cachedExtensions.data.fetchExtensions, + extensions: cachedExtensions.data.fetchExtensions.extensions.map((extension) => { + const isUpdatedExtension = + extension.apkName === response.data?.updateExtension.extension.apkName; + if (!isUpdatedExtension) { + return extension; + } + + return { + ...extension, + ...response.data?.updateExtension.extension, + }; + }), + }, + }, + }; + + this.cache.cacheResponse(EXTENSION_LIST_CACHE_KEY, undefined, updatedCachedExtensions); }); return result; diff --git a/src/screens/Extensions.tsx b/src/screens/Extensions.tsx index 3f45fb55..598748b3 100644 --- a/src/screens/Extensions.tsx +++ b/src/screens/Extensions.tsx @@ -6,7 +6,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { useContext, useEffect, useMemo, useRef, useState } from 'react'; +import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; import { fromEvent } from 'file-selector'; import IconButton from '@mui/material/IconButton'; import AddIcon from '@mui/icons-material/Add'; @@ -100,12 +100,15 @@ export function Extensions() { const isMobile = useMediaQuery(theme.breakpoints.down('sm')); const [query] = useQueryParam('query', StringParam); + const [refetchExtensions, setRefetchExtensions] = useState({}); const [fetchExtensions, { data, loading: isLoading, called }] = requestManager.useExtensionListFetch(); const allExtensions = data?.fetchExtensions.extensions; + const handleExtensionUpdate = useCallback(() => setRefetchExtensions({}), []); + useEffect(() => { fetchExtensions(); - }, []); + }, [refetchExtensions]); const filteredExtensions = useMemo( () => @@ -229,7 +232,7 @@ export function Extensions() { } const item = flatRenderItems[index] as PartialExtension; - return ; + return ; }} />