diff --git a/components/DownloadBtn.tsx b/components/DownloadBtn.tsx new file mode 100644 index 0000000..dd4701e --- /dev/null +++ b/components/DownloadBtn.tsx @@ -0,0 +1,20 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { FunctionComponent } from 'react' + +const DownloadBtn: FunctionComponent<{ downloadUrl: string }> = ({ downloadUrl }) => { + return ( +
+ + + Download + +
+ ) +} + +export default DownloadBtn diff --git a/components/FileListing.tsx b/components/FileListing.tsx index 8018250..ac7e850 100644 --- a/components/FileListing.tsx +++ b/components/FileListing.tsx @@ -15,6 +15,8 @@ import { getExtension, getFileIcon, hasKey } from '../utils/getFileIcon' import { extensions, preview } from '../utils/getPreviewType' import { VideoPreview } from './previews/VideoPreview' import { AudioPreview } from './previews/AudioPreview' +import FourOhFour from './FourOhFour' +import TextPreview from './previews/TextPreview' // Disabling SSR for some previews (image gallery view, and PDF view) const ReactViewer = dynamic(() => import('react-viewer'), { ssr: false }) @@ -86,10 +88,15 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) = const { data, error } = useSWR(`/api?path=${path}`, fetcher, { revalidateOnFocus: false, - revalidateOnReconnect: false, }) - if (error) return
Failed to load
+ if (error) { + return ( +
+ +
+ ) + } if (!data) { return (
@@ -187,7 +194,7 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) = ) case preview.text: - return
text
+ return case preview.code: return
code
@@ -210,7 +217,11 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) = } } - return
404
+ return ( +
+ +
+ ) } export default FileListing diff --git a/components/FourOhFour.tsx b/components/FourOhFour.tsx new file mode 100644 index 0000000..75e4592 --- /dev/null +++ b/components/FourOhFour.tsx @@ -0,0 +1,15 @@ +import Image from 'next/image' +import { FunctionComponent } from 'react' + +const FourOhFour: FunctionComponent<{ errorMsg: string }> = ({ errorMsg }) => { + return ( +
+
+ 404 +
+
Error: {errorMsg}
+
+ ) +} + +export default FourOhFour diff --git a/components/previews/AudioPreview.tsx b/components/previews/AudioPreview.tsx index 3c569aa..f668726 100644 --- a/components/previews/AudioPreview.tsx +++ b/components/previews/AudioPreview.tsx @@ -2,6 +2,8 @@ import { FunctionComponent, useState } from 'react' import ReactPlayer from 'react-player' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import DownloadBtn from '../DownloadBtn' + enum PlayerState { Loading, Ready, @@ -13,57 +15,67 @@ export const AudioPreview: FunctionComponent<{ file: any }> = ({ file }) => { const [playerStatus, setPlayerStatus] = useState(PlayerState.Loading) return ( -
-
-
- {playerStatus === PlayerState.Loading ? ( -
- - - - + <> +
+
+
+ {playerStatus === PlayerState.Loading ? ( +
+ + + + +
+ ) : ( + + )} +
+
+
{file.name}
+
+ Last modified:{' '} + {new Date(file.lastModifiedDateTime).toLocaleString(undefined, { + dateStyle: 'short', + timeStyle: 'short', + })}
- ) : ( - { + setPlayerStatus(PlayerState.Ready) + }} + onPlay={() => { + setPlayerStatus(PlayerState.Playing) + }} + onPause={() => { + setPlayerStatus(PlayerState.Paused) + }} + onError={() => setPlayerStatus(PlayerState.Paused)} + onEnded={() => setPlayerStatus(PlayerState.Paused)} /> - )} -
-
-
{file.name}
-
- Last modified:{' '} - {new Date(file.lastModifiedDateTime).toLocaleString(undefined, { - dateStyle: 'short', - timeStyle: 'short', - })}
- { - setPlayerStatus(PlayerState.Ready) - }} - onPlay={() => { - setPlayerStatus(PlayerState.Playing) - }} - onPause={() => { - setPlayerStatus(PlayerState.Paused) - }} - onError={() => setPlayerStatus(PlayerState.Paused)} - onEnded={() => setPlayerStatus(PlayerState.Paused)} - />
-
+
+ +
+ ) } diff --git a/components/previews/PDFPreview.tsx b/components/previews/PDFPreview.tsx index 160f532..acd5ce1 100644 --- a/components/previews/PDFPreview.tsx +++ b/components/previews/PDFPreview.tsx @@ -3,6 +3,7 @@ import { Document, Page, pdfjs } from 'react-pdf' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import Loading from '../Loading' +import DownloadBtn from '../DownloadBtn' pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.js` @@ -17,7 +18,7 @@ const PDFPreview: FunctionComponent<{ file: any }> = ({ file }) => { return (
-
+
= ({ file }) => {
-
+
-
+
Page{' '} { const v = parseInt(e.target.value) if (v <= totalPages && v >= 0) { @@ -54,7 +55,7 @@ const PDFPreview: FunctionComponent<{ file: any }> = ({ file }) => { /{totalPages}
+
) diff --git a/components/previews/TextPreview.tsx b/components/previews/TextPreview.tsx new file mode 100644 index 0000000..ab0f38e --- /dev/null +++ b/components/previews/TextPreview.tsx @@ -0,0 +1,40 @@ +import axios from 'axios' +import { FunctionComponent } from 'react' +import useSWR from 'swr' + +import FourOhFour from '../FourOhFour' +import Loading from '../Loading' +import DownloadBtn from '../DownloadBtn' + +const fetcher = (url: string) => axios.get(url).then(res => res.data) + +const TextPreview: FunctionComponent<{ file: any }> = ({ file }) => { + const { data, error } = useSWR(file['@microsoft.graph.downloadUrl'], fetcher) + if (error) { + return ( +
+ +
+ ) + } + if (!data) { + return ( +
+ +
+ ) + } + + return ( + <> +
+
{data}
+
+
+ +
+ + ) +} + +export default TextPreview diff --git a/components/previews/VideoPreview.tsx b/components/previews/VideoPreview.tsx index 7c10f23..48fe44b 100644 --- a/components/previews/VideoPreview.tsx +++ b/components/previews/VideoPreview.tsx @@ -1,19 +1,26 @@ import { FunctionComponent } from 'react' import ReactPlayer from 'react-player' +import DownloadBtn from '../DownloadBtn' + export const VideoPreview: FunctionComponent<{ file: any }> = ({ file }) => { return ( -
-
- + <> +
+
+ +
-
+
+ +
+ ) } diff --git a/pages/_app.tsx b/pages/_app.tsx index 79ac6c5..22ab878 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -14,7 +14,7 @@ import { faFile, faFolder, } from '@fortawesome/free-regular-svg-icons' -import { faMusic, faArrowLeft, faArrowRight } from '@fortawesome/free-solid-svg-icons' +import { faMusic, faArrowLeft, faArrowRight, faFileDownload } from '@fortawesome/free-solid-svg-icons' import { faGithub, faMarkdown } from '@fortawesome/free-brands-svg-icons' import type { AppProps } from 'next/app' @@ -36,7 +36,8 @@ library.add( faMarkdown, faMusic, faArrowLeft, - faArrowRight + faArrowRight, + faFileDownload ) function MyApp({ Component, pageProps }: AppProps) { diff --git a/public/404.png b/public/404.png new file mode 100644 index 0000000..29f298b Binary files /dev/null and b/public/404.png differ