mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-04-27 01:16:23 +02:00
refactor: remove unused MessageSquare icon from sidebar content
This commit is contained in:
parent
10f94ce67e
commit
23a1544a17
2 changed files with 99 additions and 4 deletions
|
|
@ -4,7 +4,7 @@ import { Button } from "@/components/ui/button";
|
|||
import { cn } from "@/lib/utils";
|
||||
import { ArrowDownIcon } from "lucide-react";
|
||||
import type { ComponentProps } from "react";
|
||||
import { useCallback } from "react";
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
|
||||
|
||||
export type ConversationProps = ComponentProps<typeof StickToBottom>;
|
||||
|
|
@ -13,11 +13,109 @@ export const Conversation = ({ className, ...props }: ConversationProps) => (
|
|||
<StickToBottom
|
||||
className={cn("relative flex-1 overflow-y-hidden", className)}
|
||||
initial="smooth"
|
||||
resize="smooth"
|
||||
role="log"
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
||||
// Threshold in pixels - if user scrolls more than this from bottom, they're considered "engaged"
|
||||
const SCROLL_ENGAGEMENT_THRESHOLD = 100;
|
||||
|
||||
/**
|
||||
* Component that preserves scroll position when user has scrolled away from bottom.
|
||||
* Place this inside a StickToBottom context to prevent unwanted scroll jumps.
|
||||
*/
|
||||
export const ScrollPositionPreserver = () => {
|
||||
const { isAtBottom } = useStickToBottomContext();
|
||||
const scrollContainerRef = useRef<HTMLElement | null>(null);
|
||||
const isUserEngagedRef = useRef(false);
|
||||
const savedScrollTopRef = useRef<number | null>(null);
|
||||
const lastContentHeightRef = useRef<number>(0);
|
||||
|
||||
useEffect(() => {
|
||||
// Find the scroll container (StickToBottom creates a scrollable element)
|
||||
const findScrollContainer = () => {
|
||||
// The scroll container is the element with overflow-y-auto/scroll
|
||||
const containers = document.querySelectorAll('[data-stick-to-bottom-scroll-container]');
|
||||
if (containers.length > 0) {
|
||||
return containers[0] as HTMLElement;
|
||||
}
|
||||
// Fallback: find by class pattern from the library
|
||||
const fallback = document.querySelector('.use-stick-to-bottom-scroll-container');
|
||||
return fallback as HTMLElement | null;
|
||||
};
|
||||
|
||||
// Try to find it, the library creates it dynamically
|
||||
const container = findScrollContainer();
|
||||
if (container) {
|
||||
scrollContainerRef.current = container;
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Track when user scrolls away from bottom
|
||||
useEffect(() => {
|
||||
if (!isAtBottom) {
|
||||
// User is not at bottom - they've scrolled up
|
||||
isUserEngagedRef.current = true;
|
||||
|
||||
// Save their current position
|
||||
if (scrollContainerRef.current) {
|
||||
savedScrollTopRef.current = scrollContainerRef.current.scrollTop;
|
||||
lastContentHeightRef.current = scrollContainerRef.current.scrollHeight;
|
||||
}
|
||||
}
|
||||
}, [isAtBottom]);
|
||||
|
||||
// When user reaches bottom again, reset engagement
|
||||
useEffect(() => {
|
||||
if (isAtBottom && isUserEngagedRef.current) {
|
||||
isUserEngagedRef.current = false;
|
||||
savedScrollTopRef.current = null;
|
||||
}
|
||||
}, [isAtBottom]);
|
||||
|
||||
// Use MutationObserver to detect content changes and restore position if needed
|
||||
useEffect(() => {
|
||||
const container = scrollContainerRef.current;
|
||||
if (!container) return;
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
// If user was engaged (scrolled away) and we have a saved position
|
||||
if (isUserEngagedRef.current && savedScrollTopRef.current !== null) {
|
||||
const currentHeight = container.scrollHeight;
|
||||
const previousHeight = lastContentHeightRef.current;
|
||||
|
||||
// If content height changed significantly and user was scrolled away
|
||||
if (Math.abs(currentHeight - previousHeight) > 10) {
|
||||
// Calculate how far from bottom they were
|
||||
const distanceFromBottom = previousHeight - savedScrollTopRef.current - container.clientHeight;
|
||||
|
||||
// Restore position relative to where they were
|
||||
// If they were reading something in the middle, keep them there
|
||||
if (distanceFromBottom > SCROLL_ENGAGEMENT_THRESHOLD) {
|
||||
// Keep them at the same scroll position (reading older content)
|
||||
container.scrollTop = savedScrollTopRef.current;
|
||||
}
|
||||
|
||||
// Update saved values
|
||||
lastContentHeightRef.current = currentHeight;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(container, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
characterData: true,
|
||||
});
|
||||
|
||||
return () => observer.disconnect();
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export type ConversationContentProps = ComponentProps<
|
||||
typeof StickToBottom.Content
|
||||
>;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import {
|
|||
FilePlus,
|
||||
Folder,
|
||||
FolderPlus,
|
||||
MessageSquare,
|
||||
Mic,
|
||||
Network,
|
||||
Pencil,
|
||||
|
|
@ -689,9 +688,7 @@ function TasksSection({
|
|||
<SidebarMenuButton
|
||||
isActive={currentRunId === run.id}
|
||||
onClick={() => actions?.onSelectRun(run.id)}
|
||||
className="gap-2"
|
||||
>
|
||||
<MessageSquare className="size-4 shrink-0" />
|
||||
<span className="truncate text-sm">{run.title || '(Untitled chat)'}</span>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue