mirror of
https://github.com/Nezumi-2711/onedrive-vercel-index.git
synced 2026-09-22 13:38:45 +00:00
handle file and folder downloads
This commit is contained in:
@@ -3,9 +3,12 @@ import type { OdFolderObject } from '../types'
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import emojiRegex from 'emoji-regex'
|
import emojiRegex from 'emoji-regex'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
import { useClipboard } from 'use-clipboard-copy'
|
||||||
|
|
||||||
import { getFileIcon } from '../utils/getFileIcon'
|
import { getFileIcon } from '../utils/getFileIcon'
|
||||||
|
import { getBaseUrl } from '../utils/getBaseUrl'
|
||||||
import { formatModifiedDateTime } from '../utils/fileDetails'
|
import { formatModifiedDateTime } from '../utils/fileDetails'
|
||||||
|
import { Checkbox, Downloading } from './FileListing'
|
||||||
|
|
||||||
type OdFolderChildren = OdFolderObject['value'][number]
|
type OdFolderChildren = OdFolderObject['value'][number]
|
||||||
|
|
||||||
@@ -25,7 +28,7 @@ const GridItem = ({ c }: { c: OdFolderChildren }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="h-32 overflow-hidden rounded border border-gray-900 dark:border-gray-500/30">
|
<div className="h-32 overflow-hidden rounded border border-gray-900/10 dark:border-gray-500/30">
|
||||||
{thumbnail ? (
|
{thumbnail ? (
|
||||||
// eslint-disable-next-line @next/next/no-img-element
|
// eslint-disable-next-line @next/next/no-img-element
|
||||||
<img className="h-full w-full object-cover object-top" src={thumbnail.url} alt={c.name} />
|
<img className="h-full w-full object-cover object-top" src={thumbnail.url} alt={c.name} />
|
||||||
@@ -67,15 +70,106 @@ const FolderGridLayout = ({
|
|||||||
handleFolderDownload,
|
handleFolderDownload,
|
||||||
toast,
|
toast,
|
||||||
}) => {
|
}) => {
|
||||||
|
const clipboard = useClipboard()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-3 gap-3 rounded bg-white p-3 dark:bg-gray-900 dark:text-gray-100 md:grid-cols-5">
|
<div className="rounded bg-white dark:bg-gray-900 dark:text-gray-100">
|
||||||
{folderChildren.map((c: OdFolderChildren) => (
|
<div className="flex items-center border-b border-gray-900/10 px-3 text-xs font-bold uppercase tracking-widest text-gray-600 dark:border-gray-500/30 dark:text-gray-400">
|
||||||
<Link key={c.id} href={`${path === '/' ? '' : path}/${encodeURIComponent(c.name)}`} passHref>
|
<div className="flex-1">{folderChildren.length} items</div>
|
||||||
<a className="overflow-hidden rounded hover:bg-gray-100 dark:hover:bg-gray-850">
|
<div className="flex p-1.5 text-gray-700 dark:text-gray-400">
|
||||||
<GridItem c={c} />
|
<Checkbox
|
||||||
</a>
|
checked={totalSelected}
|
||||||
</Link>
|
onChange={toggleTotalSelected}
|
||||||
))}
|
indeterminate={true}
|
||||||
|
title={'Select files'}
|
||||||
|
/>
|
||||||
|
{totalGenerating ? (
|
||||||
|
<Downloading title="Downloading selected files, refresh page to cancel" />
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
title="Download selected files"
|
||||||
|
className="cursor-pointer rounded p-1.5 hover:bg-gray-300 disabled:cursor-not-allowed disabled:text-gray-400 disabled:hover:bg-white dark:hover:bg-gray-600 disabled:dark:text-gray-600 disabled:hover:dark:bg-gray-900"
|
||||||
|
disabled={totalSelected === 0}
|
||||||
|
onClick={handleSelectedDownload}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={['far', 'arrow-alt-circle-down']} size="lg" />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-3 gap-3 p-3 md:grid-cols-4">
|
||||||
|
{folderChildren.map((c: OdFolderChildren) => (
|
||||||
|
<Link key={c.id} href={`${path === '/' ? '' : path}/${encodeURIComponent(c.name)}`} passHref>
|
||||||
|
<a className="group relative overflow-hidden rounded hover:bg-gray-100 dark:hover:bg-gray-850">
|
||||||
|
<div className="absolute top-0 right-0 z-10 m-1 rounded bg-white/50 py-0.5 dark:bg-gray-900/50">
|
||||||
|
{c.folder ? (
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
title="Copy folder permalink"
|
||||||
|
className="cursor-pointer rounded px-1.5 py-1 hover:bg-gray-300 dark:hover:bg-gray-600"
|
||||||
|
onClick={() => {
|
||||||
|
clipboard.copy(`${getBaseUrl()}${path === '/' ? '' : path}/${encodeURIComponent(c.name)}`)
|
||||||
|
toast('Copied folder permalink.', { icon: '👌' })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={['far', 'copy']} />
|
||||||
|
</span>
|
||||||
|
{folderGenerating[c.id] ? (
|
||||||
|
<Downloading title="Downloading folder, refresh page to cancel" />
|
||||||
|
) : (
|
||||||
|
<span
|
||||||
|
title="Download folder"
|
||||||
|
className="cursor-pointer rounded px-1.5 py-1 hover:bg-gray-300 dark:hover:bg-gray-600"
|
||||||
|
onClick={() => {
|
||||||
|
const p = `${path === '/' ? '' : path}/${encodeURIComponent(c.name)}`
|
||||||
|
handleFolderDownload(p, c.id, c.name)()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={['far', 'arrow-alt-circle-down']} />
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
title="Copy raw file permalink"
|
||||||
|
className="cursor-pointer rounded px-1.5 py-1 hover:bg-gray-300 dark:hover:bg-gray-600"
|
||||||
|
onClick={() => {
|
||||||
|
clipboard.copy(
|
||||||
|
`${getBaseUrl()}/api?path=${path === '/' ? '' : path}/${encodeURIComponent(c.name)}&raw=true`
|
||||||
|
)
|
||||||
|
toast.success('Copied raw file permalink.')
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={['far', 'copy']} />
|
||||||
|
</span>
|
||||||
|
<a
|
||||||
|
title="Download file"
|
||||||
|
className="cursor-pointer rounded px-1.5 py-1 hover:bg-gray-300 dark:hover:bg-gray-600"
|
||||||
|
href={c['@microsoft.graph.downloadUrl']}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={['far', 'arrow-alt-circle-down']} />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="absolute top-0 left-0 z-10 m-1 rounded bg-white/50 py-0.5 dark:bg-gray-900/50">
|
||||||
|
{!c.folder && !(c.name === '.password') && (
|
||||||
|
<Checkbox
|
||||||
|
checked={selected[c.id] ? 2 : 0}
|
||||||
|
onChange={() => toggleItemSelected(c.id)}
|
||||||
|
title="Select file"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<GridItem c={c} />
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export const SwitchLayout = () => {
|
|||||||
</Listbox.Button>
|
</Listbox.Button>
|
||||||
|
|
||||||
<Transition as={Fragment} leave="transition ease-in duration-100" leaveFrom="opacity-100" leaveTo="opacity-0">
|
<Transition as={Fragment} leave="transition ease-in duration-100" leaveFrom="opacity-100" leaveTo="opacity-0">
|
||||||
<Listbox.Options className="absolute mt-1 w-36 overflow-auto rounded border border-gray-900/10 bg-white py-1 shadow-lg focus:outline-none dark:border-gray-500/30 dark:bg-gray-800">
|
<Listbox.Options className="absolute z-20 mt-1 w-36 overflow-auto rounded border border-gray-900/10 bg-white py-1 shadow-lg focus:outline-none dark:border-gray-500/30 dark:bg-gray-800">
|
||||||
{layouts.map(layout => (
|
{layouts.map(layout => (
|
||||||
<Listbox.Option
|
<Listbox.Option
|
||||||
key={layout.id}
|
key={layout.id}
|
||||||
|
|||||||
Reference in New Issue
Block a user