From 967590c7ffa71d1717c4ec788b8e8ec55e2fcc7c Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 13 May 2024 07:19:26 -0700 Subject: [PATCH] Hide large GRPC messages by default --- .../components/GrpcConnectionMessagesPane.tsx | 41 +++++++++++++++---- src-web/components/core/Input.tsx | 4 +- ...tateSyncDefault.ts => useStateWithDeps.ts} | 6 ++- 3 files changed, 38 insertions(+), 13 deletions(-) rename src-web/hooks/{useStateSyncDefault.ts => useStateWithDeps.ts} (58%) diff --git a/src-web/components/GrpcConnectionMessagesPane.tsx b/src-web/components/GrpcConnectionMessagesPane.tsx index c1fbb098..2ea307bc 100644 --- a/src-web/components/GrpcConnectionMessagesPane.tsx +++ b/src-web/components/GrpcConnectionMessagesPane.tsx @@ -10,9 +10,11 @@ import { JsonAttributeTree } from './core/JsonAttributeTree'; import { KeyValueRow, KeyValueRows } from './core/KeyValueRow'; import { Separator } from './core/Separator'; import { SplitLayout } from './core/SplitLayout'; -import { HStack } from './core/Stacks'; +import { HStack, VStack } from './core/Stacks'; import { EmptyStateText } from './EmptyStateText'; import { RecentConnectionsDropdown } from './RecentConnectionsDropdown'; +import { Button } from './core/Button'; +import { useStateWithDeps } from '../hooks/useStateWithDeps'; interface Props { style?: CSSProperties; @@ -32,6 +34,8 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }: const connections = useGrpcConnections(activeRequest.id ?? null); const activeConnection = connections[0] ?? null; const events = useGrpcEvents(activeConnection?.id ?? null); + const [showLarge, setShowLarge] = useStateWithDeps(false, [activeRequest.id]); + const [showingLarge, setShowingLarge] = useState(false); const activeEvent = useMemo( () => events.find((m) => m.id === activeEventId) ?? null, @@ -102,7 +106,30 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
Message {activeEvent.eventType === 'client_message' ? 'Sent' : 'Received'}
- + {!showLarge && activeEvent.content.length > 1000 * 1000 ? ( + + Message previews larger than 1MB are hidden +
+ +
+
+ ) : ( + + )} ) : (
@@ -111,7 +138,7 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }: {activeEvent.content}
{activeEvent.error && ( -
+
{activeEvent.error}
)} @@ -196,12 +223,8 @@ function EventRow({ } />
- {content} - {error && ( - <> - ({error}) - - )} + {content.slice(0, 1000)} + {error && ({error})}
{format(createdAt + 'Z', 'HH:mm:ss.SSS')} diff --git a/src-web/components/core/Input.tsx b/src-web/components/core/Input.tsx index adcc0720..bd2e0184 100644 --- a/src-web/components/core/Input.tsx +++ b/src-web/components/core/Input.tsx @@ -2,7 +2,7 @@ import classNames from 'classnames'; import type { EditorView } from 'codemirror'; import type { HTMLAttributes, ReactNode } from 'react'; import { forwardRef, useCallback, useMemo, useRef, useState } from 'react'; -import { useStateSyncDefault } from '../../hooks/useStateSyncDefault'; +import { useStateWithDeps } from '../../hooks/useStateWithDeps'; import type { EditorProps } from './Editor'; import { Editor } from './Editor'; import { IconButton } from './IconButton'; @@ -72,7 +72,7 @@ export const Input = forwardRef(function Inp }: InputProps, ref, ) { - const [obscured, setObscured] = useStateSyncDefault(type === 'password'); + const [obscured, setObscured] = useStateWithDeps(type === 'password', [type]); const [currentValue, setCurrentValue] = useState(defaultValue ?? ''); const [focused, setFocused] = useState(false); diff --git a/src-web/hooks/useStateSyncDefault.ts b/src-web/hooks/useStateWithDeps.ts similarity index 58% rename from src-web/hooks/useStateSyncDefault.ts rename to src-web/hooks/useStateWithDeps.ts index fc2be01a..77a5c5ab 100644 --- a/src-web/hooks/useStateSyncDefault.ts +++ b/src-web/hooks/useStateWithDeps.ts @@ -1,12 +1,14 @@ +import type { DependencyList } from 'react'; import { useEffect, useState } from 'react'; /** * Like useState, except it will update the value when the default value changes */ -export function useStateSyncDefault(defaultValue: T) { +export function useStateWithDeps(defaultValue: T, deps: DependencyList) { const [value, setValue] = useState(defaultValue); useEffect(() => { setValue(defaultValue); - }, [defaultValue]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, deps); return [value, setValue] as const; }