diff --git a/src/components/IndexManager/IndexManager.tsx b/src/components/IndexManager/IndexManager.tsx
new file mode 100644
index 0000000..6687043
--- /dev/null
+++ b/src/components/IndexManager/IndexManager.tsx
@@ -0,0 +1,118 @@
+import {
+ Box,
+ ButtonBase,
+ Dialog,
+ DialogContent,
+ DialogTitle,
+ IconButton,
+ Typography,
+} from "@mui/material";
+import React, { useState } from "react";
+import { useIndexStore } from "../../state/indexes";
+import CloseIcon from "@mui/icons-material/Close";
+import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
+export const IndexManager = () => {
+ const open = useIndexStore((state) => state.open);
+ const setOpen = useIndexStore((state) => state.setOpen);
+ const [mode, setMode] = useState(1);
+
+ const handleClose = () => {
+ setOpen(null);
+ setMode(1);
+ };
+ return (
+
+ );
+};
+
+const AddMetadata = () => {
+ return hello;
+};
diff --git a/src/context/GlobalProvider.tsx b/src/context/GlobalProvider.tsx
index 4b94ccc..3e0a63b 100644
--- a/src/context/GlobalProvider.tsx
+++ b/src/context/GlobalProvider.tsx
@@ -5,6 +5,8 @@ import { useAppInfo } from "../hooks/useAppInfo";
import { useIdentifiers } from "../hooks/useIdentifiers";
import { Toaster } from "react-hot-toast";
import { useLocalStorage } from "../hooks/useLocalStorage";
+import { IndexManager } from "../components/IndexManager/IndexManager";
+import { useIndexes } from "../hooks/useIndexes";
@@ -17,6 +19,7 @@ lists: ReturnType;
appInfo: ReturnType;
identifierOperations: ReturnType
localStorageOperations: ReturnType
+indexOperations: ReturnType
}
@@ -45,8 +48,9 @@ export const GlobalProvider = ({ children, config, toastStyle = {} }: GlobalProv
const lists = useResources()
const identifierOperations = useIdentifiers(config.publicSalt, config.appName)
const localStorageOperations = useLocalStorage(config.publicSalt, config.appName)
+ const indexOperations = useIndexes()
// ✅ Merge all hooks into a single `contextValue`
- const contextValue = useMemo(() => ({ auth, lists, appInfo, identifierOperations, localStorageOperations }), [auth, lists, appInfo, identifierOperations, localStorageOperations]);
+ const contextValue = useMemo(() => ({ auth, lists, appInfo, identifierOperations, localStorageOperations, indexOperations }), [auth, lists, appInfo, identifierOperations, localStorageOperations]);
return (
+
{children}
);
diff --git a/src/hooks/useIndexes.tsx b/src/hooks/useIndexes.tsx
new file mode 100644
index 0000000..8aa28df
--- /dev/null
+++ b/src/hooks/useIndexes.tsx
@@ -0,0 +1,20 @@
+import React, { useCallback } from "react";
+import { OpenIndex, useIndexStore } from "../state/indexes";
+
+export const useIndexes = () => {
+ const setOpen = useIndexStore((state) => state.setOpen);
+ const openPageIndexManager = useCallback(
+ ({ link, name }: OpenIndex) => {
+ if(!link || !name) return
+ setOpen({
+ name,
+ link,
+ });
+ },
+ [setOpen]
+ );
+
+ return {
+ openPageIndexManager,
+ };
+};
diff --git a/src/index.ts b/src/index.ts
index d02ed18..146862c 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,8 @@
export { useResourceStatus } from './hooks/useResourceStatus';
+export { Spacer } from './common/Spacer';
import './index.css'
+export { hashWordWithoutPublicSalt } from './utils/encryption';
+export { createAvatarLink } from './utils/qortal';
export { objectToBase64 } from './utils/base64';
export { generateBloomFilterBase64, isInsideBloom } from './utils/bloomFilter';
export { addAndEncryptSymmetricKeys, decryptWithSymmetricKeys, encryptWithSymmetricKeys } from './utils/encryption';
@@ -20,4 +23,3 @@ export {Service} from './types/interfaces/resources'
export {ListItem} from './state/cache'
export {SymmetricKeys} from './utils/encryption'
-
diff --git a/src/state/indexes.ts b/src/state/indexes.ts
new file mode 100644
index 0000000..08ff4e8
--- /dev/null
+++ b/src/state/indexes.ts
@@ -0,0 +1,18 @@
+import { create } from "zustand";
+
+export interface OpenIndex {
+ link: string
+ name: string
+}
+
+interface IndexState {
+ open: OpenIndex | null;
+ setOpen: (openIndex: OpenIndex | null ) => void;
+}
+
+// ✅ Typed Zustand Store
+export const useIndexStore = create((set) => ({
+ open: null,
+ setOpen: (openIndex) =>
+ set({ open: openIndex }),
+}));
diff --git a/src/utils/encryption.ts b/src/utils/encryption.ts
index 1cf33d5..bcacd34 100644
--- a/src/utils/encryption.ts
+++ b/src/utils/encryption.ts
@@ -48,6 +48,35 @@ export async function hashWord(
}
}
+export async function hashWordWithoutPublicSalt(
+ word: string,
+ collisionStrength: number
+): Promise {
+ try {
+ if (!crypto?.subtle?.digest) throw new Error("Web Crypto not available");
+
+ const encoded = new TextEncoder().encode(word);
+ const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
+
+ return Buffer.from(hashBuffer)
+ .toString("base64")
+ .replace(/\+/g, "-")
+ .replace(/\//g, "_")
+ .replace(/=+$/, "")
+ .slice(0, collisionStrength);
+ } catch (err) {
+ const hash = SHA256(word);
+ const base64 = EncBase64.stringify(hash);
+
+ return base64
+ .replace(/\+/g, "-")
+ .replace(/\//g, "_")
+ .replace(/=+$/, "")
+ .slice(0, collisionStrength);
+ }
+}
+
+
const uid = new ShortUniqueId({ length: 10, dictionary: "alphanum" });
interface EntityConfig {
diff --git a/src/utils/qortal.ts b/src/utils/qortal.ts
new file mode 100644
index 0000000..78c3927
--- /dev/null
+++ b/src/utils/qortal.ts
@@ -0,0 +1,3 @@
+export const createAvatarLink = (qortalName: string)=> {
+ return `/arbitrary/THUMBNAIL/${encodeURIComponent(qortalName)}/qortal_avatar?async=true`
+}
\ No newline at end of file