From 760a312fc6eb20199dfd6765603b7f669abc557d Mon Sep 17 00:00:00 2001 From: Eugene Panteleymonchuk Date: Tue, 20 Feb 2024 17:20:58 +0200 Subject: [PATCH 01/10] feat: Add search state. Signed-off-by: Eugene Panteleymonchuk --- .../visualizer-threejs/VisualizerInstance.tsx | 6 ++++- .../features/visualizer-threejs/constants.ts | 14 ++++++++---- .../visualizer-threejs/hooks/useMouseMove.ts | 5 +++-- .../visualizer-threejs/store/search.ts | 22 +++++++++++++++++++ .../visualizer-threejs/store/tangle.ts | 2 +- .../visualizer-threejs/wrapper/KeyPanel.tsx | 22 ++++++++++++++----- 6 files changed, 57 insertions(+), 14 deletions(-) create mode 100644 client/src/features/visualizer-threejs/store/search.ts diff --git a/client/src/features/visualizer-threejs/VisualizerInstance.tsx b/client/src/features/visualizer-threejs/VisualizerInstance.tsx index 64a86fc0d..ba3bacd4a 100644 --- a/client/src/features/visualizer-threejs/VisualizerInstance.tsx +++ b/client/src/features/visualizer-threejs/VisualizerInstance.tsx @@ -214,7 +214,7 @@ const VisualizerInstance: React.FC> = bpsCounter.start(); } - blockMetadata.set(blockData.blockId, blockData); + blockMetadata.set(blockData.blockId, { ...blockData, treeColor: PENDING_BLOCK_COLOR }); // edges const blockStrongParents = (blockData.block.body as BasicBlockBody).strongParents ?? []; @@ -243,6 +243,10 @@ const VisualizerInstance: React.FC> = if (metadataUpdate?.blockState) { const selectedColor = BLOCK_STATE_TO_COLOR.get(metadataUpdate.blockState); if (selectedColor) { + const currentBlockMetadata = blockMetadata.get(metadataUpdate.blockId); + if (currentBlockMetadata) { + currentBlockMetadata.treeColor = selectedColor; + } addToColorQueue(metadataUpdate.blockId, selectedColor); } diff --git a/client/src/features/visualizer-threejs/constants.ts b/client/src/features/visualizer-threejs/constants.ts index 37b399ec5..1e94460fd 100644 --- a/client/src/features/visualizer-threejs/constants.ts +++ b/client/src/features/visualizer-threejs/constants.ts @@ -22,10 +22,16 @@ export const DATA_SENDER_TIME_INTERVAL = 500; export const ANIMATION_TIME_SECONDS = 3; // colors -export const PENDING_BLOCK_COLOR = new Color("#A6C3FC"); -export const ACCEPTED_BLOCK_COLOR = new Color("#0101AB"); -export const CONFIRMED_BLOCK_COLOR = new Color("#0000DB"); -export const FINALIZED_BLOCK_COLOR = new Color("#0101FF"); +export const PENDING_BLOCK_COLOR_HASH = "#A6C3FC"; +export const PENDING_BLOCK_COLOR = new Color(PENDING_BLOCK_COLOR_HASH); +export const ACCEPTED_BLOCK_COLOR_HASH = "#0101AB"; +export const ACCEPTED_BLOCK_COLOR = new Color(ACCEPTED_BLOCK_COLOR_HASH); +export const CONFIRMED_BLOCK_COLOR_HASH = "#0000DB"; +export const CONFIRMED_BLOCK_COLOR = new Color(CONFIRMED_BLOCK_COLOR_HASH); +export const FINALIZED_BLOCK_COLOR_HASH = "#0101FF"; +export const FINALIZED_BLOCK_COLOR = new Color(FINALIZED_BLOCK_COLOR_HASH); +export const SEARCH_RESULT_COLOR_HASH = "#C026D3"; +export const SEARCH_RESULT_COLOR = new Color(SEARCH_RESULT_COLOR_HASH); // TODO Remove accepted state once is added to the SDK (missing) export const BLOCK_STATE_TO_COLOR = new Map([ ["pending", PENDING_BLOCK_COLOR], diff --git a/client/src/features/visualizer-threejs/hooks/useMouseMove.ts b/client/src/features/visualizer-threejs/hooks/useMouseMove.ts index 0b6d1fd42..e8a934fb0 100644 --- a/client/src/features/visualizer-threejs/hooks/useMouseMove.ts +++ b/client/src/features/visualizer-threejs/hooks/useMouseMove.ts @@ -2,6 +2,7 @@ import { useThree } from "@react-three/fiber"; import React, { useCallback, useState, useRef, useEffect } from "react"; import * as THREE from "three"; import { useTangleStore } from "../store"; +import { SEARCH_RESULT_COLOR } from "~features/visualizer-threejs/constants"; export const useMouseMove = ({ tangleMeshRef, @@ -12,6 +13,7 @@ export const useMouseMove = ({ const [hoveredInstanceId, setHoveredInstanceId] = useState(null); const setClickedInstanceId = useTangleStore((s) => s.setClickedInstanceId); const clickedInstanceId = useTangleStore((s) => s.clickedInstanceId); + const blockMetadata = useTangleStore((s) => s.blockMetadata); const originalColorsRef = useRef>(new Map()); const updateMouseMove = useCallback( @@ -40,7 +42,6 @@ export const useMouseMove = ({ cb(null); } else { const { instanceId } = firstIntersect; - const color = new THREE.Color(0xff0000); // Red color // If we're hovering over a new instance, save the current color and set to red if (hoveredInstanceId !== instanceId) { @@ -51,7 +52,7 @@ export const useMouseMove = ({ originalColorsRef.current.set(instanceId, currentColor); // Set the new hovered instance color to red - tangleMeshRef.current.setColorAt(instanceId, color); + tangleMeshRef.current.setColorAt(instanceId, SEARCH_RESULT_COLOR); cb(instanceId); } } diff --git a/client/src/features/visualizer-threejs/store/search.ts b/client/src/features/visualizer-threejs/store/search.ts new file mode 100644 index 000000000..48951c8e9 --- /dev/null +++ b/client/src/features/visualizer-threejs/store/search.ts @@ -0,0 +1,22 @@ +import { create } from "zustand"; + +interface SearchState { + searchQuery: string; + matchingBlockIds: string[]; + setSearchQuery: (query: string) => void; + setBlockIds: (ids: string[]) => void; +} + +// Create the store +const useSearchStore = create((set) => ({ + searchQuery: '', + matchingBlockIds: [], + + // Action to update the search query + setSearchQuery: (query) => set({ searchQuery: query }), + + // Action to update the block IDs + setBlockIds: (ids) => set({ matchingBlockIds: ids }), +})); + +export default useSearchStore; diff --git a/client/src/features/visualizer-threejs/store/tangle.ts b/client/src/features/visualizer-threejs/store/tangle.ts index 9633cb195..8f6213124 100644 --- a/client/src/features/visualizer-threejs/store/tangle.ts +++ b/client/src/features/visualizer-threejs/store/tangle.ts @@ -48,7 +48,7 @@ interface TangleState { blockIdToIndex: Map; blockIdToEdges: Map; blockIdToPosition: Map; - blockMetadata: Map; + blockMetadata: Map; blockIdToAnimationPosition: Map; indexToBlockId: string[]; diff --git a/client/src/features/visualizer-threejs/wrapper/KeyPanel.tsx b/client/src/features/visualizer-threejs/wrapper/KeyPanel.tsx index f2affbbea..dce17f02f 100644 --- a/client/src/features/visualizer-threejs/wrapper/KeyPanel.tsx +++ b/client/src/features/visualizer-threejs/wrapper/KeyPanel.tsx @@ -1,33 +1,38 @@ import React from "react"; import { BlockState } from "@iota/sdk-wasm-nova/web"; - +import { + ACCEPTED_BLOCK_COLOR_HASH, + CONFIRMED_BLOCK_COLOR_HASH, + FINALIZED_BLOCK_COLOR_HASH, + PENDING_BLOCK_COLOR_HASH, SEARCH_RESULT_COLOR_HASH +} from "../constants"; import "./KeyPanel.scss"; export const KeyPanel: React.FC = () => { const statuses: { label: string; - state: BlockState; + state: BlockState | 'searchResult'; color: string; }[] = [ { label: "Pending", state: "pending", - color: "#A6C3FC", + color: PENDING_BLOCK_COLOR_HASH, }, { label: "Accepted", state: "accepted", - color: "#0101AB", + color: ACCEPTED_BLOCK_COLOR_HASH, }, { label: "Confirmed", state: "confirmed", - color: "#0000DB", + color: CONFIRMED_BLOCK_COLOR_HASH, }, { label: "Finalized", state: "finalized", - color: "#0101FF", + color: FINALIZED_BLOCK_COLOR_HASH, }, { label: "Rejected", @@ -39,6 +44,11 @@ export const KeyPanel: React.FC = () => { state: "failed", color: "#ff1d38", }, + { + label: "Search result", + state: "searchResult", + color: SEARCH_RESULT_COLOR_HASH, + }, ]; return ( From 88e275e7b8cb3260b087d20cd29e19a07699c991 Mon Sep 17 00:00:00 2001 From: Eugene Panteleymonchuk Date: Tue, 20 Feb 2024 19:33:36 +0200 Subject: [PATCH 02/10] feat: poc highlight search results Signed-off-by: Eugene Panteleymonchuk --- .../visualizer-threejs/VisualizerInstance.tsx | 10 +- .../visualizer-threejs/store/search.ts | 4 +- .../visualizer-threejs/store/tangle.ts | 11 ++ .../visualizer-threejs/useRenderTangle.tsx | 1 + .../visualizer-threejs/wrapper/Wrapper.tsx | 123 ++++++++++++------ 5 files changed, 104 insertions(+), 45 deletions(-) diff --git a/client/src/features/visualizer-threejs/VisualizerInstance.tsx b/client/src/features/visualizer-threejs/VisualizerInstance.tsx index ba3bacd4a..153af97dc 100644 --- a/client/src/features/visualizer-threejs/VisualizerInstance.tsx +++ b/client/src/features/visualizer-threejs/VisualizerInstance.tsx @@ -32,6 +32,7 @@ import { BasicBlockBody, Utils, type IBlockMetadata, type BlockState, type SlotI import { IFeedBlockData } from "~/models/api/nova/feed/IFeedBlockData"; import CameraControls from "./CameraControls"; import "./Visualizer.scss"; +import useSearchStore from "~features/visualizer-threejs/store/search"; const features = { statsEnabled: true, @@ -68,6 +69,8 @@ const VisualizerInstance: React.FC> = const blockMetadata = useTangleStore((s) => s.blockMetadata); const indexToBlockId = useTangleStore((s) => s.indexToBlockId); const clickedInstanceId = useTangleStore((s) => s.clickedInstanceId); + const matchingBlockIds = useSearchStore((state) => state.matchingBlockIds); + // Confirmed or accepted blocks by slot const confirmedBlocksBySlot = useTangleStore((s) => s.confirmedBlocksBySlot); @@ -240,6 +243,7 @@ const VisualizerInstance: React.FC> = }; function onBlockMetadataUpdate(metadataUpdate: IBlockMetadata): void { + // Utils if (metadataUpdate?.blockState) { const selectedColor = BLOCK_STATE_TO_COLOR.get(metadataUpdate.blockState); if (selectedColor) { @@ -247,7 +251,9 @@ const VisualizerInstance: React.FC> = if (currentBlockMetadata) { currentBlockMetadata.treeColor = selectedColor; } - addToColorQueue(metadataUpdate.blockId, selectedColor); + if (!matchingBlockIds.includes(metadataUpdate.blockId)) { + addToColorQueue(metadataUpdate.blockId, selectedColor); + } } const acceptedStates: BlockState[] = ["confirmed", "accepted"]; @@ -278,11 +284,9 @@ const VisualizerInstance: React.FC> = {}} selectNode={() => {}} selectedFeedItem={selectedFeedItem} setIsPlaying={setIsPlaying} diff --git a/client/src/features/visualizer-threejs/store/search.ts b/client/src/features/visualizer-threejs/store/search.ts index 48951c8e9..955f9224a 100644 --- a/client/src/features/visualizer-threejs/store/search.ts +++ b/client/src/features/visualizer-threejs/store/search.ts @@ -4,7 +4,7 @@ interface SearchState { searchQuery: string; matchingBlockIds: string[]; setSearchQuery: (query: string) => void; - setBlockIds: (ids: string[]) => void; + setMatchingBlockIds: (ids: string[]) => void; } // Create the store @@ -16,7 +16,7 @@ const useSearchStore = create((set) => ({ setSearchQuery: (query) => set({ searchQuery: query }), // Action to update the block IDs - setBlockIds: (ids) => set({ matchingBlockIds: ids }), + setMatchingBlockIds: (ids) => set({ matchingBlockIds: ids }), })); export default useSearchStore; diff --git a/client/src/features/visualizer-threejs/store/tangle.ts b/client/src/features/visualizer-threejs/store/tangle.ts index 8f6213124..5de5258f0 100644 --- a/client/src/features/visualizer-threejs/store/tangle.ts +++ b/client/src/features/visualizer-threejs/store/tangle.ts @@ -42,6 +42,7 @@ interface TangleState { colorQueue: Pick[]; addToColorQueue: (blockId: string, color: Color) => void; + addToColorQueueBulk: (list: { id: string; color: Color; }[]) => void; removeFromColorQueue: (blockIds: string[]) => void; // Map of blockId to index in Tangle 'InstancedMesh' @@ -162,6 +163,16 @@ export const useTangleStore = create()( colorQueue: [...state.colorQueue, { id, color }], })); }, + + addToColorQueueBulk: (list) => { + set((state) => ({ + ...state, + colorQueue: [ + ...state.colorQueue, + ...list.map(({ id, color }) => ({ id, color })), + ], + })); + }, removeFromColorQueue: (blockIds) => { if (blockIds.length > 0) { set((state) => ({ diff --git a/client/src/features/visualizer-threejs/useRenderTangle.tsx b/client/src/features/visualizer-threejs/useRenderTangle.tsx index 4e6e93604..3d7ec6bcc 100644 --- a/client/src/features/visualizer-threejs/useRenderTangle.tsx +++ b/client/src/features/visualizer-threejs/useRenderTangle.tsx @@ -165,6 +165,7 @@ export const useRenderTangle = () => { useEffect(() => { if (colorQueue.length > 0) { const removeIds: string[] = []; + for (const { id, color } of colorQueue) { const indexToUpdate = blockIdToIndex.get(id); diff --git a/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx b/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx index 84c8d0b31..7e9f1e2d4 100644 --- a/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx +++ b/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx @@ -6,16 +6,17 @@ import { KeyPanel } from "./KeyPanel"; import mainHeader from "~assets/modals/visualizer/main-header.json"; import { SelectedFeedInfo } from "./SelectedFeedInfo"; import { StatsPanel } from "./StatsPanel"; +import useSearchStore from "~features/visualizer-threejs/store/search"; +import { useTangleStore } from "~features/visualizer-threejs/store/tangle"; +import { IFeedBlockData } from "~models/api/nova/feed/IFeedBlockData"; +import { SEARCH_RESULT_COLOR } from "~features/visualizer-threejs/constants"; export const Wrapper = ({ blocksCount, children, - filter, isPlaying, network, networkConfig, - onChangeFilter, - selectNode, selectedFeedItem, setIsPlaying, isEdgeRenderingEnabled, @@ -23,56 +24,98 @@ export const Wrapper = ({ }: { readonly blocksCount: number; readonly children: React.ReactNode; - readonly filter: string; readonly isPlaying: boolean; readonly network: string; readonly networkConfig: INetwork; - readonly onChangeFilter: React.ChangeEventHandler; readonly selectNode: TSelectNode; readonly selectedFeedItem: TSelectFeedItemNova; readonly setIsPlaying: (isPlaying: boolean) => void; readonly isEdgeRenderingEnabled?: boolean; readonly setEdgeRenderingEnabled?: (isEnabled: boolean) => void; -}) => ( -
-
-
-

