- 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
86 lines
2.3 KiB
TypeScript
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;
|