Skip to content

Commit

Permalink
cleanup and improve required fields for upload
Browse files Browse the repository at this point in the history
  • Loading branch information
codyzu committed Jun 11, 2023
1 parent 771e64d commit fca13e6
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 101 deletions.
4 changes: 4 additions & 0 deletions src/components/UserProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ export type User = {
uid: string;
};

export type UserDoc = {
username?: string;
};

export const UserContext = createContext<{
user: User | undefined;
setUser: (nextUser: User | undefined) => void;
Expand Down
186 changes: 110 additions & 76 deletions src/pages/Upload.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useCallback, useEffect, useRef, useState} from 'react';
import {useCallback, useContext, useEffect, useRef, useState} from 'react';
import {useDropzone} from 'react-dropzone';
import {Document, Page} from 'react-pdf';
import * as pdfjs from 'pdfjs-dist';
Expand All @@ -10,6 +10,8 @@ import {
addDoc,
collection,
updateDoc,
getDoc,
doc,
} from 'firebase/firestore/lite';
import {ref as storageRef, uploadBytes, getDownloadURL} from 'firebase/storage';
import {nanoid} from 'nanoid';
Expand All @@ -20,6 +22,7 @@ import PresentationPreferencesEditor, {
} from '../components/PresentationPreferencesEditor';
import {type Note} from '../presentation';
import DefaultLayout from '../layouts/DefaultLayout';
import {UserContext, type UserDoc} from '../components/UserProvider';

const src = new URL('pdfjs-dist/build/pdf.worker.js', import.meta.url);
pdfjs.GlobalWorkerOptions.workerSrc = src.toString();
Expand All @@ -29,6 +32,27 @@ export default function Export() {
document.title = `Slidr - Upload`;
}, []);

const {user} = useContext(UserContext);
const [userData, setUserData] = useState<UserDoc>();

useEffect(() => {
async function getUserDoc() {
if (!user) {
setUserData(undefined);
return;
}

const userSnapshot = await getDoc(doc(firestore, 'users', user.uid));
if (!userSnapshot.exists()) {
setUserData({});
}

setUserData(userSnapshot.data() as UserDoc);
}

void getUserDoc();
}, [user]);

