mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-21 07:45:52 +00:00
style: 完成所有文件的lint
This commit is contained in:
@@ -1,21 +1,18 @@
|
||||
import { feature } from 'bun:bundle'
|
||||
import type { BetaContentBlock } from '@anthropic-ai/sdk/resources/beta/messages/messages.mjs'
|
||||
import { feature } from 'bun:bundle';
|
||||
import type { BetaContentBlock } from '@anthropic-ai/sdk/resources/beta/messages/messages.mjs';
|
||||
import type {
|
||||
ImageBlockParam,
|
||||
TextBlockParam,
|
||||
ThinkingBlockParam,
|
||||
ToolResultBlockParam,
|
||||
ToolUseBlockParam,
|
||||
} from '@anthropic-ai/sdk/resources/index.mjs'
|
||||
import * as React from 'react'
|
||||
import type { Command } from '../commands.js'
|
||||
import { useTerminalSize } from '../hooks/useTerminalSize.js'
|
||||
import { Box } from '@anthropic/ink'
|
||||
import type { Tools } from '../Tool.js'
|
||||
import {
|
||||
type ConnectorTextBlock,
|
||||
isConnectorTextBlock,
|
||||
} from '../types/connectorText.js'
|
||||
} from '@anthropic-ai/sdk/resources/index.mjs';
|
||||
import * as React from 'react';
|
||||
import type { Command } from '../commands.js';
|
||||
import { useTerminalSize } from '../hooks/useTerminalSize.js';
|
||||
import { Box } from '@anthropic/ink';
|
||||
import type { Tools } from '../Tool.js';
|
||||
import { type ConnectorTextBlock, isConnectorTextBlock } from '../types/connectorText.js';
|
||||
import type {
|
||||
AssistantMessage,
|
||||
AttachmentMessage as AttachmentMessageType,
|
||||
@@ -24,27 +21,27 @@ import type {
|
||||
NormalizedUserMessage,
|
||||
ProgressMessage,
|
||||
SystemMessage,
|
||||
} from '../types/message.js'
|
||||
import { type AdvisorBlock, isAdvisorBlock } from '../utils/advisor.js'
|
||||
import { isFullscreenEnvEnabled } from '../utils/fullscreen.js'
|
||||
import { logError } from '../utils/log.js'
|
||||
import type { buildMessageLookups } from '../utils/messages.js'
|
||||
import { CompactSummary } from './CompactSummary.js'
|
||||
import { AdvisorMessage } from './messages/AdvisorMessage.js'
|
||||
import { AssistantRedactedThinkingMessage } from './messages/AssistantRedactedThinkingMessage.js'
|
||||
import { AssistantTextMessage } from './messages/AssistantTextMessage.js'
|
||||
import { AssistantThinkingMessage } from './messages/AssistantThinkingMessage.js'
|
||||
import { AssistantToolUseMessage } from './messages/AssistantToolUseMessage.js'
|
||||
import { AttachmentMessage } from './messages/AttachmentMessage.js'
|
||||
import { CollapsedReadSearchContent } from './messages/CollapsedReadSearchContent.js'
|
||||
import { CompactBoundaryMessage } from './messages/CompactBoundaryMessage.js'
|
||||
import { GroupedToolUseContent } from './messages/GroupedToolUseContent.js'
|
||||
import { SystemTextMessage } from './messages/SystemTextMessage.js'
|
||||
import { UserImageMessage } from './messages/UserImageMessage.js'
|
||||
import { UserTextMessage } from './messages/UserTextMessage.js'
|
||||
import { UserToolResultMessage } from './messages/UserToolResultMessage/UserToolResultMessage.js'
|
||||
import { OffscreenFreeze } from './OffscreenFreeze.js'
|
||||
import { ExpandShellOutputProvider } from './shell/ExpandShellOutputContext.js'
|
||||
} from '../types/message.js';
|
||||
import { type AdvisorBlock, isAdvisorBlock } from '../utils/advisor.js';
|
||||
import { isFullscreenEnvEnabled } from '../utils/fullscreen.js';
|
||||
import { logError } from '../utils/log.js';
|
||||
import type { buildMessageLookups } from '../utils/messages.js';
|
||||
import { CompactSummary } from './CompactSummary.js';
|
||||
import { AdvisorMessage } from './messages/AdvisorMessage.js';
|
||||
import { AssistantRedactedThinkingMessage } from './messages/AssistantRedactedThinkingMessage.js';
|
||||
import { AssistantTextMessage } from './messages/AssistantTextMessage.js';
|
||||
import { AssistantThinkingMessage } from './messages/AssistantThinkingMessage.js';
|
||||
import { AssistantToolUseMessage } from './messages/AssistantToolUseMessage.js';
|
||||
import { AttachmentMessage } from './messages/AttachmentMessage.js';
|
||||
import { CollapsedReadSearchContent } from './messages/CollapsedReadSearchContent.js';
|
||||
import { CompactBoundaryMessage } from './messages/CompactBoundaryMessage.js';
|
||||
import { GroupedToolUseContent } from './messages/GroupedToolUseContent.js';
|
||||
import { SystemTextMessage } from './messages/SystemTextMessage.js';
|
||||
import { UserImageMessage } from './messages/UserImageMessage.js';
|
||||
import { UserTextMessage } from './messages/UserTextMessage.js';
|
||||
import { UserToolResultMessage } from './messages/UserToolResultMessage/UserToolResultMessage.js';
|
||||
import { OffscreenFreeze } from './OffscreenFreeze.js';
|
||||
import { ExpandShellOutputProvider } from './shell/ExpandShellOutputContext.js';
|
||||
|
||||
export type Props = {
|
||||
message:
|
||||
@@ -53,33 +50,33 @@ export type Props = {
|
||||
| AttachmentMessageType
|
||||
| SystemMessage
|
||||
| GroupedToolUseMessageType
|
||||
| CollapsedReadSearchGroupType
|
||||
lookups: ReturnType<typeof buildMessageLookups>
|
||||
| CollapsedReadSearchGroupType;
|
||||
lookups: ReturnType<typeof buildMessageLookups>;
|
||||
// TODO: Find a way to remove this, and leave spacing to the consumer
|
||||
/** Absolute width for the container Box. When provided, eliminates a wrapper Box in the caller. */
|
||||
containerWidth?: number
|
||||
addMargin: boolean
|
||||
tools: Tools
|
||||
commands: Command[]
|
||||
verbose: boolean
|
||||
inProgressToolUseIDs: Set<string>
|
||||
progressMessagesForMessage: ProgressMessage[]
|
||||
shouldAnimate: boolean
|
||||
shouldShowDot: boolean
|
||||
style?: 'condensed'
|
||||
width?: number | string
|
||||
isTranscriptMode: boolean
|
||||
isStatic: boolean
|
||||
onOpenRateLimitOptions?: () => void
|
||||
isActiveCollapsedGroup?: boolean
|
||||
isUserContinuation?: boolean
|
||||
containerWidth?: number;
|
||||
addMargin: boolean;
|
||||
tools: Tools;
|
||||
commands: Command[];
|
||||
verbose: boolean;
|
||||
inProgressToolUseIDs: Set<string>;
|
||||
progressMessagesForMessage: ProgressMessage[];
|
||||
shouldAnimate: boolean;
|
||||
shouldShowDot: boolean;
|
||||
style?: 'condensed';
|
||||
width?: number | string;
|
||||
isTranscriptMode: boolean;
|
||||
isStatic: boolean;
|
||||
onOpenRateLimitOptions?: () => void;
|
||||
isActiveCollapsedGroup?: boolean;
|
||||
isUserContinuation?: boolean;
|
||||
/** ID of the last thinking block (uuid:index) to show, used for hiding past thinking in transcript mode */
|
||||
lastThinkingBlockId?: string | null
|
||||
lastThinkingBlockId?: string | null;
|
||||
/** UUID of the latest user bash output message (for auto-expanding) */
|
||||
latestBashOutputUUID?: string | null
|
||||
latestBashOutputUUID?: string | null;
|
||||
/** Whether to collapse diff display for this message */
|
||||
shouldCollapseDiffs?: boolean
|
||||
}
|
||||
shouldCollapseDiffs?: boolean;
|
||||
};
|
||||
|
||||
function MessageImpl({
|
||||
message,
|
||||
@@ -112,7 +109,7 @@ function MessageImpl({
|
||||
verbose={verbose}
|
||||
isTranscriptMode={isTranscriptMode}
|
||||
/>
|
||||
)
|
||||
);
|
||||
case 'assistant':
|
||||
return (
|
||||
<Box flexDirection="column" width={containerWidth ?? '100%'}>
|
||||
@@ -139,38 +136,37 @@ function MessageImpl({
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
)
|
||||
);
|
||||
case 'user': {
|
||||
if (message.isCompactSummary) {
|
||||
return (
|
||||
<CompactSummary
|
||||
message={message}
|
||||
screen={isTranscriptMode ? 'transcript' : 'prompt'}
|
||||
/>
|
||||
)
|
||||
return <CompactSummary message={message} screen={isTranscriptMode ? 'transcript' : 'prompt'} />;
|
||||
}
|
||||
// Precompute the imageIndex prop for each content block. The previous
|
||||
// version incremented a counter inside the .map() callback, which
|
||||
// React Compiler bails on ("UpdateExpression to variables captured
|
||||
// within lambdas"). A plain for loop keeps the mutation out of a
|
||||
// closure so the compiler can memoize MessageImpl.
|
||||
const imageIndices: number[] = []
|
||||
let imagePosition = 0
|
||||
const imageIndices: number[] = [];
|
||||
let imagePosition = 0;
|
||||
for (const param of message.message.content as Array<{ type: string }>) {
|
||||
if (param.type === 'image') {
|
||||
const id = message.imagePasteIds?.[imagePosition]
|
||||
imagePosition++
|
||||
imageIndices.push(id ?? imagePosition)
|
||||
const id = message.imagePasteIds?.[imagePosition];
|
||||
imagePosition++;
|
||||
imageIndices.push(id ?? imagePosition);
|
||||
} else {
|
||||
imageIndices.push(imagePosition)
|
||||
imageIndices.push(imagePosition);
|
||||
}
|
||||
}
|
||||
// Check if this message is the latest bash output - if so, wrap content
|
||||
// with provider so OutputLine can show full output via context
|
||||
const isLatestBashOutput = latestBashOutputUUID === message.uuid
|
||||
const isLatestBashOutput = latestBashOutputUUID === message.uuid;
|
||||
const content = (
|
||||
<Box flexDirection="column" width={containerWidth ?? '100%'}>
|
||||
{(message.message.content as Array<TextBlockParam | ImageBlockParam | ToolUseBlockParam | ToolResultBlockParam>).map((param, index) => (
|
||||
{(
|
||||
message.message.content as Array<
|
||||
TextBlockParam | ImageBlockParam | ToolUseBlockParam | ToolResultBlockParam
|
||||
>
|
||||
).map((param, index) => (
|
||||
<UserMessage
|
||||
key={index}
|
||||
message={message}
|
||||
@@ -188,12 +184,8 @@ function MessageImpl({
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
)
|
||||
return isLatestBashOutput ? (
|
||||
<ExpandShellOutputProvider>{content}</ExpandShellOutputProvider>
|
||||
) : (
|
||||
content
|
||||
)
|
||||
);
|
||||
return isLatestBashOutput ? <ExpandShellOutputProvider>{content}</ExpandShellOutputProvider> : content;
|
||||
}
|
||||
case 'system':
|
||||
if (message.subtype === 'compact_boundary') {
|
||||
@@ -201,32 +193,32 @@ function MessageImpl({
|
||||
// appends instead of resetting, Messages.tsx skips the boundary
|
||||
// filter) — scroll up for history, no need for the ctrl+o hint.
|
||||
if (isFullscreenEnvEnabled()) {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
return <CompactBoundaryMessage />
|
||||
return <CompactBoundaryMessage />;
|
||||
}
|
||||
if (message.subtype === 'microcompact_boundary') {
|
||||
// Logged at creation time in createMicrocompactBoundaryMessage
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
if (feature('HISTORY_SNIP')) {
|
||||
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||
const { isSnipBoundaryMessage } =
|
||||
require('../services/compact/snipProjection.js') as typeof import('../services/compact/snipProjection.js')
|
||||
require('../services/compact/snipProjection.js') as typeof import('../services/compact/snipProjection.js');
|
||||
const { isSnipMarkerMessage } =
|
||||
require('../services/compact/snipCompact.js') as typeof import('../services/compact/snipCompact.js')
|
||||
require('../services/compact/snipCompact.js') as typeof import('../services/compact/snipCompact.js');
|
||||
/* eslint-enable @typescript-eslint/no-require-imports */
|
||||
if (isSnipBoundaryMessage(message)) {
|
||||
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||
const { SnipBoundaryMessage } =
|
||||
require('./messages/SnipBoundaryMessage.js') as typeof import('./messages/SnipBoundaryMessage.js')
|
||||
require('./messages/SnipBoundaryMessage.js') as typeof import('./messages/SnipBoundaryMessage.js');
|
||||
/* eslint-enable @typescript-eslint/no-require-imports */
|
||||
return <SnipBoundaryMessage message={message} />
|
||||
return <SnipBoundaryMessage message={message} />;
|
||||
}
|
||||
if (isSnipMarkerMessage(message)) {
|
||||
// Internal registration marker — not user-facing. The boundary
|
||||
// message (above) is what shows when snips actually execute.
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (message.subtype === 'local_command') {
|
||||
@@ -237,7 +229,7 @@ function MessageImpl({
|
||||
verbose={verbose}
|
||||
isTranscriptMode={isTranscriptMode}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
return (
|
||||
<SystemTextMessage
|
||||
@@ -246,7 +238,7 @@ function MessageImpl({
|
||||
verbose={verbose}
|
||||
isTranscriptMode={isTranscriptMode}
|
||||
/>
|
||||
)
|
||||
);
|
||||
case 'grouped_tool_use':
|
||||
return (
|
||||
<GroupedToolUseContent
|
||||
@@ -256,7 +248,7 @@ function MessageImpl({
|
||||
inProgressToolUseIDs={inProgressToolUseIDs}
|
||||
shouldAnimate={shouldAnimate}
|
||||
/>
|
||||
)
|
||||
);
|
||||
case 'collapsed_read_search':
|
||||
// OffscreenFreeze: the verb flips "Reading…"→"Read" when tools complete.
|
||||
// If the group has scrolled into scrollback by then, the update triggers
|
||||
@@ -281,7 +273,7 @@ function MessageImpl({
|
||||
isActiveGroup={isActiveCollapsedGroup}
|
||||
/>
|
||||
</OffscreenFreeze>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,24 +291,20 @@ function UserMessage({
|
||||
isTranscriptMode,
|
||||
shouldCollapseDiffs,
|
||||
}: {
|
||||
message: NormalizedUserMessage
|
||||
addMargin: boolean
|
||||
tools: Tools
|
||||
progressMessagesForMessage: ProgressMessage[]
|
||||
param:
|
||||
| TextBlockParam
|
||||
| ImageBlockParam
|
||||
| ToolUseBlockParam
|
||||
| ToolResultBlockParam
|
||||
style?: 'condensed'
|
||||
verbose: boolean
|
||||
imageIndex?: number
|
||||
isUserContinuation: boolean
|
||||
lookups: ReturnType<typeof buildMessageLookups>
|
||||
isTranscriptMode: boolean
|
||||
shouldCollapseDiffs?: boolean
|
||||
message: NormalizedUserMessage;
|
||||
addMargin: boolean;
|
||||
tools: Tools;
|
||||
progressMessagesForMessage: ProgressMessage[];
|
||||
param: TextBlockParam | ImageBlockParam | ToolUseBlockParam | ToolResultBlockParam;
|
||||
style?: 'condensed';
|
||||
verbose: boolean;
|
||||
imageIndex?: number;
|
||||
isUserContinuation: boolean;
|
||||
lookups: ReturnType<typeof buildMessageLookups>;
|
||||
isTranscriptMode: boolean;
|
||||
shouldCollapseDiffs?: boolean;
|
||||
}): React.ReactNode {
|
||||
const { columns } = useTerminalSize()
|
||||
const { columns } = useTerminalSize();
|
||||
switch (param.type) {
|
||||
case 'text':
|
||||
return (
|
||||
@@ -328,16 +316,11 @@ function UserMessage({
|
||||
isTranscriptMode={isTranscriptMode}
|
||||
timestamp={message.timestamp as string | undefined}
|
||||
/>
|
||||
)
|
||||
);
|
||||
case 'image':
|
||||
// If previous message is user (text or image), this is a continuation - use connector
|
||||
// Otherwise this image starts a new user turn - use margin
|
||||
return (
|
||||
<UserImageMessage
|
||||
imageId={imageIndex}
|
||||
addMargin={addMargin && !isUserContinuation}
|
||||
/>
|
||||
)
|
||||
return <UserImageMessage imageId={imageIndex} addMargin={addMargin && !isUserContinuation} />;
|
||||
case 'tool_result':
|
||||
return (
|
||||
<UserToolResultMessage
|
||||
@@ -352,9 +335,9 @@ function UserMessage({
|
||||
isTranscriptMode={isTranscriptMode}
|
||||
shouldCollapseDiffs={shouldCollapseDiffs}
|
||||
/>
|
||||
)
|
||||
);
|
||||
default:
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,25 +368,25 @@ function AssistantMessageBlock({
|
||||
| ImageBlockParam
|
||||
| ThinkingBlockParam
|
||||
| ToolUseBlockParam
|
||||
| ToolResultBlockParam
|
||||
addMargin: boolean
|
||||
tools: Tools
|
||||
commands: Command[]
|
||||
verbose: boolean
|
||||
inProgressToolUseIDs: Set<string>
|
||||
progressMessagesForMessage: ProgressMessage[]
|
||||
shouldAnimate: boolean
|
||||
shouldShowDot: boolean
|
||||
width?: number | string
|
||||
inProgressToolCallCount?: number
|
||||
isTranscriptMode: boolean
|
||||
lookups: ReturnType<typeof buildMessageLookups>
|
||||
onOpenRateLimitOptions?: () => void
|
||||
| ToolResultBlockParam;
|
||||
addMargin: boolean;
|
||||
tools: Tools;
|
||||
commands: Command[];
|
||||
verbose: boolean;
|
||||
inProgressToolUseIDs: Set<string>;
|
||||
progressMessagesForMessage: ProgressMessage[];
|
||||
shouldAnimate: boolean;
|
||||
shouldShowDot: boolean;
|
||||
width?: number | string;
|
||||
inProgressToolCallCount?: number;
|
||||
isTranscriptMode: boolean;
|
||||
lookups: ReturnType<typeof buildMessageLookups>;
|
||||
onOpenRateLimitOptions?: () => void;
|
||||
/** ID of this content block's message:index for thinking block comparison */
|
||||
thinkingBlockId: string
|
||||
thinkingBlockId: string;
|
||||
/** ID of the last thinking block to show, null means show all */
|
||||
lastThinkingBlockId?: string | null
|
||||
advisorModel?: string
|
||||
lastThinkingBlockId?: string | null;
|
||||
advisorModel?: string;
|
||||
}): React.ReactNode {
|
||||
if (feature('CONNECTOR_TEXT')) {
|
||||
if (isConnectorTextBlock(param)) {
|
||||
@@ -416,7 +399,7 @@ function AssistantMessageBlock({
|
||||
width={width}
|
||||
onOpenRateLimitOptions={onOpenRateLimitOptions}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
switch (param.type) {
|
||||
@@ -436,7 +419,7 @@ function AssistantMessageBlock({
|
||||
lookups={lookups}
|
||||
isTranscriptMode={isTranscriptMode}
|
||||
/>
|
||||
)
|
||||
);
|
||||
case 'text':
|
||||
return (
|
||||
<AssistantTextMessage
|
||||
@@ -447,19 +430,18 @@ function AssistantMessageBlock({
|
||||
width={width}
|
||||
onOpenRateLimitOptions={onOpenRateLimitOptions}
|
||||
/>
|
||||
)
|
||||
);
|
||||
case 'redacted_thinking':
|
||||
if (!isTranscriptMode && !verbose) {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
return <AssistantRedactedThinkingMessage addMargin={addMargin} />
|
||||
return <AssistantRedactedThinkingMessage addMargin={addMargin} />;
|
||||
case 'thinking': {
|
||||
if (!isTranscriptMode && !verbose) {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
// In transcript mode with hidePastThinking, only show the last thinking block
|
||||
const isLastThinking =
|
||||
!lastThinkingBlockId || thinkingBlockId === lastThinkingBlockId
|
||||
const isLastThinking = !lastThinkingBlockId || thinkingBlockId === lastThinkingBlockId;
|
||||
return (
|
||||
<AssistantThinkingMessage
|
||||
addMargin={addMargin}
|
||||
@@ -468,7 +450,7 @@ function AssistantMessageBlock({
|
||||
verbose={verbose}
|
||||
hideInTranscript={isTranscriptMode && !isLastThinking}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
case 'server_tool_use':
|
||||
case 'advisor_tool_result':
|
||||
@@ -483,29 +465,24 @@ function AssistantMessageBlock({
|
||||
verbose={verbose || isTranscriptMode}
|
||||
advisorModel={advisorModel}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
logError(new Error(`Unable to render server tool block: ${param.type}`))
|
||||
return null
|
||||
logError(new Error(`Unable to render server tool block: ${param.type}`));
|
||||
return null;
|
||||
default:
|
||||
logError(new Error(`Unable to render message type: ${param.type}`))
|
||||
return null
|
||||
logError(new Error(`Unable to render message type: ${param.type}`));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function hasThinkingContent(m: {
|
||||
type: string
|
||||
message?: { content: Array<{ type: string }> }
|
||||
}): boolean {
|
||||
if (m.type !== 'assistant' || !m.message) return false
|
||||
return m.message.content.some(
|
||||
b => b.type === 'thinking' || b.type === 'redacted_thinking',
|
||||
)
|
||||
export function hasThinkingContent(m: { type: string; message?: { content: Array<{ type: string }> } }): boolean {
|
||||
if (m.type !== 'assistant' || !m.message) return false;
|
||||
return m.message.content.some(b => b.type === 'thinking' || b.type === 'redacted_thinking');
|
||||
}
|
||||
|
||||
/** Exported for testing */
|
||||
export function areMessagePropsEqual(prev: Props, next: Props): boolean {
|
||||
if (prev.message.uuid !== next.message.uuid) return false
|
||||
if (prev.message.uuid !== next.message.uuid) return false;
|
||||
// Only re-render on lastThinkingBlockId change if this message actually
|
||||
// has thinking content — otherwise every message in scrollback re-renders
|
||||
// whenever streaming thinking starts/stops (CC-941).
|
||||
@@ -513,21 +490,21 @@ export function areMessagePropsEqual(prev: Props, next: Props): boolean {
|
||||
prev.lastThinkingBlockId !== next.lastThinkingBlockId &&
|
||||
hasThinkingContent(next.message as Parameters<typeof hasThinkingContent>[0])
|
||||
) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
// Verbose toggle changes thinking block visibility/expansion
|
||||
if (prev.verbose !== next.verbose) return false
|
||||
if (prev.verbose !== next.verbose) return false;
|
||||
// Only re-render if this message's "is latest bash output" status changed,
|
||||
// not when the global latestBashOutputUUID changes to a different message
|
||||
const prevIsLatest = prev.latestBashOutputUUID === prev.message.uuid
|
||||
const nextIsLatest = next.latestBashOutputUUID === next.message.uuid
|
||||
if (prevIsLatest !== nextIsLatest) return false
|
||||
if (prev.isTranscriptMode !== next.isTranscriptMode) return false
|
||||
const prevIsLatest = prev.latestBashOutputUUID === prev.message.uuid;
|
||||
const nextIsLatest = next.latestBashOutputUUID === next.message.uuid;
|
||||
if (prevIsLatest !== nextIsLatest) return false;
|
||||
if (prev.isTranscriptMode !== next.isTranscriptMode) return false;
|
||||
// containerWidth is an absolute number in the no-metadata path (wrapper
|
||||
// Box is skipped). Static messages must re-render on terminal resize.
|
||||
if (prev.containerWidth !== next.containerWidth) return false
|
||||
if (prev.isStatic && next.isStatic) return true
|
||||
return false
|
||||
if (prev.containerWidth !== next.containerWidth) return false;
|
||||
if (prev.isStatic && next.isStatic) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
export const Message = React.memo(MessageImpl, areMessagePropsEqual)
|
||||
export const Message = React.memo(MessageImpl, areMessagePropsEqual);
|
||||
|
||||
Reference in New Issue
Block a user