diff --git a/packages/ui/src/components/chat/FileAttachment.tsx b/packages/ui/src/components/chat/FileAttachment.tsx index 15d8886e..4624be90 100644 --- a/packages/ui/src/components/chat/FileAttachment.tsx +++ b/packages/ui/src/components/chat/FileAttachment.tsx @@ -6,7 +6,7 @@ import { toast } from '@/components/ui'; import { cn } from '@/lib/utils'; import { Tooltip, TooltipTrigger, TooltipContent } from '@/components/ui/tooltip'; import { useIsVSCodeRuntime } from '@/hooks/useRuntimeAPIs'; -import { useIsTextTruncated } from '@/hooks/useIsTextTruncated'; + import type { ToolPopupContent } from './message/types'; export const FileAttachmentButton = memo(() => { @@ -126,21 +126,6 @@ interface FileChipProps { onRemove: () => void; } -const TruncatedMarquee = memo(({ text, title }: { text: string; title?: string }) => { - const labelRef = useRef(null); - const isTruncated = useIsTextTruncated(labelRef, [text]); - - return ( - - {text} - - ); -}); - const FileChip = memo(({ file, onRemove }: FileChipProps) => { const getFileIcon = () => { if (file.mimeType.startsWith('image/')) { @@ -174,28 +159,29 @@ const FileChip = memo(({ file, onRemove }: FileChipProps) => { const displayName = extractFilename(file.filename); return ( -
- {} +
{file.source === 'server' ? ( - + ) : ( - + )}
{getFileIcon()} -
- +
+ + {displayName} +
- - ({formatFileSize(file.size)}) + + {formatFileSize(file.size)}
); @@ -207,9 +193,9 @@ export const AttachedFilesList = memo(() => { if (attachedFiles.length === 0) return null; return ( -
-
- Attached: +
+
+ Attached: {attachedFiles.map((file) => ( {getFileIcon(file.mime)}
- + + {extractFilename(file.filename)} +
))} diff --git a/packages/ui/src/components/chat/PermissionCard.tsx b/packages/ui/src/components/chat/PermissionCard.tsx index 1638160a..ffd5479a 100644 --- a/packages/ui/src/components/chat/PermissionCard.tsx +++ b/packages/ui/src/components/chat/PermissionCard.tsx @@ -340,12 +340,12 @@ export const PermissionCard: React.FC = ({
{} -
+
@@ -368,7 +368,7 @@ export const PermissionCard: React.FC = ({ onClick={() => handleResponse('always')} disabled={isResponding} className={cn( - "flex items-center gap-1 px-2 py-1 typography-meta font-medium rounded transition-all", + "flex items-center gap-1.5 sm:gap-1 px-3 sm:px-2 py-1.5 sm:py-1 typography-meta font-medium rounded transition-all min-h-[32px] sm:min-h-0 w-full sm:w-auto", "disabled:opacity-50 disabled:cursor-not-allowed" )} style={{ @@ -382,14 +382,18 @@ export const PermissionCard: React.FC = ({ e.currentTarget.style.backgroundColor = 'rgb(var(--muted) / 0.5)'; }} > - + {(() => { const always = (permission.always as string[]) || (permission.metadata.always as string[]) || []; if (always.length === 0) return "Always Allow"; const displayPatterns = always.slice(0, 2); const text = displayPatterns.join(", "); const hasMore = always.length > 2; - return hasMore ? `Always: ${text}...` : `Always: ${text}`; + return ( + + {hasMore ? `Always: ${text}...` : `Always: ${text}`} + + ); })()} ) : ( @@ -397,7 +401,7 @@ export const PermissionCard: React.FC = ({ onClick={() => handleResponse('always')} disabled={isResponding} className={cn( - "flex items-center gap-1 px-2 py-1 typography-meta font-medium rounded transition-all", + "flex items-center gap-1.5 sm:gap-1 px-3 sm:px-2 py-1.5 sm:py-1 typography-meta font-medium rounded transition-all min-h-[32px] sm:min-h-0 w-full sm:w-auto", "disabled:opacity-50 disabled:cursor-not-allowed" )} style={{ @@ -411,7 +415,7 @@ export const PermissionCard: React.FC = ({ e.currentTarget.style.backgroundColor = 'rgb(var(--muted) / 0.5)'; }} > - + Always Allow )} @@ -420,7 +424,7 @@ export const PermissionCard: React.FC = ({ onClick={() => handleResponse('reject')} disabled={isResponding} className={cn( - "flex items-center gap-1 px-2 py-1 typography-meta font-medium rounded transition-all", + "flex items-center gap-1.5 sm:gap-1 px-3 sm:px-2 py-1.5 sm:py-1 typography-meta font-medium rounded transition-all min-h-[32px] sm:min-h-0 w-full sm:w-auto", "disabled:opacity-50 disabled:cursor-not-allowed" )} style={{ @@ -434,12 +438,12 @@ export const PermissionCard: React.FC = ({ e.currentTarget.style.backgroundColor = 'rgb(var(--status-error) / 0.1)'; }} > - + Deny {isResponding && ( -
+
)} diff --git a/packages/ui/src/components/views/git/CommitSection.tsx b/packages/ui/src/components/views/git/CommitSection.tsx index ccebfd7d..cb7f65c2 100644 --- a/packages/ui/src/components/views/git/CommitSection.tsx +++ b/packages/ui/src/components/views/git/CommitSection.tsx @@ -13,6 +13,8 @@ import { Button } from '@/components/ui/button'; import { ButtonLarge } from '@/components/ui/button-large'; import { CommitInput } from './CommitInput'; import { AIHighlightsBox } from './AIHighlightsBox'; +import { useDeviceInfo } from '@/lib/device'; +import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'; type CommitAction = 'commit' | 'commitAndPush' | null; @@ -51,6 +53,7 @@ export const CommitSection: React.FC = ({ }) => { const hasSelectedFiles = selectedCount > 0; const canCommit = commitMessage.trim() && hasSelectedFiles && commitAction === null; + const { isMobile } = useDeviceInfo(); return ( = ({ variant="outline" onClick={onCommit} disabled={!canCommit || isGeneratingMessage} + className="whitespace-nowrap" > {commitAction === 'commit' ? ( <> @@ -136,23 +140,47 @@ export const CommitSection: React.FC = ({ )} - - {commitAction === 'commitAndPush' ? ( - <> - - Pushing... - - ) : ( - <> - - Commit & Push - - )} - + {isMobile ? ( + + + + + +

Commit & Push

+
+
+ ) : ( + + {commitAction === 'commitAndPush' ? ( + <> + + Pushing... + + ) : ( + <> + + Commit & Push + + )} + + )}