feat: triage streams with open, close (#121)
* refactor: use interfaces for function params * cleanup message retention code * support open / closed streams - Tabs for viewing separately - Context menu to close / open streams - Update stream particle status field * ui tweak * show stream state in stream-view * ui tweaks * cleanup message retention from orion api
This commit was merged in pull request #121.
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
import { useCallback, useState } from "react";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { List, LayoutGrid } from "lucide-react";
|
||||
import { List, LayoutGrid, CircleDot, CircleCheckBig } from "lucide-react";
|
||||
import { particlePath } from "@/lib/particle-path";
|
||||
import { ParticleListView } from "@/features/particles/particle-list-view";
|
||||
import { ParticleGridView } from "@/features/particles/particle-grid-view";
|
||||
import ControlsIndicator from "@/features/compose/controls-indicator";
|
||||
import { ComposeOverlay } from "./compose/compose-overlay";
|
||||
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
|
||||
import { useViewModeStore } from "@/stores/view-mode-store";
|
||||
import { useStreamParticles } from "@/hooks/use-stream-particles";
|
||||
@@ -24,13 +25,19 @@ export default function NetworkRoot() {
|
||||
const viewMode = useViewModeStore((s) => s.viewMode);
|
||||
const setViewMode = useViewModeStore((s) => s.setViewMode);
|
||||
|
||||
const { streams } = useStreamParticles(path);
|
||||
const { streams, isLoading } = useStreamParticles(path);
|
||||
const userId = useAuthStore((s) => s.user?.id);
|
||||
useDockBadge(streams, userId);
|
||||
const [composeActive, setComposeActive] = useState(false);
|
||||
const [statusTab, setStatusTab] = useState<"open" | "closed">("open");
|
||||
|
||||
const filteredStreams = useMemo(
|
||||
() => streams.filter((s) => s.status === statusTab),
|
||||
[streams, statusTab],
|
||||
);
|
||||
|
||||
const { selectedIndex } = useStreamKeyboardNav({
|
||||
streams,
|
||||
streams: filteredStreams,
|
||||
viewMode,
|
||||
enabled: !composeActive,
|
||||
onNavigate: useCallback(
|
||||
@@ -40,18 +47,18 @@ export default function NetworkRoot() {
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="relative min-h-0 flex-1">
|
||||
{/* Scrollable content */}
|
||||
<div className="h-full overflow-y-auto overscroll-contain pt-10 pb-14">
|
||||
{viewMode === "list" ? (
|
||||
<ParticleListView path={path} selectedIndex={selectedIndex} />
|
||||
) : (
|
||||
<ParticleGridView path={path} selectedIndex={selectedIndex} />
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Fixed overlays */}
|
||||
<div className="pointer-events-none absolute inset-x-0 top-0 flex justify-end px-3 pt-2">
|
||||
<div className="relative flex min-h-0 flex-1 flex-col">
|
||||
{/* Top bar — stays in place */}
|
||||
<div className="flex shrink-0 items-center justify-between p-1 border-b">
|
||||
<Tabs
|
||||
value={statusTab}
|
||||
onValueChange={(v) => setStatusTab(v as "open" | "closed")}
|
||||
>
|
||||
<TabsList>
|
||||
<TabsTrigger value="open"><CircleDot className="size-3 text-green-500" /> Open</TabsTrigger>
|
||||
<TabsTrigger value="closed"><CircleCheckBig className="size-3" /> Closed</TabsTrigger>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
<ToggleGroup
|
||||
type="single"
|
||||
value={viewMode}
|
||||
@@ -59,7 +66,6 @@ export default function NetworkRoot() {
|
||||
if (v) setViewMode(v as "list" | "grid");
|
||||
}}
|
||||
size="sm"
|
||||
className="pointer-events-auto"
|
||||
>
|
||||
<ToggleGroupItem value="list" aria-label="List view">
|
||||
<List className="size-3.5" />
|
||||
@@ -70,6 +76,15 @@ export default function NetworkRoot() {
|
||||
</ToggleGroup>
|
||||
</div>
|
||||
|
||||
{/* Scrollable content */}
|
||||
<div className="min-h-0 flex-1 overflow-y-auto overscroll-contain pb-14 py-2">
|
||||
{viewMode === "list" ? (
|
||||
<ParticleListView streams={filteredStreams} networkId={networkId!} isLoading={isLoading} selectedIndex={selectedIndex} />
|
||||
) : (
|
||||
<ParticleGridView streams={filteredStreams} networkId={networkId!} isLoading={isLoading} selectedIndex={selectedIndex} />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<ComposeOverlay networkId={networkId!} onActiveChange={setComposeActive} />
|
||||
<div className="pointer-events-none absolute inset-x-0 bottom-0 z-20 flex justify-center p-3">
|
||||
<div className="pointer-events-auto">
|
||||
|
||||
Reference in New Issue
Block a user