diff --git a/packages/ui/src/components/chat/ChatInput.tsx b/packages/ui/src/components/chat/ChatInput.tsx index df5e191d..c1381851 100644 --- a/packages/ui/src/components/chat/ChatInput.tsx +++ b/packages/ui/src/components/chat/ChatInput.tsx @@ -4557,7 +4557,6 @@ const ChatInputComponent: React.FC = ({ onOpenSettings, scrollTo diff --git a/packages/ui/src/components/chat/ChatMessage.tsx b/packages/ui/src/components/chat/ChatMessage.tsx index 1309cbf4..58485d5e 100644 --- a/packages/ui/src/components/chat/ChatMessage.tsx +++ b/packages/ui/src/components/chat/ChatMessage.tsx @@ -2,7 +2,6 @@ import React from 'react'; import type { Message, Part } from '@opencode-ai/sdk/v2'; import { useShallow } from 'zustand/react/shallow'; -import { defaultCodeDark, defaultCodeLight } from '@/lib/codeTheme'; import { MessageFreshnessDetector } from '@/lib/messageFreshness'; import { useConfigStore } from '@/stores/useConfigStore'; import { useFeatureFlagsStore } from '@/stores/useFeatureFlagsStore'; @@ -12,7 +11,6 @@ import { useSessionUIStore } from '@/sync/session-ui-store'; import { useSelectionStore } from '@/sync/selection-store'; import { useDeviceInfo } from '@/lib/device'; import { useThemeSystem } from '@/contexts/useThemeSystem'; -import { generateSyntaxTheme } from '@/lib/theme/syntaxThemeGenerator'; import { cn } from '@/lib/utils'; import type { AnimationHandlers, ContentChangeReason } from '@/hooks/useChatAutoFollow'; @@ -548,13 +546,6 @@ const ChatMessage: React.FC = ({ return false; }, [themeVariant]); - const syntaxTheme = React.useMemo(() => { - if (currentTheme) { - return generateSyntaxTheme(currentTheme); - } - return isDarkTheme ? defaultCodeDark : defaultCodeLight; - }, [currentTheme, isDarkTheme]); - const shouldAnimateMessage = React.useMemo(() => { if (isUser) return false; const freshnessDetector = MessageFreshnessDetector.getInstance(); @@ -1026,7 +1017,6 @@ const ChatMessage: React.FC = ({ isUser={isUser} isMessageCompleted={isMessageCompleted} messageFinish={messageFinish} - syntaxTheme={syntaxTheme} isMobile={isMobile} alwaysShowActions={alwaysShowMessageActions} hasTouchInput={hasTouchInput} @@ -1060,7 +1050,6 @@ const ChatMessage: React.FC = ({ isUser={isUser} isMessageCompleted={isMessageCompleted} messageFinish={messageFinish} - syntaxTheme={syntaxTheme} isMobile={isMobile} alwaysShowActions={alwaysShowMessageActions} hasTouchInput={hasTouchInput} @@ -1113,7 +1102,6 @@ const ChatMessage: React.FC = ({ messageFinish={messageFinish} messageCompletedAt={messageCompletedAt ?? undefined} messageCreatedAt={messageCreatedAt ?? undefined} - syntaxTheme={syntaxTheme} isMobile={isMobile} alwaysShowActions={alwaysShowMessageActions} hasTouchInput={hasTouchInput} @@ -1146,7 +1134,6 @@ const ChatMessage: React.FC = ({ diff --git a/packages/ui/src/components/chat/components/TurnActivity.tsx b/packages/ui/src/components/chat/components/TurnActivity.tsx index 4d04abfd..4fa46392 100644 --- a/packages/ui/src/components/chat/components/TurnActivity.tsx +++ b/packages/ui/src/components/chat/components/TurnActivity.tsx @@ -17,7 +17,6 @@ interface TurnActivityProps { isExpanded: boolean; collapsedPreviewCount?: number; onToggle: () => void; - syntaxTheme: Record; isMobile: boolean; expandedTools: Set; onToggleTool: (toolId: string) => void; diff --git a/packages/ui/src/components/chat/message/MessageBody.tsx b/packages/ui/src/components/chat/message/MessageBody.tsx index 309e597a..e2e36000 100644 --- a/packages/ui/src/components/chat/message/MessageBody.tsx +++ b/packages/ui/src/components/chat/message/MessageBody.tsx @@ -337,7 +337,6 @@ interface MessageBodyProps { messageCompletedAt?: number; messageCreatedAt?: number; - syntaxTheme: { [key: string]: React.CSSProperties }; isMobile: boolean; alwaysShowActions?: boolean; @@ -950,7 +949,6 @@ const AssistantMessageBody = React.memo(({ messageCompletedAt, messageCreatedAt, - syntaxTheme, isMobile, alwaysShowActions, hasTouchInput, @@ -1642,7 +1640,6 @@ const AssistantMessageBody = React.memo(({ isExpanded={turnGroupingContext.isGroupExpanded === true} collapsedPreviewCount={collapsedPreviewCount} onToggle={toggleActivityGroup} - syntaxTheme={syntaxTheme} isMobile={isMobile} expandedTools={expandedTools} onToggleTool={onToggleTool} @@ -1794,7 +1791,6 @@ const AssistantMessageBody = React.memo(({ part={toolPart} isExpanded={expandedTools.has(toolPart.id)} onToggle={onToggleTool} - syntaxTheme={syntaxTheme} isMobile={isMobile} alwaysShowActions={alwaysShowMessageActions} onContentChange={onContentChange} @@ -1866,7 +1862,6 @@ const AssistantMessageBody = React.memo(({ effectiveStreamPhase, showReasoningTraces, shouldDeferSortedInlineText, - syntaxTheme, toggleActivityGroup, turnGroupingContext, visibleParts, diff --git a/packages/ui/src/components/chat/message/ToolOutputDialog.tsx b/packages/ui/src/components/chat/message/ToolOutputDialog.tsx index 45b0cc95..798ecbb2 100644 --- a/packages/ui/src/components/chat/message/ToolOutputDialog.tsx +++ b/packages/ui/src/components/chat/message/ToolOutputDialog.tsx @@ -32,7 +32,6 @@ import { runtimeFetch } from '@/lib/runtime-fetch'; interface ToolOutputDialogProps { popup: ToolPopupContent; onOpenChange: (open: boolean) => void; - syntaxTheme: { [key: string]: React.CSSProperties }; isMobile: boolean; } @@ -984,7 +983,7 @@ const MermaidPreviewDialog: React.FC<{ return createPortal(content, document.body); }; -const ToolOutputDialog: React.FC = ({ popup, onOpenChange, syntaxTheme, isMobile }) => { +const ToolOutputDialog: React.FC = ({ popup, onOpenChange, isMobile }) => { const { t } = useI18n(); const [diffViewMode, setDiffViewMode] = React.useState('unified'); const pierreThemeConfig = usePierreThemeConfig(); @@ -1170,7 +1169,7 @@ const ToolOutputDialog: React.FC = ({ popup, onOpenChange if (tool === 'web-search' || tool === 'websearch' || tool === 'search_web') { return ( - renderWebSearchOutput(popup.content, syntaxTheme) || ( + renderWebSearchOutput(popup.content) || ( void; - syntaxTheme: Record; isMobile: boolean; expandedTools: Set; onToggleTool: (toolId: string) => void; @@ -373,7 +372,6 @@ type AggregatedRow = interface ExpandableToolRowProps { activity: TurnActivityPart; isExpanded: boolean; - syntaxTheme: Record; isMobile: boolean; onToggleTool: (toolId: string) => void; onShowPopup: (content: ToolPopupContent) => void; @@ -385,7 +383,6 @@ interface ExpandableToolRowProps { const ExpandableToolRow: React.FC = ({ activity, isExpanded, - syntaxTheme, isMobile, onToggleTool, onShowPopup, @@ -402,7 +399,6 @@ const ExpandableToolRow: React.FC = ({ part={activity.part as ToolPartType} isExpanded={isExpanded} onToggle={handleToggle} - syntaxTheme={syntaxTheme} isMobile={isMobile} onContentChange={onContentChange} onShowPopup={onShowPopup} @@ -425,7 +421,6 @@ const ExpandableToolRow: React.FC = ({ const MemoExpandableToolRow = React.memo(ExpandableToolRow, (prev, next) => { return prev.isExpanded === next.isExpanded - && prev.syntaxTheme === next.syntaxTheme && prev.isMobile === next.isMobile && prev.onToggleTool === next.onToggleTool && prev.onShowPopup === next.onShowPopup @@ -826,7 +821,6 @@ const ProgressiveGroup: React.FC = ({ isExpanded, collapsedPreviewCount = 0, onToggle, - syntaxTheme, isMobile, expandedTools, onToggleTool, @@ -915,7 +909,6 @@ const ProgressiveGroup: React.FC = ({ key={row.activity.id} activity={row.activity} isExpanded={expandedTools.has(row.activity.id)} - syntaxTheme={syntaxTheme} isMobile={isMobile} onToggleTool={onToggleTool} onShowPopup={onShowPopup} @@ -942,7 +935,6 @@ const ProgressiveGroup: React.FC = ({ key={row.activity.id} activity={row.activity} isExpanded={expandedTools.has(row.activity.id)} - syntaxTheme={syntaxTheme} isMobile={isMobile} onToggleTool={onToggleTool} onShowPopup={onShowPopup} diff --git a/packages/ui/src/components/chat/message/parts/ToolPart.tsx b/packages/ui/src/components/chat/message/parts/ToolPart.tsx index 7da0df7e..e5fde9a1 100644 --- a/packages/ui/src/components/chat/message/parts/ToolPart.tsx +++ b/packages/ui/src/components/chat/message/parts/ToolPart.tsx @@ -59,7 +59,6 @@ interface ToolPartProps { part: ToolPartType; isExpanded: boolean; onToggle: (toolId: string) => void; - syntaxTheme: { [key: string]: React.CSSProperties }; isMobile: boolean; alwaysShowActions?: boolean; onContentChange?: (reason?: ContentChangeReason) => void; @@ -843,7 +842,6 @@ const ToolScrollableTextOutput: React.FC<{ part: ToolPartType; metadata: Record | undefined; input: Record | undefined; - syntaxTheme: { [key: string]: React.CSSProperties }; }> = ({ output, part, metadata, input }) => { const { t } = useI18n(); const renderedOutput = getToolOutputText(output, part, metadata); @@ -1594,7 +1592,6 @@ DiffPreview.displayName = 'DiffPreview'; interface ToolExpandedContentProps { part: ToolPartType; state: ToolStateUnion; - syntaxTheme: { [key: string]: React.CSSProperties }; currentDirectory: string; isExpanded: boolean; onShowPopup?: (content: ToolPopupContent) => void; @@ -1603,7 +1600,6 @@ interface ToolExpandedContentProps { const ToolExpandedContent: React.FC = React.memo(({ part, state, - syntaxTheme, currentDirectory, isExpanded, onShowPopup, @@ -1853,7 +1849,6 @@ const ToolExpandedContent: React.FC = React.memo(({ part={part} metadata={metadata} input={input} - syntaxTheme={syntaxTheme} />, { className: part.tool === 'bash' ? 'p-1 rounded-none' : 'p-1', @@ -1944,7 +1939,6 @@ const ToolPartContent: React.FC = ({ part, isExpanded, onToggle, - syntaxTheme, isMobile, onContentChange, onShowPopup, @@ -2844,7 +2838,6 @@ const ToolPartContent: React.FC = ({ = (props) => { export default React.memo(ToolPart, (prev, next) => { return areRenderRelevantPartsEqual([prev.part], [next.part]) && prev.isExpanded === next.isExpanded - && prev.syntaxTheme === next.syntaxTheme && prev.isMobile === next.isMobile && prev.alwaysShowActions === next.alwaysShowActions && prev.onContentChange === next.onContentChange diff --git a/packages/ui/src/components/chat/message/toolRenderers.tsx b/packages/ui/src/components/chat/message/toolRenderers.tsx index d63ab4bc..785dfa84 100644 --- a/packages/ui/src/components/chat/message/toolRenderers.tsx +++ b/packages/ui/src/components/chat/message/toolRenderers.tsx @@ -510,7 +510,7 @@ export const renderTodoOutput = ( } }; -export const renderWebSearchOutput = (output: string, _syntaxTheme: { [key: string]: React.CSSProperties }, options?: { unstyled?: boolean }) => { +export const renderWebSearchOutput = (output: string, options?: { unstyled?: boolean }) => { try { return (
= ({ targetPath = null }) => { const runtimeApis = useRuntimeAPIs(); const { isMobile } = useDeviceInfo(); const { currentTheme } = useThemeSystem(); - React.useMemo(() => generateSyntaxTheme(currentTheme), [currentTheme]); const session = React.useMemo(() => { if (!currentSessionId) return null; diff --git a/packages/ui/src/lib/theme/syntaxThemeGenerator.ts b/packages/ui/src/lib/theme/syntaxThemeGenerator.ts deleted file mode 100644 index ad835944..00000000 --- a/packages/ui/src/lib/theme/syntaxThemeGenerator.ts +++ /dev/null @@ -1,208 +0,0 @@ -import type { Theme } from '@/types/theme'; - -export function generateSyntaxTheme(theme: Theme) { - const syntax = theme.colors.syntax; - const surface = theme.colors.surface; - - return { - 'code[class*="language-"]': { - color: syntax.base.foreground, - background: 'transparent', - fontFamily: 'Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace', - fontSize: '1em', - textAlign: 'left' as const, - whiteSpace: 'pre', - wordSpacing: 'normal', - wordBreak: 'normal' as const, - wordWrap: 'normal' as const, - lineHeight: '1.5', - MozTabSize: '4', - OTabSize: '4', - tabSize: '4', - WebkitHyphens: 'none' as const, - MozHyphens: 'none' as const, - msHyphens: 'none' as const, - hyphens: 'none' as const, - }, - 'pre[class*="language-"]': { - color: syntax.base.foreground, - background: 'transparent', - fontFamily: 'Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace', - fontSize: '1em', - textAlign: 'left' as const, - whiteSpace: 'pre', - wordSpacing: 'normal', - wordBreak: 'normal' as const, - wordWrap: 'normal' as const, - lineHeight: '1.5', - MozTabSize: '4', - OTabSize: '4', - tabSize: '4', - WebkitHyphens: 'none' as const, - MozHyphens: 'none' as const, - msHyphens: 'none' as const, - hyphens: 'none' as const, - padding: '0', - margin: '0', - overflow: 'auto', - }, - - comment: { - color: syntax.base.comment, - fontStyle: 'italic', - }, - prolog: { - color: syntax.base.comment, - }, - doctype: { - color: syntax.base.comment, - }, - cdata: { - color: syntax.base.comment, - }, - - punctuation: { - color: syntax.tokens?.punctuation || surface.mutedForeground, - }, - - property: { - color: syntax.tokens?.variableProperty || syntax.base.variable, - }, - tag: { - color: syntax.tokens?.tag || syntax.base.keyword, - }, - 'attr-name': { - color: syntax.tokens?.tagAttribute || syntax.base.variable, - }, - 'attr-value': { - color: syntax.tokens?.tagAttributeValue || syntax.base.string, - }, - - boolean: { - color: syntax.tokens?.boolean || syntax.base.number, - }, - number: { - color: syntax.base.number, - }, - constant: { - color: syntax.tokens?.constant || syntax.base.number, - }, - symbol: { - color: syntax.tokens?.constant || syntax.base.number, - }, - - string: { - color: syntax.base.string, - }, - char: { - color: syntax.base.string, - }, - - function: { - color: syntax.base.function, - }, - builtin: { - color: syntax.tokens?.functionBuiltin || syntax.base.function, - }, - - 'class-name': { - color: syntax.tokens?.className || syntax.base.type, - }, - namespace: { - color: syntax.tokens?.namespace || syntax.base.type, - opacity: 0.8, - }, - - keyword: { - color: syntax.base.keyword, - }, - atrule: { - color: syntax.base.keyword, - }, - selector: { - color: syntax.base.function, - }, - - operator: { - color: syntax.base.operator, - }, - - variable: { - color: syntax.base.variable, - }, - - regex: { - color: syntax.tokens?.regex || syntax.base.string, - }, - - url: { - color: syntax.base.function, - textDecoration: 'underline', - }, - entity: { - color: syntax.base.function, - cursor: 'help', - }, - - '.language-css .token.string': { - color: syntax.base.string, - }, - '.style .token.string': { - color: syntax.base.string, - }, - - deleted: { - color: theme.colors.status.error, - backgroundColor: theme.colors.status.errorBackground, - }, - inserted: { - color: theme.colors.status.success, - backgroundColor: theme.colors.status.successBackground, - }, - - title: { - color: theme.colors.primary.base, - fontWeight: 'bold', - }, - 'code-block': { - color: syntax.base.string, - }, - 'code-snippet': { - color: syntax.base.string, - }, - list: { - color: syntax.base.variable, - }, - hr: { - color: surface.mutedForeground, - }, - table: { - color: syntax.base.function, - }, - blockquote: { - color: surface.mutedForeground, - fontStyle: 'italic', - }, - - important: { - color: syntax.base.keyword, - fontWeight: 'bold', - }, - bold: { - fontWeight: 'bold', - }, - italic: { - fontStyle: 'italic', - }, - strike: { - textDecoration: 'line-through', - }, - - decorator: { - color: syntax.tokens?.decorator || syntax.base.function, - }, - annotation: { - color: syntax.tokens?.decorator || syntax.base.function, - }, - }; -} \ No newline at end of file