diff --git a/js/src/features/particles/particle-list-view.tsx b/js/src/features/particles/particle-list-view.tsx
index 578cb51..ffd48cf 100644
--- a/js/src/features/particles/particle-list-view.tsx
+++ b/js/src/features/particles/particle-list-view.tsx
@@ -1,4 +1,4 @@
-import { useMemo, useRef, useEffect, memo } from "react";
+import { useMemo, useRef, useEffect, useCallback, memo } from "react";
import { useNavigate } from "react-router-dom";
import {
Radio,
@@ -78,13 +78,13 @@ function getMessagePreview(particle: Particle): string {
const StreamRow = memo(function StreamRow({
particle,
networkId,
- onClick,
+ onNavigate,
isSelected,
shortcutKey,
}: {
particle: Particle & { type: "stream"; properties: StreamProperties };
networkId: string;
- onClick: () => void;
+ onNavigate: (streamId: string) => void;
isSelected?: boolean;
shortcutKey?: number;
}) {
@@ -156,8 +156,8 @@ const StreamRow = memo(function StreamRow({
{ if (e.key === "Enter" || e.key === " ") onClick(); }}
+ onClick={() => onNavigate(particle.id)}
+ onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") onNavigate(particle.id); }}
className={cn(
"flex w-full items-center gap-3 px-4 py-3 text-left cursor-pointer transition-colors hover:bg-accent",
isSelected && "bg-accent",
@@ -250,6 +250,11 @@ export function ParticleListView({ streams, networkId, isLoading, selectedIndex
const navigate = useNavigate();
const rowRefs = useRef<(HTMLDivElement | null)[]>([]);
+ const navigateToStream = useCallback(
+ (streamId: string) => navigate(`/${networkId}/${streamId}`),
+ [navigate, networkId],
+ );
+
useEffect(() => {
if (selectedIndex !== null && selectedIndex !== undefined && selectedIndex >= 0) {
rowRefs.current[selectedIndex]?.scrollIntoView({ block: "nearest" });
@@ -281,7 +286,7 @@ export function ParticleListView({ streams, networkId, isLoading, selectedIndex
navigate(`/${networkId}/${stream.id}`)}
+ onNavigate={navigateToStream}
isSelected={index === selectedIndex}
shortcutKey={index < 9 ? index + 1 : undefined}
/>