Skip to content

Commit

Permalink
improved dragging + sticky behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
pablonyx committed Jan 19, 2025
1 parent 36483e9 commit e6c10cf
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 138 deletions.
200 changes: 105 additions & 95 deletions web/src/app/chat/folders/FolderDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ interface FolderDropdownProps {
onDelete?: (folderId: number) => void;
onDrop?: (folderId: number, chatSessionId: string) => void;
children?: ReactNode;
index: number;
}

export const FolderDropdown = forwardRef<HTMLDivElement, FolderDropdownProps>(
Expand All @@ -46,6 +47,7 @@ export const FolderDropdown = forwardRef<HTMLDivElement, FolderDropdownProps>(
onEdit,
onDrop,
children,
index,
},
ref
) => {
Expand Down Expand Up @@ -160,110 +162,118 @@ export const FolderDropdown = forwardRef<HTMLDivElement, FolderDropdownProps>(
onDrop={handleDrop}
>
<div
ref={ref}
className="flex overflow-visible items-center w-full text-text-darker rounded-md p-1 relative"
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
className="sticky top-0 bg-background-sidebar z-10"
style={{ zIndex: 1000 - index }}
>
<button
className="flex overflow-hidden items-center flex-grow"
onClick={() => !isEditing && setIsOpen(!isOpen)}
{...(isEditing ? {} : listeners)}
<div
ref={ref}
className="flex overflow-visible items-center w-full text-text-darker rounded-md p-1 relative bg-background-sidebar sticky top-0"
style={{ zIndex: 10 - index }}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
{isOpen ? (
<Caret size={16} className="mr-1" />
) : (
<Caret size={16} className="-rotate-90 mr-1" />
)}
{isEditing ? (
<div ref={editingRef} className="flex-grow z-[9999] relative">
<input
ref={inputRef}
type="text"
value={newFolderName}
onChange={(e) => setNewFolderName(e.target.value)}
className="text-sm font-medium bg-transparent outline-none w-full pb-1 border-b border-[#6c6c6c] transition-colors duration-200"
onKeyDown={(e) => {
if (e.key === "Enter") {
handleEdit();
}
}}
onClick={(e) => e.stopPropagation()}
/>
</div>
) : (
<div className="flex items-center">
<span className="text-sm font-[500]">{folder.folder_name}</span>
</div>
)}
</button>
{isHovered && !isEditing && folder.folder_id && (
<button
onClick={(e) => {
e.stopPropagation();
setIsEditing(true);
}}
className="ml-auto px-1"
className="flex overflow-hidden items-center flex-grow"
onClick={() => !isEditing && setIsOpen(!isOpen)}
{...(isEditing ? {} : listeners)}
>
<PencilIcon size={14} />
</button>
)}
{(isHovered || isDeletePopoverOpen) &&
!isEditing &&
folder.folder_id && (
<Popover
open={isDeletePopoverOpen}
onOpenChange={setIsDeletePopoverOpen}
content={
<button
onClick={(e) => {
e.stopPropagation();
handleDeleteClick();
{isOpen ? (
<Caret size={16} className="mr-1" />
) : (
<Caret size={16} className="-rotate-90 mr-1" />
)}
{isEditing ? (
<div ref={editingRef} className="flex-grow z-[9999] relative">
<input
ref={inputRef}
type="text"
value={newFolderName}
onChange={(e) => setNewFolderName(e.target.value)}
className="text-sm font-medium bg-transparent outline-none w-full pb-1 border-b border-[#6c6c6c] transition-colors duration-200"
onKeyDown={(e) => {
if (e.key === "Enter") {
handleEdit();
}
}}
className="px-1"
>
<FiTrash2 size={14} />
</button>
}
popover={
<div className="p-3 w-64 border border-border rounded-lg bg-background z-50">
<p className="text-sm mb-3">
Are you sure you want to delete this folder?
</p>
<div className="flex justify-center gap-2">
<button
className="px-3 py-1 text-sm bg-gray-200 rounded"
onClick={handleCancelDelete}
>
Cancel
</button>
<button
className="px-3 py-1 text-sm bg-red-500 text-white rounded"
onClick={handleConfirmDelete}
>
Delete
</button>
onClick={(e) => e.stopPropagation()}
/>
</div>
) : (
<div className="flex items-center">
<span className="text-sm font-[500]">
{folder.folder_name}
</span>
</div>
)}
</button>
{isHovered && !isEditing && folder.folder_id && (
<button
onClick={(e) => {
e.stopPropagation();
setIsEditing(true);
}}
className="ml-auto px-1"
>
<PencilIcon size={14} />
</button>
)}
{(isHovered || isDeletePopoverOpen) &&
!isEditing &&
folder.folder_id && (
<Popover
open={isDeletePopoverOpen}
onOpenChange={setIsDeletePopoverOpen}
content={
<button
onClick={(e) => {
e.stopPropagation();
handleDeleteClick();
}}
className="px-1"
>
<FiTrash2 size={14} />
</button>
}
popover={
<div className="p-3 w-64 border border-border rounded-lg bg-background z-50">
<p className="text-sm mb-3">
Are you sure you want to delete this folder?
</p>
<div className="flex justify-center gap-2">
<button
className="px-3 py-1 text-sm bg-gray-200 rounded"
onClick={handleCancelDelete}
>
Cancel
</button>
<button
className="px-3 py-1 text-sm bg-red-500 text-white rounded"
onClick={handleConfirmDelete}
>
Delete
</button>
</div>
</div>
</div>
}
requiresContentPadding
sideOffset={6}
/>
}
requiresContentPadding
sideOffset={6}
/>
)}
{isEditing && (
<div className="flex -my-1 z-[9999]">
<button onClick={handleEdit} className="p-1">
<FiCheck size={14} />
</button>
<button onClick={() => setIsEditing(false)} className="p-1">
<FiX size={14} />
</button>
</div>
)}
{isEditing && (
<div className="flex -my-1 z-[9999]">
<button onClick={handleEdit} className="p-1">
<FiCheck size={14} />
</button>
<button onClick={() => setIsEditing(false)} className="p-1">
<FiX size={14} />
</button>
</div>
</div>
{isOpen && (
<div className="overflow-visible mr-3 ml-1 mt-1">{children}</div>
)}
</div>
{isOpen && (
<div className="overflow-visible mr-3 ml-1 mt-1">{children}</div>
)}
</div>
);
}
Expand Down
5 changes: 4 additions & 1 deletion web/src/app/chat/input/ChatInputBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,10 @@ export function ChatInputBar({
style={{ scrollbarWidth: "thin" }}
role="textarea"
aria-multiline
placeholder={`Message ${selectedAssistant.name} assistant...`}
placeholder={`Message ${truncateString(
selectedAssistant.name,
70
)} assistant...`}
value={message}
onKeyDown={(event) => {
if (
Expand Down
12 changes: 1 addition & 11 deletions web/src/app/chat/sessionSidebar/ChatSessionDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,10 @@ export function ChatSessionDisplay({
const [popoverOpen, setPopoverOpen] = useState(false);
const inputRef = useRef<HTMLInputElement>(null);
const renamingRef = useRef<HTMLDivElement>(null);
const [isMobile, setIsMobile] = useState(false);

const { refreshChatSessions, refreshFolders } = useChatContext();

useEffect(() => {
const mediaQuery = window.matchMedia("(max-width: 768px)");
setIsMobile(mediaQuery.matches);

const handleResize = (e: MediaQueryListEvent) => setIsMobile(e.matches);
mediaQuery.addListener(handleResize);

return () => mediaQuery.removeListener(handleResize);
}, []);

const isMobile = settings?.isMobile;
const handlePopoverOpenChange = useCallback(
(open: boolean) => {
setPopoverOpen(open);
Expand Down
4 changes: 2 additions & 2 deletions web/src/app/chat/sessionSidebar/HistorySidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ export const HistorySidebar = forwardRef<HTMLDivElement, HistorySidebarProps>(
</div>
)}

<div className="h-full overflow-y-auto">
<div className="flex px-4 font-normal text-sm gap-x-2 leading-normal text-[#6c6c6c]/80 items-center font-normal leading-normal">
<div className="h-full relative overflow-y-auto">
<div className="flex px-4 font-normal text-sm gap-x-2 leading-normal text-[#6c6c6c]/80 items-center font-normal leading-normal">
Assistants
</div>
<DndContext
Expand Down
Loading

0 comments on commit e6c10cf

Please sign in to comment.