audio and video preview, mobile compatibility
This commit is contained in:
parent
2ea2db2cee
commit
b1cced5e7e
8 changed files with 64 additions and 22 deletions
|
@ -8,7 +8,7 @@ const Breadcrumb: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) =>
|
||||||
const { path } = query
|
const { path } = query
|
||||||
if (Array.isArray(path)) {
|
if (Array.isArray(path)) {
|
||||||
return (
|
return (
|
||||||
<div className="py-2 text-sm text-gray-600 flex">
|
<div className="pb-4 text-sm text-gray-600 flex flex-wrap">
|
||||||
<div className="p-1 hover:text-black transition-all duration-75">
|
<div className="p-1 hover:text-black transition-all duration-75">
|
||||||
<Link href="/">🚩 Home</Link>
|
<Link href="/">🚩 Home</Link>
|
||||||
</div>
|
</div>
|
||||||
|
@ -26,7 +26,7 @@ const Breadcrumb: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) =>
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="py-2 text-sm text-gray-600 hover:text-black transition-all duration-75">
|
<div className="pb-4 text-sm text-gray-600 hover:text-black transition-all duration-75">
|
||||||
<div className="p-1">
|
<div className="p-1">
|
||||||
<Link href="/">🚩 Home</Link>
|
<Link href="/">🚩 Home</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,7 +2,7 @@ import axios from 'axios'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
|
||||||
import { ParsedUrlQuery } from 'querystring'
|
import { ParsedUrlQuery } from 'querystring'
|
||||||
import { FunctionComponent, useState } from 'react'
|
import { FunctionComponent, useEffect, useState } from 'react'
|
||||||
import { ImageDecorator } from 'react-viewer/lib/ViewerProps'
|
import { ImageDecorator } from 'react-viewer/lib/ViewerProps'
|
||||||
|
|
||||||
import useSWR from 'swr'
|
import useSWR from 'swr'
|
||||||
|
@ -55,20 +55,20 @@ const FileListItem: FunctionComponent<{
|
||||||
}> = ({ fileContent: c }) => {
|
}> = ({ fileContent: c }) => {
|
||||||
return (
|
return (
|
||||||
<div className="p-3 grid grid-cols-10 items-center space-x-2 cursor-pointer hover:bg-gray-100">
|
<div className="p-3 grid grid-cols-10 items-center space-x-2 cursor-pointer hover:bg-gray-100">
|
||||||
<div className="flex space-x-2 items-center col-span-7 truncate">
|
<div className="flex space-x-2 items-center col-span-10 md:col-span-7 truncate">
|
||||||
{/* <div>{c.file ? c.file.mimeType : 'folder'}</div> */}
|
{/* <div>{c.file ? c.file.mimeType : 'folder'}</div> */}
|
||||||
<div className="w-5 text-center">
|
<div className="w-5 text-center">
|
||||||
<FontAwesomeIcon icon={c.file ? getFileIcon(c.name) : ['far', 'folder']} />
|
<FontAwesomeIcon icon={c.file ? getFileIcon(c.name) : ['far', 'folder']} />
|
||||||
</div>
|
</div>
|
||||||
<div className="truncate">{c.name}</div>
|
<div className="truncate">{c.name}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="font-mono text-sm col-span-2 text-gray-700">
|
<div className="hidden md:visible font-mono text-sm col-span-2 text-gray-700">
|
||||||
{new Date(c.lastModifiedDateTime).toLocaleString(undefined, {
|
{new Date(c.lastModifiedDateTime).toLocaleString(undefined, {
|
||||||
dateStyle: 'short',
|
dateStyle: 'short',
|
||||||
timeStyle: 'short',
|
timeStyle: 'short',
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div className="font-mono text-sm text-gray-700">{humanFileSize(c.size)}</div>
|
<div className="hidden md:visible font-mono text-sm text-gray-700">{humanFileSize(c.size)}</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,12 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) =
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const path = queryToPath(query)
|
const path = queryToPath(query)
|
||||||
const { data, error } = useSWR(`/api?path=${path}`, fetcher)
|
|
||||||
|
const { data, error } = useSWR(`/api?path=${path}`, fetcher, {
|
||||||
|
revalidateOnFocus: false,
|
||||||
|
revalidateOnReconnect: false,
|
||||||
|
})
|
||||||
|
|
||||||
if (error) return <div>Failed to load</div>
|
if (error) return <div>Failed to load</div>
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return (
|
return (
|
||||||
|
@ -134,9 +139,9 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) =
|
||||||
return (
|
return (
|
||||||
<div className="bg-white shadow rounded">
|
<div className="bg-white shadow rounded">
|
||||||
<div className="p-3 grid grid-cols-10 items-center space-x-2 border-b border-gray-200">
|
<div className="p-3 grid grid-cols-10 items-center space-x-2 border-b border-gray-200">
|
||||||
<div className="col-span-7 font-bold">Name</div>
|
<div className="col-span-10 md:col-span-7 font-bold">Name</div>
|
||||||
<div className="font-bold col-span-2">Last Modified</div>
|
<div className="hidden md:visible font-bold col-span-2">Last Modified</div>
|
||||||
<div className="font-bold">Size</div>
|
<div className="hidden md:visible font-bold">Size</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{imagesInFolder.length !== 0 && (
|
{imagesInFolder.length !== 0 && (
|
||||||
|
|
|
@ -1,17 +1,32 @@
|
||||||
import { FunctionComponent } from 'react'
|
import { FunctionComponent } from 'react'
|
||||||
import ReactPlayer from 'react-player'
|
import ReactPlayer from 'react-player'
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
|
||||||
export const AudioPreview: FunctionComponent<{ file: any }> = ({ file }) => {
|
export const AudioPreview: FunctionComponent<{ file: any }> = ({ file }) => {
|
||||||
return (
|
return (
|
||||||
<div className="bg-white rounded shadow p-3 w-full">
|
<div className="bg-white rounded shadow p-3 w-full">
|
||||||
<div className="text-center mb-6">{file.name}</div>
|
<div className="flex space-x-4">
|
||||||
<ReactPlayer
|
<div className="flex items-center justify-center p-10 bg-gray-100 rounded">
|
||||||
url={file['@microsoft.graph.downloadUrl']}
|
<FontAwesomeIcon className="" icon="music" size="lg" />
|
||||||
controls
|
</div>
|
||||||
width="100%"
|
<div className="flex flex-col w-full space-y-2">
|
||||||
height="48px"
|
<div>{file.name}</div>
|
||||||
config={{ file: { forceAudio: true } }}
|
<div className="text-gray-500 text-sm">
|
||||||
/>
|
Last modified:{' '}
|
||||||
|
{new Date(file.lastModifiedDateTime).toLocaleString(undefined, {
|
||||||
|
dateStyle: 'short',
|
||||||
|
timeStyle: 'short',
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<ReactPlayer
|
||||||
|
url={file['@microsoft.graph.downloadUrl']}
|
||||||
|
controls
|
||||||
|
width="100%"
|
||||||
|
height="48px"
|
||||||
|
config={{ file: { forceAudio: true } }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
21
package-lock.json
generated
21
package-lock.json
generated
|
@ -10,6 +10,7 @@
|
||||||
"@fortawesome/fontawesome-svg-core": "^1.2.35",
|
"@fortawesome/fontawesome-svg-core": "^1.2.35",
|
||||||
"@fortawesome/free-brands-svg-icons": "^5.15.3",
|
"@fortawesome/free-brands-svg-icons": "^5.15.3",
|
||||||
"@fortawesome/free-regular-svg-icons": "^5.15.3",
|
"@fortawesome/free-regular-svg-icons": "^5.15.3",
|
||||||
|
"@fortawesome/free-solid-svg-icons": "^5.15.3",
|
||||||
"@fortawesome/react-fontawesome": "^0.1.14",
|
"@fortawesome/react-fontawesome": "^0.1.14",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"next": "11.0.0",
|
"next": "11.0.0",
|
||||||
|
@ -177,6 +178,18 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@fortawesome/free-solid-svg-icons": {
|
||||||
|
"version": "5.15.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz",
|
||||||
|
"integrity": "sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@fortawesome/fontawesome-common-types": "^0.2.35"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@fortawesome/react-fontawesome": {
|
"node_modules/@fortawesome/react-fontawesome": {
|
||||||
"version": "0.1.14",
|
"version": "0.1.14",
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz",
|
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz",
|
||||||
|
@ -6107,6 +6120,14 @@
|
||||||
"@fortawesome/fontawesome-common-types": "^0.2.35"
|
"@fortawesome/fontawesome-common-types": "^0.2.35"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@fortawesome/free-solid-svg-icons": {
|
||||||
|
"version": "5.15.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz",
|
||||||
|
"integrity": "sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q==",
|
||||||
|
"requires": {
|
||||||
|
"@fortawesome/fontawesome-common-types": "^0.2.35"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@fortawesome/react-fontawesome": {
|
"@fortawesome/react-fontawesome": {
|
||||||
"version": "0.1.14",
|
"version": "0.1.14",
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz",
|
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz",
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
"@fortawesome/fontawesome-svg-core": "^1.2.35",
|
"@fortawesome/fontawesome-svg-core": "^1.2.35",
|
||||||
"@fortawesome/free-brands-svg-icons": "^5.15.3",
|
"@fortawesome/free-brands-svg-icons": "^5.15.3",
|
||||||
"@fortawesome/free-regular-svg-icons": "^5.15.3",
|
"@fortawesome/free-regular-svg-icons": "^5.15.3",
|
||||||
|
"@fortawesome/free-solid-svg-icons": "^5.15.3",
|
||||||
"@fortawesome/react-fontawesome": "^0.1.14",
|
"@fortawesome/react-fontawesome": "^0.1.14",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"next": "11.0.0",
|
"next": "11.0.0",
|
||||||
|
|
|
@ -18,7 +18,7 @@ export default function Folders() {
|
||||||
|
|
||||||
<main className="flex flex-col w-full flex-1 bg-gray-50">
|
<main className="flex flex-col w-full flex-1 bg-gray-50">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<div className="mx-auto w-full max-w-4xl mb-8">
|
<div className="mx-auto w-full max-w-4xl p-4">
|
||||||
<Breadcrumb query={query} />
|
<Breadcrumb query={query} />
|
||||||
<FileListing query={query} />
|
<FileListing query={query} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,8 +13,8 @@ import {
|
||||||
faFileAlt,
|
faFileAlt,
|
||||||
faFile,
|
faFile,
|
||||||
faFolder,
|
faFolder,
|
||||||
faCaretSquareDown,
|
|
||||||
} from '@fortawesome/free-regular-svg-icons'
|
} from '@fortawesome/free-regular-svg-icons'
|
||||||
|
import { faMusic } from '@fortawesome/free-solid-svg-icons'
|
||||||
import { faGithub, faMarkdown } from '@fortawesome/free-brands-svg-icons'
|
import { faGithub, faMarkdown } from '@fortawesome/free-brands-svg-icons'
|
||||||
|
|
||||||
import type { AppProps } from 'next/app'
|
import type { AppProps } from 'next/app'
|
||||||
|
@ -34,7 +34,7 @@ library.add(
|
||||||
faFolder,
|
faFolder,
|
||||||
faGithub,
|
faGithub,
|
||||||
faMarkdown,
|
faMarkdown,
|
||||||
faCaretSquareDown
|
faMusic
|
||||||
)
|
)
|
||||||
|
|
||||||
function MyApp({ Component, pageProps }: AppProps) {
|
function MyApp({ Component, pageProps }: AppProps) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ export default function Home() {
|
||||||
|
|
||||||
<main className="flex flex-col w-full flex-1 bg-gray-50">
|
<main className="flex flex-col w-full flex-1 bg-gray-50">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<div className="mx-auto w-full max-w-4xl mb-8">
|
<div className="mx-auto w-full max-w-4xl p-4">
|
||||||
<Breadcrumb />
|
<Breadcrumb />
|
||||||
<FileListing />
|
<FileListing />
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue