Files
redux-scraper/app/javascript/bundles/Main/components/FileCarousel.tsx
Dylan Knutson 127dd9be51 Add Bluesky file display components and utilities
- Add SkySection component for displaying Bluesky-specific file information
- Add byteCountToHumanSize utility for formatting file sizes
- Update PostFiles, FileCarousel, FileDetails, and DisplayedFile components
- Enhance posts helper with file display logic
- Update post model and view templates
- Remove deprecated file details sky section partial
2025-08-12 18:14:13 +00:00

86 lines
2.3 KiB
TypeScript

import * as React from 'react';
import { FileData } from './PostFiles';
interface FileCarouselProps {
files: FileData[];
totalFiles: number;
selectedIndex: number;
onFileSelect: (fileId: number, index: number) => void;
}
export const FileCarousel: React.FC<FileCarouselProps> = ({
files,
totalFiles,
selectedIndex,
onFileSelect,
}) => {
const handleFileClick = (file: FileData) => {
onFileSelect(file.id, file.index);
};
// Only render if there are multiple files
if (files.length <= 1) {
return null;
}
return (
<div className="mb-4">
<div className="flex gap-2 overflow-x-auto" id="file-carousel">
{files.map((file) => {
const isSelected = file.index === selectedIndex;
const buttonClasses = [
'flex-shrink-0',
'w-20',
'h-20',
'rounded-md',
'border-2',
'transition-all',
'duration-200',
'hover:border-blue-400',
isSelected ? 'border-blue-500' : 'border-gray-300',
];
if (file.thumbnailPath?.type === 'url') {
buttonClasses.push('overflow-hidden');
} else {
buttonClasses.push(
'bg-gray-100',
'flex',
'items-center',
'justify-center',
);
}
const thumbnail =
file.thumbnailPath?.type === 'url' ? (
<img
src={file.thumbnailPath.value}
className="h-full w-full object-cover"
alt={`File ${file.index + 1}`}
/>
) : file.thumbnailPath?.type === 'icon' ? (
<i className={`${file.thumbnailPath.value} text-slate-500`}></i>
) : (
<i className="fa-solid fa-file text-gray-400"></i>
);
return (
<button
key={file.id}
className={buttonClasses.join(' ')}
onClick={() => handleFileClick(file)}
data-file-id={file.id}
data-index={file.index}
title={`File ${file.index + 1} of ${totalFiles}`}
>
{thumbnail}
</button>
);
})}
</div>
</div>
);
};
export default FileCarousel;