fix: list of streams glitching to top
This was due to real-time changes to items leading to scrolling to top. Closes #123
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useMemo } from "react";
|
||||
import { useMemo, useRef, useEffect, memo } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import {
|
||||
Radio,
|
||||
@@ -75,7 +75,7 @@ function getMessagePreview(particle: Particle): string {
|
||||
}
|
||||
}
|
||||
|
||||
function StreamRow({
|
||||
const StreamRow = memo(function StreamRow({
|
||||
particle,
|
||||
networkId,
|
||||
onClick,
|
||||
@@ -234,7 +234,7 @@ function StreamRow({
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
interface ParticleListViewProps {
|
||||
streams: StreamParticle[];
|
||||
@@ -248,6 +248,13 @@ interface ParticleListViewProps {
|
||||
*/
|
||||
export function ParticleListView({ streams, networkId, isLoading, selectedIndex }: ParticleListViewProps) {
|
||||
const navigate = useNavigate();
|
||||
const rowRefs = useRef<(HTMLDivElement | null)[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedIndex !== null && selectedIndex !== undefined && selectedIndex >= 0) {
|
||||
rowRefs.current[selectedIndex]?.scrollIntoView({ block: "nearest" });
|
||||
}
|
||||
}, [selectedIndex]);
|
||||
|
||||
if (isLoading) {
|
||||
return <Progress />;
|
||||
@@ -269,7 +276,7 @@ export function ParticleListView({ streams, networkId, isLoading, selectedIndex
|
||||
{streams.map((stream, index) => (
|
||||
<StreamContextMenu key={stream.id} particle={stream} networkId={networkId}>
|
||||
<div
|
||||
ref={index === selectedIndex ? (el) => el?.scrollIntoView({ block: "nearest" }) : undefined}
|
||||
ref={(el) => { rowRefs.current[index] = el; }}
|
||||
>
|
||||
<StreamRow
|
||||
particle={stream}
|
||||
|
||||
@@ -13,9 +13,14 @@ export function useStreamKeyboardNav({
|
||||
}: UseStreamKeyboardNavOptions) {
|
||||
const [selectedIndex, setSelectedIndex] = useState<number | null>(null);
|
||||
|
||||
// Reset selection to first item when streams change or view mode switches
|
||||
// Initialize selection when streams first load; clear if streams become empty.
|
||||
// Do NOT reset on every Firestore update — that would scroll the list to the top.
|
||||
useEffect(() => {
|
||||
setSelectedIndex(streams.length > 0 ? 0 : null);
|
||||
setSelectedIndex((prev) => {
|
||||
if (streams.length === 0) return null;
|
||||
if (prev === null) return 0;
|
||||
return prev;
|
||||
});
|
||||
}, [streams.length]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user