Visualizer

- -
-
-
-
Search
- +}) => { + const searchQuery = useSearchStore((state) => state.searchQuery); + const setSearchQuery = useSearchStore((state) => state.setSearchQuery); + const matchingBlockIds = useSearchStore((state) => state.matchingBlockIds); + const setMatchingBlockIds = useSearchStore((state) => state.setMatchingBlockIds); + const blockMetadata = useTangleStore((state) => state.blockMetadata); + const addToColorQueueBulk = useTangleStore((s) => s.addToColorQueueBulk); + + + const matchLatestFinalizedSlot = React.useCallback((block: IFeedBlockData, searchQuery: string) => { + if (!searchQuery || Number.isNaN(Number(searchQuery))) { + return false; + } + + const latestFinalizedSlot = block?.block?.header?.latestFinalizedSlot; + + return latestFinalizedSlot === Number(searchQuery); + }, []); + + React.useEffect(() => { + console.log('--- blo', blockMetadata); + if (searchQuery) { + const tempMatchingBlockIds: string[] = []; + blockMetadata.forEach((i) => { + if (matchLatestFinalizedSlot(i, searchQuery)) { + tempMatchingBlockIds.push(i.blockId); + } + }); + + + addToColorQueueBulk(tempMatchingBlockIds.map((id) => ({id: id, color: SEARCH_RESULT_COLOR}))); + setMatchingBlockIds(tempMatchingBlockIds); + } else { + if (matchingBlockIds.length > 0) { + + } + setMatchingBlockIds([]); + } + }, [searchQuery]); + + + return ( +
+
+
+

Visualizer

+
-
-
-
- {children} -
-
- +
+
+
Search
+ { + setSearchQuery(e.target.value); + }} maxLength={2000} /> +
- {isEdgeRenderingEnabled !== undefined && setEdgeRenderingEnabled !== undefined && ( -
-

Show edges:

- setEdgeRenderingEnabled(checked)} - /> +
+
+ {children} +
+
+
- )} + {isEdgeRenderingEnabled !== undefined && setEdgeRenderingEnabled !== undefined && ( +
+

Show edges:

+ setEdgeRenderingEnabled(checked)} + /> +
+ )} +
+ + {selectedFeedItem && } +
- - {selectedFeedItem && } - -
-); + ); +}; Wrapper.defaultProps = { isEdgeRenderingEnabled: undefined, From 993b73222e19d7838fc4f9984ab4b77b692af19d Mon Sep 17 00:00:00 2001 From: Eugene Panteleymonchuk Date: Wed, 21 Feb 2024 17:23:07 +0200 Subject: [PATCH 03/10] feat: highlight when add new block (not done) Signed-off-by: Eugene Panteleymonchuk --- .../visualizer-threejs/useRenderTangle.tsx | 19 +++++-- .../visualizer-threejs/wrapper/Wrapper.tsx | 50 ++++++++++++++----- 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/client/src/features/visualizer-threejs/useRenderTangle.tsx b/client/src/features/visualizer-threejs/useRenderTangle.tsx index 3d7ec6bcc..7c57a2f1c 100644 --- a/client/src/features/visualizer-threejs/useRenderTangle.tsx +++ b/client/src/features/visualizer-threejs/useRenderTangle.tsx @@ -1,10 +1,12 @@ import { useThree } from "@react-three/fiber"; import { useEffect, useRef } from "react"; import * as THREE from "three"; -import { MAX_BLOCK_INSTANCES, NODE_SIZE_DEFAULT, ANIMATION_TIME_SECONDS } from "./constants"; +import { MAX_BLOCK_INSTANCES, NODE_SIZE_DEFAULT, ANIMATION_TIME_SECONDS, SEARCH_RESULT_COLOR } from "./constants"; import { useMouseMove } from "./hooks/useMouseMove"; import { BlockState, IBlockInitPosition, useConfigStore, useTangleStore } from "./store"; import { useRenderEdges } from "./useRenderEdges"; +import useSearchStore from "~features/visualizer-threejs/store/search"; +import { Color } from "three"; const SPHERE_GEOMETRY = new THREE.SphereGeometry(NODE_SIZE_DEFAULT, 32, 16); const SPHERE_MATERIAL = new THREE.MeshPhongMaterial(); @@ -27,7 +29,7 @@ export const useRenderTangle = () => { const updateBlockIdToIndex = useTangleStore((s) => s.updateBlockIdToIndex); const blockIdToPosition = useTangleStore((s) => s.blockIdToPosition); const blockIdToAnimationPosition = useTangleStore((s) => s.blockIdToAnimationPosition); - + const matchingBlockIds = useSearchStore((state) => state.matchingBlockIds); function updateInstancedMeshPosition( instancedMesh: THREE.InstancedMesh, index: number, @@ -166,10 +168,11 @@ export const useRenderTangle = () => { if (colorQueue.length > 0) { const removeIds: string[] = []; - for (const { id, color } of colorQueue) { + for (const { id, color: colorFromQueue } of colorQueue) { const indexToUpdate = blockIdToIndex.get(id); if (indexToUpdate) { + const color = determineColor(matchingBlockIds, colorFromQueue, id); tangleMeshRef.current.setColorAt(indexToUpdate, color); if (tangleMeshRef.current.instanceColor) { @@ -182,5 +185,13 @@ export const useRenderTangle = () => { removeFromColorQueue(removeIds); } - }, [colorQueue, blockIdToIndex]); + }, [colorQueue, blockIdToIndex, matchingBlockIds]); }; + + +function determineColor(matchingBlockIds: string[], metadataColor: Color, blockId: string) { + if (matchingBlockIds.includes(blockId)) { + return SEARCH_RESULT_COLOR; + } + return metadataColor; +} diff --git a/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx b/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx index 7e9f1e2d4..9c0dd2f02 100644 --- a/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx +++ b/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx @@ -10,6 +10,7 @@ import useSearchStore from "~features/visualizer-threejs/store/search"; import { useTangleStore } from "~features/visualizer-threejs/store/tangle"; import { IFeedBlockData } from "~models/api/nova/feed/IFeedBlockData"; import { SEARCH_RESULT_COLOR } from "~features/visualizer-threejs/constants"; +import { Color } from "three"; export const Wrapper = ({ blocksCount, @@ -52,26 +53,49 @@ export const Wrapper = ({ }, []); React.useEffect(() => { - console.log('--- blo', blockMetadata); - if (searchQuery) { - const tempMatchingBlockIds: string[] = []; - blockMetadata.forEach((i) => { - if (matchLatestFinalizedSlot(i, searchQuery)) { - tempMatchingBlockIds.push(i.blockId); - } - }); + // [] Search empty - put value + // [] check matches + // [] if matches - add to color queue + // [] Search empty - remove value + // [] remove from color queue + // [] Search not empty - put value + // [] check matches + // [] if matches - add to color queue + const colorsQueue = []; - addToColorQueueBulk(tempMatchingBlockIds.map((id) => ({id: id, color: SEARCH_RESULT_COLOR}))); - setMatchingBlockIds(tempMatchingBlockIds); - } else { - if (matchingBlockIds.length > 0) { + const tempMatchingBlockIds: string[] = []; + blockMetadata.forEach((i) => { + if (matchLatestFinalizedSlot(i, searchQuery)) { + tempMatchingBlockIds.push(i.blockId); } - setMatchingBlockIds([]); + }); + + + // before we need to clear the previous search results + if (matchingBlockIds.length > 0) { + matchingBlockIds.forEach((id) => { + const metadata = blockMetadata.get(id); + const treeColor = metadata?.treeColor as Color; + if (treeColor) { + colorsQueue.push({id: id, color: treeColor}); + } + }); } + + if (tempMatchingBlockIds.length > 0) { + colorsQueue.push(...tempMatchingBlockIds.map((id) => ({id: id, color: SEARCH_RESULT_COLOR}))); + } + + addToColorQueueBulk(colorsQueue); + setMatchingBlockIds(tempMatchingBlockIds); }, [searchQuery]); + React.useEffect(() => { + + }, [matchingBlockIds]); + return (
From 56d45336efeaadfce24128ff199f7c86d7165524 Mon Sep 17 00:00:00 2001 From: Eugene Panteleymonchuk Date: Thu, 22 Feb 2024 10:47:42 +0200 Subject: [PATCH 04/10] feat: highlight when add new block Signed-off-by: Eugene Panteleymonchuk --- .../visualizer-threejs/VisualizerInstance.tsx | 8 +++- .../visualizer-threejs/hooks/useSearch.ts | 41 ++++++++++++++++ .../visualizer-threejs/store/search.ts | 6 ++- .../visualizer-threejs/wrapper/Wrapper.tsx | 48 ++++++++----------- 4 files changed, 72 insertions(+), 31 deletions(-) create mode 100644 client/src/features/visualizer-threejs/hooks/useSearch.ts diff --git a/client/src/features/visualizer-threejs/VisualizerInstance.tsx b/client/src/features/visualizer-threejs/VisualizerInstance.tsx index 153af97dc..4780e262b 100644 --- a/client/src/features/visualizer-threejs/VisualizerInstance.tsx +++ b/client/src/features/visualizer-threejs/VisualizerInstance.tsx @@ -33,6 +33,7 @@ import { IFeedBlockData } from "~/models/api/nova/feed/IFeedBlockData"; import CameraControls from "./CameraControls"; import "./Visualizer.scss"; import useSearchStore from "~features/visualizer-threejs/store/search"; +import { useSearch } from "~features/visualizer-threejs/hooks/useSearch"; const features = { statsEnabled: true, @@ -44,6 +45,7 @@ const VisualizerInstance: React.FC> = params: { network }, }, }) => { + const { isSearchMatch, highlightSearchBlock } = useSearch(); const [networkConfig] = useNetworkConfig(network); const generateYZPositions = getGenerateDynamicYZPosition(); const themeMode = useGetThemeMode(); @@ -71,7 +73,6 @@ const VisualizerInstance: React.FC> = const clickedInstanceId = useTangleStore((s) => s.clickedInstanceId); const matchingBlockIds = useSearchStore((state) => state.matchingBlockIds); - // Confirmed or accepted blocks by slot const confirmedBlocksBySlot = useTangleStore((s) => s.confirmedBlocksBySlot); const addToConfirmedBlocksSlot = useTangleStore((s) => s.addToConfirmedBlocksBySlot); @@ -229,6 +230,10 @@ const VisualizerInstance: React.FC> = addToEdgeQueue(blockData.blockId, blockWeakParents); } + if (isSearchMatch(blockData)) { + highlightSearchBlock(blockData.blockId); + } + addBlock({ id: blockData.blockId, color: PENDING_BLOCK_COLOR, @@ -243,7 +248,6 @@ const VisualizerInstance: React.FC> = }; function onBlockMetadataUpdate(metadataUpdate: IBlockMetadata): void { - // Utils if (metadataUpdate?.blockState) { const selectedColor = BLOCK_STATE_TO_COLOR.get(metadataUpdate.blockState); if (selectedColor) { diff --git a/client/src/features/visualizer-threejs/hooks/useSearch.ts b/client/src/features/visualizer-threejs/hooks/useSearch.ts new file mode 100644 index 000000000..90eee82b6 --- /dev/null +++ b/client/src/features/visualizer-threejs/hooks/useSearch.ts @@ -0,0 +1,41 @@ +// import React from "react"; +import { IFeedBlockData } from "~models/api/nova/feed/IFeedBlockData"; +import useSearchStore from "~features/visualizer-threejs/store/search"; +import { useTangleStore } from "~features/visualizer-threejs/store"; +import { SEARCH_RESULT_COLOR } from "~features/visualizer-threejs/constants"; + +export const useSearch = () => { + const searchQuery = useSearchStore((state) => state.searchQuery); + const addToColorQueue = useTangleStore((s) => s.addToColorQueue); + + const isSearchMatch = (block: IFeedBlockData) => { + const searchQuery = useSearchStore.getState().searchQuery; + + return matchLatestFinalizedSlot(block, searchQuery); + }; + + const highlightSearchBlock = (blockId: string) => { + useSearchStore.getState().addMatchingBlockId(blockId); + addToColorQueue(blockId, SEARCH_RESULT_COLOR); + }; + + return { + searchQuery, + isSearchMatch, + highlightSearchBlock, + }; +}; + +export function isSearchMatch(block: IFeedBlockData, searchQuery: string) { + return matchLatestFinalizedSlot(block, searchQuery); // note: here we can add more checks as separate functions +} + +export function matchLatestFinalizedSlot(block: IFeedBlockData, searchQuery: string) { + if (!searchQuery || Number.isNaN(Number(searchQuery))) { + return false; + } + + const latestFinalizedSlot = block?.block?.header?.latestFinalizedSlot; + + return latestFinalizedSlot === Number(searchQuery); +} diff --git a/client/src/features/visualizer-threejs/store/search.ts b/client/src/features/visualizer-threejs/store/search.ts index 955f9224a..88e918490 100644 --- a/client/src/features/visualizer-threejs/store/search.ts +++ b/client/src/features/visualizer-threejs/store/search.ts @@ -5,11 +5,12 @@ interface SearchState { matchingBlockIds: string[]; setSearchQuery: (query: string) => void; setMatchingBlockIds: (ids: string[]) => void; + addMatchingBlockId: (id: string) => void; } // Create the store const useSearchStore = create((set) => ({ - searchQuery: '', + searchQuery: "", matchingBlockIds: [], // Action to update the search query @@ -17,6 +18,9 @@ const useSearchStore = create((set) => ({ // Action to update the block IDs setMatchingBlockIds: (ids) => set({ matchingBlockIds: ids }), + + // Action to add a block ID + addMatchingBlockId: (id) => set((state) => ({ matchingBlockIds: [...state.matchingBlockIds, id] })), })); export default useSearchStore; diff --git a/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx b/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx index 9c0dd2f02..1771421c7 100644 --- a/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx +++ b/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx @@ -8,9 +8,10 @@ import { SelectedFeedInfo } from "./SelectedFeedInfo"; import { StatsPanel } from "./StatsPanel"; import useSearchStore from "~features/visualizer-threejs/store/search"; import { useTangleStore } from "~features/visualizer-threejs/store/tangle"; -import { IFeedBlockData } from "~models/api/nova/feed/IFeedBlockData"; +// import { IFeedBlockData } from "~models/api/nova/feed/IFeedBlockData"; import { SEARCH_RESULT_COLOR } from "~features/visualizer-threejs/constants"; import { Color } from "three"; +import { isSearchMatch } from "~features/visualizer-threejs/hooks/useSearch"; export const Wrapper = ({ blocksCount, @@ -41,61 +42,46 @@ export const Wrapper = ({ const blockMetadata = useTangleStore((state) => state.blockMetadata); const addToColorQueueBulk = useTangleStore((s) => s.addToColorQueueBulk); - - const matchLatestFinalizedSlot = React.useCallback((block: IFeedBlockData, searchQuery: string) => { - if (!searchQuery || Number.isNaN(Number(searchQuery))) { - return false; - } - - const latestFinalizedSlot = block?.block?.header?.latestFinalizedSlot; - - return latestFinalizedSlot === Number(searchQuery); - }, []); - React.useEffect(() => { // [] Search empty - put value - // [] check matches - // [] if matches - add to color queue + // [] check matches + // [] if matches - add to color queue // [] Search empty - remove value - // [] remove from color queue + // [] remove from color queue // [] Search not empty - put value - // [] check matches - // [] if matches - add to color queue + // [] check matches + // [] if matches - add to color queue const colorsQueue = []; const tempMatchingBlockIds: string[] = []; blockMetadata.forEach((i) => { - if (matchLatestFinalizedSlot(i, searchQuery)) { + if (isSearchMatch(i, searchQuery)) { tempMatchingBlockIds.push(i.blockId); } }); - // before we need to clear the previous search results if (matchingBlockIds.length > 0) { matchingBlockIds.forEach((id) => { const metadata = blockMetadata.get(id); const treeColor = metadata?.treeColor as Color; if (treeColor) { - colorsQueue.push({id: id, color: treeColor}); + colorsQueue.push({ id: id, color: treeColor }); } }); } if (tempMatchingBlockIds.length > 0) { - colorsQueue.push(...tempMatchingBlockIds.map((id) => ({id: id, color: SEARCH_RESULT_COLOR}))); + colorsQueue.push(...tempMatchingBlockIds.map((id) => ({ id: id, color: SEARCH_RESULT_COLOR }))); } addToColorQueueBulk(colorsQueue); setMatchingBlockIds(tempMatchingBlockIds); }, [searchQuery]); - React.useEffect(() => { - - }, [matchingBlockIds]); - + React.useEffect(() => {}, [matchingBlockIds]); return (
@@ -107,9 +93,15 @@ export const Wrapper = ({
Search
- { - setSearchQuery(e.target.value); - }} maxLength={2000} /> + { + setSearchQuery(e.target.value); + }} + maxLength={2000} + />
From e56d6a5de2f75846c3779c3594a6398ae9bbe814 Mon Sep 17 00:00:00 2001 From: Eugene Panteleymonchuk Date: Thu, 22 Feb 2024 10:49:30 +0200 Subject: [PATCH 05/10] fix: format Signed-off-by: Eugene Panteleymonchuk --- .../features/visualizer-threejs/hooks/useMouseMove.ts | 1 - client/src/features/visualizer-threejs/store/tangle.ts | 9 +++------ .../src/features/visualizer-threejs/useRenderTangle.tsx | 1 - .../src/features/visualizer-threejs/wrapper/KeyPanel.tsx | 5 +++-- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/client/src/features/visualizer-threejs/hooks/useMouseMove.ts b/client/src/features/visualizer-threejs/hooks/useMouseMove.ts index e8a934fb0..b78d966df 100644 --- a/client/src/features/visualizer-threejs/hooks/useMouseMove.ts +++ b/client/src/features/visualizer-threejs/hooks/useMouseMove.ts @@ -13,7 +13,6 @@ export const useMouseMove = ({ const [hoveredInstanceId, setHoveredInstanceId] = useState(null); const setClickedInstanceId = useTangleStore((s) => s.setClickedInstanceId); const clickedInstanceId = useTangleStore((s) => s.clickedInstanceId); - const blockMetadata = useTangleStore((s) => s.blockMetadata); const originalColorsRef = useRef>(new Map()); const updateMouseMove = useCallback( diff --git a/client/src/features/visualizer-threejs/store/tangle.ts b/client/src/features/visualizer-threejs/store/tangle.ts index 5de5258f0..783c8eb71 100644 --- a/client/src/features/visualizer-threejs/store/tangle.ts +++ b/client/src/features/visualizer-threejs/store/tangle.ts @@ -42,14 +42,14 @@ interface TangleState { colorQueue: Pick[]; addToColorQueue: (blockId: string, color: Color) => void; - addToColorQueueBulk: (list: { id: string; color: Color; }[]) => void; + addToColorQueueBulk: (list: { id: string; color: Color }[]) => void; removeFromColorQueue: (blockIds: string[]) => void; // Map of blockId to index in Tangle 'InstancedMesh' blockIdToIndex: Map; blockIdToEdges: Map; blockIdToPosition: Map; - blockMetadata: Map; + blockMetadata: Map; blockIdToAnimationPosition: Map; indexToBlockId: string[]; @@ -167,10 +167,7 @@ export const useTangleStore = create()( addToColorQueueBulk: (list) => { set((state) => ({ ...state, - colorQueue: [ - ...state.colorQueue, - ...list.map(({ id, color }) => ({ id, color })), - ], + colorQueue: [...state.colorQueue, ...list.map(({ id, color }) => ({ id, color }))], })); }, removeFromColorQueue: (blockIds) => { diff --git a/client/src/features/visualizer-threejs/useRenderTangle.tsx b/client/src/features/visualizer-threejs/useRenderTangle.tsx index 7c57a2f1c..53ad2ad9e 100644 --- a/client/src/features/visualizer-threejs/useRenderTangle.tsx +++ b/client/src/features/visualizer-threejs/useRenderTangle.tsx @@ -188,7 +188,6 @@ export const useRenderTangle = () => { }, [colorQueue, blockIdToIndex, matchingBlockIds]); }; - function determineColor(matchingBlockIds: string[], metadataColor: Color, blockId: string) { if (matchingBlockIds.includes(blockId)) { return SEARCH_RESULT_COLOR; diff --git a/client/src/features/visualizer-threejs/wrapper/KeyPanel.tsx b/client/src/features/visualizer-threejs/wrapper/KeyPanel.tsx index dce17f02f..36d207c6b 100644 --- a/client/src/features/visualizer-threejs/wrapper/KeyPanel.tsx +++ b/client/src/features/visualizer-threejs/wrapper/KeyPanel.tsx @@ -4,14 +4,15 @@ import { ACCEPTED_BLOCK_COLOR_HASH, CONFIRMED_BLOCK_COLOR_HASH, FINALIZED_BLOCK_COLOR_HASH, - PENDING_BLOCK_COLOR_HASH, SEARCH_RESULT_COLOR_HASH + PENDING_BLOCK_COLOR_HASH, + SEARCH_RESULT_COLOR_HASH, } from "../constants"; import "./KeyPanel.scss"; export const KeyPanel: React.FC = () => { const statuses: { label: string; - state: BlockState | 'searchResult'; + state: BlockState | "searchResult"; color: string; }[] = [ { From 9aa1c3244c3b57d8ebf3367c16a3d5b29a2f5671 Mon Sep 17 00:00:00 2001 From: Eugene Panteleymonchuk Date: Thu, 22 Feb 2024 10:56:14 +0200 Subject: [PATCH 06/10] refactor: clean code. Signed-off-by: Eugene Panteleymonchuk --- .../visualizer-threejs/useRenderTangle.tsx | 19 ++++--------------- .../visualizer-threejs/wrapper/Wrapper.tsx | 9 --------- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/client/src/features/visualizer-threejs/useRenderTangle.tsx b/client/src/features/visualizer-threejs/useRenderTangle.tsx index 53ad2ad9e..4e6e93604 100644 --- a/client/src/features/visualizer-threejs/useRenderTangle.tsx +++ b/client/src/features/visualizer-threejs/useRenderTangle.tsx @@ -1,12 +1,10 @@ import { useThree } from "@react-three/fiber"; import { useEffect, useRef } from "react"; import * as THREE from "three"; -import { MAX_BLOCK_INSTANCES, NODE_SIZE_DEFAULT, ANIMATION_TIME_SECONDS, SEARCH_RESULT_COLOR } from "./constants"; +import { MAX_BLOCK_INSTANCES, NODE_SIZE_DEFAULT, ANIMATION_TIME_SECONDS } from "./constants"; import { useMouseMove } from "./hooks/useMouseMove"; import { BlockState, IBlockInitPosition, useConfigStore, useTangleStore } from "./store"; import { useRenderEdges } from "./useRenderEdges"; -import useSearchStore from "~features/visualizer-threejs/store/search"; -import { Color } from "three"; const SPHERE_GEOMETRY = new THREE.SphereGeometry(NODE_SIZE_DEFAULT, 32, 16); const SPHERE_MATERIAL = new THREE.MeshPhongMaterial(); @@ -29,7 +27,7 @@ export const useRenderTangle = () => { const updateBlockIdToIndex = useTangleStore((s) => s.updateBlockIdToIndex); const blockIdToPosition = useTangleStore((s) => s.blockIdToPosition); const blockIdToAnimationPosition = useTangleStore((s) => s.blockIdToAnimationPosition); - const matchingBlockIds = useSearchStore((state) => state.matchingBlockIds); + function updateInstancedMeshPosition( instancedMesh: THREE.InstancedMesh, index: number, @@ -167,12 +165,10 @@ export const useRenderTangle = () => { useEffect(() => { if (colorQueue.length > 0) { const removeIds: string[] = []; - - for (const { id, color: colorFromQueue } of colorQueue) { + for (const { id, color } of colorQueue) { const indexToUpdate = blockIdToIndex.get(id); if (indexToUpdate) { - const color = determineColor(matchingBlockIds, colorFromQueue, id); tangleMeshRef.current.setColorAt(indexToUpdate, color); if (tangleMeshRef.current.instanceColor) { @@ -185,12 +181,5 @@ export const useRenderTangle = () => { removeFromColorQueue(removeIds); } - }, [colorQueue, blockIdToIndex, matchingBlockIds]); + }, [colorQueue, blockIdToIndex]); }; - -function determineColor(matchingBlockIds: string[], metadataColor: Color, blockId: string) { - if (matchingBlockIds.includes(blockId)) { - return SEARCH_RESULT_COLOR; - } - return metadataColor; -} diff --git a/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx b/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx index 1771421c7..50fa0f77e 100644 --- a/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx +++ b/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx @@ -43,15 +43,6 @@ export const Wrapper = ({ const addToColorQueueBulk = useTangleStore((s) => s.addToColorQueueBulk); React.useEffect(() => { - // [] Search empty - put value - // [] check matches - // [] if matches - add to color queue - // [] Search empty - remove value - // [] remove from color queue - // [] Search not empty - put value - // [] check matches - // [] if matches - add to color queue - const colorsQueue = []; const tempMatchingBlockIds: string[] = []; From ad25b2005a4899939a8d441f18aac34e9c5ff6a3 Mon Sep 17 00:00:00 2001 From: Eugene Panteleymonchuk Date: Thu, 22 Feb 2024 11:13:01 +0200 Subject: [PATCH 07/10] search by blockId Signed-off-by: Eugene Panteleymonchuk --- .../src/features/visualizer-threejs/hooks/useSearch.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/client/src/features/visualizer-threejs/hooks/useSearch.ts b/client/src/features/visualizer-threejs/hooks/useSearch.ts index 90eee82b6..46c2a31d8 100644 --- a/client/src/features/visualizer-threejs/hooks/useSearch.ts +++ b/client/src/features/visualizer-threejs/hooks/useSearch.ts @@ -10,8 +10,7 @@ export const useSearch = () => { const isSearchMatch = (block: IFeedBlockData) => { const searchQuery = useSearchStore.getState().searchQuery; - - return matchLatestFinalizedSlot(block, searchQuery); + return matchLatestFinalizedSlot(block, searchQuery) || matchByBlockId(block, searchQuery); }; const highlightSearchBlock = (blockId: string) => { @@ -27,7 +26,11 @@ export const useSearch = () => { }; export function isSearchMatch(block: IFeedBlockData, searchQuery: string) { - return matchLatestFinalizedSlot(block, searchQuery); // note: here we can add more checks as separate functions + return matchLatestFinalizedSlot(block, searchQuery) || matchByBlockId(block, searchQuery); // note: here we can add more checks as separate functions +} + +export function matchByBlockId(block: IFeedBlockData, searchQuery: string) { + return block.blockId === searchQuery; } export function matchLatestFinalizedSlot(block: IFeedBlockData, searchQuery: string) { From 48596dd9b3798089107bec167ceae66c87edc720 Mon Sep 17 00:00:00 2001 From: Eugene P Date: Mon, 26 Feb 2024 17:06:52 +0200 Subject: [PATCH 08/10] chore: Update client/src/features/visualizer-threejs/hooks/useMouseMove.ts Co-authored-by: JCNoguera <88061365+VmMad@users.noreply.github.com> --- client/src/features/visualizer-threejs/hooks/useMouseMove.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/features/visualizer-threejs/hooks/useMouseMove.ts b/client/src/features/visualizer-threejs/hooks/useMouseMove.ts index b78d966df..cfd8ce83c 100644 --- a/client/src/features/visualizer-threejs/hooks/useMouseMove.ts +++ b/client/src/features/visualizer-threejs/hooks/useMouseMove.ts @@ -42,7 +42,7 @@ export const useMouseMove = ({ } else { const { instanceId } = firstIntersect; - // If we're hovering over a new instance, save the current color and set to red + // If we're hovering over a new instance, save the current color and set the hovered color if (hoveredInstanceId !== instanceId) { clearHoveredSpheres(); // Save the original color of the new hovered instance From 832b099e85a7f7cfc3468a12967fc963b95d8fe1 Mon Sep 17 00:00:00 2001 From: Eugene P Date: Mon, 26 Feb 2024 17:07:04 +0200 Subject: [PATCH 09/10] chore: Update client/src/features/visualizer-threejs/hooks/useMouseMove.ts Co-authored-by: JCNoguera <88061365+VmMad@users.noreply.github.com> --- client/src/features/visualizer-threejs/hooks/useMouseMove.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/features/visualizer-threejs/hooks/useMouseMove.ts b/client/src/features/visualizer-threejs/hooks/useMouseMove.ts index cfd8ce83c..01a8ce3e8 100644 --- a/client/src/features/visualizer-threejs/hooks/useMouseMove.ts +++ b/client/src/features/visualizer-threejs/hooks/useMouseMove.ts @@ -50,7 +50,7 @@ export const useMouseMove = ({ tangleMeshRef.current.getColorAt(instanceId, currentColor); originalColorsRef.current.set(instanceId, currentColor); - // Set the new hovered instance color to red + // Set the instance to the hovered color tangleMeshRef.current.setColorAt(instanceId, SEARCH_RESULT_COLOR); cb(instanceId); } From 1c4bd3a0d15d35dd986f474ccd5780871de48b8c Mon Sep 17 00:00:00 2001 From: Eugene Panteleymonchuk Date: Mon, 26 Feb 2024 17:25:24 +0200 Subject: [PATCH 10/10] feat: updates after review Signed-off-by: Eugene Panteleymonchuk --- .../features/visualizer-threejs/constants.ts | 17 +++++++---------- .../visualizer-threejs/hooks/useMouseMove.ts | 4 ++-- .../visualizer-threejs/hooks/useSearch.ts | 2 +- .../visualizer-threejs/wrapper/KeyPanel.tsx | 18 ++++++------------ .../visualizer-threejs/wrapper/Wrapper.tsx | 3 +-- 5 files changed, 17 insertions(+), 27 deletions(-) diff --git a/client/src/features/visualizer-threejs/constants.ts b/client/src/features/visualizer-threejs/constants.ts index 1e94460fd..2eb711bd0 100644 --- a/client/src/features/visualizer-threejs/constants.ts +++ b/client/src/features/visualizer-threejs/constants.ts @@ -22,16 +22,13 @@ export const DATA_SENDER_TIME_INTERVAL = 500; export const ANIMATION_TIME_SECONDS = 3; // colors -export const PENDING_BLOCK_COLOR_HASH = "#A6C3FC"; -export const PENDING_BLOCK_COLOR = new Color(PENDING_BLOCK_COLOR_HASH); -export const ACCEPTED_BLOCK_COLOR_HASH = "#0101AB"; -export const ACCEPTED_BLOCK_COLOR = new Color(ACCEPTED_BLOCK_COLOR_HASH); -export const CONFIRMED_BLOCK_COLOR_HASH = "#0000DB"; -export const CONFIRMED_BLOCK_COLOR = new Color(CONFIRMED_BLOCK_COLOR_HASH); -export const FINALIZED_BLOCK_COLOR_HASH = "#0101FF"; -export const FINALIZED_BLOCK_COLOR = new Color(FINALIZED_BLOCK_COLOR_HASH); -export const SEARCH_RESULT_COLOR_HASH = "#C026D3"; -export const SEARCH_RESULT_COLOR = new Color(SEARCH_RESULT_COLOR_HASH); +export const PENDING_BLOCK_COLOR = new Color("#A6C3FC"); +export const ACCEPTED_BLOCK_COLOR = new Color("#0101AB"); +export const CONFIRMED_BLOCK_COLOR = new Color("#0000DB"); +export const FINALIZED_BLOCK_COLOR = new Color("#0101FF"); +export const SEARCH_RESULT_COLOR = new Color("#C026D3"); +export const HOVERED_BLOCK_COLOR = SEARCH_RESULT_COLOR; + // TODO Remove accepted state once is added to the SDK (missing) export const BLOCK_STATE_TO_COLOR = new Map([ ["pending", PENDING_BLOCK_COLOR], diff --git a/client/src/features/visualizer-threejs/hooks/useMouseMove.ts b/client/src/features/visualizer-threejs/hooks/useMouseMove.ts index 01a8ce3e8..7ccd6aae7 100644 --- a/client/src/features/visualizer-threejs/hooks/useMouseMove.ts +++ b/client/src/features/visualizer-threejs/hooks/useMouseMove.ts @@ -2,7 +2,7 @@ import { useThree } from "@react-three/fiber"; import React, { useCallback, useState, useRef, useEffect } from "react"; import * as THREE from "three"; import { useTangleStore } from "../store"; -import { SEARCH_RESULT_COLOR } from "~features/visualizer-threejs/constants"; +import { HOVERED_BLOCK_COLOR } from "~features/visualizer-threejs/constants"; export const useMouseMove = ({ tangleMeshRef, @@ -51,7 +51,7 @@ export const useMouseMove = ({ originalColorsRef.current.set(instanceId, currentColor); // Set the instance to the hovered color - tangleMeshRef.current.setColorAt(instanceId, SEARCH_RESULT_COLOR); + tangleMeshRef.current.setColorAt(instanceId, HOVERED_BLOCK_COLOR); cb(instanceId); } } diff --git a/client/src/features/visualizer-threejs/hooks/useSearch.ts b/client/src/features/visualizer-threejs/hooks/useSearch.ts index 46c2a31d8..b4d898421 100644 --- a/client/src/features/visualizer-threejs/hooks/useSearch.ts +++ b/client/src/features/visualizer-threejs/hooks/useSearch.ts @@ -26,7 +26,7 @@ export const useSearch = () => { }; export function isSearchMatch(block: IFeedBlockData, searchQuery: string) { - return matchLatestFinalizedSlot(block, searchQuery) || matchByBlockId(block, searchQuery); // note: here we can add more checks as separate functions + return matchLatestFinalizedSlot(block, searchQuery) || matchByBlockId(block, searchQuery); } export function matchByBlockId(block: IFeedBlockData, searchQuery: string) { diff --git a/client/src/features/visualizer-threejs/wrapper/KeyPanel.tsx b/client/src/features/visualizer-threejs/wrapper/KeyPanel.tsx index 9d7012114..4aaa63e5a 100644 --- a/client/src/features/visualizer-threejs/wrapper/KeyPanel.tsx +++ b/client/src/features/visualizer-threejs/wrapper/KeyPanel.tsx @@ -1,12 +1,6 @@ import React, { memo } from "react"; import { BlockState } from "@iota/sdk-wasm-nova/web"; -import { - ACCEPTED_BLOCK_COLOR_HASH, - CONFIRMED_BLOCK_COLOR_HASH, - FINALIZED_BLOCK_COLOR_HASH, - PENDING_BLOCK_COLOR_HASH, - SEARCH_RESULT_COLOR_HASH, -} from "../constants"; +import { ACCEPTED_BLOCK_COLOR, CONFIRMED_BLOCK_COLOR, FINALIZED_BLOCK_COLOR, PENDING_BLOCK_COLOR, SEARCH_RESULT_COLOR } from "../constants"; import "./KeyPanel.scss"; import StatsPanel from "~features/visualizer-threejs/wrapper/StatsPanel"; @@ -19,22 +13,22 @@ export const KeyPanel = ({ network }: { network: string }) => { { label: "Pending", state: "pending", - color: PENDING_BLOCK_COLOR_HASH, + color: PENDING_BLOCK_COLOR.getStyle(), }, { label: "Accepted", state: "accepted", - color: ACCEPTED_BLOCK_COLOR_HASH, + color: ACCEPTED_BLOCK_COLOR.getStyle(), }, { label: "Confirmed", state: "confirmed", - color: CONFIRMED_BLOCK_COLOR_HASH, + color: CONFIRMED_BLOCK_COLOR.getStyle(), }, { label: "Finalized", state: "finalized", - color: FINALIZED_BLOCK_COLOR_HASH, + color: FINALIZED_BLOCK_COLOR.getStyle(), }, { label: "Rejected", @@ -49,7 +43,7 @@ export const KeyPanel = ({ network }: { network: string }) => { { label: "Search result", state: "searchResult", - color: SEARCH_RESULT_COLOR_HASH, + color: SEARCH_RESULT_COLOR.getStyle(), }, ]; diff --git a/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx b/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx index c455dc4e0..ba7340a13 100644 --- a/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx +++ b/client/src/features/visualizer-threejs/wrapper/Wrapper.tsx @@ -8,7 +8,6 @@ import { SelectedFeedInfo } from "./SelectedFeedInfo"; import useSearchStore from "~features/visualizer-threejs/store/search"; import { useTangleStore } from "~features/visualizer-threejs/store/tangle"; import { SEARCH_RESULT_COLOR } from "~features/visualizer-threejs/constants"; -import { Color } from "three"; import { isSearchMatch } from "~features/visualizer-threejs/hooks/useSearch"; export const Wrapper = ({ @@ -55,7 +54,7 @@ export const Wrapper = ({ if (matchingBlockIds.length > 0) { matchingBlockIds.forEach((id) => { const metadata = blockMetadata.get(id); - const treeColor = metadata?.treeColor as Color; + const treeColor = metadata?.treeColor; if (treeColor) { colorsQueue.push({ id: id, color: treeColor }); }