refactor: replace individual provider logos with a unified SessionProviderLogo component

This commit is contained in:
Haileyesus
2026-02-11 15:49:00 +03:00
parent 8e411187f3
commit 79d7934a4b
10 changed files with 44 additions and 79 deletions

View File

@@ -0,0 +1,24 @@
import type { SessionProvider } from '../types/app';
import ClaudeLogo from './ClaudeLogo';
import CodexLogo from './CodexLogo';
import CursorLogo from './CursorLogo';
type SessionProviderLogoProps = {
provider?: SessionProvider | string | null;
className?: string;
};
export default function SessionProviderLogo({
provider = 'claude',
className = 'w-5 h-5',
}: SessionProviderLogoProps) {
if (provider === 'cursor') {
return <CursorLogo className={className} />;
}
if (provider === 'codex') {
return <CodexLogo className={className} />;
}
return <ClaudeLogo className={className} />;
}

View File

@@ -5,9 +5,6 @@ import { Badge } from './ui/badge';
import { X, Plus, Settings as SettingsIcon, Shield, AlertTriangle, Moon, Sun, Server, Edit3, Trash2, Globe, Terminal, Zap, FolderOpen, LogIn, Key, GitBranch, Check } from 'lucide-react';
import { useTheme } from '../contexts/ThemeContext';
import { useTranslation } from 'react-i18next';
import ClaudeLogo from './ClaudeLogo';
import CursorLogo from './CursorLogo';
import CodexLogo from './CodexLogo';
import CredentialsSettings from './CredentialsSettings';
import GitSettings from './GitSettings';
import TasksSettings from './TasksSettings';

View File

