From 720a771b2aa49dead9ff9d46be106b22c2c9a564 Mon Sep 17 00:00:00 2001 From: Haileyesus Date: Wed, 11 Feb 2026 18:58:06 +0300 Subject: [PATCH] feat(chat): move thinking modes, token usage pie, and related logic into chat folder --- .../chat/constants/thinkingModes.ts | 44 ++++++++++ .../chat/hooks/useChatComposerState.ts | 4 +- .../view/subcomponents/ChatInputControls.tsx | 6 +- .../subcomponents/ThinkingModeSelector.tsx} | 84 +++++-------------- .../view/subcomponents/TokenUsagePie.tsx} | 13 +-- 5 files changed, 80 insertions(+), 71 deletions(-) create mode 100644 src/components/chat/constants/thinkingModes.ts rename src/components/{ThinkingModeSelector.jsx => chat/view/subcomponents/ThinkingModeSelector.tsx} (75%) rename src/components/{TokenUsagePie.jsx => chat/view/subcomponents/TokenUsagePie.tsx} (87%) diff --git a/src/components/chat/constants/thinkingModes.ts b/src/components/chat/constants/thinkingModes.ts new file mode 100644 index 0000000..3b28131 --- /dev/null +++ b/src/components/chat/constants/thinkingModes.ts @@ -0,0 +1,44 @@ +import { Brain, Zap, Sparkles, Atom } from 'lucide-react'; + +export const thinkingModes = [ + { + id: 'none', + name: 'Standard', + description: 'Regular Claude response', + icon: null, + prefix: '', + color: 'text-gray-600' + }, + { + id: 'think', + name: 'Think', + description: 'Basic extended thinking', + icon: Brain, + prefix: 'think', + color: 'text-blue-600' + }, + { + id: 'think-hard', + name: 'Think Hard', + description: 'More thorough evaluation', + icon: Zap, + prefix: 'think hard', + color: 'text-purple-600' + }, + { + id: 'think-harder', + name: 'Think Harder', + description: 'Deep analysis with alternatives', + icon: Sparkles, + prefix: 'think harder', + color: 'text-indigo-600' + }, + { + id: 'ultrathink', + name: 'Ultrathink', + description: 'Maximum thinking budget', + icon: Atom, + prefix: 'ultrathink', + color: 'text-red-600' + } +]; \ No newline at end of file diff --git a/src/components/chat/hooks/useChatComposerState.ts b/src/components/chat/hooks/useChatComposerState.ts index fa0184a..9b6713c 100644 --- a/src/components/chat/hooks/useChatComposerState.ts +++ b/src/components/chat/hooks/useChatComposerState.ts @@ -11,7 +11,9 @@ import type { } from 'react'; import { useDropzone } from 'react-dropzone'; import { authenticatedFetch } from '../../../utils/api'; -import { thinkingModes } from '../../ThinkingModeSelector.jsx'; + +import { thinkingModes } from '../constants/thinkingModes'; + import { grantClaudeToolPermission } from '../utils/chatPermissions'; import { safeLocalStorage } from '../utils/chatStorage'; import type { diff --git a/src/components/chat/view/subcomponents/ChatInputControls.tsx b/src/components/chat/view/subcomponents/ChatInputControls.tsx index d7bf906..98c9be0 100644 --- a/src/components/chat/view/subcomponents/ChatInputControls.tsx +++ b/src/components/chat/view/subcomponents/ChatInputControls.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; -import ThinkingModeSelector from '../../ThinkingModeSelector.jsx'; -import TokenUsagePie from '../../TokenUsagePie'; -import type { PermissionMode, Provider } from '../types'; +import ThinkingModeSelector from './ThinkingModeSelector.jsx'; +import TokenUsagePie from './TokenUsagePie'; +import type { PermissionMode, Provider } from '../../types/types'; interface ChatInputControlsProps { permissionMode: PermissionMode | string; diff --git a/src/components/ThinkingModeSelector.jsx b/src/components/chat/view/subcomponents/ThinkingModeSelector.tsx similarity index 75% rename from src/components/ThinkingModeSelector.jsx rename to src/components/chat/view/subcomponents/ThinkingModeSelector.tsx index 5cc6357..e0ae4d3 100644 --- a/src/components/ThinkingModeSelector.jsx +++ b/src/components/chat/view/subcomponents/ThinkingModeSelector.tsx @@ -1,55 +1,21 @@ -import React, { useState, useRef, useEffect } from 'react'; -import { Brain, Zap, Sparkles, Atom, X } from 'lucide-react'; +import { useState, useRef, useEffect } from 'react'; +import { Brain, X } from 'lucide-react'; import { useTranslation } from 'react-i18next'; -const thinkingModes = [ - { - id: 'none', - name: 'Standard', - description: 'Regular Claude response', - icon: null, - prefix: '', - color: 'text-gray-600' - }, - { - id: 'think', - name: 'Think', - description: 'Basic extended thinking', - icon: Brain, - prefix: 'think', - color: 'text-blue-600' - }, - { - id: 'think-hard', - name: 'Think Hard', - description: 'More thorough evaluation', - icon: Zap, - prefix: 'think hard', - color: 'text-purple-600' - }, - { - id: 'think-harder', - name: 'Think Harder', - description: 'Deep analysis with alternatives', - icon: Sparkles, - prefix: 'think harder', - color: 'text-indigo-600' - }, - { - id: 'ultrathink', - name: 'Ultrathink', - description: 'Maximum thinking budget', - icon: Atom, - prefix: 'ultrathink', - color: 'text-red-600' - } -]; +import { thinkingModes } from '../../constants/thinkingModes'; -function ThinkingModeSelector({ selectedMode, onModeChange, onClose, className = '' }) { +type ThinkingModeSelectorProps = { + selectedMode: string; + onModeChange: (modeId: string) => void; + onClose?: () => void; + className?: string; +}; + +function ThinkingModeSelector({ selectedMode, onModeChange, onClose, className = '' }: ThinkingModeSelectorProps) { const { t } = useTranslation('chat'); // Mapping from mode ID to translation key - const modeKeyMap = { + const modeKeyMap: Record = { 'think-hard': 'thinkHard', 'think-harder': 'thinkHarder' }; @@ -65,11 +31,11 @@ function ThinkingModeSelector({ selectedMode, onModeChange, onClose, className = }); const [isOpen, setIsOpen] = useState(false); - const dropdownRef = useRef(null); + const dropdownRef = useRef(null); useEffect(() => { - const handleClickOutside = (event) => { - if (dropdownRef.current && !dropdownRef.current.contains(event.target)) { + const handleClickOutside = (event: MouseEvent) => { + if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { setIsOpen(false); if (onClose) onClose(); } @@ -87,11 +53,10 @@ function ThinkingModeSelector({ selectedMode, onModeChange, onClose, className =