Skip to content

Commit

Permalink
feat: add video to popups (#98)
Browse files Browse the repository at this point in the history
  • Loading branch information
DeutscherDude authored Aug 25, 2024
1 parent 45e6c92 commit 73d789d
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ interface DataTableProps<TData, TValue> {
includeColumnsSelector?: boolean;
}

export function DataTable<TData, TValue>({
export function DataTable<TData extends object, TValue>({
columns,
data,
pageIndex,
Expand Down Expand Up @@ -85,6 +85,13 @@ export function DataTable<TData, TValue>({
...state,
},
rowCount,
getRowId: (originalRow, index) => {
if ('id' in originalRow && typeof originalRow.id === 'string') {
return originalRow.id;
}

return index.toString();
},
});

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,47 @@
import { ArrowLeftIcon, ArrowRightIcon } from '@heroicons/react/24/solid';
import { Eye } from 'lucide-react';
import { type ReactNode, useDeferredValue, useEffect, useState } from 'react';
import { type ReactNode, useDeferredValue, useEffect, useMemo, useState } from 'react';

import { Dialog, DialogContent, DialogTrigger } from '../../../../../@/components/ui/dialog';
import { Dialog, DialogContent, DialogTitle, DialogTrigger } from '../../../../../@/components/ui/dialog';

import { cn } from '@/lib/utils';

interface ImageProps {
const VIDEO_FILE_EXTENSIONS = [
'.mp4',
'.mkv',
'.avi',
'.mov',
'.wmv',
'.flv',
'.webm',
'.m4v',
'.mpeg',
'.3gp',
'.ogv',
'.vob',
'.rm',
'.divx',
'.mxf',
'.ts',
'.f4v',
'.mts',
'.m2ts',
];

interface MediaProps {
source: string;
previewImageSrc: string;
alt: string;
hasNext: boolean;
hasPrevious: boolean;
onClick: () => void;
onNext: () => void;
onPrevious: () => void;
onClose: () => void;
className?: string | undefined;
previewImageSrc: string;
alt: string;
}

export function Image({
export const Media = ({
alt,
hasNext,
hasPrevious,
Expand All @@ -30,7 +52,7 @@ export function Image({
source,
className,
previewImageSrc,
}: ImageProps): JSX.Element {
}: MediaProps): JSX.Element => {
const [open, setOpen] = useState(false);

useEffect(() => {
Expand All @@ -44,18 +66,34 @@ export function Image({
setOpen(val);
};

const isVideoFile = useMemo(() => {
return VIDEO_FILE_EXTENSIONS.some((extension) => {
return alt.endsWith(extension);
});
}, [alt]);

return (
<Dialog
open={open}
onOpenChange={onOpenChange}
>
<DialogTrigger asChild>
<div className="w-full h-full relative group">
<img
alt={alt}
src={source}
className={cn('cursor-pointer w-full h-full object-cover aspect-square', className)}
/>
{isVideoFile && (
<video className="h-20 w-20">
<source
src={source}
type="video/webm"
/>
</video>
)}
{!isVideoFile && (
<img
alt={alt}
src={source}
className={cn('cursor-pointer w-full h-full object-cover aspect-square', className)}
/>
)}
<div
onClick={onClick}
className="flex justify-center items-center absolute cursor-pointer opacity-0 group-hover:opacity-100 w-full h-full object-fill bg-gray-500/50 inset-0"
Expand All @@ -68,27 +106,41 @@ export function Image({
excludeCloseIcon={true}
className="p-0 m-0 border-none sm:max-w-4xl "
>
<DialogTitle className="hidden">Image container</DialogTitle>
<div className="relative">
<img
alt={alt}
src={previewImageSrc}
className="w-full h-[80vh] object-cover"
/>
<div className="absolute top-0 left-0 w-full h-full z-10">
{isVideoFile && (
<video
className="w-full h-full"
controls
>
<source
src={source}
type="video/webm"
/>
</video>
)}
{!isVideoFile && (
<img
alt={alt}
src={previewImageSrc}
className="w-full h-[80vh] object-contain"
/>
)}
<div className="absolute top-0 left-0 w-full h-full z-10 pointer-events-none">
<div className="flex h-full w-full z-10">
<div className="flex justify-start items-center w-full h-full">
{hasPrevious && (
<ArrowLeftIcon
onClick={onPrevious}
className="cursor-pointer w-20 h-20 text-primary-foreground"
className="opacity-0 hover:opacity-100 cursor-pointer w-20 h-20 text-primary pointer-events-auto"
/>
)}
</div>
<div className="flex justify-end items-center w-full h-full">
{hasNext && (
<ArrowRightIcon
onClick={onNext}
className="cursor-pointer w-20 h-20 text-primary-foreground"
className="opacity-0 hover:opacity-100 cursor-pointer w-20 h-20 text-primary pointer-events-auto"
/>
)}
</div>
Expand All @@ -98,7 +150,7 @@ export function Image({
</DialogContent>
</Dialog>
);
}
};

export interface PreviewableResource {
url: string;
Expand All @@ -120,10 +172,10 @@ export function PopupGallery({

return (
<div className="h-20 w-20">
<Image
source={resources[originalPreviewResourceIndex].url}
alt={resources[originalPreviewResourceIndex].name}
onClick={() => console.log('clicked')}
<Media
source={resources[previewResourceIndex].url}
alt={resources[previewResourceIndex].name}
onClick={() => {}}
onPrevious={() => setPreviewResourceIndex(previewResourceIndex - 1)}
onNext={() => setPreviewResourceIndex(previewResourceIndex + 1)}
previewImageSrc={resources[deferredIndex].url ?? ''}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ export const CreateResourceModal: FC<CreateResourceModalProps> = ({ bucketName }
files,
setFiles,
bucketName,
onUploaded: () => {
setOpen(false);

setFileName('');
},
});

const fileInputRef = useRef<HTMLInputElement | null>(null);
Expand Down Expand Up @@ -77,10 +82,6 @@ export const CreateResourceModal: FC<CreateResourceModalProps> = ({ bucketName }
}

await upload();

setFileName('');

setOpen(false);
};

const isAllowedFormat = (type: string): boolean => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useCreateResourcesMutation } from '../../api/user/mutations/createResou
interface UseFileUploadPayload {
files: File[];
setFiles: (files: File[]) => void;
onUploaded: () => void;
bucketName: string;
}

Expand All @@ -19,19 +20,26 @@ interface UseFileUploadReturn {

const MAX_CHUNK_SIZE = 100_000_000; // ~100MB

const FILE_UPLOAD_TIMEOUT = Number(import.meta.env['VITE_MAX_FILE_UPLOAD_TIMEOUT']);
const parsedFileUpload = Number(import.meta.env['VITE_MAX_FILE_UPLOAD_TIMEOUT']);

export const useFileUpload = ({ files, bucketName, setFiles }: UseFileUploadPayload): UseFileUploadReturn => {
const FILE_UPLOAD_TIMEOUT = Number.isNaN(parsedFileUpload) ? 18 * 1000 : parsedFileUpload;

export const useFileUpload = ({
files,
bucketName,
setFiles,
onUploaded,
}: UseFileUploadPayload): UseFileUploadReturn => {
const queryClient = useQueryClient();

const accessToken = useUserTokensStore((selector) => selector.accessToken);

const abortController = useRef(new AbortController());

const { toast } = useToast();

const { mutateAsync, isPending: isUploading } = useCreateResourcesMutation({});

const accessToken = useUserTokensStore((selector) => selector.accessToken);

const upload = async (): Promise<void> => {
let runningTotalSize = 0;

Expand Down Expand Up @@ -125,6 +133,8 @@ export const useFileUpload = ({ files, bucketName, setFiles }: UseFileUploadPayl
});
}

onUploaded();

await queryClient.invalidateQueries({
predicate: (query) => query.queryKey[0] === 'findBucketResources' && query.queryKey[1] === bucketName,
});
Expand Down

0 comments on commit 73d789d

Please sign in to comment.