mirror of
https://github.com/Qortal/qapp-core.git
synced 2025-07-12 12:21:24 +00:00
added useBlockedNames
This commit is contained in:
parent
0e23cab129
commit
c5ec6fb988
42
src/hooks/useBlockedNames.tsx
Normal file
42
src/hooks/useBlockedNames.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { useListStore } from "../state/lists";
|
||||
import { useCacheStore } from "../state/cache";
|
||||
|
||||
export const useBlockedNames = () => {
|
||||
const filterOutItemsByNames = useListStore(state => state.filterOutItemsByNames)
|
||||
const filterSearchCacheItemsByNames = useCacheStore((s)=> s.filterSearchCacheItemsByNames)
|
||||
|
||||
|
||||
const addToBlockedList = useCallback(async (names: string[]) => {
|
||||
const response = await qortalRequest({
|
||||
action: "ADD_LIST_ITEMS",
|
||||
list_name: "blockedNames",
|
||||
items: names,
|
||||
});
|
||||
if (response === true) {
|
||||
filterOutItemsByNames(names)
|
||||
filterSearchCacheItemsByNames(names)
|
||||
return true;
|
||||
} else throw new Error("Unable to block names");
|
||||
}, []);
|
||||
|
||||
const removeFromBlockedList = useCallback(async (names: string[]) => {
|
||||
const response = await qortalRequest({
|
||||
action: "DELETE_LIST_ITEM",
|
||||
list_name: "blockedNames",
|
||||
items: names,
|
||||
});
|
||||
if (response === true) {
|
||||
return true;
|
||||
} else throw new Error("Unable to remove blocked names");
|
||||
}, []);
|
||||
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
removeFromBlockedList,
|
||||
addToBlockedList,
|
||||
}),
|
||||
[addToBlockedList, removeFromBlockedList]
|
||||
);
|
||||
};
|
@ -23,6 +23,7 @@ export interface Resource {
|
||||
}
|
||||
export const useResources = (retryAttempts: number = 2, maxSize = 5242880) => {
|
||||
const setSearchCache = useCacheStore((s) => s.setSearchCache);
|
||||
const deleteSearchCache = useCacheStore((s)=> s.deleteSearchCache)
|
||||
const getSearchCache = useCacheStore((s) => s.getSearchCache);
|
||||
const getResourceCache = useCacheStore((s) => s.getResourceCache);
|
||||
const setResourceCache = useCacheStore((s) => s.setResourceCache);
|
||||
@ -32,7 +33,12 @@ export const useResources = (retryAttempts: number = 2, maxSize = 5242880) => {
|
||||
const addList = useListStore((s) => s.addList);
|
||||
const setPublish = usePublishStore((state)=> state.setPublish)
|
||||
|
||||
const deleteList = useListStore(state => state.deleteList)
|
||||
const deleteListInStore = useListStore(state => state.deleteList)
|
||||
|
||||
const deleteList = useCallback((listName: string)=> {
|
||||
deleteListInStore(listName)
|
||||
deleteSearchCache(listName)
|
||||
}, [])
|
||||
const requestControllers = new Map<string, AbortController>();
|
||||
|
||||
const getArbitraryResource = async (
|
||||
|
@ -11,6 +11,7 @@ export { useListReturn } from './hooks/useListData';
|
||||
export { useAllResourceStatus } from './hooks/useAllResourceStatus';
|
||||
export { useQortBalance } from './hooks/useBalance';
|
||||
export { useAuth } from './hooks/useAuth';
|
||||
export { useBlockedNames } from './hooks/useBlockedNames';
|
||||
import './index.css'
|
||||
export { executeEvent, subscribeToEvent, unsubscribeFromEvent } from './utils/events';
|
||||
export { formatBytes, formatDuration } from './utils/numbers';
|
||||
|
@ -71,6 +71,9 @@ interface CacheState {
|
||||
resourceCacheExpiryDuration: number;
|
||||
setSearchCacheExpiryDuration: (duration: number) => void;
|
||||
setResourceCacheExpiryDuration: (duration: number)=> void;
|
||||
deleteSearchCache: (listName: string) => void;
|
||||
filterSearchCacheItemsByNames: (names: string[]) => void;
|
||||
|
||||
}
|
||||
|
||||
export const useCacheStore = create<CacheState>
|
||||
@ -128,6 +131,12 @@ export const useCacheStore = create<CacheState>
|
||||
},
|
||||
};
|
||||
}),
|
||||
deleteSearchCache: (listName) =>
|
||||
set((state) => {
|
||||
const updatedSearchCache = { ...state.searchCache };
|
||||
delete updatedSearchCache[listName];
|
||||
return { searchCache: updatedSearchCache };
|
||||
}),
|
||||
setSearchParamsForList: (listName, searchParamsStringified) =>
|
||||
set((state) => {
|
||||
const existingList = state.searchCache[listName] || {};
|
||||
@ -238,6 +247,27 @@ export const useCacheStore = create<CacheState>
|
||||
);
|
||||
return { searchCache: validSearchCache };
|
||||
}),
|
||||
filterSearchCacheItemsByNames: (names) =>
|
||||
set((state) => {
|
||||
const updatedSearchCache: SearchCache = {};
|
||||
|
||||
for (const [listName, list] of Object.entries(state.searchCache)) {
|
||||
const updatedSearches: { [searchTerm: string]: QortalMetadata[] } = {};
|
||||
|
||||
for (const [term, items] of Object.entries(list.searches)) {
|
||||
updatedSearches[term] = items.filter(
|
||||
(item) => !names.includes(item.name)
|
||||
);
|
||||
}
|
||||
|
||||
updatedSearchCache[listName] = {
|
||||
...list,
|
||||
searches: updatedSearches,
|
||||
};
|
||||
}
|
||||
|
||||
return { searchCache: updatedSearchCache };
|
||||
}),
|
||||
}),
|
||||
|
||||
);
|
@ -1,8 +1,7 @@
|
||||
import {create} from "zustand";
|
||||
import { create } from "zustand";
|
||||
import { QortalMetadata } from "../types/interfaces/resources";
|
||||
import { persist } from "zustand/middleware";
|
||||
|
||||
|
||||
interface ListsState {
|
||||
[listName: string]: {
|
||||
name: string;
|
||||
@ -15,15 +14,16 @@ interface ListStore {
|
||||
|
||||
// CRUD Operations
|
||||
addList: (name: string, items: QortalMetadata[]) => void;
|
||||
removeFromList: (name: string, length: number)=> void;
|
||||
removeFromList: (name: string, length: number) => void;
|
||||
addItem: (listName: string, item: QortalMetadata) => void;
|
||||
addItems: (listName: string, items: QortalMetadata[]) => void;
|
||||
addItems: (listName: string, items: QortalMetadata[]) => void;
|
||||
updateItem: (listName: string, item: QortalMetadata) => void;
|
||||
deleteItem: (listName: string, itemKey: string) => void;
|
||||
deleteList: (listName: string) => void;
|
||||
|
||||
// Getter function
|
||||
getListByName: (listName: string) => QortalMetadata[]
|
||||
getListByName: (listName: string) => QortalMetadata[];
|
||||
filterOutItemsByNames: (names: string[]) => void;
|
||||
}
|
||||
|
||||
export const useListStore = create<ListStore>((set, get) => ({
|
||||
@ -40,7 +40,13 @@ export const useListStore = create<ListStore>((set, get) => ({
|
||||
set((state) => ({
|
||||
lists: {
|
||||
...state.lists,
|
||||
[name]: { name, items: state.lists[name].items.slice(0, state.lists[name].items.length - length) }, // ✅ Store items as an array
|
||||
[name]: {
|
||||
name,
|
||||
items: state.lists[name].items.slice(
|
||||
0,
|
||||
state.lists[name].items.length - length
|
||||
),
|
||||
}, // ✅ Store items as an array
|
||||
},
|
||||
})),
|
||||
|
||||
@ -50,7 +56,9 @@ export const useListStore = create<ListStore>((set, get) => ({
|
||||
|
||||
const itemKey = `${item.name}-${item.service}-${item.identifier}`;
|
||||
const existingItem = state.lists[listName].items.find(
|
||||
(existing) => `${existing.name}-${existing.service}-${existing.identifier}` === itemKey
|
||||
(existing) =>
|
||||
`${existing.name}-${existing.service}-${existing.identifier}` ===
|
||||
itemKey
|
||||
);
|
||||
|
||||
if (existingItem) return state; // Avoid duplicates
|
||||
@ -65,52 +73,51 @@ export const useListStore = create<ListStore>((set, get) => ({
|
||||
},
|
||||
};
|
||||
}),
|
||||
addItems: (listName, items) =>
|
||||
set((state) => {
|
||||
|
||||
if (!state.lists[listName]) {
|
||||
console.warn(`List "${listName}" does not exist. Creating a new list.`);
|
||||
return {
|
||||
lists: {
|
||||
...state.lists,
|
||||
[listName]: { name: listName, items: [...items] }, // ✅ Create new list if missing
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// ✅ Generate existing keys correctly
|
||||
const existingKeys = new Set(
|
||||
state.lists[listName].items.map(
|
||||
(item) => `${item.name}-${item.service}-${item.identifier}`
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
// ✅ Ensure we correctly compare identifiers
|
||||
const newItems = items.filter((item) => {
|
||||
const itemKey = `${item.name}-${item.service}-${item.identifier}`;
|
||||
const isDuplicate = existingKeys.has(itemKey);
|
||||
|
||||
return !isDuplicate; // ✅ Only keep items that are NOT in the existing list
|
||||
});
|
||||
|
||||
|
||||
if (newItems.length === 0) {
|
||||
console.warn("No new items were added because they were all considered duplicates.");
|
||||
return state; // ✅ Prevent unnecessary re-renders if no changes
|
||||
}
|
||||
|
||||
return {
|
||||
lists: {
|
||||
...state.lists,
|
||||
[listName]: {
|
||||
...state.lists[listName],
|
||||
items: [...state.lists[listName].items, ...newItems], // ✅ Append only new items
|
||||
},
|
||||
},
|
||||
};
|
||||
}),
|
||||
|
||||
addItems: (listName, items) =>
|
||||
set((state) => {
|
||||
if (!state.lists[listName]) {
|
||||
console.warn(`List "${listName}" does not exist. Creating a new list.`);
|
||||
return {
|
||||
lists: {
|
||||
...state.lists,
|
||||
[listName]: { name: listName, items: [...items] }, // ✅ Create new list if missing
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// ✅ Generate existing keys correctly
|
||||
const existingKeys = new Set(
|
||||
state.lists[listName].items.map(
|
||||
(item) => `${item.name}-${item.service}-${item.identifier}`
|
||||
)
|
||||
);
|
||||
|
||||
// ✅ Ensure we correctly compare identifiers
|
||||
const newItems = items.filter((item) => {
|
||||
const itemKey = `${item.name}-${item.service}-${item.identifier}`;
|
||||
const isDuplicate = existingKeys.has(itemKey);
|
||||
|
||||
return !isDuplicate; // ✅ Only keep items that are NOT in the existing list
|
||||
});
|
||||
|
||||
if (newItems.length === 0) {
|
||||
console.warn(
|
||||
"No new items were added because they were all considered duplicates."
|
||||
);
|
||||
return state; // ✅ Prevent unnecessary re-renders if no changes
|
||||
}
|
||||
|
||||
return {
|
||||
lists: {
|
||||
...state.lists,
|
||||
[listName]: {
|
||||
...state.lists[listName],
|
||||
items: [...state.lists[listName].items, ...newItems], // ✅ Append only new items
|
||||
},
|
||||
},
|
||||
};
|
||||
}),
|
||||
|
||||
updateItem: (listName, item) =>
|
||||
set((state) => {
|
||||
if (!state.lists[listName]) return state;
|
||||
@ -123,7 +130,8 @@ export const useListStore = create<ListStore>((set, get) => ({
|
||||
[listName]: {
|
||||
...state.lists[listName],
|
||||
items: state.lists[listName].items.map((existing) =>
|
||||
`${existing.name}-${existing.service}-${existing.identifier}` === itemKey
|
||||
`${existing.name}-${existing.service}-${existing.identifier}` ===
|
||||
itemKey
|
||||
? item // ✅ Update item
|
||||
: existing
|
||||
),
|
||||
@ -142,7 +150,8 @@ export const useListStore = create<ListStore>((set, get) => ({
|
||||
[listName]: {
|
||||
...state.lists[listName],
|
||||
items: state.lists[listName].items.filter(
|
||||
(item) => `${item.name}-${item.service}-${item.identifier}` !== itemKey
|
||||
(item) =>
|
||||
`${item.name}-${item.service}-${item.identifier}` !== itemKey
|
||||
), // ✅ Remove from array
|
||||
},
|
||||
},
|
||||
@ -160,4 +169,16 @@ export const useListStore = create<ListStore>((set, get) => ({
|
||||
}),
|
||||
|
||||
getListByName: (listName) => get().lists[listName]?.items || [], // ✅ Get a list by name
|
||||
filterOutItemsByNames: (names) =>
|
||||
set((state) => {
|
||||
const updatedLists: ListsState = {};
|
||||
|
||||
for (const [listName, listData] of Object.entries(state.lists)) {
|
||||
updatedLists[listName] = {
|
||||
...listData,
|
||||
items: listData.items.filter((item) => !names.includes(item.name)),
|
||||
};
|
||||
}
|
||||
return { lists: updatedLists };
|
||||
}),
|
||||
}));
|
||||
|
Loading…
x
Reference in New Issue
Block a user