diff --git a/package-lock.json b/package-lock.json
index dd2464cc..406f630b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8873,12 +8873,12 @@
}
},
"node_modules/lucide-react": {
- "version": "0.439.0",
- "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.439.0.tgz",
- "integrity": "sha512-PafSWvDTpxdtNEndS2HIHxcNAbd54OaqSYJO90/b63rab2HWYqDbH194j0i82ZFdWOAcf0AHinRykXRRK2PJbw==",
+ "version": "0.474.0",
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.474.0.tgz",
+ "integrity": "sha512-CmghgHkh0OJNmxGKWc0qfPJCYHASPMVSyGY8fj3xgk4v84ItqDg64JNKFZn5hC6E0vHi6gxnbCgwhyVB09wQtA==",
"license": "ISC",
"peerDependencies": {
- "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc"
+ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/make-cancellable-promise": {
@@ -15491,7 +15491,7 @@
},
"packages/plugin-runtime-types": {
"name": "@yaakapp/api",
- "version": "0.4.0",
+ "version": "0.4.1",
"dependencies": {
"@types/node": "^22.5.4"
},
@@ -15657,7 +15657,7 @@
"history": "^5.3.0",
"jotai": "^2.9.3",
"js-md5": "^0.8.3",
- "lucide-react": "^0.439.0",
+ "lucide-react": "^0.474.0",
"mime": "^4.0.4",
"nanoid": "^5.0.9",
"papaparse": "^5.4.1",
diff --git a/src-web/components/GrpcConnectionMessagesPane.tsx b/src-web/components/GrpcConnectionMessagesPane.tsx
index 643bd76e..8843fc1f 100644
--- a/src-web/components/GrpcConnectionMessagesPane.tsx
+++ b/src-web/components/GrpcConnectionMessagesPane.tsx
@@ -14,6 +14,7 @@ import { Icon } from './core/Icon';
import { IconButton } from './core/IconButton';
import { JsonAttributeTree } from './core/JsonAttributeTree';
import { KeyValueRow, KeyValueRows } from './core/KeyValueRow';
+import { LoadingIcon } from './core/LoadingIcon';
import { Separator } from './core/Separator';
import { SplitLayout } from './core/SplitLayout';
import { HStack, VStack } from './core/Stacks';
@@ -70,7 +71,7 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
{events.length} Messages
{activeConnection.state !== 'closed' && (
-
+
)}
diff --git a/src-web/components/HttpResponsePane.tsx b/src-web/components/HttpResponsePane.tsx
index 38688ea3..217b7244 100644
--- a/src-web/components/HttpResponsePane.tsx
+++ b/src-web/components/HttpResponsePane.tsx
@@ -11,7 +11,7 @@ import { Banner } from './core/Banner';
import { CountBadge } from './core/CountBadge';
import { DurationTag } from './core/DurationTag';
import { HotKeyList } from './core/HotKeyList';
-import { Icon } from './core/Icon';
+import { LoadingIcon } from './core/LoadingIcon';
import { SizeTag } from './core/SizeTag';
import { HStack } from './core/Stacks';
import { StatusTag } from './core/StatusTag';
@@ -120,7 +120,7 @@ export function HttpResponsePane({ style, className, activeRequestId }: Props) {
'whitespace-nowrap w-full pl-3 overflow-x-auto font-mono text-sm',
)}
>
- {activeResponse.state !== 'closed' &&
}
+ {activeResponse.state !== 'closed' &&
}
•
{activeResponse.state === 'initialized' ? (
-
+
) : activeResponse.state === 'closed' && activeResponse.contentLength === 0 ? (
Empty
@@ -217,7 +217,7 @@ function EnsureCompleteResponse({
if (response.state !== 'closed') {
return (
-
+
);
}
diff --git a/src-web/components/WebsocketResponsePane.tsx b/src-web/components/WebsocketResponsePane.tsx
index 9f89efdf..0c2b2a85 100644
--- a/src-web/components/WebsocketResponsePane.tsx
+++ b/src-web/components/WebsocketResponsePane.tsx
@@ -15,6 +15,7 @@ import { Button } from './core/Button';
import { Editor } from './core/Editor/Editor';
import { Icon } from './core/Icon';
import { IconButton } from './core/IconButton';
+import { LoadingIcon } from './core/LoadingIcon';
import { Separator } from './core/Separator';
import { SplitLayout } from './core/SplitLayout';
import { HStack, VStack } from './core/Stacks';
@@ -71,7 +72,7 @@ export function WebsocketResponsePane({ activeRequest }: Props) {
{activeConnection.state !== 'closed' && (
-
+
)}
•
diff --git a/src-web/components/core/Button.tsx b/src-web/components/core/Button.tsx
index ffb79982..14564426 100644
--- a/src-web/components/core/Button.tsx
+++ b/src-web/components/core/Button.tsx
@@ -5,6 +5,7 @@ import type { HotkeyAction } from '../../hooks/useHotKey';
import { useFormattedHotkey, useHotKey } from '../../hooks/useHotKey';
import { trackEvent } from '../../lib/analytics';
import { Icon } from './Icon';
+import { LoadingIcon } from './LoadingIcon';
export type ButtonProps = Omit, 'color' | 'onChange'> & {
innerClassName?: string;
@@ -125,7 +126,7 @@ export const Button = forwardRef(function Button
{...props}
>
{isLoading ? (
-
+
) : leftSlot ? (
{leftSlot}
) : null}
diff --git a/src-web/components/core/LoadingIcon.tsx b/src-web/components/core/LoadingIcon.tsx
new file mode 100644
index 00000000..0353baa8
--- /dev/null
+++ b/src-web/components/core/LoadingIcon.tsx
@@ -0,0 +1,35 @@
+import classNames from 'classnames';
+
+interface Props {
+ size?: '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
+ className?: string;
+}
+
+export function LoadingIcon({ size = 'md', className }: Props) {
+ const classes = classNames(
+ className,
+ 'text-inherit flex-shrink-0',
+ size === 'xl' && 'h-6 w-6',
+ size === 'lg' && 'h-5 w-5',
+ size === 'md' && 'h-4 w-4',
+ size === 'sm' && 'h-3.5 w-3.5',
+ size === 'xs' && 'h-3 w-3',
+ size === '2xs' && 'h-2.5 w-2.5',
+ 'animate-spin',
+ );
+
+ return (
+
+ );
+}
diff --git a/src-web/components/responseViewers/BinaryViewer.tsx b/src-web/components/responseViewers/BinaryViewer.tsx
index fcadcdbe..50cf269a 100644
--- a/src-web/components/responseViewers/BinaryViewer.tsx
+++ b/src-web/components/responseViewers/BinaryViewer.tsx
@@ -1,10 +1,10 @@
-import { useSaveResponse } from '../../hooks/useSaveResponse';
import type { HttpResponse } from '@yaakapp-internal/models';
+import { useSaveResponse } from '../../hooks/useSaveResponse';
import { getContentTypeHeader } from '../../lib/model_util';
import { Banner } from '../core/Banner';
import { Button } from '../core/Button';
-import { Icon } from '../core/Icon';
import { InlineCode } from '../core/InlineCode';
+import { LoadingIcon } from '../core/LoadingIcon';
import { EmptyStateText } from '../EmptyStateText';
interface Props {
@@ -19,7 +19,7 @@ export function BinaryViewer({ response }: Props) {
if (response.state === 'closed') {
return (
-
+
);
}
diff --git a/src-web/components/sidebar/Sidebar.tsx b/src-web/components/sidebar/Sidebar.tsx
index 51658d8b..9a589970 100644
--- a/src-web/components/sidebar/Sidebar.tsx
+++ b/src-web/components/sidebar/Sidebar.tsx
@@ -14,9 +14,7 @@ import { getActiveRequest } from '../../hooks/useActiveRequest';
import { useActiveWorkspace } from '../../hooks/useActiveWorkspace';
import { useCreateDropdownItems } from '../../hooks/useCreateDropdownItems';
import { useDeleteAnyRequest } from '../../hooks/useDeleteAnyRequest';
-import { useGrpcConnections } from '../../hooks/useGrpcConnections';
import { useHotKey } from '../../hooks/useHotKey';
-import { useHttpResponses } from '../../hooks/useHttpResponses';
import { useSidebarHidden } from '../../hooks/useSidebarHidden';
import { getSidebarCollapsedMap } from '../../hooks/useSidebarItemCollapsed';
import { useUpdateAnyFolder } from '../../hooks/useUpdateAnyFolder';
@@ -51,8 +49,6 @@ export function Sidebar({ className }: Props) {
const [hidden, setHidden] = useSidebarHidden();
const sidebarRef = useRef(null);
const activeWorkspace = useActiveWorkspace();
- const httpResponses = useHttpResponses();
- const grpcConnections = useGrpcConnections();
const [hasFocus, setHasFocus] = useState(false);
const [selectedId, setSelectedId] = useAtom(sidebarSelectedIdAtom);
const [selectedTree, setSelectedTree] = useState(null);
@@ -372,8 +368,6 @@ export function Sidebar({ className }: Props) {
;
type DragItem = {
@@ -58,6 +65,7 @@ export const SidebarItem = memo(function SidebarItem({
className,
latestHttpResponse,
latestGrpcConnection,
+ latestWebsocketConnection,
children,
}: SidebarItemProps) {
const ref = useRef(null);
@@ -283,13 +291,19 @@ export const SidebarItem = memo(function SidebarItem({
{latestGrpcConnection ? (
{latestGrpcConnection.state !== 'closed' && (
-
+
+ )}
+
+ ) : latestWebsocketConnection ? (
+
+ {latestWebsocketConnection.state !== 'closed' && (
+
)}
) : latestHttpResponse ? (
{latestHttpResponse.state !== 'closed' ? (
-
+
) : (
)}
diff --git a/src-web/components/sidebar/SidebarItems.tsx b/src-web/components/sidebar/SidebarItems.tsx
index 0722ca41..7099278f 100644
--- a/src-web/components/sidebar/SidebarItems.tsx
+++ b/src-web/components/sidebar/SidebarItems.tsx
@@ -1,6 +1,8 @@
-import type { GrpcConnection, HttpResponse } from '@yaakapp-internal/models';
import classNames from 'classnames';
import React, { Fragment, memo } from 'react';
+import { useGrpcConnections } from '../../hooks/useGrpcConnections';
+import { useHttpResponses } from '../../hooks/useHttpResponses';
+import { useWebsocketConnections } from '../../hooks/useWebsocketConnections';
import { VStack } from '../core/Stacks';
import { DropMarker } from '../DropMarker';
import type { SidebarTreeNode } from './Sidebar';
@@ -17,8 +19,6 @@ export interface SidebarItemsProps {
handleEnd: (id: string) => void;
handleDragStart: (id: string) => void;
onSelect: (requestId: string) => void;
- httpResponses: HttpResponse[];
- grpcConnections: GrpcConnection[];
}
export const SidebarItems = memo(function SidebarItems({
@@ -32,9 +32,11 @@ export const SidebarItems = memo(function SidebarItems({
handleEnd,
handleMove,
handleDragStart,
- httpResponses,
- grpcConnections,
}: SidebarItemsProps) {
+ const httpResponses = useHttpResponses();
+ const grpcConnections = useGrpcConnections();
+ const websocketConnections = useWebsocketConnections();
+
return (
r.requestId === child.id) ?? null}
latestGrpcConnection={grpcConnections.find((c) => c.requestId === child.id) ?? null}
+ latestWebsocketConnection={
+ websocketConnections.find((c) => c.requestId === child.id) ?? null
+ }
onMove={handleMove}
onEnd={handleEnd}
onSelect={onSelect}
@@ -71,8 +76,6 @@ export const SidebarItems = memo(function SidebarItems({
handleMove={handleMove}
hoveredIndex={hoveredIndex}
hoveredTree={hoveredTree}
- httpResponses={httpResponses}
- grpcConnections={grpcConnections}
onSelect={onSelect}
selectedTree={selectedTree}
tree={child}
diff --git a/src-web/package.json b/src-web/package.json
index b32bfe9a..c54ff187 100644
--- a/src-web/package.json
+++ b/src-web/package.json
@@ -49,7 +49,7 @@
"history": "^5.3.0",
"jotai": "^2.9.3",
"js-md5": "^0.8.3",
- "lucide-react": "^0.439.0",
+ "lucide-react": "^0.474.0",
"mime": "^4.0.4",
"nanoid": "^5.0.9",
"papaparse": "^5.4.1",