mirror of
https://github.com/block/goose.git
synced 2026-07-17 12:56:20 +02:00
nicer
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Card, CardContent } from './ui/card';
|
||||
import { Folder, FileText, Image } from 'lucide-react';
|
||||
import { FolderGit2, FileText, ImageIcon, FileSpreadsheet, FileType, File } from 'lucide-react';
|
||||
import { createSession } from '../sessions';
|
||||
import { useNavigation } from '../hooks/useNavigation';
|
||||
import { useConfig } from './ConfigContext';
|
||||
@@ -15,28 +15,39 @@ interface RecentFilesProps {
|
||||
const TYPE_CONFIG: Record<
|
||||
RecentItemType,
|
||||
{
|
||||
icon: typeof Folder;
|
||||
icon: typeof File;
|
||||
color: string;
|
||||
bgColor: string;
|
||||
}
|
||||
> = {
|
||||
repo: {
|
||||
icon: Folder,
|
||||
color: 'text-green-600',
|
||||
bgColor: 'bg-green-50 dark:bg-green-950',
|
||||
icon: FolderGit2,
|
||||
color: 'text-green-600 dark:text-green-400',
|
||||
bgColor: 'bg-green-100 dark:bg-green-900/50',
|
||||
},
|
||||
document: {
|
||||
icon: FileText,
|
||||
color: 'text-blue-600',
|
||||
bgColor: 'bg-blue-50 dark:bg-blue-950',
|
||||
color: 'text-blue-600 dark:text-blue-400',
|
||||
bgColor: 'bg-blue-100 dark:bg-blue-900/50',
|
||||
},
|
||||
image: {
|
||||
icon: Image,
|
||||
color: 'text-purple-600',
|
||||
bgColor: 'bg-purple-50 dark:bg-purple-950',
|
||||
icon: ImageIcon,
|
||||
color: 'text-purple-600 dark:text-purple-400',
|
||||
bgColor: 'bg-purple-100 dark:bg-purple-900/50',
|
||||
},
|
||||
};
|
||||
|
||||
function getIconForFile(item: RecentItem) {
|
||||
if (item.type === 'repo') return FolderGit2;
|
||||
if (item.type === 'image') return ImageIcon;
|
||||
|
||||
const ext = item.name.split('.').pop()?.toLowerCase() || '';
|
||||
if (['xlsx', 'xls', 'csv'].includes(ext)) return FileSpreadsheet;
|
||||
if (['pdf'].includes(ext)) return FileType;
|
||||
if (['md', 'txt', 'doc', 'docx'].includes(ext)) return FileText;
|
||||
return File;
|
||||
}
|
||||
|
||||
export function RecentFiles({ onSessionStarting }: RecentFilesProps) {
|
||||
const [recentFiles, setRecentFiles] = useState<RecentItem[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
@@ -66,7 +77,6 @@ export function RecentFiles({ onSessionStarting }: RecentFilesProps) {
|
||||
onSessionStarting?.();
|
||||
|
||||
try {
|
||||
// Determine working directory based on item type
|
||||
const workingDir = item.type === 'repo' ? item.fullPath : undefined;
|
||||
|
||||
const session = await createSession(workingDir || '', {
|
||||
@@ -80,7 +90,6 @@ export function RecentFiles({ onSessionStarting }: RecentFilesProps) {
|
||||
})
|
||||
);
|
||||
|
||||
// Build the initial prompt based on item type
|
||||
let initialPrompt = '';
|
||||
if (item.type === 'image') {
|
||||
initialPrompt = `Please analyze this image: ${item.fullPath}`;
|
||||
@@ -103,22 +112,12 @@ export function RecentFiles({ onSessionStarting }: RecentFilesProps) {
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
|
||||
{[1, 2, 3, 4].map((i) => (
|
||||
<Card
|
||||
key={i}
|
||||
className="w-full py-4 px-4 border-none rounded-xl bg-background-default"
|
||||
>
|
||||
<CardContent className="p-0">
|
||||
<div className="flex items-center gap-3">
|
||||
<Skeleton className="h-10 w-10 rounded-lg" />
|
||||
<div className="flex-1">
|
||||
<Skeleton className="h-4 w-32 mb-2" />
|
||||
<Skeleton className="h-3 w-48" />
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{[1, 2, 3, 4, 5, 6].map((i) => (
|
||||
<div key={i} className="flex flex-col items-center gap-3 p-4">
|
||||
<Skeleton className="h-16 w-16 rounded-2xl" />
|
||||
<Skeleton className="h-4 w-24" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
@@ -129,17 +128,17 @@ export function RecentFiles({ onSessionStarting }: RecentFilesProps) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
|
||||
{recentFiles.map((item) => {
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{recentFiles.map((item, index) => {
|
||||
const config = TYPE_CONFIG[item.type];
|
||||
const Icon = config.icon;
|
||||
const Icon = getIconForFile(item);
|
||||
|
||||
return (
|
||||
<Card
|
||||
key={item.fullPath}
|
||||
className={`w-full py-4 px-4 border-none rounded-xl bg-background-default cursor-pointer
|
||||
transition-all duration-200 hover:bg-background-muted hover:scale-[1.01]
|
||||
${startingItem === item.fullPath ? 'opacity-70' : ''}
|
||||
className={`w-full py-5 px-4 border-none rounded-2xl bg-background-muted/50 cursor-pointer
|
||||
transition-all duration-200 hover:bg-background-muted hover:scale-[1.02]
|
||||
${startingItem === item.fullPath ? 'opacity-70 scale-[0.98]' : ''}
|
||||
${startingItem && startingItem !== item.fullPath ? 'pointer-events-none opacity-50' : ''}`}
|
||||
onClick={() => handleItemClick(item)}
|
||||
role="button"
|
||||
@@ -149,18 +148,18 @@ export function RecentFiles({ onSessionStarting }: RecentFilesProps) {
|
||||
handleItemClick(item);
|
||||
}
|
||||
}}
|
||||
style={{ animationDelay: `${index * 0.05}s` }}
|
||||
>
|
||||
<CardContent className="p-0">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="flex flex-col items-center text-center gap-3">
|
||||
<div
|
||||
className={`flex-shrink-0 w-10 h-10 rounded-lg ${config.bgColor} flex items-center justify-center`}
|
||||
className={`w-16 h-16 rounded-2xl ${config.bgColor} flex items-center justify-center`}
|
||||
>
|
||||
<Icon className={`w-5 h-5 ${config.color}`} />
|
||||
<Icon className={`w-8 h-8 ${config.color}`} strokeWidth={1.5} />
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<h4 className="text-sm font-medium truncate">{item.name}</h4>
|
||||
<p className="text-xs text-text-muted truncate">{item.path}</p>
|
||||
<p className="text-xs text-text-subtle mt-1">{item.suggestion}</p>
|
||||
<div className="min-w-0 w-full">
|
||||
<h3 className="text-sm font-medium truncate">{item.name}</h3>
|
||||
<p className="text-xs text-text-muted truncate">{item.suggestion}</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
Reference in New Issue
Block a user