mirror of
https://github.com/Qortal/qapp-core.git
synced 2025-06-15 01:41:21 +00:00
fix metadata
This commit is contained in:
parent
f613054b9a
commit
720950529f
@ -90,11 +90,11 @@ export const MemorizedComponent = ({
|
|||||||
disableScrollTracker
|
disableScrollTracker
|
||||||
}: PropsResourceListDisplay) => {
|
}: PropsResourceListDisplay) => {
|
||||||
const { fetchResources } = useResources();
|
const { fetchResources } = useResources();
|
||||||
const { getTemporaryResources, filterOutDeletedResources } = useCacheStore();
|
const { filterOutDeletedResources } = useCacheStore();
|
||||||
const memoizedParams = useMemo(() => JSON.stringify(search), [search]);
|
const memoizedParams = useMemo(() => JSON.stringify(search), [search]);
|
||||||
const addList = useListStore().addList
|
const addList = useListStore().addList
|
||||||
const removeFromList = useListStore().removeFromList
|
const removeFromList = useListStore().removeFromList
|
||||||
|
const temporaryResources = useCacheStore().getTemporaryResources(listName)
|
||||||
const addItems = useListStore().addItems
|
const addItems = useListStore().addItems
|
||||||
const list = useListStore().getListByName(listName)
|
const list = useListStore().getListByName(listName)
|
||||||
const [isLoading, setIsLoading] = useState(list?.length > 0 ? false : true);
|
const [isLoading, setIsLoading] = useState(list?.length > 0 ? false : true);
|
||||||
@ -151,10 +151,9 @@ export const MemorizedComponent = ({
|
|||||||
setResourceCacheExpiryDuration(resourceCacheDuration)
|
setResourceCacheExpiryDuration(resourceCacheDuration)
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const listToDisplay = useMemo(()=> {
|
const listToDisplay = useMemo(()=> {
|
||||||
return filterOutDeletedResources([...getTemporaryResources(listName), ...list])
|
return filterOutDeletedResources([...temporaryResources, ...list])
|
||||||
}, [list, listName, filterOutDeletedResources, getTemporaryResources])
|
}, [list, listName, filterOutDeletedResources, temporaryResources])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import React, { useCallback } from "react";
|
import React, { useCallback } from "react";
|
||||||
import {
|
import {
|
||||||
|
|
||||||
QortalMetadata,
|
QortalMetadata,
|
||||||
QortalSearchParams,
|
QortalSearchParams,
|
||||||
} from "../types/interfaces/resources";
|
} from "../types/interfaces/resources";
|
||||||
import { useCacheStore } from "../state/cache";
|
import { ListItem, useCacheStore } from "../state/cache";
|
||||||
import { RequestQueueWithPromise } from "../utils/queue";
|
import { RequestQueueWithPromise } from "../utils/queue";
|
||||||
import { base64ToUint8Array, uint8ArrayToObject } from "../utils/base64";
|
import { base64ToUint8Array, uint8ArrayToObject } from "../utils/base64";
|
||||||
|
|
||||||
@ -13,7 +12,6 @@ export const requestQueueProductPublishesBackup = new RequestQueueWithPromise(
|
|||||||
5
|
5
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
interface TemporaryResource {
|
interface TemporaryResource {
|
||||||
qortalMetadata: QortalMetadata;
|
qortalMetadata: QortalMetadata;
|
||||||
data: any;
|
data: any;
|
||||||
@ -25,11 +23,10 @@ export const useResources = () => {
|
|||||||
getResourceCache,
|
getResourceCache,
|
||||||
setResourceCache,
|
setResourceCache,
|
||||||
addTemporaryResource,
|
addTemporaryResource,
|
||||||
markResourceAsDeleted
|
markResourceAsDeleted,
|
||||||
} = useCacheStore();
|
} = useCacheStore();
|
||||||
const requestControllers = new Map<string, AbortController>();
|
const requestControllers = new Map<string, AbortController>();
|
||||||
|
|
||||||
|
|
||||||
const getArbitraryResource = async (
|
const getArbitraryResource = async (
|
||||||
url: string,
|
url: string,
|
||||||
key: string
|
key: string
|
||||||
@ -43,7 +40,7 @@ export const useResources = () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(url, { signal: controller.signal });
|
const res = await fetch(url, { signal: controller.signal });
|
||||||
if(!res?.ok) throw new Error('Error in downloading')
|
if (!res?.ok) throw new Error("Error in downloading");
|
||||||
return await res.text();
|
return await res.text();
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (error?.name === "AbortError") {
|
if (error?.name === "AbortError") {
|
||||||
@ -65,22 +62,46 @@ export const useResources = () => {
|
|||||||
requestControllers.clear();
|
requestControllers.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchIndividualPublish = useCallback(
|
const fetchIndividualPublishJson = useCallback(
|
||||||
async (item: QortalMetadata) => {
|
async (
|
||||||
|
item: QortalMetadata,
|
||||||
|
includeMetadata?: boolean
|
||||||
|
): Promise<false | ListItem | null | undefined> => {
|
||||||
try {
|
try {
|
||||||
const key = `${item?.service}-${item?.name}-${item?.identifier}`;
|
const key = `${item?.service}-${item?.name}-${item?.identifier}`;
|
||||||
|
|
||||||
const cachedProduct = getResourceCache(
|
const cachedProduct = getResourceCache(
|
||||||
`${item?.service}-${item?.name}-${item?.identifier}`
|
`${item?.service}-${item?.name}-${item?.identifier}`
|
||||||
);
|
);
|
||||||
if (cachedProduct) return;
|
|
||||||
|
if (cachedProduct) return cachedProduct;
|
||||||
setResourceCache(
|
setResourceCache(
|
||||||
`${item?.service}-${item?.name}-${item?.identifier}`,
|
`${item?.service}-${item?.name}-${item?.identifier}`,
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
let hasFailedToDownload = false;
|
let hasFailedToDownload = false;
|
||||||
let res: string | undefined = undefined;
|
let res: string | undefined = undefined;
|
||||||
|
let metadata
|
||||||
try {
|
try {
|
||||||
|
if (includeMetadata) {
|
||||||
|
const url = `/arbitrary/resources/search?mode=ALL&service=${item?.service}&limit=1&includemetadata=true&reverse=true&excludeblocked=true&name=${item?.name}&exactmatchnames=true&offset=0&identifier=${item?.identifier}`;
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!response?.ok) return false;
|
||||||
|
const resMetadata = await response.json();
|
||||||
|
if (resMetadata?.length === 0) {
|
||||||
|
setResourceCache(
|
||||||
|
`${item?.service}-${item?.name}-${item?.identifier}`,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
metadata = resMetadata[0];
|
||||||
|
}
|
||||||
res = await requestQueueProductPublishes.enqueue(
|
res = await requestQueueProductPublishes.enqueue(
|
||||||
(): Promise<string> => {
|
(): Promise<string> => {
|
||||||
return getArbitraryResource(
|
return getArbitraryResource(
|
||||||
@ -93,7 +114,6 @@ export const useResources = () => {
|
|||||||
hasFailedToDownload = true;
|
hasFailedToDownload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (res === "canceled") return false;
|
if (res === "canceled") return false;
|
||||||
|
|
||||||
if (hasFailedToDownload) {
|
if (hasFailedToDownload) {
|
||||||
@ -125,7 +145,7 @@ export const useResources = () => {
|
|||||||
const toObject = uint8ArrayToObject(toUint);
|
const toObject = uint8ArrayToObject(toUint);
|
||||||
const fullDataObject = {
|
const fullDataObject = {
|
||||||
data: { ...toObject },
|
data: { ...toObject },
|
||||||
qortalMetadata: item,
|
qortalMetadata: includeMetadata ? metadata : item,
|
||||||
};
|
};
|
||||||
setResourceCache(
|
setResourceCache(
|
||||||
`${item?.service}-${item?.name}-${item?.identifier}`,
|
`${item?.service}-${item?.name}-${item?.identifier}`,
|
||||||
@ -143,10 +163,10 @@ export const useResources = () => {
|
|||||||
const fetchDataFromResults = useCallback(
|
const fetchDataFromResults = useCallback(
|
||||||
(responseData: QortalMetadata[]): void => {
|
(responseData: QortalMetadata[]): void => {
|
||||||
for (const item of responseData) {
|
for (const item of responseData) {
|
||||||
fetchIndividualPublish(item);
|
fetchIndividualPublishJson(item, false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[fetchIndividualPublish]
|
[fetchIndividualPublishJson]
|
||||||
);
|
);
|
||||||
|
|
||||||
const fetchResources = useCallback(
|
const fetchResources = useCallback(
|
||||||
@ -158,18 +178,18 @@ export const useResources = () => {
|
|||||||
if (cancelRequests) {
|
if (cancelRequests) {
|
||||||
cancelAllRequests();
|
cancelAllRequests();
|
||||||
}
|
}
|
||||||
|
|
||||||
const cacheKey = generateCacheKey(params);
|
const cacheKey = generateCacheKey(params);
|
||||||
const searchCache = getSearchCache(listName, cacheKey);
|
const searchCache = getSearchCache(listName, cacheKey);
|
||||||
if (searchCache) {
|
if (searchCache) {
|
||||||
return searchCache;
|
return searchCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
let responseData: QortalMetadata[] = [];
|
let responseData: QortalMetadata[] = [];
|
||||||
let filteredResults: QortalMetadata[] = [];
|
let filteredResults: QortalMetadata[] = [];
|
||||||
let lastCreated = params.before || null;
|
let lastCreated = params.before || null;
|
||||||
const targetLimit = params.limit ?? 20; // Use `params.limit` if provided, else default to 20
|
const targetLimit = params.limit ?? 20; // Use `params.limit` if provided, else default to 20
|
||||||
|
|
||||||
while (filteredResults.length < targetLimit) {
|
while (filteredResults.length < targetLimit) {
|
||||||
const response = await qortalRequest({
|
const response = await qortalRequest({
|
||||||
action: "SEARCH_QDN_RESOURCES",
|
action: "SEARCH_QDN_RESOURCES",
|
||||||
@ -178,36 +198,35 @@ export const useResources = () => {
|
|||||||
limit: targetLimit - filteredResults.length, // Adjust limit dynamically
|
limit: targetLimit - filteredResults.length, // Adjust limit dynamically
|
||||||
before: lastCreated,
|
before: lastCreated,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response || response.length === 0) {
|
if (!response || response.length === 0) {
|
||||||
break; // No more data available
|
break; // No more data available
|
||||||
}
|
}
|
||||||
|
|
||||||
responseData = response;
|
responseData = response;
|
||||||
const validResults = responseData.filter(item => item.size !== 32);
|
const validResults = responseData.filter((item) => item.size !== 32);
|
||||||
filteredResults = [...filteredResults, ...validResults];
|
filteredResults = [...filteredResults, ...validResults];
|
||||||
|
|
||||||
if (filteredResults.length >= targetLimit) {
|
if (filteredResults.length >= targetLimit) {
|
||||||
filteredResults = filteredResults.slice(0, targetLimit);
|
filteredResults = filteredResults.slice(0, targetLimit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastCreated = responseData[responseData.length - 1]?.created;
|
lastCreated = responseData[responseData.length - 1]?.created;
|
||||||
if (!lastCreated) break;
|
if (!lastCreated) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
setSearchCache(listName, cacheKey, filteredResults);
|
setSearchCache(listName, cacheKey, filteredResults);
|
||||||
fetchDataFromResults(filteredResults);
|
fetchDataFromResults(filteredResults);
|
||||||
|
|
||||||
return filteredResults;
|
return filteredResults;
|
||||||
},
|
},
|
||||||
[getSearchCache, setSearchCache, fetchDataFromResults]
|
[getSearchCache, setSearchCache, fetchDataFromResults]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const addNewResources = useCallback(
|
const addNewResources = useCallback(
|
||||||
(listName: string, resources: TemporaryResource[]) => {
|
(listName: string, resources: TemporaryResource[]) => {
|
||||||
|
|
||||||
addTemporaryResource(
|
addTemporaryResource(
|
||||||
listName,
|
listName,
|
||||||
resources.map((item) => item.qortalMetadata)
|
resources.map((item) => item.qortalMetadata)
|
||||||
@ -215,42 +234,38 @@ export const useResources = () => {
|
|||||||
resources.forEach((temporaryResource) => {
|
resources.forEach((temporaryResource) => {
|
||||||
setResourceCache(
|
setResourceCache(
|
||||||
`${temporaryResource?.qortalMetadata?.service}-${temporaryResource?.qortalMetadata?.name}-${temporaryResource?.qortalMetadata?.identifier}`,
|
`${temporaryResource?.qortalMetadata?.service}-${temporaryResource?.qortalMetadata?.name}-${temporaryResource?.qortalMetadata?.identifier}`,
|
||||||
temporaryResource.data
|
temporaryResource
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const updateNewResources = useCallback(
|
const updateNewResources = useCallback((resources: TemporaryResource[]) => {
|
||||||
(resources: TemporaryResource[]) => {
|
resources.forEach((temporaryResource) => {
|
||||||
|
setResourceCache(
|
||||||
resources.forEach((temporaryResource) => {
|
`${temporaryResource?.qortalMetadata?.service}-${temporaryResource?.qortalMetadata?.name}-${temporaryResource?.qortalMetadata?.identifier}`,
|
||||||
setResourceCache(
|
temporaryResource
|
||||||
`${temporaryResource?.qortalMetadata?.service}-${temporaryResource?.qortalMetadata?.name}-${temporaryResource?.qortalMetadata?.identifier}`,
|
);
|
||||||
temporaryResource.data
|
});
|
||||||
);
|
}, []);
|
||||||
});
|
|
||||||
},
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
const deleteProduct = useCallback(async (qortalMetadata: QortalMetadata)=> {
|
|
||||||
if(!qortalMetadata?.service || !qortalMetadata?.identifier) throw new Error('Missing fields')
|
|
||||||
await qortalRequest({
|
|
||||||
action: "PUBLISH_QDN_RESOURCE",
|
|
||||||
service: qortalMetadata.service,
|
|
||||||
identifier: qortalMetadata.identifier,
|
|
||||||
base64: 'RA==',
|
|
||||||
});
|
|
||||||
markResourceAsDeleted(qortalMetadata)
|
|
||||||
return true
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
|
const deleteProduct = useCallback(async (qortalMetadata: QortalMetadata) => {
|
||||||
|
if (!qortalMetadata?.service || !qortalMetadata?.identifier)
|
||||||
|
throw new Error("Missing fields");
|
||||||
|
await qortalRequest({
|
||||||
|
action: "PUBLISH_QDN_RESOURCE",
|
||||||
|
service: qortalMetadata.service,
|
||||||
|
identifier: qortalMetadata.identifier,
|
||||||
|
base64: "RA==",
|
||||||
|
});
|
||||||
|
markResourceAsDeleted(qortalMetadata);
|
||||||
|
return true;
|
||||||
|
}, []);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fetchResources,
|
fetchResources,
|
||||||
fetchIndividualPublish,
|
fetchIndividualPublishJson,
|
||||||
addNewResources,
|
addNewResources,
|
||||||
updateNewResources,
|
updateNewResources,
|
||||||
deleteProduct,
|
deleteProduct,
|
||||||
|
@ -145,6 +145,7 @@ export const useCacheStore = create<CacheState>
|
|||||||
|
|
||||||
addTemporaryResource: (listName, newResources, customExpiry) =>
|
addTemporaryResource: (listName, newResources, customExpiry) =>
|
||||||
set((state) => {
|
set((state) => {
|
||||||
|
|
||||||
const expiry = Date.now() + (customExpiry || 5 * 60 * 1000);
|
const expiry = Date.now() + (customExpiry || 5 * 60 * 1000);
|
||||||
|
|
||||||
const existingResources = state.searchCache[listName]?.temporaryNewResources || [];
|
const existingResources = state.searchCache[listName]?.temporaryNewResources || [];
|
||||||
|
@ -60,6 +60,14 @@ export interface QortalMetadata {
|
|||||||
name: string
|
name: string
|
||||||
identifier: string
|
identifier: string
|
||||||
service: Service
|
service: Service
|
||||||
|
metadata?: {
|
||||||
|
title?: string
|
||||||
|
category?: number
|
||||||
|
categoryName?: string
|
||||||
|
tags?: string[]
|
||||||
|
description?: string
|
||||||
|
}
|
||||||
|
updated?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QortalSearchParams {
|
export interface QortalSearchParams {
|
||||||
@ -72,6 +80,7 @@ export interface QortalMetadata {
|
|||||||
title?: string;
|
title?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
prefix?: boolean;
|
prefix?: boolean;
|
||||||
|
includemetadata?: boolean;
|
||||||
exactMatchNames?: boolean;
|
exactMatchNames?: boolean;
|
||||||
minLevel?: number;
|
minLevel?: number;
|
||||||
nameListFilter?: string;
|
nameListFilter?: string;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user