feat: add single player mode

This commit is contained in:
David Nguyen
2023-09-20 13:48:30 +10:00
committed by Mythie
parent cdae3a9a45
commit 34232c79e5
86 changed files with 2576 additions and 410 deletions

View File

@ -0,0 +1,56 @@
'use client';
import { useState } from 'react';
import * as DialogPrimitive from '@radix-ui/react-dialog';
import { X } from 'lucide-react';
import { cn } from '@documenso/ui/lib/utils';
import { Dialog, DialogOverlay, DialogPortal } from '../../primitives/dialog';
import { LazyPDFViewerNoLoader } from '../../primitives/lazy-pdf-viewer';
export type DocumentDialogProps = {
document: string;
} & Omit<DialogPrimitive.DialogProps, 'children'>;
/**
* A dialog which renders the provided document.
*/
export default function DocumentDialog({ document, ...props }: DocumentDialogProps) {
const [documentLoaded, setDocumentLoaded] = useState(false);
const onDocumentLoad = () => {
setDocumentLoaded(true);
};
return (
<Dialog {...props}>
<DialogPortal>
<DialogOverlay className="bg-black/80" />
<DialogPrimitive.Content
className={cn(
'animate-in data-[state=open]:fade-in-90 sm:zoom-in-90 pointer-events-none fixed z-50 h-screen w-screen overflow-y-auto px-2 py-14 opacity-0 transition-opacity lg:py-32',
{
'opacity-100': documentLoaded,
},
)}
onClick={() => props.onOpenChange?.(false)}
>
<LazyPDFViewerNoLoader
className="mx-auto w-full max-w-3xl xl:max-w-5xl"
document={`data:application/pdf;base64,${document}`}
onClick={(e) => e.stopPropagation()}
onDocumentLoad={onDocumentLoad}
/>
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none">
<X className="h-6 w-6 text-white" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</DialogPortal>
</Dialog>
);
}

View File

@ -0,0 +1,78 @@
'use client';
import { HTMLAttributes, useState } from 'react';
import { Download } from 'lucide-react';
import { getFile } from '@documenso/lib/universal/upload/get-file';
import { DocumentData } from '@documenso/prisma/client';
import { Button } from '@documenso/ui/primitives/button';
import { useToast } from '@documenso/ui/primitives/use-toast';
export type DownloadButtonProps = HTMLAttributes<HTMLButtonElement> & {
disabled?: boolean;
fileName?: string;
documentData?: DocumentData;
};
export const DocumentDownloadButton = ({
className,
fileName,
documentData,
disabled,
...props
}: DownloadButtonProps) => {
const { toast } = useToast();
const [isLoading, setIsLoading] = useState(false);
const onDownloadClick = async () => {
try {
setIsLoading(true);
if (!documentData) {
return;
}
const bytes = await getFile(documentData);
const blob = new Blob([bytes], {
type: 'application/pdf',
});
const link = window.document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName || 'document.pdf';
link.click();
window.URL.revokeObjectURL(link.href);
} catch (err) {
console.error(err);
toast({
title: 'Error',
description: 'An error occurred while downloading your document.',
variant: 'destructive',
});
} finally {
setIsLoading(false);
}
};
return (
<Button
type="button"
variant="outline"
className={className}
disabled={disabled || !documentData}
onClick={onDownloadClick}
loading={isLoading}
{...props}
>
<Download className="mr-2 h-5 w-5" />
Download
</Button>
);
};