const [file, setFile] = useState<File>();
const [pageIndex, setPageIndex] = useState(0);
const [pageCount, setPageCount] = useState(0);
Expand All @@ -43,7 +67,14 @@ export default function Export() {
setFile(acceptedFiles[0]);
const presentationRef = await addDoc(
collection(firestore, 'presentations'),
{created: new Date(), uid: auth.currentUser?.uid},
{
created: new Date(),
uid: auth.currentUser?.uid,
username: userData?.username ?? '',
pages: [],
notes: [],
title: '',
},
);
setPresentationRef(presentationRef);
const originalName = `${nanoid()}.pdf`;
Expand Down Expand Up @@ -213,83 +244,86 @@ export default function Export() {

return (
<DefaultLayout title="Upload Presentation">
<div className="overflow-hidden flex flex-col items-center p-4 gap-6 pb-10 w-full max-w-screen-md mx-auto">
{!file && (
<div
className="btn rounded-md p-8 flex flex-col items-center justify-center w-full max-w-screen-sm aspect-video gap-4 cursor-pointer mx-6"
{...getRootProps()}
>
<input {...getInputProps()} />
{isDragActive ? (
<>
<div className="i-tabler-arrow-big-down-lines text-6xl animate-bounce animate-duration-500 text-teal-500" />
<div className="text-center">
Drop the pdf presentation here...
</div>
</>
) : (
<>
<div className="i-tabler-arrow-big-down-lines text-6xl animate-bounce" />
<div className="text-center">
Drag &apos;n&apos; drop a pdf presentation here, or click to
select a pdf presentation
</div>
</>
)}
</div>
)}
{file && (
<div className="flex flex-col w-full max-w-screen-sm aspect-video">
<Document
file={file}
className="w-full aspect-video relative rounded-t-md overflow-hidden"
onLoadSuccess={(pdf) => {
setPageCount(pdf.numPages);
}}
{/* TODO: loading spinner */}
{userData && (
<div className="overflow-hidden flex flex-col items-center p-4 gap-6 pb-10 w-full max-w-screen-md mx-auto">
{!file && (
<div
className="btn rounded-md p-8 flex flex-col items-center justify-center w-full max-w-screen-sm aspect-video gap-4 cursor-pointer mx-6"
{...getRootProps()}
>
<Page
pageIndex={pageIndex}
className="w-full h-full"
canvasRef={canvasRef}
width={1920}
// We want the exported images to be 1920, irrespective of the pixel ratio
// Fix the ratio to 1
devicePixelRatio={1}
onRenderSuccess={() => {
pageRendered();
<input {...getInputProps()} />
{isDragActive ? (
<>
<div className="i-tabler-arrow-big-down-lines text-6xl animate-bounce animate-duration-500 text-teal-500" />
<div className="text-center">
Drop the pdf presentation here...
</div>
</>
) : (
<>
<div className="i-tabler-arrow-big-down-lines text-6xl animate-bounce" />
<div className="text-center">
Drag &apos;n&apos; drop a pdf presentation here, or click to
select a pdf presentation
</div>
</>
)}
</div>
)}
{file && (
<div className="relative flex flex-col w-full max-w-screen-sm">
<Document
file={file}
className="w-full aspect-video relative rounded-t-md"
onLoadSuccess={(pdf) => {
setPageCount(pdf.numPages);
}}
>
<Page
pageIndex={pageIndex}
className="w-full aspect-video"
canvasRef={canvasRef}
width={1920}
// We want the exported images to be 1920, irrespective of the pixel ratio
// Fix the ratio to 1
devicePixelRatio={1}
onRenderSuccess={() => {
pageRendered();
}}
/>
<div className="absolute top-0 left-0 w-full h-full flex flex-col items-center justify-center bg-teal-800 bg-opacity-90">
<div className={clsx('w-10 h-10', icon)} />
<div>{message}</div>
</div>
</Document>
<div
className="h-[6px] bg-teal"
style={{width: `${((pageIndex + 1) * 100) / pageCount}%`}}
/>
<div className="absolute top-0 left-0 w-full h-full flex flex-col items-center justify-center bg-teal-800 bg-opacity-90">
<div className={clsx('w-10 h-10', icon)} />
<div>{message}</div>
</div>
</Document>
<div
className="h-[6px] bg-teal"
style={{width: `${((pageIndex + 1) * 100) / pageCount}%`}}
/>
<div>Rendering slide: {pageIndex + 1}</div>
</div>
)}
<PresentationPreferencesEditor
saveState={savingState}
notes={notes}
title={title}
setNotes={(updater) => {
setNotes(updater);
}}
setTitle={(nextTitle) => {
setTitle(nextTitle);
}}
pages={pages}
onSave={() => {
void savePreferences();
}}
onDirty={() => {
setSavingState('dirty');
}}
/>
</div>
<div>Rendering slide: {pageIndex + 1}</div>
</div>
)}
<PresentationPreferencesEditor
saveState={savingState}
notes={notes}
title={title}
setNotes={(updater) => {
setNotes(updater);
}}
setTitle={(nextTitle) => {
setTitle(nextTitle);
}}
pages={pages}
onSave={() => {
void savePreferences();
}}
onDirty={() => {
setSavingState('dirty');
}}
/>
</div>
)}
</DefaultLayout>
);
}
6 changes: 1 addition & 5 deletions src/pages/UserPreferences.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@ import {useContext, useEffect, useState} from 'react';
import {doc, getDoc, setDoc} from 'firebase/firestore/lite';
import {useDebouncedCallback} from 'use-debounce';
import DefaultLayout from '../layouts/DefaultLayout';
import {UserContext} from '../components/UserProvider';
import {UserContext, type UserDoc} from '../components/UserProvider';
import {firestore} from '../firebase';
import SaveIndicator from '../components/SaveIndicator';

type UserDoc = {
username?: string;
};

export default function UserPreferences() {
const {user} = useContext(UserContext);
const [userData, setUserData] = useState<UserDoc>({});
Expand Down
21 changes: 1 addition & 20 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,10 @@ import {defineConfig} from 'vite';
import react from '@vitejs/plugin-react';
import unoCSS from 'unocss/vite';
import {imagetools} from 'vite-imagetools';
import {run} from 'vite-plugin-run';

// https://vitejs.dev/config/
export default defineConfig(({command, mode}) => {
return {
plugins: [
{
...run({
silent: false,
input: [
{
// Generate thumbs when pdfs change
name: 'generate pdf thumbs',
run: ['pnpm', 'run', 'thumbs'],
pattern: 'src/presentations/*.pdf',
},
],
}),
apply: 'serve',
},
imagetools(),
unoCSS(),
react(),
],
plugins: [imagetools(), unoCSS(), react()],
};
});

0 comments on commit fca13e6

Please sign in to comment.