@@ -1,9 +1,7 @@
// @ts-nocheck
import React, { memo, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import ClaudeLogo from '../../ClaudeLogo.jsx';
import CursorLogo from '../../CursorLogo.jsx';
import CodexLogo from '../../CodexLogo.jsx';
import SessionProviderLogo from '../../SessionProviderLogo';
import type { ChatMessage, Provider } from '../types';
import { Markdown } from '../markdown/Markdown';
import { formatUsageLimitText } from '../utils/chatFormatting';
@@ -128,13 +126,7 @@ const MessageComponent = memo(({ message, index, prevMessage, createDiff, onFile
</div>
) : (
<div className="w-8 h-8 rounded-full flex items-center justify-center text-white text-sm flex-shrink-0 p-1">
{selectedProvider === 'cursor' ? (
<CursorLogo className="w-full h-full" />
) : selectedProvider === 'codex' ? (
<CodexLogo className="w-full h-full" />
) : (
<ClaudeLogo className="w-full h-full" />
)}
<SessionProviderLogo provider={selectedProvider} className="w-full h-full" />
</div>
)}
<div className="text-sm font-medium text-gray-900 dark:text-white">

View File

@@ -1,8 +1,6 @@
import { useTranslation } from 'react-i18next';
import type { Dispatch, RefObject, SetStateAction } from 'react';
import ClaudeLogo from '../../ClaudeLogo.jsx';
import CursorLogo from '../../CursorLogo.jsx';
import CodexLogo from '../../CodexLogo.jsx';
import SessionProviderLogo from '../../SessionProviderLogo';
import MessageComponent from '../messages/MessageComponent';
import ProviderSelectionEmptyState from './ProviderSelectionEmptyState';
import type { ChatMessage, Provider } from '../types';
@@ -55,13 +53,7 @@ function AssistantThinkingIndicator() {
<div className="w-full">
<div className="flex items-center space-x-3 mb-2">
<div className="w-8 h-8 rounded-full flex items-center justify-center text-white text-sm flex-shrink-0 p-1 bg-transparent">
{selectedProvider === 'cursor' ? (
<CursorLogo className="w-full h-full" />
) : selectedProvider === 'codex' ? (
<CodexLogo className="w-full h-full" />
) : (
<ClaudeLogo className="w-full h-full" />
)}
<SessionProviderLogo provider={selectedProvider} className="w-full h-full" />
</div>
<div className="text-sm font-medium text-gray-900 dark:text-white">
{selectedProvider === 'cursor' ? 'Cursor' : selectedProvider === 'codex' ? 'Codex' : 'Claude'}

View File

@@ -1,8 +1,6 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import ClaudeLogo from '../../ClaudeLogo.jsx';
import CursorLogo from '../../CursorLogo.jsx';
import CodexLogo from '../../CodexLogo.jsx';
import SessionProviderLogo from '../../SessionProviderLogo';
import NextTaskBanner from '../../NextTaskBanner.jsx';
import { CLAUDE_MODELS, CURSOR_MODELS, CODEX_MODELS } from '../../../../shared/modelConstants';
import type { Provider } from '../types';
@@ -68,7 +66,7 @@ export default function ProviderSelectionEmptyState({
}`}
>
<div className="flex flex-col items-center justify-center h-full gap-3">
<ClaudeLogo className="w-10 h-10" />
<SessionProviderLogo provider="claude" className="w-10 h-10" />
<div>
<p className="font-semibold text-gray-900 dark:text-white">Claude Code</p>
<p className="text-xs text-gray-500 dark:text-gray-400">{t('providerSelection.providerInfo.anthropic')}</p>
@@ -94,7 +92,7 @@ export default function ProviderSelectionEmptyState({
}`}
>
<div className="flex flex-col items-center justify-center h-full gap-3">
<CursorLogo className="w-10 h-10" />
<SessionProviderLogo provider="cursor" className="w-10 h-10" />
<div>
<p className="font-semibold text-gray-900 dark:text-white">Cursor</p>
<p className="text-xs text-gray-500 dark:text-gray-400">{t('providerSelection.providerInfo.cursorEditor')}</p>
@@ -120,7 +118,7 @@ export default function ProviderSelectionEmptyState({
}`}
>
<div className="flex flex-col items-center justify-center h-full gap-3">
<CodexLogo className="w-10 h-10" />
<SessionProviderLogo provider="codex" className="w-10 h-10" />
<div>
<p className="font-semibold text-gray-900 dark:text-white">Codex</p>
<p className="text-xs text-gray-500 dark:text-gray-400">{t('providerSelection.providerInfo.openai')}</p>

View File

@@ -1,6 +1,5 @@
import { useTranslation } from 'react-i18next';
import ClaudeLogo from '../ClaudeLogo';
import CursorLogo from '../CursorLogo';
import SessionProviderLogo from '../SessionProviderLogo';
import type { AppTab, Project, ProjectSession } from '../../types/app';
type MainContentTitleProps = {
@@ -49,11 +48,7 @@ export default function MainContentTitle({
<div className="min-w-0 flex items-center gap-2 flex-1 overflow-x-auto scrollbar-hide">
{showSessionIcon && (
<div className="w-5 h-5 flex-shrink-0 flex items-center justify-center">
{selectedSession?.__provider === 'cursor' ? (
<CursorLogo className="w-4 h-4" />
) : (
<ClaudeLogo className="w-4 h-4" />
)}
<SessionProviderLogo provider={selectedSession?.__provider} className="w-4 h-4" />
</div>
)}

View File

@@ -1,16 +1,13 @@
import { Button } from '../ui/button';
import { Badge } from '../ui/badge';
import { LogIn } from 'lucide-react';
import ClaudeLogo from '../ClaudeLogo';
import CursorLogo from '../CursorLogo';
import CodexLogo from '../CodexLogo';
import SessionProviderLogo from '../SessionProviderLogo';
import { useTranslation } from 'react-i18next';
const agentConfig = {
claude: {
name: 'Claude',
description: 'Anthropic Claude AI assistant',
Logo: ClaudeLogo,
bgClass: 'bg-blue-50 dark:bg-blue-900/20',
borderClass: 'border-blue-200 dark:border-blue-800',
textClass: 'text-blue-900 dark:text-blue-100',
@@ -20,7 +17,6 @@ const agentConfig = {
cursor: {
name: 'Cursor',
description: 'Cursor AI-powered code editor',
Logo: CursorLogo,
bgClass: 'bg-purple-50 dark:bg-purple-900/20',
borderClass: 'border-purple-200 dark:border-purple-800',
textClass: 'text-purple-900 dark:text-purple-100',
@@ -30,7 +26,6 @@ const agentConfig = {
codex: {
name: 'Codex',
description: 'OpenAI Codex AI assistant',
Logo: CodexLogo,
bgClass: 'bg-gray-100 dark:bg-gray-800/50',
borderClass: 'border-gray-300 dark:border-gray-600',
textClass: 'text-gray-900 dark:text-gray-100',
@@ -42,12 +37,11 @@ const agentConfig = {
export default function AccountContent({ agent, authStatus, onLogin }) {
const { t } = useTranslation('settings');
const config = agentConfig[agent];
const { Logo } = config;
return (
<div className="space-y-6">
<div className="flex items-center gap-3 mb-4">
<Logo className="w-6 h-6" />
<SessionProviderLogo provider={agent} className="w-6 h-6" />
<div>
<h3 className="text-lg font-medium text-foreground">{config.name}</h3>
<p className="text-sm text-muted-foreground">{t(`agents.account.${agent}.description`)}</p>

View File

@@ -1,23 +1,18 @@
import ClaudeLogo from '../ClaudeLogo';
import CursorLogo from '../CursorLogo';
import CodexLogo from '../CodexLogo';
import SessionProviderLogo from '../SessionProviderLogo';
import { useTranslation } from 'react-i18next';
const agentConfig = {
claude: {
name: 'Claude',
color: 'blue',
Logo: ClaudeLogo,
},
cursor: {
name: 'Cursor',
color: 'purple',
Logo: CursorLogo,
},
codex: {
name: 'Codex',
color: 'gray',
Logo: CodexLogo,
},
};
@@ -46,7 +41,6 @@ export default function AgentListItem({ agentId, authStatus, isSelected, onClick
const { t } = useTranslation('settings');
const config = agentConfig[agentId];
const colors = colorClasses[config.color];
const { Logo } = config;
// Mobile: horizontal layout with bottom border
if (isMobile) {
@@ -60,7 +54,7 @@ export default function AgentListItem({ agentId, authStatus, isSelected, onClick
}`}
>
<div className="flex flex-col items-center gap-1">
<Logo className="w-5 h-5" />
<SessionProviderLogo provider={agentId} className="w-5 h-5" />
<span className="text-xs font-medium text-foreground">{config.name}</span>
{authStatus?.authenticated && (
<span className={`w-1.5 h-1.5 rounded-full ${colors.dot}`} />
@@ -81,7 +75,7 @@ export default function AgentListItem({ agentId, authStatus, isSelected, onClick
}`}
>
<div className="flex items-center gap-2 mb-1">
<Logo className="w-4 h-4" />
<SessionProviderLogo provider={agentId} className="w-4 h-4" />
<span className="font-medium text-foreground">{config.name}</span>
</div>
<div className="text-xs text-muted-foreground pl-6">

View File

@@ -1,21 +0,0 @@
import type { SessionProvider } from '../../types/app';
import ClaudeLogo from '../ClaudeLogo';
import CodexLogo from '../CodexLogo';
import CursorLogo from '../CursorLogo';
type SessionProviderIconProps = {
provider: SessionProvider;
className: string;
};
export default function SessionProviderIcon({ provider, className }: SessionProviderIconProps) {
if (provider === 'cursor') {
return <CursorLogo className={className} />;
}
if (provider === 'codex') {
return <CodexLogo className={className} />;
}
return <ClaudeLogo className={className} />;
}

View File

@@ -7,7 +7,7 @@ import { formatTimeAgo } from '../../utils/dateUtils';
import type { Project, ProjectSession, SessionProvider } from '../../types/app';
import type { SessionWithProvider, TouchHandlerFactory } from './types';
import { createSessionViewModel } from './utils';
import SessionProviderIcon from './SessionProviderIcon';
import SessionProviderLogo from '../SessionProviderLogo';
type SidebarSessionItemProps = {
project: Project;
@@ -92,7 +92,7 @@ export default function SidebarSessionItem({
isSelected ? 'bg-primary/10' : 'bg-muted/50',
)}
>
<SessionProviderIcon provider={session.__provider} className="w-3 h-3" />
<SessionProviderLogo provider={session.__provider} className="w-3 h-3" />
</div>
<div className="min-w-0 flex-1">
@@ -108,7 +108,7 @@ export default function SidebarSessionItem({
</Badge>
)}
<span className="ml-1 opacity-70">
<SessionProviderIcon provider={session.__provider} className="w-3 h-3" />
<SessionProviderLogo provider={session.__provider} className="w-3 h-3" />
</span>
</div>
</div>
@@ -140,7 +140,7 @@ export default function SidebarSessionItem({
onTouchEnd={touchHandlerFactory(() => onSessionSelect(session, project.name))}
>
<div className="flex items-start gap-2 min-w-0 w-full">
<SessionProviderIcon provider={session.__provider} className="w-3 h-3 mt-0.5 flex-shrink-0" />
<SessionProviderLogo provider={session.__provider} className="w-3 h-3 mt-0.5 flex-shrink-0" />
<div className="min-w-0 flex-1">
<div className="text-xs font-medium truncate text-foreground">{sessionView.sessionName}</div>
<div className="flex items-center gap-1 mt-0.5">
@@ -157,7 +157,7 @@ export default function SidebarSessionItem({
</Badge>
)}
<span className="ml-1 opacity-70 group-hover:opacity-0 transition-opacity">
<SessionProviderIcon provider={session.__provider} className="w-3 h-3" />
<SessionProviderLogo provider={session.__provider} className="w-3 h-3" />
</span>
</div>
</div>