Architecture: - Feature-sliced directory: entities/, shared/, features/, widgets/ - Consolidated API client (shared/api/client.ts) — all endpoints in one file - Single WebSocket manager (shared/ws/socket.ts) with typed event bus - Extracted hooks: useAudioPlayback, useAudioTransmit, useLocalStorage, useUIState - UI primitives moved to shared/ui/ with barrel export - Added Skeleton, Toast, MobileTabBar components Bug fixes (8/8): 1. useMemo→useEffect in RecordingsSubPanel (async side-effect anti-pattern) 2. ArrayBuffer.slice() before WebSocket send (shared buffer bug) 3. Proper useEffect dependency arrays throughout 4. Stable React keys (no index fallbacks) 5. onReanalyze properly awaited (Promise<void> return) 6. monitorGuild memoized with useMemo 7. localStorage validation with shape checking 8. Deleted duplicate socket logic (ws/client.ts removed) UI polish: - Glass-morphism design tokens (backdrop-blur, translucent cards) - Gradient mesh background with subtle radial overlays - Expandable sidebar + mobile bottom tab bar - Skeleton loading placeholders - Audio visualizer with CSS pulse animation Deleted: src/api/, src/components/, src/hooks/, src/types/, src/ws/, src/lib/ Added: 40 new files across feature-sliced structure Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
35 lines
1.3 KiB
TypeScript
35 lines
1.3 KiB
TypeScript
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
import type * as React from "react";
|
|
import { cn } from "../lib/utils";
|
|
|
|
export function ScrollArea({ className, children, ...props }: React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>) {
|
|
return (
|
|
<ScrollAreaPrimitive.Root className={cn("relative overflow-hidden", className)} {...props}>
|
|
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">{children}</ScrollAreaPrimitive.Viewport>
|
|
<ScrollBar />
|
|
<ScrollAreaPrimitive.Corner />
|
|
</ScrollAreaPrimitive.Root>
|
|
);
|
|
}
|
|
|
|
function ScrollBar({
|
|
className,
|
|
orientation = "vertical",
|
|
...props
|
|
}: React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
|
|
return (
|
|
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
|
orientation={orientation}
|
|
className={cn(
|
|
"flex touch-none select-none transition-colors",
|
|
orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent p-[1px]",
|
|
orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent p-[1px]",
|
|
className,
|
|
)}
|
|
{...props}
|
|
>
|
|
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
|
|
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
);
|
|
}
|